-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathuseOl.ts
104 lines (93 loc) · 3.22 KB
/
useOl.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import { type Ref, type ShallowRef, computed, readonly, ref, shallowRef } from 'vue'
import Map from 'ol/Map'
import View from 'ol/View'
import type { Coordinate } from 'ol/coordinate'
import { createEventHook } from '@vueuse/shared'
import type { MapBrowserEvent } from 'ol'
import type { Extent } from 'ol/extent'
import BaseLayer from 'ol/layer/Base'
// global state, created in module scope
const map: ShallowRef<Map> = shallowRef(new Map({ view: new View({ center: [0, 0], zoom: 1 }) }))
const layers: Ref<BaseLayer[]> = ref([])
const center: Ref<Coordinate | undefined> = ref()
const extent: Ref<Extent | undefined> = ref()
const resolution: Ref<number | undefined> = ref()
const zoom: Ref<number | undefined> = ref()
const pointerCoordinate: Ref<Coordinate> = ref([])
const pointerPixel: Ref<Coordinate> = ref([])
const mapLoading = ref(false)
const mapMoving = ref(false)
const zoomRounded = computed(() => (zoom.value ? Math.round(zoom.value) : undefined))
const { on: onMapClick, trigger: triggerMapClick } =
createEventHook<MapBrowserEvent<PointerEvent>>()
const { on: onMapSingleClick, trigger: triggerMapSingleClick } =
createEventHook<MapBrowserEvent<PointerEvent>>()
map.value.getLayers().on('change:length', (event) => {
layers.value = event.target.getArray()
})
// TODO: remove listener on unmount
map.value.on('click', triggerMapClick)
map.value.on('singleclick', triggerMapSingleClick)
map.value.on('pointermove', (event) => {
pointerCoordinate.value = event.coordinate
pointerPixel.value = event.pixel
})
map.value.on('loadstart', () => {
mapLoading.value = true
})
map.value.on('loadend', () => {
mapLoading.value = false
})
map.value.on('movestart', () => {
mapMoving.value = true
})
map.value.on('moveend', () => {
mapMoving.value = false
})
const view = map.value.getView()
const syncMapProperties = () => {
center.value = view?.getCenter()
resolution.value = view?.getResolution()
zoom.value = view?.getZoom()
extent.value = view?.calculateExtent()
}
// TODO: when view is changed externally, the listeners are gone
view.on(['change', 'change:center', 'change:resolution'], () => {
syncMapProperties()
})
map.value.on('change:size', () => {
syncMapProperties()
})
syncMapProperties()
/**
* A hook that returns an object with various properties and functions related to the OpenLayers map.
* @returns The object
*/
export function useOl() {
return {
/** Hook executed on map click */
onMapClick,
/** Hook executed on single map click */
onMapSingleClick,
/** The OpenLayers map instance */
map: computed(() => map.value),
/** The layers registered on the map */
layers: computed(() => layers.value),
/** The center of the map */
center: readonly(center),
/** The extent of the map */
extent: readonly(extent),
/** If map is currently loading */
mapLoading: readonly(mapLoading),
/** If map is currently moving */
mapMoving: readonly(mapMoving),
/** The zoom of the map */
zoom: readonly(zoom),
/** The rounded zoom of the map */
zoomRounded,
/** The coordinate of the pointer (mouse cursor) */
pointerCoordinate: readonly(pointerCoordinate),
/** The pixel of the point (mouse cursor) */
pointerPixel: readonly(pointerPixel)
}
}