@geops/rvf-mobility-web-component 0.1.64 → 0.1.66
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/CHANGELOG.md +36 -0
- package/docutils.js +125 -51
- package/index.html +48 -21
- package/index.js +291 -234
- package/package.json +12 -12
- package/search.html +25 -22
- package/src/BaseLayer/BaseLayer.tsx +18 -2
- package/src/Copyright/Copyright.tsx +2 -2
- package/src/Copyright/index.tsx +1 -1
- package/src/LayerTree/TreeItem/TreeItem.tsx +1 -1
- package/src/LinesNetworkPlanLayerHighlight/LinesNetworkPlanLayerHighlight.tsx +1 -0
- package/src/Map/Map.tsx +27 -1
- package/src/MapLayout/MapLayout.tsx +1 -1
- package/src/MapLayout/index.tsx +1 -1
- package/src/MobilityMap/MobilityMap.tsx +5 -11
- package/src/MobilityMap/MobilityMapAttributes.ts +8 -5
- package/src/MobilitySearch/MobilitySearchAttributes.ts +12 -0
- package/src/NotificationDetails/NotificationDetails.tsx +75 -57
- package/src/OverlayDetailsHeader/OverlayDetailsHeader.tsx +1 -1
- package/src/Permalink/Permalink.tsx +17 -6
- package/src/PermalinkInput/PermalinkInput.tsx +4 -1
- package/src/RealtimeLayer/index.tsx +1 -1
- package/src/RvfCopyright/RvfCopyright.tsx +32 -0
- package/src/RvfCopyright/index.tsx +1 -0
- package/src/RvfInputCopy/RvfInputCopy.tsx +18 -8
- package/src/RvfMapLayout/RvfMapLayout.tsx +198 -0
- package/src/RvfMapLayout/index.tsx +1 -0
- package/src/RvfMobilityMap/RvfMobilityMap.tsx +10 -580
- package/src/RvfRealtimeLayer/RvfRealtimeLayer.tsx +64 -0
- package/src/RvfRealtimeLayer/index.tsx +1 -0
- package/src/RvfStationsLayer/RvfStationsLayer.tsx +19 -0
- package/src/RvfStationsLayer/index.tsx +1 -0
- package/src/ShareMenu/ShareMenu.tsx +3 -1
- package/src/StationsLayer/index.tsx +1 -1
- package/src/ui/InputCopy/InputCopy.tsx +21 -10
- package/src/utils/constants.ts +1 -1
- package/src/utils/getUrlFromTemplate.test.ts +23 -0
- package/src/utils/getUrlFromTemplate.ts +47 -0
- package/src/utils/hooks/useI18n.tsx +2 -4
- package/src/utils/hooks/useInitialLayersVisiblity.tsx +27 -4
- package/src/utils/hooks/useInitialPermalink.tsx +31 -21
- package/src/utils/hooks/usePermalink.tsx +25 -0
- package/src/utils/translations.ts +4 -0
|
@@ -1,200 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
type MaplibreLayer,
|
|
3
|
-
type MaplibreStyleLayer,
|
|
4
|
-
type MapsetLayer as MbtMapsetLayer,
|
|
5
|
-
type RealtimeLayer as MbtRealtimeLayer,
|
|
6
|
-
type MocoLayer,
|
|
7
|
-
} from "mobility-toolbox-js/ol";
|
|
1
|
+
import { type MaplibreStyleLayer } from "mobility-toolbox-js/ol";
|
|
8
2
|
import { memo } from "preact/compat";
|
|
9
|
-
import {
|
|
10
|
-
import { twMerge } from "tailwind-merge";
|
|
3
|
+
import { useMemo, useState } from "preact/hooks";
|
|
11
4
|
|
|
12
|
-
import
|
|
13
|
-
import Copyright from "../Copyright";
|
|
14
|
-
import EmbedNavigation from "../EmbedNavigation";
|
|
15
|
-
import ExportMenuButton from "../ExportMenuButton";
|
|
16
|
-
import FeaturesInfosListener from "../FeaturesInfosListener";
|
|
17
|
-
import GeolocationButton from "../GeolocationButton";
|
|
18
|
-
import LayerTreeButton from "../LayerTreeButton";
|
|
19
|
-
import LayoutState from "../LayoutState";
|
|
20
|
-
import LinesNetworkPlanLayer from "../LinesNetworkPlanLayer";
|
|
21
|
-
import Map from "../Map";
|
|
22
|
-
import MapDispatchEvents from "../MapDispatchEvents";
|
|
23
|
-
import MapsetLayer from "../MapsetLayer";
|
|
5
|
+
import MobilityMap from "../MobilityMap/MobilityMap";
|
|
24
6
|
import MobilityMapAttributes from "../MobilityMap/MobilityMapAttributes";
|
|
25
|
-
import NotificationsLayer from "../NotificationsLayer";
|
|
26
|
-
import Overlay from "../Overlay";
|
|
27
|
-
import OverlayContent from "../OverlayContent";
|
|
28
|
-
import Permalink from "../Permalink";
|
|
29
|
-
import RealtimeLayer from "../RealtimeLayer";
|
|
30
|
-
import RvfMainLinkButton from "../RvfMainLinkButton";
|
|
31
|
-
import RvfPoisLayer from "../RvfPoisLayer";
|
|
32
|
-
import RvfSelectedFeatureHighlightLayer from "../RvfSelectedFeatureHighlightLayer";
|
|
33
|
-
import RvfSellingPointsLayer from "../RvfSellingPointsLayer";
|
|
34
|
-
import RvfSharedMobilityLayerGroup from "../RvfSharedMobilityLayerGroup";
|
|
35
|
-
import RvfTarifZonenLayer from "../RvfTarifZonenLayer";
|
|
36
|
-
import ScaleLine from "../ScaleLine";
|
|
37
|
-
import Search from "../Search";
|
|
38
|
-
import SearchButton from "../SearchButton";
|
|
39
|
-
import ShareMenuButton from "../ShareMenuButton";
|
|
40
|
-
import SingleClickListener from "../SingleClickListener";
|
|
41
|
-
import StationsLayer from "../StationsLayer";
|
|
42
|
-
import fullTrajectoryStyle from "../utils/fullTrajectoryStyle";
|
|
43
|
-
import getBgColor from "../utils/getBgColor";
|
|
44
|
-
import { getRadius } from "../utils/getRadius";
|
|
45
|
-
import getTextColor from "../utils/getTextColor";
|
|
46
|
-
import { I18nContext } from "../utils/hooks/useI18n";
|
|
47
|
-
import useInitialLayersVisiblity from "../utils/hooks/useInitialLayersVisiblity";
|
|
48
|
-
import useInitialPermalink from "../utils/hooks/useInitialPermalink";
|
|
49
|
-
import { MapContext } from "../utils/hooks/useMapContext";
|
|
50
7
|
import { RvfContext } from "../utils/hooks/useRvfContext";
|
|
51
|
-
import i18n from "../utils/i18n";
|
|
52
|
-
import realtimeRVFStyle from "../utils/realtimeRVFStyle";
|
|
53
|
-
import WindowMessageListener from "../WindowMessageListener";
|
|
54
|
-
import ZoomButtons from "../ZoomButtons";
|
|
55
8
|
|
|
56
|
-
// @ts-expect-error bad type definition
|
|
57
|
-
import tailwind from "../style.css";
|
|
58
|
-
// @ts-expect-error bad type definition
|
|
59
|
-
import style from "./index.css";
|
|
60
|
-
|
|
61
|
-
import type {
|
|
62
|
-
LayerGetFeatureInfoResponse,
|
|
63
|
-
RealtimeStation,
|
|
64
|
-
RealtimeStationId,
|
|
65
|
-
RealtimeStopSequence,
|
|
66
|
-
RealtimeTrainId,
|
|
67
|
-
SituationType,
|
|
68
|
-
} from "mobility-toolbox-js/types";
|
|
69
|
-
import type { Feature, Map as OlMap } from "ol";
|
|
70
9
|
import type { Group } from "ol/layer";
|
|
71
10
|
|
|
72
11
|
import type { MobilityMapProps } from "../MobilityMap/MobilityMap";
|
|
73
12
|
|
|
74
|
-
|
|
75
|
-
bus: 25,
|
|
76
|
-
coach: 15,
|
|
77
|
-
train: 30,
|
|
78
|
-
tram: 20,
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
export type RvfMobilityMapProps = {
|
|
82
|
-
details: string;
|
|
83
|
-
embed: string;
|
|
84
|
-
layers: string; // list of visible layers on load
|
|
85
|
-
layertree: string;
|
|
86
|
-
print: string;
|
|
87
|
-
queryablelayers: string;
|
|
88
|
-
share: string;
|
|
89
|
-
toolbar: string;
|
|
90
|
-
} & MobilityMapProps;
|
|
91
|
-
|
|
92
|
-
const baseLayerProps = {
|
|
93
|
-
mapLibreOptions: {
|
|
94
|
-
// For printing purpose
|
|
95
|
-
maxCanvasSize: [20000, 20000] as [number, number], // remove 4096 limitations
|
|
96
|
-
preserveDrawingBuffer: true,
|
|
97
|
-
},
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const styleProps = {
|
|
101
|
-
//fontSize: 16
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const scrollableHandlerProps = {
|
|
105
|
-
style: { width: "calc(100% - 60px)" },
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
const realtimeLayerProps = {
|
|
109
|
-
fullTrajectoryStyle: fullTrajectoryStyle,
|
|
110
|
-
getMotsByZoom: (z: number) => {
|
|
111
|
-
if (z < 9) {
|
|
112
|
-
return ["rail"];
|
|
113
|
-
}
|
|
114
|
-
return null;
|
|
115
|
-
},
|
|
116
|
-
sort: (
|
|
117
|
-
{ properties: { delay: delayA, type: typeA } },
|
|
118
|
-
{ properties: { delay: delayB, type: typeB } },
|
|
119
|
-
) => {
|
|
120
|
-
if (typeA !== typeB) {
|
|
121
|
-
if (PRIORITY_FROM_TYPE[typeA] < PRIORITY_FROM_TYPE[typeB]) {
|
|
122
|
-
return -1;
|
|
123
|
-
}
|
|
124
|
-
return 1;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if (delayA === delayB) {
|
|
128
|
-
return 0;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if (delayA < delayB) {
|
|
132
|
-
return -1;
|
|
133
|
-
}
|
|
134
|
-
return 1;
|
|
135
|
-
},
|
|
136
|
-
style: realtimeRVFStyle,
|
|
137
|
-
styleOptions: {
|
|
138
|
-
getBgColor: getBgColor,
|
|
139
|
-
getMaxRadiusForStrokeAndDelay: () => {
|
|
140
|
-
return 4;
|
|
141
|
-
},
|
|
142
|
-
getMaxRadiusForText: () => {
|
|
143
|
-
return 8;
|
|
144
|
-
},
|
|
145
|
-
getRadius: getRadius,
|
|
146
|
-
getTextColor: getTextColor,
|
|
147
|
-
},
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
function RvfMobilityMap(props: RvfMobilityMapProps) {
|
|
151
|
-
const eventNodeRef = useRef<HTMLDivElement>();
|
|
152
|
-
const [baseLayer, setBaseLayer] = useState<MaplibreLayer>();
|
|
153
|
-
const [isFollowing, setIsFollowing] = useState<boolean>(false);
|
|
154
|
-
const [isTracking, setIsTracking] = useState<boolean>(false);
|
|
155
|
-
const [isEmbed, setIsEmbed] = useState<boolean>(false);
|
|
156
|
-
const [hasGeolocation, setHasGeolocation] = useState<boolean>(false);
|
|
157
|
-
const [hasLnp, setHasLnp] = useState<boolean>(false);
|
|
158
|
-
const [hasDetails, setHasDetails] = useState<boolean>(false);
|
|
159
|
-
const [hasMapset, setHasMapset] = useState<boolean>(false);
|
|
160
|
-
const [hasNotification, setHasNotification] = useState<boolean>(false);
|
|
161
|
-
const [hasPermalink, setHasPermalink] = useState<boolean>(false);
|
|
162
|
-
const [hasPrint, setHasPrint] = useState<boolean>(false);
|
|
163
|
-
const [hasRealtime, setHasRealtime] = useState<boolean>(false);
|
|
164
|
-
const [hasSearch, setHasSearch] = useState<boolean>(false);
|
|
165
|
-
const [hasStations, setHasStations] = useState<boolean>(false);
|
|
166
|
-
const [hasToolbar, setHasToolbar] = useState<boolean>(false);
|
|
167
|
-
const [hasShare, setHasShare] = useState<boolean>(false);
|
|
168
|
-
const [hasLayerTree, setHasLayerTree] = useState<boolean>(false);
|
|
169
|
-
const [isOverlayOpen, setIsOverlayOpen] = useState<boolean>(false);
|
|
170
|
-
const [isExportMenuOpen, setIsExportMenuOpen] = useState<boolean>(false);
|
|
171
|
-
const [isShareMenuOpen, setIsShareMenuOpen] = useState<boolean>(false);
|
|
172
|
-
const [isLayerTreeOpen, setIsLayerTreeOpen] = useState<boolean>(false);
|
|
173
|
-
const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);
|
|
174
|
-
const [stopSequence, setStopSequence] = useState<RealtimeStopSequence>();
|
|
175
|
-
const [stationsLayer, setStationsLayer] = useState<MaplibreStyleLayer>();
|
|
176
|
-
const [station, setStation] = useState<RealtimeStation>();
|
|
177
|
-
const [realtimeLayer, setRealtimeLayer] = useState<MbtRealtimeLayer>();
|
|
178
|
-
const [notificationsLayer, setNotificationsLayer] = useState<MocoLayer>();
|
|
179
|
-
const [linesNetworkPlanLayer, setLinesNetworkPlanLayer] =
|
|
180
|
-
useState<MaplibreStyleLayer>();
|
|
181
|
-
const [mapsetLayer, setMapsetLayer] = useState<MbtMapsetLayer>();
|
|
182
|
-
|
|
183
|
-
const [map, setMap] = useState<OlMap>();
|
|
184
|
-
const [stationId, setStationId] = useState<RealtimeStationId>();
|
|
185
|
-
const [trainId, setTrainId] = useState<RealtimeTrainId>();
|
|
186
|
-
const [linesIds, setLinesIds] = useState<string[]>();
|
|
187
|
-
const [featuresInfos, setFeaturesInfos] = useState<
|
|
188
|
-
LayerGetFeatureInfoResponse[]
|
|
189
|
-
>([]);
|
|
190
|
-
const [featuresInfosHovered, setFeaturesInfosHovered] = useState<
|
|
191
|
-
LayerGetFeatureInfoResponse[]
|
|
192
|
-
>([]);
|
|
193
|
-
const [selectedFeature, setSelectedFeature] = useState<Feature>();
|
|
194
|
-
const [selectedFeatures, setSelectedFeatures] = useState<Feature[]>();
|
|
195
|
-
|
|
196
|
-
const [permalinkUrlSearchParams, setPermalinkUrlSearchParams] =
|
|
197
|
-
useState<URLSearchParams>();
|
|
13
|
+
function RvfMobilityMap(props: MobilityMapProps) {
|
|
198
14
|
const [sellingPointsLayer, setSellingPointsLayer] =
|
|
199
15
|
useState<MaplibreStyleLayer>();
|
|
200
16
|
const [tarifZonenLayer, setTarifZonenLayer] = useState<MaplibreStyleLayer>();
|
|
@@ -202,141 +18,6 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
|
|
|
202
18
|
const [sharedMobilityLayerGroup, setSharedMobilityLayerGroup] =
|
|
203
19
|
useState<Group>();
|
|
204
20
|
|
|
205
|
-
const [previewNotifications, setPreviewNotifications] =
|
|
206
|
-
useState<SituationType[]>();
|
|
207
|
-
|
|
208
|
-
const { lang, layers, mainlink } = props;
|
|
209
|
-
|
|
210
|
-
// Apply initial visibility of layers
|
|
211
|
-
useInitialLayersVisiblity(map, layers);
|
|
212
|
-
|
|
213
|
-
const mapContextValue = useMemo(() => {
|
|
214
|
-
return {
|
|
215
|
-
// MobilityMapProps
|
|
216
|
-
...props,
|
|
217
|
-
// MapContextProps
|
|
218
|
-
baseLayer,
|
|
219
|
-
featuresInfos,
|
|
220
|
-
featuresInfosHovered,
|
|
221
|
-
hasDetails,
|
|
222
|
-
hasGeolocation,
|
|
223
|
-
hasLayerTree,
|
|
224
|
-
hasLnp,
|
|
225
|
-
hasMapset,
|
|
226
|
-
hasNotification,
|
|
227
|
-
hasPermalink,
|
|
228
|
-
hasPrint,
|
|
229
|
-
hasRealtime,
|
|
230
|
-
hasSearch,
|
|
231
|
-
hasShare,
|
|
232
|
-
hasStations,
|
|
233
|
-
hasToolbar,
|
|
234
|
-
isEmbed,
|
|
235
|
-
isExportMenuOpen,
|
|
236
|
-
isFollowing,
|
|
237
|
-
isLayerTreeOpen,
|
|
238
|
-
isOverlayOpen,
|
|
239
|
-
isSearchOpen,
|
|
240
|
-
isShareMenuOpen,
|
|
241
|
-
isTracking,
|
|
242
|
-
linesIds,
|
|
243
|
-
linesNetworkPlanLayer,
|
|
244
|
-
map,
|
|
245
|
-
mapsetLayer,
|
|
246
|
-
notificationsLayer,
|
|
247
|
-
permalinkUrlSearchParams,
|
|
248
|
-
previewNotifications,
|
|
249
|
-
realtimeLayer,
|
|
250
|
-
selectedFeature,
|
|
251
|
-
selectedFeatures,
|
|
252
|
-
setBaseLayer,
|
|
253
|
-
setFeaturesInfos,
|
|
254
|
-
setFeaturesInfosHovered,
|
|
255
|
-
setHasDetails,
|
|
256
|
-
setHasGeolocation,
|
|
257
|
-
setHasLayerTree,
|
|
258
|
-
setHasLnp,
|
|
259
|
-
setHasMapset,
|
|
260
|
-
setHasNotification,
|
|
261
|
-
setHasPermalink,
|
|
262
|
-
setHasPrint,
|
|
263
|
-
setHasRealtime,
|
|
264
|
-
setHasSearch,
|
|
265
|
-
setHasShare,
|
|
266
|
-
setHasStations,
|
|
267
|
-
setHasToolbar,
|
|
268
|
-
setIsEmbed,
|
|
269
|
-
setIsExportMenuOpen,
|
|
270
|
-
setIsFollowing,
|
|
271
|
-
setIsLayerTreeOpen,
|
|
272
|
-
setIsOverlayOpen,
|
|
273
|
-
setIsSearchOpen,
|
|
274
|
-
setIsShareMenuOpen,
|
|
275
|
-
setIsTracking,
|
|
276
|
-
setLinesIds,
|
|
277
|
-
setLinesNetworkPlanLayer,
|
|
278
|
-
setMap,
|
|
279
|
-
setMapsetLayer,
|
|
280
|
-
setNotificationsLayer,
|
|
281
|
-
setPermalinkUrlSearchParams,
|
|
282
|
-
setPreviewNotifications,
|
|
283
|
-
setRealtimeLayer,
|
|
284
|
-
setSelectedFeature,
|
|
285
|
-
setSelectedFeatures,
|
|
286
|
-
setStation,
|
|
287
|
-
setStationId,
|
|
288
|
-
setStationsLayer,
|
|
289
|
-
setStopSequence,
|
|
290
|
-
setTrainId,
|
|
291
|
-
station,
|
|
292
|
-
stationId,
|
|
293
|
-
stationsLayer,
|
|
294
|
-
stopSequence,
|
|
295
|
-
trainId,
|
|
296
|
-
};
|
|
297
|
-
}, [
|
|
298
|
-
props,
|
|
299
|
-
baseLayer,
|
|
300
|
-
featuresInfos,
|
|
301
|
-
featuresInfosHovered,
|
|
302
|
-
hasDetails,
|
|
303
|
-
hasGeolocation,
|
|
304
|
-
hasLayerTree,
|
|
305
|
-
hasLnp,
|
|
306
|
-
hasMapset,
|
|
307
|
-
hasNotification,
|
|
308
|
-
hasPermalink,
|
|
309
|
-
hasPrint,
|
|
310
|
-
hasRealtime,
|
|
311
|
-
hasSearch,
|
|
312
|
-
hasShare,
|
|
313
|
-
hasStations,
|
|
314
|
-
hasToolbar,
|
|
315
|
-
isEmbed,
|
|
316
|
-
isExportMenuOpen,
|
|
317
|
-
isFollowing,
|
|
318
|
-
isLayerTreeOpen,
|
|
319
|
-
isOverlayOpen,
|
|
320
|
-
isSearchOpen,
|
|
321
|
-
isShareMenuOpen,
|
|
322
|
-
isTracking,
|
|
323
|
-
linesIds,
|
|
324
|
-
linesNetworkPlanLayer,
|
|
325
|
-
map,
|
|
326
|
-
mapsetLayer,
|
|
327
|
-
notificationsLayer,
|
|
328
|
-
permalinkUrlSearchParams,
|
|
329
|
-
previewNotifications,
|
|
330
|
-
realtimeLayer,
|
|
331
|
-
selectedFeature,
|
|
332
|
-
selectedFeatures,
|
|
333
|
-
station,
|
|
334
|
-
stationId,
|
|
335
|
-
stationsLayer,
|
|
336
|
-
stopSequence,
|
|
337
|
-
trainId,
|
|
338
|
-
]);
|
|
339
|
-
|
|
340
21
|
const rvfContextValue = useMemo(() => {
|
|
341
22
|
return {
|
|
342
23
|
poisLayer,
|
|
@@ -355,258 +36,15 @@ function RvfMobilityMap(props: RvfMobilityMapProps) {
|
|
|
355
36
|
tarifZonenLayer,
|
|
356
37
|
]);
|
|
357
38
|
|
|
358
|
-
const copyrightOptions = useMemo(() => {
|
|
359
|
-
return {
|
|
360
|
-
format: (copyrights) => {
|
|
361
|
-
const newCopyrights = [];
|
|
362
|
-
let alreadyAGeopsLink = false;
|
|
363
|
-
copyrights.forEach((copyright) => {
|
|
364
|
-
if (/geops/i.test(copyright)) {
|
|
365
|
-
// Hack until all geOps tiles are the same
|
|
366
|
-
// Currently there is some geops.com or geops.ch links
|
|
367
|
-
if (!alreadyAGeopsLink) {
|
|
368
|
-
alreadyAGeopsLink = true;
|
|
369
|
-
newCopyrights.push(copyright);
|
|
370
|
-
}
|
|
371
|
-
} else if (!/(sbb|rvf)/i.test(copyright)) {
|
|
372
|
-
newCopyrights.push(copyright);
|
|
373
|
-
}
|
|
374
|
-
});
|
|
375
|
-
|
|
376
|
-
return newCopyrights.join(" | ");
|
|
377
|
-
},
|
|
378
|
-
};
|
|
379
|
-
}, []);
|
|
380
|
-
|
|
381
|
-
const stationsLayerProps = useMemo(() => {
|
|
382
|
-
return {
|
|
383
|
-
layersFilter: ({ metadata }) => {
|
|
384
|
-
return metadata?.["general.filter"] === "stations";
|
|
385
|
-
},
|
|
386
|
-
};
|
|
387
|
-
}, []);
|
|
388
|
-
|
|
389
|
-
useEffect(() => {
|
|
390
|
-
i18n.locale(lang);
|
|
391
|
-
}, [lang]);
|
|
392
|
-
|
|
393
39
|
return (
|
|
394
|
-
<
|
|
395
|
-
{
|
|
396
|
-
|
|
397
|
-
<style>
|
|
398
|
-
{`:host {
|
|
399
|
-
--tw-divide-y-reverse: 0;
|
|
400
|
-
--tw-border-style: solid;
|
|
401
|
-
--tw-font-weight: initial;
|
|
402
|
-
--tw-tracking: initial;
|
|
403
|
-
--tw-translate-x: 0;
|
|
404
|
-
--tw-translate-y: 0;
|
|
405
|
-
--tw-translate-z: 0;
|
|
406
|
-
--tw-rotate-x: rotateX(0);
|
|
407
|
-
--tw-rotate-y: rotateY(0);
|
|
408
|
-
--tw-rotate-z: rotateZ(0);
|
|
409
|
-
--tw-skew-x: skewX(0);
|
|
410
|
-
--tw-skew-y: skewY(0);
|
|
411
|
-
--tw-space-x-reverse: 0;
|
|
412
|
-
--tw-gradient-position: initial;
|
|
413
|
-
--tw-gradient-from: #0000;
|
|
414
|
-
--tw-gradient-via: #0000;
|
|
415
|
-
--tw-gradient-to: #0000;
|
|
416
|
-
--tw-gradient-stops: initial;
|
|
417
|
-
--tw-gradient-via-stops: initial;
|
|
418
|
-
--tw-gradient-from-position: 0%;
|
|
419
|
-
--tw-gradient-via-position: 50%;
|
|
420
|
-
--tw-gradient-to-position: 100%;
|
|
421
|
-
--tw-shadow: 0 0 #0000;
|
|
422
|
-
--tw-shadow-color: initial;
|
|
423
|
-
--tw-inset-shadow: 0 0 #0000;
|
|
424
|
-
--tw-inset-shadow-color: initial;
|
|
425
|
-
--tw-ring-color: initial;
|
|
426
|
-
--tw-ring-shadow: 0 0 #0000;
|
|
427
|
-
--tw-inset-ring-color: initial;
|
|
428
|
-
--tw-inset-ring-shadow: 0 0 #0000;
|
|
429
|
-
--tw-ring-inset: initial;
|
|
430
|
-
--tw-ring-offset-width: 0px;
|
|
431
|
-
--tw-ring-offset-color: #fff;
|
|
432
|
-
--tw-ring-offset-shadow: 0 0 #0000;
|
|
433
|
-
--tw-blur: initial;
|
|
434
|
-
--tw-brightness: initial;
|
|
435
|
-
--tw-contrast: initial;
|
|
436
|
-
--tw-grayscale: initial;
|
|
437
|
-
--tw-hue-rotate: initial;
|
|
438
|
-
--tw-invert: initial;
|
|
439
|
-
--tw-opacity: initial;
|
|
440
|
-
--tw-saturate: initial;
|
|
441
|
-
--tw-sepia: initial;
|
|
442
|
-
--tw-drop-shadow: initial;
|
|
443
|
-
--tw-duration: initial;
|
|
444
|
-
--tw-ease: initial;
|
|
445
|
-
}`}
|
|
446
|
-
</style>
|
|
447
|
-
<style>{tailwind}</style>
|
|
448
|
-
<style>{style}</style>
|
|
449
|
-
<MapContext.Provider value={mapContextValue}>
|
|
450
|
-
<RvfContext.Provider value={rvfContextValue}>
|
|
451
|
-
<LayoutState />
|
|
452
|
-
<Permalink replaceState={hasPermalink} />
|
|
453
|
-
<MapDispatchEvents node={eventNodeRef.current} wcAttributes={props} />
|
|
454
|
-
<WindowMessageListener eventNode={eventNodeRef.current} />
|
|
455
|
-
<SingleClickListener />
|
|
456
|
-
<FeaturesInfosListener />
|
|
457
|
-
|
|
458
|
-
<div
|
|
459
|
-
className="@container/main relative size-full overflow-hidden font-sans"
|
|
460
|
-
ref={eventNodeRef}
|
|
461
|
-
style={styleProps}
|
|
462
|
-
>
|
|
463
|
-
<div className="relative flex size-full flex-col text-base @lg/main:flex-row-reverse">
|
|
464
|
-
<Map className="relative flex-1 overflow-visible">
|
|
465
|
-
<BaseLayer {...baseLayerProps} />
|
|
466
|
-
{isEmbed && <EmbedNavigation />}
|
|
467
|
-
{hasNotification && <NotificationsLayer />}
|
|
468
|
-
<RvfSelectedFeatureHighlightLayer />
|
|
469
|
-
{hasRealtime && <RealtimeLayer {...realtimeLayerProps} />}
|
|
470
|
-
<StationsLayer minZoom={10} {...stationsLayerProps} />
|
|
471
|
-
<RvfTarifZonenLayer />
|
|
472
|
-
<RvfSellingPointsLayer />
|
|
473
|
-
{hasLnp && <LinesNetworkPlanLayer />}
|
|
474
|
-
|
|
475
|
-
{hasMapset && <MapsetLayer />}
|
|
476
|
-
|
|
477
|
-
<RvfPoisLayer />
|
|
478
|
-
<RvfSharedMobilityLayerGroup />
|
|
479
|
-
{mainlink && (
|
|
480
|
-
<RvfMainLinkButton className="absolute inset-x-2 bottom-8 z-10" />
|
|
481
|
-
)}
|
|
482
|
-
|
|
483
|
-
<div className="pointer-events-none absolute inset-x-2 bottom-2 z-10 flex items-end justify-between gap-2 text-[10px]">
|
|
484
|
-
<ScaleLine className="bg-slate-50/70" />
|
|
485
|
-
<Copyright
|
|
486
|
-
className="pointer-events-auto bg-slate-50/70"
|
|
487
|
-
options={copyrightOptions}
|
|
488
|
-
/>
|
|
489
|
-
</div>
|
|
490
|
-
<div className="absolute top-2 right-2 z-10 flex">
|
|
491
|
-
{hasGeolocation && (
|
|
492
|
-
<GeolocationButton title={"Geolokalisierung"} />
|
|
493
|
-
)}
|
|
494
|
-
</div>
|
|
495
|
-
<div className="absolute right-2 bottom-10 z-10 flex flex-col justify-between gap-2">
|
|
496
|
-
<ZoomButtons />
|
|
497
|
-
</div>
|
|
498
|
-
|
|
499
|
-
{!hasToolbar && hasSearch && (
|
|
500
|
-
<div
|
|
501
|
-
className={twMerge(
|
|
502
|
-
"absolute top-2 right-2 left-2 z-10 max-w-96",
|
|
503
|
-
isOverlayOpen && "@lg:left-68",
|
|
504
|
-
)}
|
|
505
|
-
>
|
|
506
|
-
<Search />
|
|
507
|
-
</div>
|
|
508
|
-
)}
|
|
509
|
-
</Map>
|
|
510
|
-
|
|
511
|
-
<div className="pointer-events-none absolute top-2 bottom-2 left-2 z-10 flex flex-col gap-2">
|
|
512
|
-
{hasToolbar && (
|
|
513
|
-
<div
|
|
514
|
-
className={
|
|
515
|
-
"pointer-events-none relative z-10 w-fit rounded-2xl bg-black/10 p-0 backdrop-blur-sm *:pointer-events-auto"
|
|
516
|
-
}
|
|
517
|
-
// className="w-fit rounded-2xl bg-black/10 p-1 backdrop-blur-sm">
|
|
518
|
-
>
|
|
519
|
-
{hasSearch && (
|
|
520
|
-
<div
|
|
521
|
-
className={twMerge(
|
|
522
|
-
"absolute top-12 left-0 w-0 p-0 opacity-0 transition-all @sm:top-0 @sm:left-[calc(100%-43px)] @md:left-[calc(100%-47px)]",
|
|
523
|
-
isSearchOpen ? "w-64 opacity-100" : "",
|
|
524
|
-
)}
|
|
525
|
-
>
|
|
526
|
-
<Search
|
|
527
|
-
className={
|
|
528
|
-
"border-grey @container m-0 h-[40px] rounded-2xl border p-2 px-4 text-base @sm/main:h-[44px] @sm/main:rounded-l-none @sm/main:rounded-r-2xl @md/main:h-[48px]"
|
|
529
|
-
}
|
|
530
|
-
inputClassName="h-6 text-base"
|
|
531
|
-
inputContainerClassName="border-none"
|
|
532
|
-
resultClassName="text-base **:hover:cursor-pointer hover:text-red-500 p-2"
|
|
533
|
-
resultsContainerClassName="@container rounded-b-2xl max-h-[200px] overflow-y-auto border border-grey border-t-0 "
|
|
534
|
-
withResultsClassName="text-base !rounded-b-none"
|
|
535
|
-
/>
|
|
536
|
-
</div>
|
|
537
|
-
)}
|
|
538
|
-
|
|
539
|
-
<div
|
|
540
|
-
className={twMerge(
|
|
541
|
-
"border-grey relative flex gap-[1px] overflow-hidden rounded-2xl border @sm/main:h-[44px] @md/main:h-[48px]",
|
|
542
|
-
"*:size-[38px] *:rounded-none *:border-none *:@sm/main:size-[42px] *:@md/main:!size-[46px]",
|
|
543
|
-
"*:first:!rounded-l-2xl",
|
|
544
|
-
"*:last:!rounded-r-2xl",
|
|
545
|
-
isSearchOpen
|
|
546
|
-
? "@sm:rounded-r-none @sm:border-r-0 @sm:*:last:!rounded-r-none @sm:*:last:border-r-0"
|
|
547
|
-
: "",
|
|
548
|
-
)}
|
|
549
|
-
>
|
|
550
|
-
{hasPrint && <ExportMenuButton />}
|
|
551
|
-
{hasShare && <ShareMenuButton />}
|
|
552
|
-
{hasLayerTree && <LayerTreeButton />}
|
|
553
|
-
{hasSearch && <SearchButton />}
|
|
554
|
-
</div>
|
|
555
|
-
</div>
|
|
556
|
-
)}
|
|
557
|
-
|
|
558
|
-
{/* Desktop (>= lg) */}
|
|
559
|
-
<div
|
|
560
|
-
className={twMerge(
|
|
561
|
-
"pointer-events-none flex w-0 flex-1 flex-col overflow-hidden rounded-2xl",
|
|
562
|
-
isOverlayOpen ? "@lg:min-w-[320px]" : "p-0",
|
|
563
|
-
)}
|
|
564
|
-
style={{ containerType: "normal" }}
|
|
565
|
-
>
|
|
566
|
-
<Overlay
|
|
567
|
-
className={
|
|
568
|
-
"border-grey @container/overlay pointer-events-auto relative hidden flex-col overflow-hidden rounded-2xl border bg-white text-base shadow-lg @lg:flex"
|
|
569
|
-
}
|
|
570
|
-
ScrollableHandlerProps={scrollableHandlerProps}
|
|
571
|
-
>
|
|
572
|
-
<OverlayContent
|
|
573
|
-
hasDetails={hasDetails}
|
|
574
|
-
hasLayerTree={hasLayerTree}
|
|
575
|
-
hasPrint={hasPrint}
|
|
576
|
-
hasRealtime={hasRealtime}
|
|
577
|
-
hasSearch={false}
|
|
578
|
-
hasShare={hasShare}
|
|
579
|
-
/>
|
|
580
|
-
</Overlay>
|
|
581
|
-
</div>
|
|
582
|
-
</div>
|
|
583
|
-
|
|
584
|
-
{/* Mobile */}
|
|
585
|
-
<Overlay
|
|
586
|
-
className={
|
|
587
|
-
isOverlayOpen
|
|
588
|
-
? "absolute bottom-0 z-20 flex max-h-[70%] min-h-[75px] w-full flex-col border-t bg-white @lg:hidden"
|
|
589
|
-
: "@lg:hidden"
|
|
590
|
-
}
|
|
591
|
-
ScrollableHandlerProps={scrollableHandlerProps}
|
|
592
|
-
>
|
|
593
|
-
<OverlayContent
|
|
594
|
-
hasDetails={hasDetails}
|
|
595
|
-
hasLayerTree={hasLayerTree}
|
|
596
|
-
hasPrint={hasPrint}
|
|
597
|
-
hasRealtime={hasRealtime}
|
|
598
|
-
hasSearch={false} // The search could be in the overlay but we decide to put it in the toolbar for better UX
|
|
599
|
-
hasShare={hasShare}
|
|
600
|
-
/>
|
|
601
|
-
</Overlay>
|
|
602
|
-
</div>
|
|
603
|
-
</div>
|
|
604
|
-
</RvfContext.Provider>
|
|
605
|
-
</MapContext.Provider>
|
|
606
|
-
</I18nContext.Provider>
|
|
40
|
+
<RvfContext.Provider value={rvfContextValue}>
|
|
41
|
+
<MobilityMap {...props} />
|
|
42
|
+
</RvfContext.Provider>
|
|
607
43
|
);
|
|
608
44
|
}
|
|
609
45
|
|
|
46
|
+
const MemoRvFMobilityMap = memo(RvfMobilityMap);
|
|
47
|
+
|
|
610
48
|
// We creates a wrapper to inject the default props values from MobilityMapAttributes.
|
|
611
49
|
const defaultProps: Partial<MobilityMapProps> = {};
|
|
612
50
|
Object.entries(MobilityMapAttributes).forEach(([key]) => {
|
|
@@ -614,15 +52,7 @@ Object.entries(MobilityMapAttributes).forEach(([key]) => {
|
|
|
614
52
|
});
|
|
615
53
|
|
|
616
54
|
function MobilityMapWithDefaultProps(props: MobilityMapProps) {
|
|
617
|
-
|
|
618
|
-
const { permalinktemplate } = props;
|
|
619
|
-
const { permalinktemplate: defaultPermalinkTemplate } = defaultProps;
|
|
620
|
-
const propsFromPermalink = useInitialPermalink(
|
|
621
|
-
permalinktemplate || defaultPermalinkTemplate,
|
|
622
|
-
);
|
|
623
|
-
return (
|
|
624
|
-
<RvfMobilityMap {...defaultProps} {...props} {...propsFromPermalink} />
|
|
625
|
-
);
|
|
55
|
+
return <MemoRvFMobilityMap {...defaultProps} {...props} />;
|
|
626
56
|
}
|
|
627
57
|
|
|
628
58
|
export default memo(MobilityMapWithDefaultProps);
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { memo } from "preact/compat";
|
|
2
|
+
|
|
3
|
+
import RealtimeLayer from "../RealtimeLayer/RealtimeLayer";
|
|
4
|
+
import fullTrajectoryStyle from "../utils/fullTrajectoryStyle";
|
|
5
|
+
import getBgColor from "../utils/getBgColor";
|
|
6
|
+
import { getRadius } from "../utils/getRadius";
|
|
7
|
+
import getTextColor from "../utils/getTextColor";
|
|
8
|
+
import realtimeRVFStyle from "../utils/realtimeRVFStyle";
|
|
9
|
+
|
|
10
|
+
import type { RealtimeLayerOptions } from "mobility-toolbox-js/ol";
|
|
11
|
+
|
|
12
|
+
const PRIORITY_FROM_TYPE = {
|
|
13
|
+
bus: 25,
|
|
14
|
+
coach: 15,
|
|
15
|
+
train: 30,
|
|
16
|
+
tram: 20,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const defaultProps: Partial<RealtimeLayerOptions> = {
|
|
20
|
+
fullTrajectoryStyle: fullTrajectoryStyle,
|
|
21
|
+
getMotsByZoom: (z: number) => {
|
|
22
|
+
if (z < 9) {
|
|
23
|
+
return ["rail"];
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
},
|
|
27
|
+
sort: (
|
|
28
|
+
{ properties: { delay: delayA, type: typeA } },
|
|
29
|
+
{ properties: { delay: delayB, type: typeB } },
|
|
30
|
+
) => {
|
|
31
|
+
if (typeA !== typeB) {
|
|
32
|
+
if (PRIORITY_FROM_TYPE[typeA] < PRIORITY_FROM_TYPE[typeB]) {
|
|
33
|
+
return -1;
|
|
34
|
+
}
|
|
35
|
+
return 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (delayA === delayB) {
|
|
39
|
+
return 0;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (delayA < delayB) {
|
|
43
|
+
return -1;
|
|
44
|
+
}
|
|
45
|
+
return 1;
|
|
46
|
+
},
|
|
47
|
+
style: realtimeRVFStyle,
|
|
48
|
+
styleOptions: {
|
|
49
|
+
getBgColor: getBgColor,
|
|
50
|
+
getMaxRadiusForStrokeAndDelay: () => {
|
|
51
|
+
return 4;
|
|
52
|
+
},
|
|
53
|
+
getMaxRadiusForText: () => {
|
|
54
|
+
return 8;
|
|
55
|
+
},
|
|
56
|
+
getRadius: getRadius,
|
|
57
|
+
getTextColor: getTextColor,
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
function RvfRealtimeLayer(props: Partial<RealtimeLayerOptions>) {
|
|
61
|
+
return <RealtimeLayer {...defaultProps} {...props} />;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default memo(RvfRealtimeLayer);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./RvfRealtimeLayer";
|