-
Notifications
You must be signed in to change notification settings - Fork 3
/
use-map.js
61 lines (53 loc) · 1.61 KB
/
use-map.js
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
import lonlat from '@conveyal/lonlat'
import mapboxgl from 'mapbox-gl'
import React from 'react'
import {POI_ID} from '../constants'
// Default NavigationControl
const navControl = new mapboxgl.NavigationControl({showCompass: false})
export default function useMap(mapProps, events, setMap) {
const ref = React.useRef(null)
// Runs on mount
React.useEffect(() => {
let accessToken = mapProps.accessToken || process.env.MAPBOX_ACCESS_TOKEN
if (!accessToken) {
const accessToken = window.prompt('Enter a Mapbox access token')
mapProps.updateMap({accessToken})
}
mapboxgl.accessToken = accessToken
// Create map
const m = (window.map = new mapboxgl.Map({
center: mapProps.center,
container: ref.current,
maxBounds: mapProps.maxBounds,
minZoom: mapProps.minZoom,
style: mapProps.style,
zoom: mapProps.zoom
}))
m.on('load', () => {
setMap(m)
m.addControl(navControl, 'top-right')
})
m.on('click', e => {
const bbox = [
[e.point.x - 5, e.point.y - 5],
[e.point.x + 5, e.point.y + 5]
]
const pois = m.queryRenderedFeatures(bbox, {layers: [POI_ID]})
if (pois.length > 0) {
const poi = pois[0]
events.onClick({
label: poi.properties.label,
position: lonlat(poi.geometry.coordinates)
})
} else {
events.onClick({position: lonlat(e.lngLat)})
}
})
m.on('moveend', () => events.onMove(lonlat(m.getCenter())))
m.on('zoomend', () => events.onZoom(m.getZoom()))
return () => {
if (m) m.remove()
}
}, [ref])
return ref
}