@geops/rvf-mobility-web-component 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.vscode/settings.json +2 -0
- package/CHANGELOG.md +17 -0
- package/docutils.js +1 -1
- package/index.html +1 -1
- package/index.js +119 -107
- package/package.json +1 -1
- package/src/NotificationLayer/NotificationLayer.tsx +2 -2
- package/src/RouteIcon/RouteIcon.tsx +21 -12
- package/src/RvfExportMenu/RvfExportMenu.tsx +2 -0
- package/src/RvfFeatureDetails/RVFSellingPointDetails/RVFSellingPointDetails.tsx +47 -0
- package/src/RvfFeatureDetails/RVFSellingPointDetails/index.js +1 -0
- package/src/RvfFeatureDetails/RvfFeatureDetails.tsx +4 -1
- package/src/RvfLineNetworkPlanLayer/RvfLineNetworkPlanLayer.tsx +4 -1
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +55 -12
- package/src/RvfSelectedFeatureHighlightLayer/RvfSelectedFeatureHighlightLayer.tsx +58 -32
- package/src/RvfSharedMobilityLayerGroup/RvfSharedMobilityLayerGroup.tsx +364 -123
- package/src/StationsLayer/StationsLayer.tsx +1 -1
- package/src/icons/NoRealtime/NoRealtime.tsx +44 -0
- package/src/icons/NoRealtime/index.tsx +1 -0
- package/src/icons/NoRealtime/norealtime.svg +6 -0
- package/src/utils/constants.ts +22 -1
- package/src/utils/exportPdf.ts +3 -3
- package/src/utils/fullTrajectoryStyle.ts +0 -1
- package/src/utils/getMainColorForVehicle.test.ts +21 -23
- package/src/utils/getRadius.ts +25 -24
- package/src/utils/hooks/useUpdatePermalink.tsx +5 -0
- package/src/utils/realtimeRVFStyle.ts +70 -8
- package/src/utils/sharingStylesUtils.ts +5 -5
- package/src/utils/sharingWFSUtils.ts +46 -16
- package/src/RvfSharedMobilityLayerGroup2/RvfSharedMobilityLayerGroup2.tsx +0 -740
- package/src/RvfSharedMobilityLayerGroup2/index.tsx +0 -1
|
@@ -1,740 +0,0 @@
|
|
|
1
|
-
import type { Options } from "ol/layer/Group";
|
|
2
|
-
|
|
3
|
-
import { FeatureCollection, Point } from "geojson";
|
|
4
|
-
import { GeoJSONSource } from "maplibre-gl";
|
|
5
|
-
import { MaplibreStyleLayer } from "mobility-toolbox-js/ol";
|
|
6
|
-
import { Extent } from "ol/extent";
|
|
7
|
-
import { Group } from "ol/layer";
|
|
8
|
-
import { unByKey } from "ol/Observable";
|
|
9
|
-
import { transformExtent } from "ol/proj";
|
|
10
|
-
import { memo } from "preact/compat";
|
|
11
|
-
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
|
|
12
|
-
|
|
13
|
-
import Bicycle from "../icons/Bike";
|
|
14
|
-
import Car from "../icons/Car";
|
|
15
|
-
import CargoBike from "../icons/CargoBike";
|
|
16
|
-
import Ride from "../icons/Ride";
|
|
17
|
-
import Scooter from "../icons/Scooter";
|
|
18
|
-
import {
|
|
19
|
-
BIKE_FORM_FACTOR,
|
|
20
|
-
BIKE_OTHERS_FEED_IDS,
|
|
21
|
-
CAR_FORM_FACTOR,
|
|
22
|
-
CAR_OTHERS_FEED_IDS,
|
|
23
|
-
CARGOBIKE_FORM_FACTOR,
|
|
24
|
-
CARGOBIKE_FRELO_ID,
|
|
25
|
-
CARGOBIKE_OTHERS_FEED_IDS,
|
|
26
|
-
FRELO_FEED_ID,
|
|
27
|
-
GRUNFLOTTE_FEED_ID,
|
|
28
|
-
NATURENERGIE_FEED_ID,
|
|
29
|
-
RVF_LAYERS_NAMES,
|
|
30
|
-
RVF_LAYERS_TITLES,
|
|
31
|
-
SCOOTER_FORM_FACTOR,
|
|
32
|
-
} from "../utils/constants";
|
|
33
|
-
import useMapContext from "../utils/hooks/useMapContext";
|
|
34
|
-
import useRvfContext from "../utils/hooks/useRvfContext";
|
|
35
|
-
import {
|
|
36
|
-
getSharingClusterStyleLayers,
|
|
37
|
-
getSharingStyleLayers,
|
|
38
|
-
} from "../utils/sharingStylesUtils";
|
|
39
|
-
import {
|
|
40
|
-
fetchSharingWFS,
|
|
41
|
-
SharingStationWFS,
|
|
42
|
-
SharingVehicleWFS,
|
|
43
|
-
} from "../utils/sharingWFSUtils";
|
|
44
|
-
|
|
45
|
-
const BIKE_FRELO_SOURCE_ID = "bikeFrelo";
|
|
46
|
-
const BIKE_OTHERS_SOURCE_ID = "bikeOthers";
|
|
47
|
-
const CARGOBIKE_FRELO_SOURCE_ID = "cargobikeFrelo";
|
|
48
|
-
const CARGOBIKE_OTHERS_SOURCE_ID = "cargobikeOthers";
|
|
49
|
-
const CAR_GRF_SOURCE_ID = "carGrf";
|
|
50
|
-
const CAR_NATUR_SOURCE_ID = "carNature";
|
|
51
|
-
const CAR_OTHERS_SOURCE_ID = "carOthers";
|
|
52
|
-
const SCOOTER_SOURCE_ID = "scooter";
|
|
53
|
-
// const HITCHHIKING_SOURCE_ID = "hitchhiking";
|
|
54
|
-
|
|
55
|
-
export type GroupOptions = Options & Record<string, unknown>;
|
|
56
|
-
|
|
57
|
-
const fetchStations = async (
|
|
58
|
-
typeName: string,
|
|
59
|
-
feedIds: string[],
|
|
60
|
-
abortController: AbortController,
|
|
61
|
-
) => {
|
|
62
|
-
const stations = (await fetchSharingWFS(
|
|
63
|
-
typeName,
|
|
64
|
-
abortController,
|
|
65
|
-
)) as FeatureCollection<Point, SharingStationWFS>;
|
|
66
|
-
|
|
67
|
-
const featureCollection = {
|
|
68
|
-
features: stations.features.filter((feature) => {
|
|
69
|
-
return feedIds ? feedIds.includes(feature.properties.feed_id) : true;
|
|
70
|
-
}),
|
|
71
|
-
type: "FeatureCollection",
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
return featureCollection as FeatureCollection<Point, SharingStationWFS>;
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
const fetchVehicles = async (
|
|
78
|
-
formFactor: string,
|
|
79
|
-
feedIds: string[],
|
|
80
|
-
extent4326: Extent,
|
|
81
|
-
abortController: AbortController,
|
|
82
|
-
) => {
|
|
83
|
-
const freeFloat = (await fetchSharingWFS(
|
|
84
|
-
"sharing_vehicles",
|
|
85
|
-
abortController,
|
|
86
|
-
extent4326,
|
|
87
|
-
)) as FeatureCollection<Point, SharingVehicleWFS>;
|
|
88
|
-
|
|
89
|
-
const featureCollection = {
|
|
90
|
-
features: freeFloat.features.filter((feature) => {
|
|
91
|
-
return (
|
|
92
|
-
(feedIds ? feedIds.includes(feature.properties.feed_id) : true) &&
|
|
93
|
-
feature.properties.form_factor === formFactor
|
|
94
|
-
);
|
|
95
|
-
}),
|
|
96
|
-
type: "FeatureCollection",
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
return featureCollection as FeatureCollection<Point, SharingVehicleWFS>;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
let cacheStations = new Map<
|
|
103
|
-
string,
|
|
104
|
-
FeatureCollection<Point, SharingStationWFS>
|
|
105
|
-
>();
|
|
106
|
-
|
|
107
|
-
const fetchLayerData = async (
|
|
108
|
-
typeName: string,
|
|
109
|
-
formFactor: string,
|
|
110
|
-
feedIds: string[],
|
|
111
|
-
extent: Extent,
|
|
112
|
-
abortController: AbortController,
|
|
113
|
-
) => {
|
|
114
|
-
const cacheKey = typeName + feedIds?.toString();
|
|
115
|
-
const stations =
|
|
116
|
-
cacheStations[cacheKey] ||
|
|
117
|
-
(await fetchStations(typeName, feedIds, abortController));
|
|
118
|
-
const freeFloat = await fetchVehicles(
|
|
119
|
-
formFactor,
|
|
120
|
-
feedIds,
|
|
121
|
-
extent,
|
|
122
|
-
abortController,
|
|
123
|
-
);
|
|
124
|
-
|
|
125
|
-
if (!cacheStations[cacheKey]) {
|
|
126
|
-
cacheStations[cacheKey] = stations;
|
|
127
|
-
}
|
|
128
|
-
return {
|
|
129
|
-
features: [...stations.features, ...freeFloat.features],
|
|
130
|
-
type: "FeatureCollection",
|
|
131
|
-
} as FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>;
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
function RvfSharedMobilityLayerGroup2(props: GroupOptions) {
|
|
135
|
-
const { baseLayer, map } = useMapContext();
|
|
136
|
-
const { setSharedMobilityLayerGroup } = useRvfContext();
|
|
137
|
-
|
|
138
|
-
// Layers
|
|
139
|
-
const [bikeFreloLayer, setBikeFreloLayer] = useState<MaplibreStyleLayer>();
|
|
140
|
-
const [bikeOthersLayer, setBikeOthersLayer] = useState<MaplibreStyleLayer>();
|
|
141
|
-
const [cargobikeFreloLayer, setCargobikeFreloLayer] =
|
|
142
|
-
useState<MaplibreStyleLayer>();
|
|
143
|
-
const [cargobikeOthersLayer, setCargobikeOthersLayer] =
|
|
144
|
-
useState<MaplibreStyleLayer>();
|
|
145
|
-
const [carGrfLayer, setCarGrfLayer] = useState<MaplibreStyleLayer>();
|
|
146
|
-
const [carNaturLayer, setCarNaturLayer] = useState<MaplibreStyleLayer>();
|
|
147
|
-
const [carOthersLayer, setCarOthersLayer] = useState<MaplibreStyleLayer>();
|
|
148
|
-
const [scooterLayer, setScooterLayer] = useState<MaplibreStyleLayer>();
|
|
149
|
-
|
|
150
|
-
// GeoJSON data
|
|
151
|
-
const [bikeFreloData, setBikeFreloData] =
|
|
152
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
153
|
-
const [bikeOthersData, setBikeOthersData] =
|
|
154
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
155
|
-
const [cargobikeFreloData, setCargobikeFreloData] =
|
|
156
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
157
|
-
const [cargobikeOthersData, setCargobikeOthersData] =
|
|
158
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
159
|
-
const [carGrfData, setCarGrfData] =
|
|
160
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
161
|
-
const [carNaturData, setCarNaturData] =
|
|
162
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
163
|
-
const [carOthersData, setCarOthersData] =
|
|
164
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
165
|
-
const [scooterData, setScooterData] =
|
|
166
|
-
useState<FeatureCollection<Point, SharingStationWFS | SharingVehicleWFS>>();
|
|
167
|
-
|
|
168
|
-
const updateData = useCallback(() => {
|
|
169
|
-
const abortController = new AbortController();
|
|
170
|
-
const extent = transformExtent(
|
|
171
|
-
map.getView().calculateExtent(),
|
|
172
|
-
"EPSG:3857",
|
|
173
|
-
"EPSG:4326",
|
|
174
|
-
);
|
|
175
|
-
|
|
176
|
-
const fetchData = async () => {
|
|
177
|
-
const bikeFreloData = await fetchLayerData(
|
|
178
|
-
"sharing_stations_bicycle",
|
|
179
|
-
BIKE_FORM_FACTOR,
|
|
180
|
-
[FRELO_FEED_ID],
|
|
181
|
-
extent,
|
|
182
|
-
abortController,
|
|
183
|
-
);
|
|
184
|
-
setBikeFreloData(bikeFreloData);
|
|
185
|
-
const bikeOthersData = await fetchLayerData(
|
|
186
|
-
"sharing_stations_bicycle",
|
|
187
|
-
BIKE_FORM_FACTOR,
|
|
188
|
-
BIKE_OTHERS_FEED_IDS,
|
|
189
|
-
extent,
|
|
190
|
-
abortController,
|
|
191
|
-
);
|
|
192
|
-
setBikeOthersData(bikeOthersData);
|
|
193
|
-
|
|
194
|
-
const cargobikeFreloData = await fetchLayerData(
|
|
195
|
-
"sharing_stations_cargo_bicycle",
|
|
196
|
-
CARGOBIKE_FORM_FACTOR,
|
|
197
|
-
[CARGOBIKE_FRELO_ID],
|
|
198
|
-
extent,
|
|
199
|
-
abortController,
|
|
200
|
-
);
|
|
201
|
-
setCargobikeFreloData(cargobikeFreloData);
|
|
202
|
-
|
|
203
|
-
const cargobikeOthersData = await fetchLayerData(
|
|
204
|
-
"sharing_stations_cargo_bicycle",
|
|
205
|
-
CARGOBIKE_FORM_FACTOR,
|
|
206
|
-
CARGOBIKE_OTHERS_FEED_IDS,
|
|
207
|
-
extent,
|
|
208
|
-
abortController,
|
|
209
|
-
);
|
|
210
|
-
setCargobikeOthersData(cargobikeOthersData);
|
|
211
|
-
|
|
212
|
-
const carGrfData = await fetchLayerData(
|
|
213
|
-
"sharing_stations_car",
|
|
214
|
-
CAR_FORM_FACTOR,
|
|
215
|
-
[GRUNFLOTTE_FEED_ID],
|
|
216
|
-
extent,
|
|
217
|
-
abortController,
|
|
218
|
-
);
|
|
219
|
-
setCarGrfData(carGrfData);
|
|
220
|
-
|
|
221
|
-
const carNaturData = await fetchLayerData(
|
|
222
|
-
"sharing_stations_car",
|
|
223
|
-
CAR_FORM_FACTOR,
|
|
224
|
-
[NATURENERGIE_FEED_ID],
|
|
225
|
-
extent,
|
|
226
|
-
abortController,
|
|
227
|
-
);
|
|
228
|
-
setCarNaturData(carNaturData);
|
|
229
|
-
|
|
230
|
-
const carOthers = await fetchLayerData(
|
|
231
|
-
"sharing_stations_car",
|
|
232
|
-
CAR_FORM_FACTOR,
|
|
233
|
-
CAR_OTHERS_FEED_IDS,
|
|
234
|
-
extent,
|
|
235
|
-
abortController,
|
|
236
|
-
);
|
|
237
|
-
setCarOthersData(carOthers);
|
|
238
|
-
|
|
239
|
-
const scooterData = await fetchLayerData(
|
|
240
|
-
"sharing_stations_scooters_standing",
|
|
241
|
-
SCOOTER_FORM_FACTOR,
|
|
242
|
-
null,
|
|
243
|
-
extent,
|
|
244
|
-
abortController,
|
|
245
|
-
);
|
|
246
|
-
setScooterData(scooterData);
|
|
247
|
-
};
|
|
248
|
-
|
|
249
|
-
fetchData();
|
|
250
|
-
|
|
251
|
-
return () => {
|
|
252
|
-
abortController.abort();
|
|
253
|
-
};
|
|
254
|
-
}, [map]);
|
|
255
|
-
|
|
256
|
-
// Request all stations and vehicleson each moveend event
|
|
257
|
-
useEffect(() => {
|
|
258
|
-
const key = map?.on("moveend", updateData);
|
|
259
|
-
const key2 = map?.once("rendercomplete", updateData);
|
|
260
|
-
return () => {
|
|
261
|
-
unByKey(key);
|
|
262
|
-
unByKey(key2);
|
|
263
|
-
};
|
|
264
|
-
}, [map, updateData]);
|
|
265
|
-
|
|
266
|
-
useEffect(() => {
|
|
267
|
-
const mbMap = bikeFreloLayer?.maplibreLayer?.mapLibreMap;
|
|
268
|
-
if (!mbMap || !bikeFreloData) {
|
|
269
|
-
return;
|
|
270
|
-
}
|
|
271
|
-
const source = mbMap.getSource(BIKE_FRELO_SOURCE_ID);
|
|
272
|
-
(source as GeoJSONSource)?.setData(bikeFreloData);
|
|
273
|
-
}, [bikeFreloData, bikeFreloLayer?.maplibreLayer?.mapLibreMap]);
|
|
274
|
-
|
|
275
|
-
useEffect(() => {
|
|
276
|
-
const mbMap = bikeOthersLayer?.maplibreLayer?.mapLibreMap;
|
|
277
|
-
if (!mbMap || !bikeOthersData) {
|
|
278
|
-
return;
|
|
279
|
-
}
|
|
280
|
-
const source = mbMap.getSource(BIKE_OTHERS_SOURCE_ID);
|
|
281
|
-
(source as GeoJSONSource)?.setData(bikeOthersData);
|
|
282
|
-
}, [bikeOthersData, bikeOthersLayer?.maplibreLayer?.mapLibreMap]);
|
|
283
|
-
|
|
284
|
-
useEffect(() => {
|
|
285
|
-
const mbMap = cargobikeFreloLayer?.maplibreLayer?.mapLibreMap;
|
|
286
|
-
if (!mbMap || !cargobikeFreloData) {
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const source = mbMap.getSource(CARGOBIKE_FRELO_SOURCE_ID);
|
|
290
|
-
(source as GeoJSONSource)?.setData(cargobikeFreloData);
|
|
291
|
-
}, [cargobikeFreloData, cargobikeFreloLayer?.maplibreLayer?.mapLibreMap]);
|
|
292
|
-
|
|
293
|
-
useEffect(() => {
|
|
294
|
-
const mbMap = cargobikeOthersLayer?.maplibreLayer?.mapLibreMap;
|
|
295
|
-
if (!mbMap || !cargobikeOthersData) {
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
const source = mbMap.getSource(CARGOBIKE_OTHERS_SOURCE_ID);
|
|
299
|
-
(source as GeoJSONSource)?.setData(cargobikeOthersData);
|
|
300
|
-
}, [cargobikeOthersData, cargobikeOthersLayer?.maplibreLayer?.mapLibreMap]);
|
|
301
|
-
|
|
302
|
-
useEffect(() => {
|
|
303
|
-
const mbMap = carGrfLayer?.maplibreLayer?.mapLibreMap;
|
|
304
|
-
if (!mbMap || !carGrfData) {
|
|
305
|
-
return;
|
|
306
|
-
}
|
|
307
|
-
const source = mbMap.getSource(CAR_GRF_SOURCE_ID);
|
|
308
|
-
(source as GeoJSONSource)?.setData(carGrfData);
|
|
309
|
-
}, [carGrfData, carGrfLayer?.maplibreLayer?.mapLibreMap]);
|
|
310
|
-
useEffect(() => {
|
|
311
|
-
const mbMap = carNaturLayer?.maplibreLayer?.mapLibreMap;
|
|
312
|
-
if (!mbMap || !carNaturData) {
|
|
313
|
-
return;
|
|
314
|
-
}
|
|
315
|
-
const source = mbMap.getSource(CAR_NATUR_SOURCE_ID);
|
|
316
|
-
(source as GeoJSONSource)?.setData(carNaturData);
|
|
317
|
-
}, [carNaturData, carNaturLayer?.maplibreLayer?.mapLibreMap]);
|
|
318
|
-
|
|
319
|
-
useEffect(() => {
|
|
320
|
-
const mbMap = carOthersLayer?.maplibreLayer?.mapLibreMap;
|
|
321
|
-
if (!mbMap || !carOthersData) {
|
|
322
|
-
return;
|
|
323
|
-
}
|
|
324
|
-
const source = mbMap.getSource(CAR_OTHERS_SOURCE_ID);
|
|
325
|
-
(source as GeoJSONSource)?.setData(carOthersData);
|
|
326
|
-
}, [carOthersData, carOthersLayer?.maplibreLayer?.mapLibreMap]);
|
|
327
|
-
|
|
328
|
-
useEffect(() => {
|
|
329
|
-
const mbMap = scooterLayer?.maplibreLayer?.mapLibreMap;
|
|
330
|
-
if (!mbMap || !scooterData) {
|
|
331
|
-
return;
|
|
332
|
-
}
|
|
333
|
-
const source = mbMap.getSource(SCOOTER_SOURCE_ID);
|
|
334
|
-
(source as GeoJSONSource)?.setData(scooterData);
|
|
335
|
-
}, [scooterData, scooterLayer?.maplibreLayer?.mapLibreMap]);
|
|
336
|
-
|
|
337
|
-
const group = useMemo(() => {
|
|
338
|
-
if (!baseLayer) {
|
|
339
|
-
return null;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
const sharingBicycle = new Group({
|
|
343
|
-
layers: [
|
|
344
|
-
new MaplibreStyleLayer({
|
|
345
|
-
// isQueryable: true,
|
|
346
|
-
layersFilter: ({ metadata }) => {
|
|
347
|
-
return metadata?.["rvf.filter"] === "bike";
|
|
348
|
-
},
|
|
349
|
-
maplibreLayer: baseLayer,
|
|
350
|
-
maxZoom: 18,
|
|
351
|
-
visible: false,
|
|
352
|
-
}),
|
|
353
|
-
// createMobiDataBwWfsLayer(
|
|
354
|
-
// API_REQUEST_FEATURE_TYPE.stations.bike,
|
|
355
|
-
// "green",
|
|
356
|
-
// ),
|
|
357
|
-
// createFreeFloatMobilityLayer(
|
|
358
|
-
// API_REQUEST_FEATURE_TYPE.freeFloat.bike,
|
|
359
|
-
// "green",
|
|
360
|
-
// "bicycle",
|
|
361
|
-
// ),
|
|
362
|
-
],
|
|
363
|
-
name: RVF_LAYERS_NAMES.fahrrad,
|
|
364
|
-
// title: (
|
|
365
|
-
// <div className="flex items-center justify-between gap-2">
|
|
366
|
-
// {RVF_LAYERS_TITLES.fahrrad}
|
|
367
|
-
// <Bicycle />
|
|
368
|
-
// </div>
|
|
369
|
-
// ),
|
|
370
|
-
} as GroupOptions);
|
|
371
|
-
|
|
372
|
-
const sharingCar = new Group({
|
|
373
|
-
layers: [
|
|
374
|
-
new MaplibreStyleLayer({
|
|
375
|
-
// isQueryable: true,
|
|
376
|
-
layersFilter: ({ metadata }) => {
|
|
377
|
-
return metadata?.["rvf.filter"] === "car";
|
|
378
|
-
},
|
|
379
|
-
maplibreLayer: baseLayer,
|
|
380
|
-
maxZoom: 18,
|
|
381
|
-
visible: false,
|
|
382
|
-
}),
|
|
383
|
-
// createMobiDataBwWfsLayer(
|
|
384
|
-
// API_REQUEST_FEATURE_TYPE.stations.car,
|
|
385
|
-
// "green",
|
|
386
|
-
// ),
|
|
387
|
-
// createFreeFloatMobilityLayer(
|
|
388
|
-
// API_REQUEST_FEATURE_TYPE.freeFloat.car,
|
|
389
|
-
// "green",
|
|
390
|
-
// "car",
|
|
391
|
-
// ),
|
|
392
|
-
],
|
|
393
|
-
// name: RVF_LAYERS_NAMES.auto,
|
|
394
|
-
// title: (
|
|
395
|
-
// <div className="flex items-center justify-between gap-2">
|
|
396
|
-
// {RVF_LAYERS_TITLES.auto}
|
|
397
|
-
// <Car />
|
|
398
|
-
// </div>
|
|
399
|
-
// ),
|
|
400
|
-
} as GroupOptions);
|
|
401
|
-
|
|
402
|
-
const sharingCargoBicycle = new Group({
|
|
403
|
-
layers: [
|
|
404
|
-
new MaplibreStyleLayer({
|
|
405
|
-
// isQueryable: true,
|
|
406
|
-
layersFilter: ({ metadata }) => {
|
|
407
|
-
return metadata?.["rvf.filter"] === "cargo_bike";
|
|
408
|
-
},
|
|
409
|
-
maplibreLayer: baseLayer,
|
|
410
|
-
maxZoom: 18,
|
|
411
|
-
visible: false,
|
|
412
|
-
}),
|
|
413
|
-
// createMobiDataBwWfsLayer(
|
|
414
|
-
// API_REQUEST_FEATURE_TYPE.stations.cargoBike,
|
|
415
|
-
// "green",
|
|
416
|
-
// ),
|
|
417
|
-
// createFreeFloatMobilityLayer(
|
|
418
|
-
// API_REQUEST_FEATURE_TYPE.freeFloat.cargoBike,
|
|
419
|
-
// "green",
|
|
420
|
-
// "cargo_bicycle",
|
|
421
|
-
// ),
|
|
422
|
-
],
|
|
423
|
-
// name: RVF_LAYERS_NAMES.cargobike,
|
|
424
|
-
// title: (
|
|
425
|
-
// <div className="flex items-center justify-between gap-2">
|
|
426
|
-
// {RVF_LAYERS_TITLES.cargobike}
|
|
427
|
-
// <CargoBike />
|
|
428
|
-
// </div>
|
|
429
|
-
// ),
|
|
430
|
-
} as GroupOptions);
|
|
431
|
-
|
|
432
|
-
// const sharingScooter = new Group({
|
|
433
|
-
// layers: [
|
|
434
|
-
// No scooter station data available
|
|
435
|
-
// new MaplibreStyleLayer({
|
|
436
|
-
// isQueryable: true,
|
|
437
|
-
// layersFilter: ({ metadata }) => {
|
|
438
|
-
// return metadata?.["rvf.filter"] === "scooter";
|
|
439
|
-
// },
|
|
440
|
-
// maplibreLayer: baseLayer,
|
|
441
|
-
// }),
|
|
442
|
-
// https://www.mobidata-bw.de/dataset/escootch
|
|
443
|
-
// createMobiDataBwWfsLayer(
|
|
444
|
-
// API_REQUEST_FEATURE_TYPE.stations.scooter,
|
|
445
|
-
// "green",
|
|
446
|
-
// ),
|
|
447
|
-
// createFreeFloatMobilityLayer(
|
|
448
|
-
// API_REQUEST_FEATURE_TYPE.freeFloat.scooter,
|
|
449
|
-
// "green",
|
|
450
|
-
// "scooter",
|
|
451
|
-
// ),
|
|
452
|
-
// ],
|
|
453
|
-
// name: RVF_LAYERS_NAMES.eroller,
|
|
454
|
-
// title: (
|
|
455
|
-
// <div className="flex items-center justify-between gap-2">
|
|
456
|
-
// {RVF_LAYERS_TITLES.eroller}
|
|
457
|
-
// <Scooter />
|
|
458
|
-
// </div>
|
|
459
|
-
// ),
|
|
460
|
-
// } as GroupOptions);
|
|
461
|
-
|
|
462
|
-
const sharingHitchHiking = new MaplibreStyleLayer({
|
|
463
|
-
isQueryable: true,
|
|
464
|
-
layersFilter: ({ metadata }) => {
|
|
465
|
-
return metadata?.["rvf.filter"] === "hitchhiking";
|
|
466
|
-
},
|
|
467
|
-
maplibreLayer: baseLayer,
|
|
468
|
-
name: RVF_LAYERS_NAMES.mitfahrpunkte,
|
|
469
|
-
title: (
|
|
470
|
-
<div className="flex items-center justify-between gap-2">
|
|
471
|
-
{RVF_LAYERS_TITLES.mitfahrpunkte}
|
|
472
|
-
<Ride />
|
|
473
|
-
</div>
|
|
474
|
-
),
|
|
475
|
-
visible: false,
|
|
476
|
-
});
|
|
477
|
-
|
|
478
|
-
const bikeFrelo = new MaplibreStyleLayer({
|
|
479
|
-
isQueryable: true,
|
|
480
|
-
maplibreLayer: baseLayer,
|
|
481
|
-
name: RVF_LAYERS_NAMES.bikeFrelo,
|
|
482
|
-
sources: {
|
|
483
|
-
[BIKE_FRELO_SOURCE_ID]: {
|
|
484
|
-
data: { features: [], type: "FeatureCollection" },
|
|
485
|
-
// data: "https://api.mobidata-bw.de/geoserver/MobiData-BW/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=MobiData-BW%3Asharing_stations_bicycle&maxFeatures=20000&outputFormat=application/json",
|
|
486
|
-
promoteId: "id",
|
|
487
|
-
type: "geojson",
|
|
488
|
-
},
|
|
489
|
-
},
|
|
490
|
-
styleLayers: getSharingStyleLayers(BIKE_FRELO_SOURCE_ID),
|
|
491
|
-
|
|
492
|
-
title: (
|
|
493
|
-
<div className="flex items-center justify-between gap-2">
|
|
494
|
-
{"Frelo"}
|
|
495
|
-
<Bicycle />
|
|
496
|
-
</div>
|
|
497
|
-
),
|
|
498
|
-
});
|
|
499
|
-
setBikeFreloLayer(bikeFrelo);
|
|
500
|
-
|
|
501
|
-
const bikeOthers = new MaplibreStyleLayer({
|
|
502
|
-
isQueryable: true,
|
|
503
|
-
maplibreLayer: baseLayer,
|
|
504
|
-
name: RVF_LAYERS_NAMES.bikeOthers,
|
|
505
|
-
sources: {
|
|
506
|
-
[BIKE_OTHERS_SOURCE_ID]: {
|
|
507
|
-
data: { features: [], type: "FeatureCollection" },
|
|
508
|
-
promoteId: "id",
|
|
509
|
-
type: "geojson",
|
|
510
|
-
},
|
|
511
|
-
},
|
|
512
|
-
styleLayers: getSharingStyleLayers(BIKE_OTHERS_SOURCE_ID),
|
|
513
|
-
title: (
|
|
514
|
-
<div className="flex items-center justify-between gap-2">
|
|
515
|
-
{"Fahrrad, andere Anbieter"}
|
|
516
|
-
<Bicycle />
|
|
517
|
-
</div>
|
|
518
|
-
),
|
|
519
|
-
});
|
|
520
|
-
setBikeOthersLayer(bikeOthers);
|
|
521
|
-
|
|
522
|
-
const cargobikeFrelo = new MaplibreStyleLayer({
|
|
523
|
-
isQueryable: true,
|
|
524
|
-
maplibreLayer: baseLayer,
|
|
525
|
-
name: RVF_LAYERS_NAMES.cargobikeFrelo,
|
|
526
|
-
sources: {
|
|
527
|
-
[CARGOBIKE_FRELO_SOURCE_ID]: {
|
|
528
|
-
data: { features: [], type: "FeatureCollection" },
|
|
529
|
-
promoteId: "id",
|
|
530
|
-
type: "geojson",
|
|
531
|
-
},
|
|
532
|
-
},
|
|
533
|
-
styleLayers: getSharingStyleLayers(
|
|
534
|
-
CARGOBIKE_FRELO_SOURCE_ID,
|
|
535
|
-
"rvf_shared_cargo_bike",
|
|
536
|
-
),
|
|
537
|
-
title: (
|
|
538
|
-
<div className="flex items-center justify-between gap-2">
|
|
539
|
-
{"Lastenfrelo"}
|
|
540
|
-
<CargoBike />
|
|
541
|
-
</div>
|
|
542
|
-
),
|
|
543
|
-
});
|
|
544
|
-
setCargobikeFreloLayer(cargobikeFrelo);
|
|
545
|
-
|
|
546
|
-
const cargobikeOthers = new MaplibreStyleLayer({
|
|
547
|
-
isQueryable: true,
|
|
548
|
-
maplibreLayer: baseLayer,
|
|
549
|
-
name: RVF_LAYERS_NAMES.cargobikeOthers,
|
|
550
|
-
sources: {
|
|
551
|
-
[CARGOBIKE_OTHERS_SOURCE_ID]: {
|
|
552
|
-
data: { features: [], type: "FeatureCollection" },
|
|
553
|
-
promoteId: "id",
|
|
554
|
-
type: "geojson",
|
|
555
|
-
},
|
|
556
|
-
},
|
|
557
|
-
styleLayers: getSharingStyleLayers(
|
|
558
|
-
CARGOBIKE_OTHERS_SOURCE_ID,
|
|
559
|
-
"rvf_shared_cargo_bike",
|
|
560
|
-
),
|
|
561
|
-
title: (
|
|
562
|
-
<div className="flex items-center justify-between gap-2">
|
|
563
|
-
{"Lastenrad, andere Anbieter"}
|
|
564
|
-
<CargoBike />
|
|
565
|
-
</div>
|
|
566
|
-
),
|
|
567
|
-
});
|
|
568
|
-
setCargobikeOthersLayer(cargobikeOthers);
|
|
569
|
-
|
|
570
|
-
const carGrf = new MaplibreStyleLayer({
|
|
571
|
-
isQueryable: true,
|
|
572
|
-
maplibreLayer: baseLayer,
|
|
573
|
-
name: RVF_LAYERS_NAMES.carGrf,
|
|
574
|
-
sources: {
|
|
575
|
-
[CAR_GRF_SOURCE_ID]: {
|
|
576
|
-
data: { features: [], type: "FeatureCollection" },
|
|
577
|
-
promoteId: "id",
|
|
578
|
-
type: "geojson",
|
|
579
|
-
},
|
|
580
|
-
},
|
|
581
|
-
styleLayers: getSharingStyleLayers(CAR_GRF_SOURCE_ID, "rvf_shared_car"),
|
|
582
|
-
title: (
|
|
583
|
-
<div className="flex items-center justify-between gap-2">
|
|
584
|
-
{"Grüne Flotte"}
|
|
585
|
-
<Car />
|
|
586
|
-
</div>
|
|
587
|
-
),
|
|
588
|
-
});
|
|
589
|
-
setCarGrfLayer(carGrf);
|
|
590
|
-
|
|
591
|
-
const carNatur = new MaplibreStyleLayer({
|
|
592
|
-
isQueryable: true,
|
|
593
|
-
maplibreLayer: baseLayer,
|
|
594
|
-
name: RVF_LAYERS_NAMES.carNatur,
|
|
595
|
-
sources: {
|
|
596
|
-
[CAR_NATUR_SOURCE_ID]: {
|
|
597
|
-
data: { features: [], type: "FeatureCollection" },
|
|
598
|
-
promoteId: "id",
|
|
599
|
-
type: "geojson",
|
|
600
|
-
},
|
|
601
|
-
},
|
|
602
|
-
styleLayers: getSharingStyleLayers(CAR_NATUR_SOURCE_ID, "rvf_shared_car"),
|
|
603
|
-
title: (
|
|
604
|
-
<div className="flex items-center justify-between gap-2">
|
|
605
|
-
{"Naturenergie-Sharing"}
|
|
606
|
-
<Car />
|
|
607
|
-
</div>
|
|
608
|
-
),
|
|
609
|
-
});
|
|
610
|
-
setCarNaturLayer(carNatur);
|
|
611
|
-
|
|
612
|
-
const carOthers = new MaplibreStyleLayer({
|
|
613
|
-
isQueryable: true,
|
|
614
|
-
maplibreLayer: baseLayer,
|
|
615
|
-
name: RVF_LAYERS_NAMES.carOthers,
|
|
616
|
-
sources: {
|
|
617
|
-
[CAR_OTHERS_SOURCE_ID]: {
|
|
618
|
-
data: { features: [], type: "FeatureCollection" },
|
|
619
|
-
promoteId: "id",
|
|
620
|
-
type: "geojson",
|
|
621
|
-
},
|
|
622
|
-
},
|
|
623
|
-
styleLayers: getSharingStyleLayers(
|
|
624
|
-
CAR_OTHERS_SOURCE_ID,
|
|
625
|
-
"rvf_shared_car",
|
|
626
|
-
),
|
|
627
|
-
title: (
|
|
628
|
-
<div className="flex items-center justify-between gap-2">
|
|
629
|
-
{"Auto, andere Anbieter"}
|
|
630
|
-
<Car />
|
|
631
|
-
</div>
|
|
632
|
-
),
|
|
633
|
-
});
|
|
634
|
-
setCarOthersLayer(carOthers);
|
|
635
|
-
|
|
636
|
-
const scooter = new MaplibreStyleLayer({
|
|
637
|
-
isQueryable: true,
|
|
638
|
-
maplibreLayer: baseLayer,
|
|
639
|
-
name: RVF_LAYERS_NAMES.eroller,
|
|
640
|
-
sources: {
|
|
641
|
-
[SCOOTER_SOURCE_ID]: {
|
|
642
|
-
cluster: true,
|
|
643
|
-
clusterRadius: 40,
|
|
644
|
-
data: { features: [], type: "FeatureCollection" },
|
|
645
|
-
generateId: true,
|
|
646
|
-
maxzoom: 21,
|
|
647
|
-
type: "geojson",
|
|
648
|
-
},
|
|
649
|
-
},
|
|
650
|
-
styleLayers: getSharingClusterStyleLayers(
|
|
651
|
-
SCOOTER_SOURCE_ID,
|
|
652
|
-
"rvf_shared_scooter",
|
|
653
|
-
),
|
|
654
|
-
title: (
|
|
655
|
-
<div className="flex items-center justify-between gap-2">
|
|
656
|
-
{RVF_LAYERS_TITLES.eroller}
|
|
657
|
-
<Scooter />
|
|
658
|
-
</div>
|
|
659
|
-
),
|
|
660
|
-
});
|
|
661
|
-
setScooterLayer(scooter);
|
|
662
|
-
|
|
663
|
-
// const hitchhiking = new MaplibreStyleLayer({
|
|
664
|
-
// maplibreLayer: baseLayer,
|
|
665
|
-
// name: RVF_LAYERS_NAMES.mitfahrpunkte,
|
|
666
|
-
// sources: {
|
|
667
|
-
// [HITCHHIKING_SOURCE_ID]: {
|
|
668
|
-
// data: { features: [], type: "FeatureCollection" },
|
|
669
|
-
// type: "geojson",
|
|
670
|
-
// },
|
|
671
|
-
// },
|
|
672
|
-
// styleLayers: getStyleLayers(HITCHHIKING_SOURCE_ID, "rvf_shared_car"),
|
|
673
|
-
// title: "E-Roller",
|
|
674
|
-
// });
|
|
675
|
-
// setHitchhikingLayer(hitchhiking);
|
|
676
|
-
|
|
677
|
-
return new Group({
|
|
678
|
-
layers: [
|
|
679
|
-
sharingBicycle,
|
|
680
|
-
sharingCargoBicycle,
|
|
681
|
-
sharingCar,
|
|
682
|
-
bikeFrelo,
|
|
683
|
-
bikeOthers,
|
|
684
|
-
cargobikeFrelo,
|
|
685
|
-
cargobikeOthers,
|
|
686
|
-
carGrf,
|
|
687
|
-
carNatur,
|
|
688
|
-
carOthers,
|
|
689
|
-
scooter,
|
|
690
|
-
sharingHitchHiking,
|
|
691
|
-
// hitchhiking,
|
|
692
|
-
],
|
|
693
|
-
...props,
|
|
694
|
-
} as GroupOptions);
|
|
695
|
-
}, [baseLayer, props]);
|
|
696
|
-
|
|
697
|
-
// Reload features every minute
|
|
698
|
-
useEffect(() => {
|
|
699
|
-
const interval = window.setInterval(() => {
|
|
700
|
-
// group.getLayers().forEach((layer: Group) => {
|
|
701
|
-
// layer.getLayers?.().forEach((layer: MaplibreStyleLayer | Vector) => {
|
|
702
|
-
// const source = layer.getSource();
|
|
703
|
-
// source?.refresh();
|
|
704
|
-
|
|
705
|
-
// // For cluster source
|
|
706
|
-
// (
|
|
707
|
-
// (source as Cluster<Feature<Point>>)?.getSource?.() as VectorSource<
|
|
708
|
-
// Feature<Point>
|
|
709
|
-
// >
|
|
710
|
-
// )?.refresh();
|
|
711
|
-
// });
|
|
712
|
-
// });
|
|
713
|
-
// Redo the request to get the latest data abou vhicle available
|
|
714
|
-
// @ts-expect-error - type issue
|
|
715
|
-
cacheStations = {};
|
|
716
|
-
updateData();
|
|
717
|
-
}, 60000);
|
|
718
|
-
return () => {
|
|
719
|
-
window.clearInterval(interval);
|
|
720
|
-
};
|
|
721
|
-
}, [group, updateData]);
|
|
722
|
-
|
|
723
|
-
useEffect(() => {
|
|
724
|
-
setSharedMobilityLayerGroup(group);
|
|
725
|
-
}, [group, setSharedMobilityLayerGroup]);
|
|
726
|
-
|
|
727
|
-
useEffect(() => {
|
|
728
|
-
if (!map || !group) {
|
|
729
|
-
return;
|
|
730
|
-
}
|
|
731
|
-
map.addLayer(group);
|
|
732
|
-
|
|
733
|
-
return () => {
|
|
734
|
-
map.removeLayer(group);
|
|
735
|
-
};
|
|
736
|
-
}, [map, group]);
|
|
737
|
-
|
|
738
|
-
return null;
|
|
739
|
-
}
|
|
740
|
-
export default memo(RvfSharedMobilityLayerGroup2);
|