@geops/rvf-mobility-web-component 0.1.77 → 0.1.79
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 +14 -0
- package/README.md +1 -0
- package/index.js +189 -189
- package/package.json +11 -11
- package/src/MapsetLayer/MapsetLayer.tsx +6 -76
- package/src/MobilityMap/MobilityMapAttributes.ts +1 -8
- package/src/MobilityNotifications/MobilityNotifications.tsx +50 -14
- package/src/icons/Warning/exported_features_20251029101203.kml +17 -0
- package/src/NotificationsLayer/MocoLayer2.ts +0 -91
- package/src/utils/addSourceAndLayers.ts +0 -130
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@geops/rvf-mobility-web-component",
|
|
3
3
|
"license": "UNLICENSED",
|
|
4
4
|
"description": "Web components for rvf in the domains of mobility and logistics.",
|
|
5
|
-
"version": "0.1.
|
|
5
|
+
"version": "0.1.79",
|
|
6
6
|
"homepage": "https://rvf-mobility-web-component-geops.vercel.app/",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"main": "index.js",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"graphql-request": "^7.1.2",
|
|
12
12
|
"jspdf": "^3.0.3",
|
|
13
13
|
"lodash.debounce": "^4.0.8",
|
|
14
|
-
"maplibre-gl": "^5.
|
|
15
|
-
"mobility-toolbox-js": "3.4.
|
|
14
|
+
"maplibre-gl": "^5.10.0",
|
|
15
|
+
"mobility-toolbox-js": "3.4.7",
|
|
16
16
|
"ol": "^10.6.1",
|
|
17
17
|
"preact": "^10.27.2",
|
|
18
18
|
"preact-custom-element": "^4.5.1",
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"devDependencies": {
|
|
26
26
|
"@commitlint/cli": "^20.1.0",
|
|
27
27
|
"@commitlint/config-conventional": "^20.0.0",
|
|
28
|
-
"@eslint/js": "^9.
|
|
28
|
+
"@eslint/js": "^9.38.0",
|
|
29
29
|
"@geops/eslint-config-react": "^1.6.0-beta.1",
|
|
30
|
-
"@tailwindcss/cli": "^4.1.
|
|
30
|
+
"@tailwindcss/cli": "^4.1.16",
|
|
31
31
|
"@tailwindcss/container-queries": "^0.1.1",
|
|
32
32
|
"@testing-library/preact": "^3.2.4",
|
|
33
33
|
"@types/geojson": "^7946.0.16",
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"@types/lodash": "^4.17.20",
|
|
36
36
|
"@types/preact-custom-element": "^4.0.4",
|
|
37
37
|
"concurrently": "^9.2.1",
|
|
38
|
-
"esbuild": "^0.25.
|
|
38
|
+
"esbuild": "^0.25.11",
|
|
39
39
|
"esbuild-sass-plugin": "^3.3.1",
|
|
40
|
-
"eslint": "^9.
|
|
40
|
+
"eslint": "^9.38.0",
|
|
41
41
|
"eslint-plugin-tailwindcss": "^4.0.0-beta.0",
|
|
42
42
|
"fixpack": "^4.0.0",
|
|
43
43
|
"generact": "^0.4.0",
|
|
@@ -47,15 +47,15 @@
|
|
|
47
47
|
"jest-environment-jsdom": "^30.2.0",
|
|
48
48
|
"jest-preset-preact": "^4.1.1",
|
|
49
49
|
"next": "15.5.5",
|
|
50
|
-
"preact-render-to-string": "^6.6.
|
|
50
|
+
"preact-render-to-string": "^6.6.3",
|
|
51
51
|
"prettier": "^3.6.2",
|
|
52
|
-
"prettier-plugin-tailwindcss": "^0.
|
|
52
|
+
"prettier-plugin-tailwindcss": "^0.7.1",
|
|
53
53
|
"standard-version": "^9.5.0",
|
|
54
54
|
"tailwind-merge": "^3.3.1",
|
|
55
|
-
"tailwindcss": "^4.1.
|
|
55
|
+
"tailwindcss": "^4.1.16",
|
|
56
56
|
"ts-jest": "^29.4.5",
|
|
57
57
|
"typescript": "^5.9.3",
|
|
58
|
-
"typescript-eslint": "^8.46.
|
|
58
|
+
"typescript-eslint": "^8.46.2"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"build": "yarn build:css && yarn build:js && cp index*.js* doc/public/",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { MapsetLayer as MtbMapsetLayer } from "mobility-toolbox-js/ol";
|
|
2
2
|
import { unByKey } from "ol/Observable";
|
|
3
|
-
import { transformExtent } from "ol/proj";
|
|
4
3
|
import { memo } from "preact/compat";
|
|
5
4
|
import { useEffect, useMemo } from "preact/hooks";
|
|
6
5
|
|
|
@@ -8,8 +7,8 @@ import { LAYER_NAME_MAPSET } from "../utils/constants";
|
|
|
8
7
|
import useMapContext from "../utils/hooks/useMapContext";
|
|
9
8
|
|
|
10
9
|
import type { MapsetLayerOptions } from "mobility-toolbox-js/ol";
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
import type { Feature } from "ol";
|
|
11
|
+
import type { EventTypes } from "ol/Observable";
|
|
13
12
|
|
|
14
13
|
export const isFeatureOutsideZoomLimit = (feature, map) => {
|
|
15
14
|
const zoom = map?.getView()?.getZoom();
|
|
@@ -23,7 +22,6 @@ function MapsetLayer(props?: Partial<MapsetLayerOptions>) {
|
|
|
23
22
|
apikey,
|
|
24
23
|
baseLayer,
|
|
25
24
|
map,
|
|
26
|
-
mapsetbbox,
|
|
27
25
|
mapsetplanid,
|
|
28
26
|
mapsettags,
|
|
29
27
|
mapsettenants,
|
|
@@ -37,38 +35,8 @@ function MapsetLayer(props?: Partial<MapsetLayerOptions>) {
|
|
|
37
35
|
return null;
|
|
38
36
|
}
|
|
39
37
|
|
|
40
|
-
let bbox = undefined;
|
|
41
|
-
if (mapsetbbox) {
|
|
42
|
-
bbox = mapsetbbox?.split(",").map((coord) => {
|
|
43
|
-
return Number(coord.trim());
|
|
44
|
-
});
|
|
45
|
-
if (
|
|
46
|
-
bbox.length === 4 &&
|
|
47
|
-
!bbox.some((coord) => {
|
|
48
|
-
return Number.isNaN(coord);
|
|
49
|
-
})
|
|
50
|
-
) {
|
|
51
|
-
bbox = transformExtent(bbox, "EPSG:3857", "EPSG:4326");
|
|
52
|
-
}
|
|
53
|
-
} else {
|
|
54
|
-
// we have to wait that the map is well sized to get the extent
|
|
55
|
-
// It triggers an erro in FF without this
|
|
56
|
-
if (
|
|
57
|
-
map.getView()?.getCenter() &&
|
|
58
|
-
map.getSize()[0] > 0 &&
|
|
59
|
-
map.getSize()[1] > 0
|
|
60
|
-
) {
|
|
61
|
-
bbox = transformExtent(
|
|
62
|
-
map.getView()?.calculateExtent(),
|
|
63
|
-
"EPSG:3857",
|
|
64
|
-
"EPSG:4326",
|
|
65
|
-
);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
38
|
return new MtbMapsetLayer({
|
|
69
39
|
apiKey: apikey,
|
|
70
|
-
bbox,
|
|
71
|
-
mapseturl: mapseturl || undefined,
|
|
72
40
|
name: LAYER_NAME_MAPSET,
|
|
73
41
|
planId: mapsetplanid ?? undefined,
|
|
74
42
|
tags: mapsettags?.split(",").map((t) => {
|
|
@@ -77,14 +45,13 @@ function MapsetLayer(props?: Partial<MapsetLayerOptions>) {
|
|
|
77
45
|
tenants: mapsettenants?.split(",").map((t) => {
|
|
78
46
|
return t.trim();
|
|
79
47
|
}),
|
|
80
|
-
timestamp: mapsettimestamp
|
|
81
|
-
|
|
48
|
+
timestamp: mapsettimestamp, // Load only standard plan
|
|
49
|
+
url: mapseturl,
|
|
82
50
|
...(props || {}),
|
|
83
51
|
});
|
|
84
52
|
}, [
|
|
85
53
|
baseLayer,
|
|
86
54
|
map,
|
|
87
|
-
mapsetbbox,
|
|
88
55
|
apikey,
|
|
89
56
|
mapseturl,
|
|
90
57
|
mapsetplanid,
|
|
@@ -109,49 +76,12 @@ function MapsetLayer(props?: Partial<MapsetLayerOptions>) {
|
|
|
109
76
|
};
|
|
110
77
|
}, [map, layer]);
|
|
111
78
|
|
|
112
|
-
|
|
113
|
-
const view = map?.getView();
|
|
114
|
-
if (!view || !layer) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
const handleMoveEnd = () => {
|
|
118
|
-
if (mapsetplanid || !layer.get("visible")) {
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
clearTimeout(moveEndTimeout);
|
|
122
|
-
moveEndTimeout = setTimeout(() => {
|
|
123
|
-
const currentBbox = transformExtent(
|
|
124
|
-
view.calculateExtent(map.getSize()),
|
|
125
|
-
"EPSG:3857",
|
|
126
|
-
"EPSG:4326",
|
|
127
|
-
);
|
|
128
|
-
layer.bbox = currentBbox;
|
|
129
|
-
layer.zoom = view.getZoom();
|
|
130
|
-
}, 100);
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
const listeners = [
|
|
134
|
-
layer.on("change:visible", () => {
|
|
135
|
-
if (layer.get("visible")) {
|
|
136
|
-
handleMoveEnd();
|
|
137
|
-
}
|
|
138
|
-
}),
|
|
139
|
-
view.on("change:center", handleMoveEnd),
|
|
140
|
-
view.on("change:resolution", handleMoveEnd),
|
|
141
|
-
];
|
|
142
|
-
|
|
143
|
-
return () => {
|
|
144
|
-
clearTimeout(moveEndTimeout);
|
|
145
|
-
unByKey(listeners);
|
|
146
|
-
};
|
|
147
|
-
}, [map, layer, mapsetplanid]);
|
|
148
|
-
|
|
149
|
-
// Apply fetaure's minzoom and maxzoom to its style
|
|
79
|
+
// Apply feature's minzoom and maxzoom to its style
|
|
150
80
|
// TODO should be done by the mapset layer itself
|
|
151
81
|
useEffect(() => {
|
|
152
82
|
let key = null;
|
|
153
83
|
if (layer) {
|
|
154
|
-
key = layer.on("updatefeatures", () => {
|
|
84
|
+
key = layer.on("updatefeatures" as EventTypes, () => {
|
|
155
85
|
const features = layer.getSource()?.getFeatures();
|
|
156
86
|
if (!features?.length) {
|
|
157
87
|
return;
|
|
@@ -40,7 +40,6 @@ export type MobilityMapAttributeName =
|
|
|
40
40
|
| "mainlink"
|
|
41
41
|
| "mainlinktitle"
|
|
42
42
|
| "mapset"
|
|
43
|
-
| "mapsetbbox"
|
|
44
43
|
| "mapsetplanid"
|
|
45
44
|
| "mapsettags"
|
|
46
45
|
| "mapsettenants"
|
|
@@ -191,12 +190,6 @@ where:
|
|
|
191
190
|
public: true,
|
|
192
191
|
type: "boolean",
|
|
193
192
|
},
|
|
194
|
-
mapsetbbox: {
|
|
195
|
-
defaultValue: MAX_EXTENT.join(","),
|
|
196
|
-
description:
|
|
197
|
-
"The BBOX to constrain the boundary of the mapset layer in EPSG:3857 coordinates. Mandatory for mapset layer. <br/>Ex: 831634,5933959,940649,6173660 .",
|
|
198
|
-
public: false,
|
|
199
|
-
},
|
|
200
193
|
mapsetplanid: {
|
|
201
194
|
description:
|
|
202
195
|
"The id of the mapset plan to display. Mostly for debugging purposes.",
|
|
@@ -216,7 +209,7 @@ where:
|
|
|
216
209
|
public: false,
|
|
217
210
|
},
|
|
218
211
|
mapseturl: {
|
|
219
|
-
defaultValue: "https://editor.mapset.io/api/v1",
|
|
212
|
+
defaultValue: "https://editor.mapset.io/api/v1/",
|
|
220
213
|
description: `The ${geopsMapsetApiLink} url to use.`,
|
|
221
214
|
public: true,
|
|
222
215
|
},
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MocoAPI } from "mobility-toolbox-js/ol";
|
|
2
|
+
import { SeverityEnumeration } from "mobility-toolbox-js/types";
|
|
2
3
|
import { memo, useEffect, useState } from "preact/compat";
|
|
3
4
|
|
|
4
5
|
import SituationDetails from "../SituationDetails";
|
|
@@ -19,6 +20,17 @@ export type MobilityNotificationsProps = Record<
|
|
|
19
20
|
null | string | undefined
|
|
20
21
|
>;
|
|
21
22
|
|
|
23
|
+
const severityOrder = {
|
|
24
|
+
[SeverityEnumeration.NoImpact]: 2,
|
|
25
|
+
[SeverityEnumeration.Normal]: 5,
|
|
26
|
+
[SeverityEnumeration.Severe]: 6,
|
|
27
|
+
[SeverityEnumeration.Slight]: 4,
|
|
28
|
+
[SeverityEnumeration.Undefined]: 1,
|
|
29
|
+
[SeverityEnumeration.Unknown]: 0,
|
|
30
|
+
[SeverityEnumeration.VerySevere]: 7,
|
|
31
|
+
[SeverityEnumeration.VerySlight]: 3,
|
|
32
|
+
};
|
|
33
|
+
|
|
22
34
|
function MobilityNotifications({
|
|
23
35
|
apikey,
|
|
24
36
|
lang,
|
|
@@ -59,20 +71,44 @@ function MobilityNotifications({
|
|
|
59
71
|
<I18nContext.Provider value={i18n}>
|
|
60
72
|
<style>{tailwind}</style>
|
|
61
73
|
<div className="flex w-full flex-col gap-6">
|
|
62
|
-
{situations
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
{situations
|
|
75
|
+
?.sort((a, b) => {
|
|
76
|
+
// sort by startDate
|
|
77
|
+
const startDateA = a.affectedTimeIntervalsStart;
|
|
78
|
+
const startDateB = b.affectedTimeIntervalsStart;
|
|
79
|
+
if (startDateA && startDateB) {
|
|
80
|
+
if (startDateA === startDateB) {
|
|
81
|
+
// Sort by severity;
|
|
82
|
+
const severityA =
|
|
83
|
+
a.publications.find((pub) => {
|
|
84
|
+
return !!pub.severity;
|
|
85
|
+
})?.severity || 0;
|
|
86
|
+
const severityB =
|
|
87
|
+
b.publications.find((pub) => {
|
|
88
|
+
return !!pub.severity;
|
|
89
|
+
})?.severity || 0;
|
|
90
|
+
return severityOrder[severityA] > severityOrder[severityB]
|
|
91
|
+
? -1
|
|
92
|
+
: 1;
|
|
93
|
+
}
|
|
94
|
+
return startDateA < startDateB ? -1 : 1;
|
|
95
|
+
}
|
|
96
|
+
})
|
|
97
|
+
.map((situation) => {
|
|
98
|
+
console.log("Rendering situation", situation.id, situation.title);
|
|
99
|
+
return (
|
|
100
|
+
<SituationDetails
|
|
101
|
+
canToggle={true}
|
|
102
|
+
headerClassName="text-rvf-h3 font-semibold"
|
|
103
|
+
iconClassName="w-8 h-8 text-red"
|
|
104
|
+
key={situation.id}
|
|
105
|
+
reasonClassName="hidden"
|
|
106
|
+
situation={situation}
|
|
107
|
+
timeIntervalClassName="pl-1 text-base py-3 font-semibold text-balance"
|
|
108
|
+
useShortMonth={false}
|
|
109
|
+
></SituationDetails>
|
|
110
|
+
);
|
|
111
|
+
})}
|
|
76
112
|
</div>
|
|
77
113
|
</I18nContext.Provider>
|
|
78
114
|
);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
|
|
2
|
+
- creation app/repo/deploy (lint) -> 4h
|
|
3
|
+
- creation map with ArcGIS Maps SDK with SBB base layer(one or more?) -> 4h
|
|
4
|
+
- add Betriebspunkte and Linien layers on the map -> 4h
|
|
5
|
+
- using URL parameter "?betriebspunkte=BN":
|
|
6
|
+
- ask the ArcGIS FeatureServer the Betriebpunkte corresponding to URL paramter -> 4h
|
|
7
|
+
- zoom on it with a buffer if 5km -> 2h
|
|
8
|
+
- ask the ArcGIS FeatureServer the Gemeinde, the Kanton of the Betriebspunkte -> 4h
|
|
9
|
+
- ask the ArcGIS FeatureServer all Linien available in this 5km extent -> 3h
|
|
10
|
+
- show a dialog with Kanton, Gemiende and the list of selectable lines -> 4h
|
|
11
|
+
- define the default "KM von" and "KM bis" for each Linie using the 5km extent -> 4h
|
|
12
|
+
- display "KM von" and "KM bis" in the dialog as input text -> 2h
|
|
13
|
+
|
|
14
|
+
- add a tool to select an area by bbox -> 1d
|
|
15
|
+
- add a tool to select an area by "Frei Skizze" -> 1d
|
|
16
|
+
- use the area drawn to recalculate the "KM von" and "KM bis" of all Linien -> 3h
|
|
17
|
+
-
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
getFeatureCollectionToRenderFromSituation,
|
|
3
|
-
MocoLayer,
|
|
4
|
-
} from "mobility-toolbox-js/ol";
|
|
5
|
-
import { unByKey } from "ol/Observable";
|
|
6
|
-
|
|
7
|
-
import type { GeoJSONSource } from "maplibre-gl";
|
|
8
|
-
import type { MocoNotificationFeatureCollectionToRender } from "mobility-toolbox-js/ol";
|
|
9
|
-
import type { Map } from "ol";
|
|
10
|
-
|
|
11
|
-
export const MOCO_SOURCE_ID = "moco";
|
|
12
|
-
export const MOCO_MD_LAYER_FILTER = "moco";
|
|
13
|
-
class MocoLayer2 extends MocoLayer {
|
|
14
|
-
constructor(options) {
|
|
15
|
-
super(options);
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
attachToMap(map: Map): void {
|
|
19
|
-
super.attachToMap(map);
|
|
20
|
-
unByKey(this.olEventsKeys);
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
getDataByGraph(
|
|
24
|
-
data: MocoNotificationFeatureCollectionToRender,
|
|
25
|
-
): MocoNotificationFeatureCollectionToRender {
|
|
26
|
-
// const zoom = this.getMapInternal()?.getView()?.getZoom();
|
|
27
|
-
// const graphs = (
|
|
28
|
-
// this.maplibreLayer?.mapLibreMap?.getStyle() as MapsStyleSpecification
|
|
29
|
-
// ).metadata?.graphs;
|
|
30
|
-
|
|
31
|
-
// const graph = getGraphByZoom(zoom, graphs);
|
|
32
|
-
const newData: MocoNotificationFeatureCollectionToRender = {
|
|
33
|
-
features: (data?.features || []).filter((feature) => {
|
|
34
|
-
delete feature.properties?.publicationStops;
|
|
35
|
-
delete feature.properties?.publicationLines;
|
|
36
|
-
delete feature.properties?.publication;
|
|
37
|
-
delete feature.properties?.situation;
|
|
38
|
-
return (
|
|
39
|
-
feature.properties?.graph === "osm" ||
|
|
40
|
-
// feature.properties?.graph === "np_topo4" ||
|
|
41
|
-
// feature.properties?.graph === "np_topo5" ||
|
|
42
|
-
// feature.properties?.graph === "np_topo6" //||
|
|
43
|
-
feature.properties?.graph === "np_topo7" ||
|
|
44
|
-
feature.properties?.graph === "np_topo8" ||
|
|
45
|
-
feature.properties?.graph === "np_topo9" ||
|
|
46
|
-
feature.properties?.graph === "np_topo10" ||
|
|
47
|
-
feature.properties?.graph === "np_topo11" ||
|
|
48
|
-
feature.properties?.graph === "np_topo12" ||
|
|
49
|
-
feature.properties?.graph === "np_topo13" ||
|
|
50
|
-
feature.properties?.graph === "np_topo14" ||
|
|
51
|
-
feature.properties?.graph === "np_topo15"
|
|
52
|
-
);
|
|
53
|
-
}),
|
|
54
|
-
type: "FeatureCollection",
|
|
55
|
-
};
|
|
56
|
-
return newData;
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* This function updates the GeoJSON source data, with the current situations available in this.situations.
|
|
60
|
-
* @returns
|
|
61
|
-
*/
|
|
62
|
-
async updateData(): Promise<boolean | undefined> {
|
|
63
|
-
if (this.loadAll) {
|
|
64
|
-
const situations = await this.loadData();
|
|
65
|
-
// We don't use the setter here to avoid infinite loop
|
|
66
|
-
this.set("situations", situations ?? []);
|
|
67
|
-
}
|
|
68
|
-
const source = this.maplibreLayer?.mapLibreMap?.getSource(MOCO_SOURCE_ID);
|
|
69
|
-
if (!source) {
|
|
70
|
-
// eslint-disable-next-line no-console
|
|
71
|
-
console.warn("MocoLayer: No source found for id : ", MOCO_SOURCE_ID);
|
|
72
|
-
return Promise.reject(new Error("No source found"));
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
const data = {
|
|
76
|
-
features: (this.situations ?? []).flatMap((situation) => {
|
|
77
|
-
return getFeatureCollectionToRenderFromSituation(situation).features;
|
|
78
|
-
}),
|
|
79
|
-
type: "FeatureCollection",
|
|
80
|
-
} as MocoNotificationFeatureCollectionToRender;
|
|
81
|
-
// this.#dataInternal = data;
|
|
82
|
-
|
|
83
|
-
// Apply new data to the source
|
|
84
|
-
console.log(this.getDataByGraph(data));
|
|
85
|
-
// console.log(JSON.stringify(this.getDataByGraph(data)));
|
|
86
|
-
(source as GeoJSONSource).setData(this.getDataByGraph(data));
|
|
87
|
-
return Promise.resolve(true);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export default MocoLayer2;
|
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
import sbbConstructionBanner from "../icons/sbb_construction_banner.png";
|
|
2
|
-
// import sbbAddStop from "../icons/sbb_add_stop.png";
|
|
3
|
-
// import sbbAlternative from "../icons/sbb_alternative.png";
|
|
4
|
-
// import sbbCancellation from "../icons/sbb_cancellation.png";
|
|
5
|
-
import sbbConstruction from "../icons/sbb_construction.png";
|
|
6
|
-
// import sbbDelay from "../icons/sbb_delay.png";
|
|
7
|
-
import sbbDisruptionBanner from "../icons/sbb_disruption_banner.png";
|
|
8
|
-
import sbbDisruption from "../icons/sbb_disruption.png";
|
|
9
|
-
// import sbbInfo from "../icons/sbb_info.png";
|
|
10
|
-
import sbbMissedConnectionBanner from "../icons/sbb_missed_connection_banner.png";
|
|
11
|
-
import sbbMissedConnection from "../icons/sbb_missed_connection.png";
|
|
12
|
-
import sbbReplacementBusBanner from "../icons/sbb_replacementbus_banner.png";
|
|
13
|
-
// import sbbPlatformChange from "../icons/sbb_platform_change.png";
|
|
14
|
-
import sbbReplacementBus from "../icons/sbb_replacementbus.png";
|
|
15
|
-
// import sbbReRoute from "../icons/sbb_reroute.png";
|
|
16
|
-
// import warningbanner from "../icons/warning-banner.png";
|
|
17
|
-
// import warning from "../icons/warning.png";
|
|
18
|
-
|
|
19
|
-
// export const AffectedLineStyleCategoryChoices = {
|
|
20
|
-
// Construction: "CONSTRUCTION",
|
|
21
|
-
// Disruption: "DISRUPTION",
|
|
22
|
-
// IndustrialAction: "INDUSTRIAL_ACTION",
|
|
23
|
-
// LiftFailure: "LIFT_FAILURE",
|
|
24
|
-
// Other: "OTHER",
|
|
25
|
-
// RailReplacement: "RAIL_REPLACEMENT",
|
|
26
|
-
// SpecialEvent: "SPECIAL_EVENT",
|
|
27
|
-
// VehicleFaulure: "VEHICLE_FAULURE",
|
|
28
|
-
// Warning: "WARNING",
|
|
29
|
-
// } as const;
|
|
30
|
-
const defaultIcon = sbbMissedConnection;
|
|
31
|
-
const defaultIconBanner = sbbMissedConnectionBanner;
|
|
32
|
-
export const icons = {
|
|
33
|
-
CONSTRUCTION: sbbConstruction,
|
|
34
|
-
CONSTRUCTION_BANNER: sbbConstructionBanner,
|
|
35
|
-
DISRUPTION: sbbDisruption,
|
|
36
|
-
DISRUPTION_BANNER: sbbDisruptionBanner,
|
|
37
|
-
INDUSTRIAL_ACTION: defaultIcon,
|
|
38
|
-
INDUSTRIAL_ACTION_BANNER: defaultIconBanner,
|
|
39
|
-
LIFT_FAILURE: defaultIcon,
|
|
40
|
-
LIFT_FAILURE_BANNER: defaultIconBanner,
|
|
41
|
-
OTHER: defaultIcon,
|
|
42
|
-
OTHER_BANNER: defaultIconBanner,
|
|
43
|
-
RAIL_REPLACEMENT: sbbReplacementBus,
|
|
44
|
-
|
|
45
|
-
RAIL_REPLACEMENT_BANNER: sbbReplacementBusBanner,
|
|
46
|
-
SPECIAL_EVENT: defaultIcon,
|
|
47
|
-
SPECIAL_EVENT_BANNER: defaultIconBanner,
|
|
48
|
-
VEHICLE_FAULURE: defaultIcon,
|
|
49
|
-
VEHICLE_FAULURE_BANNER: defaultIconBanner,
|
|
50
|
-
warning: defaultIcon,
|
|
51
|
-
WARNING: defaultIcon,
|
|
52
|
-
warningBanner: defaultIconBanner,
|
|
53
|
-
};
|
|
54
|
-
|
|
55
|
-
// Add a source and styleLayer using the id in parameter.
|
|
56
|
-
const addSourceAndLayers = (
|
|
57
|
-
mapboxLayer,
|
|
58
|
-
sourceId,
|
|
59
|
-
sourceData,
|
|
60
|
-
styleLayer,
|
|
61
|
-
beforeLayerId,
|
|
62
|
-
) => {
|
|
63
|
-
if (!mapboxLayer.loaded) {
|
|
64
|
-
mapboxLayer.once("load", () => {
|
|
65
|
-
addSourceAndLayers(
|
|
66
|
-
mapboxLayer,
|
|
67
|
-
sourceId,
|
|
68
|
-
sourceData,
|
|
69
|
-
styleLayer,
|
|
70
|
-
beforeLayerId,
|
|
71
|
-
);
|
|
72
|
-
});
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
const { mbMap } = mapboxLayer;
|
|
76
|
-
|
|
77
|
-
Object.keys(icons).forEach((icon) => {
|
|
78
|
-
if (!mbMap.getImage(icon)) {
|
|
79
|
-
mbMap.loadImage(icons[icon]).then((image) => {
|
|
80
|
-
if (!mbMap.getImage(icon)) {
|
|
81
|
-
mbMap.addImage(icon, image.data);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
// Update source
|
|
88
|
-
if (sourceId && sourceData) {
|
|
89
|
-
const source = mbMap.getSource(sourceId);
|
|
90
|
-
if (source) {
|
|
91
|
-
source.setData(sourceData);
|
|
92
|
-
} else {
|
|
93
|
-
mbMap.addSource(sourceId, {
|
|
94
|
-
data: sourceData,
|
|
95
|
-
generateId: true,
|
|
96
|
-
type: "geojson",
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Update layer
|
|
102
|
-
if (styleLayer) {
|
|
103
|
-
let layer = mbMap.getLayer(sourceId);
|
|
104
|
-
if (layer) {
|
|
105
|
-
mbMap.removeLayer(layer.id);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
// styleLayer could be an array of styles to add.
|
|
109
|
-
let styleLayers = styleLayer;
|
|
110
|
-
if (!Array.isArray(styleLayer)) {
|
|
111
|
-
styleLayers = [styleLayer];
|
|
112
|
-
}
|
|
113
|
-
styleLayers.forEach((style) => {
|
|
114
|
-
if (mbMap.getSource(style.source)) {
|
|
115
|
-
layer = mbMap.getLayer(style.id);
|
|
116
|
-
if (layer) {
|
|
117
|
-
mbMap.removeLayer(layer.id);
|
|
118
|
-
}
|
|
119
|
-
mbMap.addLayer(style, beforeLayerId);
|
|
120
|
-
} else {
|
|
121
|
-
console.warn(
|
|
122
|
-
`The source ${style.source} doesn't exist. This layer can't be added`,
|
|
123
|
-
style,
|
|
124
|
-
);
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
export default addSourceAndLayers;
|