-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
171 lines (151 loc) · 4.54 KB
/
index.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
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// This is an example of loading a beryl gbfs data onto a mapbox map.
// you'll need a mapbox accessToken.
// https://docs.mapbox.com/help/glossary/access-token/
mapboxgl.accessToken = `<YOUR_MAPBOX_TOKEN>`;
const map = new mapboxgl.Map({
container: "map",
style: "mapbox://styles/mapbox/streets-v11",
center: [-1.849634547032906, 52.5473807294093],
zoom: 10,
});
map.scrollZoom.disable();
map.addControl(new mapboxgl.NavigationControl());
map.on("load", async () => {
const stationsUrl =
"https://gbfs.beryl.cc/v2/West_Midlands/station_information.json";
const regionsUrl =
"https://gbfs.beryl.cc/v2/West_Midlands/geofencing_zones.json";
// Get some data from beryls gbfs feed.
const [responseBounderies, responseStations] = await Promise.all([
fetch(regionsUrl).then((res) => res.json()),
fetch(stationsUrl).then((res) => res.json()),
]);
// this stores <description>: [lat, long]
// so that look ups via the <button> eventListner
// are simple.
const geoJSONCache = {}
const regionsGeoJson =
responseBounderies.data.geofencing_zones.features.reduce(
(acc, feature) => {
feature.properties.description =
feature.properties.name + " region";
acc.features.push(feature);
const coordinates = feature.geometry.coordinates[0][0][0].slice(0, 2);
geoJSONCache[feature.properties.description] = coordinates;
return acc;
},
{
type: "FeatureCollection",
features: [],
}
);
const stationsGeoJson = responseStations.data.stations.sort((a, b) => {
// This ensures the tab order from top-to-bottom.
if (a.lat < b.lat) {
return 1
} else if (a.lat > b.lat) {
return -1
} else {
return 0
}
}).reduce(
(acc, station, index) => {
// build station geojson from station response.
const feature = {
type: "Feature",
properties: {
id: station.id,
name: station.name,
capacity: station.capacity,
description: station.name + " station",
tabindex: index,
},
geometry: {
type: "Point",
coordinates: [station.lon, station.lat],
},
};
acc.features.push(feature);
const coordinates = feature.geometry.coordinates;
geoJSONCache[feature.properties.description] = coordinates;
return acc;
},
{
type: "FeatureCollection",
features: [],
}
);
map.addLayer({
id: "stations",
type: "symbol",
source: {
type: "geojson",
data: stationsGeoJson,
},
layout: {
"icon-image": "bicycle-share",
},
});
map.addLayer({
id: "regions",
type: "line",
source: {
type: "geojson",
data: regionsGeoJson,
},
layout: {},
paint: {
"line-color": "#fb406f",
"line-width": 3,
},
});
map.addControl(
new MapboxAccessibility({
// A string value representing a property key in the data. This
// will be used as the text in voiceover.
accessibleLabelProperty: "description",
// The layers within the style that
// 1. Contain the `accessibleLabelProperty` value as a key
// 2. Should be used for voiceover.
layers: ["stations", "regions"],
})
);
const eventHandler = (e) => {
const description = e.target.ariaLabel;
const coordinates = geoJSONCache[description]
const popup = new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(description)
.addTo(map);
popup.on('close', () => {
// Focus back on the feature that opened the popup.
e.target.focus()
})
};
const container = map.getContainer()
// click load the popup.
container.addEventListener("click", (e) => {
// Note there is a easier way to do this
// via the map.on('click') api however
// this is simpler way to share behaviour with keydown.
// something mapbox events don't support.
if (
e.target.className === "mapboxgl-accessibility-marker"
) {
e.preventDefault();
eventHandler(e)
}
});
// give keyboard user the same behaviour as mouse.
container.addEventListener("keydown", (e) => {
if (
e.which === 13 &&
e.target.className === "mapboxgl-accessibility-marker"
) {
e.preventDefault();
eventHandler(e)
}
});
const mapDescription = document.createTextNode(`The map displays the ${regionsGeoJson.features.length} regions and ${stationsGeoJson.features.length} stations of Beryl bike share scheme in West Midlands.`);
container.appendChild(mapDescription);
});