-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathmap.tsx
153 lines (138 loc) · 4.41 KB
/
map.tsx
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
import React, { useEffect, useState } from "react";
import mapboxgl from "mapbox-gl";
import "./App.css";
import { mapOnLoad } from "./layers";
// @ts-ignore
import MapboxDirections from "@mapbox/mapbox-gl-directions/dist/mapbox-gl-directions";
import "@mapbox/mapbox-gl-directions/dist/mapbox-gl-directions.css";
import MapboxGeocoder from "@mapbox/mapbox-gl-geocoder";
import "@mapbox/mapbox-gl-geocoder/dist/mapbox-gl-geocoder.css";
import { debouncedFetchAndDrawMarkers } from "./api";
import { LoadingStatusType } from "./interfaces";
const MAPBOX_TOKEN =
"pk.eyJ1IjoiamFrZWMiLCJhIjoiY2tkaHplNGhjMDAyMDJybW4ybmRqbTBmMyJ9.AR_fnEuka8-cFb4Snp3upw";
const min_overpass_turbo_zoom = 15;
/** Also the min zoom of the vector tileserver */
// const max_overpass_turbo_zoom = 15;
mapboxgl.accessToken = MAPBOX_TOKEN;
export function Map() {
const mapContainer = React.useRef<HTMLDivElement>(null);
const mapRef = React.useRef<mapboxgl.Map | null>(null);
const markers = React.useRef<mapboxgl.Marker[]>([]);
const [loadingStatus, setLoadingStatus] =
useState<LoadingStatusType>("ready_to_load");
const [lng, setLng] = useState(151.2160755932166);
const [lat, setLat] = useState(-33.88056647217827);
const [zoom, setZoom] = useState(17.504322191852786);
useEffect(() => {
// This is called on every pan
if (mapContainer.current === null) {
return;
}
if (mapRef.current !== null) {
return;
}
mapRef.current = new mapboxgl.Map({
container: mapContainer.current,
center: [lng, lat],
zoom: zoom,
hash: true,
style: "mapbox://styles/mapbox/dark-v11",
});
const map = mapRef.current;
map.on("load", mapOnLoad(map));
map.addControl(new mapboxgl.NavigationControl());
map.addControl(new mapboxgl.FullscreenControl());
map.addControl(
new MapboxGeocoder({
accessToken: mapboxgl.accessToken,
mapboxgl: mapboxgl,
}),
"top-left"
);
// map.addControl(
// new MapboxDirections({
// accessToken: mapboxgl.accessToken,
// }),
// "top-left"
// );
map.addControl(
new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true,
},
trackUserLocation: true,
})
);
map.on("move", () => {
if (!map) {
return; // wait for map to initialize
}
const { lng, lat } = map.getCenter();
const zoom = map.getZoom();
if (zoom < min_overpass_turbo_zoom) {
setLoadingStatus("too_zoomed_out");
} else {
setLoadingStatus("ready_to_load");
}
console.log(lng, lat, zoom);
setLng(map.getCenter().lng);
setLat(map.getCenter().lat);
setZoom(map.getZoom());
});
if (map.getZoom() < min_overpass_turbo_zoom) {
setLoadingStatus("too_zoomed_out");
} else {
console.log(`zoom is ${map.getZoom()}`);
debouncedFetchAndDrawMarkers(map, markers, setLoadingStatus);
}
map.on("moveend", async () => {
if (map === null) {
return;
}
const zoom = map.getZoom();
if (zoom > min_overpass_turbo_zoom) {
console.log(`zoom is ${zoom}`);
debouncedFetchAndDrawMarkers(map, markers, setLoadingStatus);
}
});
});
const statusMessages = {
loading: "Loading safety ratings...",
success: "Done loading safety ratings",
ready_to_load: "About to load ratings...",
too_zoomed_out: "Zoom in to see street safety ratings",
unknownerror: "Error loading. Please wait a bit",
"429error": "Too many requests, please try in a bit",
};
const statusText = statusMessages[loadingStatus];
return (
<div>
<div className="sidebar">
<label>
<span color="red">Warning:</span> Data is open source and not guaranteed to be
accurate.
<br></br>
<a
target="_blank"
rel="noopener noreferrer"
href="https://github.com/jakecoppinger/safe-cycling-map/blob/main/docs/key.md"
>
View map key and how safety is calculated
</a>
<br></br>
<a
target="_blank"
rel="noopener noreferrer"
href="https://github.com/jakecoppinger/safe-cycling-map"
>
About this map
</a>
<br></br>
{statusText}
</label>
</div>
<div ref={mapContainer} className="map-container" />
</div>
);
}