mobility-toolbox-js 2.0.1-beta.13 → 2.1.0
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/api/RealtimeAPI.d.ts +279 -0
- package/api/RealtimeAPI.d.ts.map +1 -0
- package/api/RealtimeAPI.js +466 -0
- package/api/RoutingAPI.d.ts +37 -0
- package/api/RoutingAPI.d.ts.map +1 -0
- package/api/RoutingAPI.js +32 -12
- package/api/StopsAPI.d.ts +38 -0
- package/api/StopsAPI.d.ts.map +1 -0
- package/api/StopsAPI.js +33 -9
- package/api/index.d.ts +4 -0
- package/api/index.d.ts.map +1 -0
- package/api/index.js +3 -3
- package/api/typedefs.d.ts +179 -0
- package/api/typedefs.d.ts.map +1 -0
- package/api/typedefs.js +75 -0
- package/common/api/HttpAPI.d.ts +31 -0
- package/common/api/HttpAPI.d.ts.map +1 -0
- package/common/api/HttpAPI.js +54 -27
- package/common/api/WebSocketAPI.d.ts +153 -0
- package/common/api/WebSocketAPI.d.ts.map +1 -0
- package/common/api/WebSocketAPI.js +330 -164
- package/common/controls/ControlCommon.d.ts +76 -0
- package/common/controls/ControlCommon.d.ts.map +1 -0
- package/common/controls/ControlCommon.js +150 -0
- package/common/controls/CopyrightControlCommon.d.ts +13 -0
- package/common/controls/CopyrightControlCommon.d.ts.map +1 -0
- package/common/controls/CopyrightControlCommon.js +34 -0
- package/common/controls/StopFinderControlCommon.d.ts +55 -0
- package/common/controls/StopFinderControlCommon.d.ts.map +1 -0
- package/common/controls/StopFinderControlCommon.js +144 -0
- package/common/index.d.ts +3 -0
- package/common/index.d.ts.map +1 -0
- package/common/index.js +2 -4
- package/common/layers/LayerCommon.d.ts +94 -0
- package/common/layers/LayerCommon.d.ts.map +1 -0
- package/common/layers/LayerCommon.js +244 -0
- package/common/mixins/RealtimeLayerMixin.d.ts +286 -0
- package/common/mixins/RealtimeLayerMixin.d.ts.map +1 -0
- package/common/mixins/RealtimeLayerMixin.js +776 -0
- package/common/mixins/UserInteractionsLayerMixin.d.ts +60 -0
- package/common/mixins/UserInteractionsLayerMixin.d.ts.map +1 -0
- package/common/mixins/UserInteractionsLayerMixin.js +241 -0
- package/common/styles/index.d.ts +5 -0
- package/common/styles/index.d.ts.map +1 -0
- package/common/styles/index.js +4 -4
- package/common/styles/realtimeDefaultStyle.d.ts +36 -0
- package/common/styles/realtimeDefaultStyle.d.ts.map +1 -0
- package/common/styles/realtimeDefaultStyle.js +275 -0
- package/common/styles/realtimeDelayStyle.d.ts +12 -0
- package/common/styles/realtimeDelayStyle.d.ts.map +1 -0
- package/common/styles/realtimeDelayStyle.js +13 -0
- package/common/styles/realtimeHeadingStyle.d.ts +12 -0
- package/common/styles/realtimeHeadingStyle.d.ts.map +1 -0
- package/common/styles/realtimeHeadingStyle.js +85 -0
- package/common/styles/realtimeSimpleStyle.d.ts +4 -0
- package/common/styles/realtimeSimpleStyle.d.ts.map +1 -0
- package/common/styles/realtimeSimpleStyle.js +23 -0
- package/common/typedefs.d.ts +111 -0
- package/common/typedefs.d.ts.map +1 -0
- package/common/typedefs.js +52 -0
- package/common/utils/compareDepartures.d.ts +11 -0
- package/common/utils/compareDepartures.d.ts.map +1 -0
- package/common/utils/compareDepartures.js +35 -0
- package/common/utils/createCanvas.d.ts +10 -0
- package/common/utils/createCanvas.d.ts.map +1 -0
- package/common/utils/createCanvas.js +27 -0
- package/common/utils/createRealtimeFilters.d.ts +13 -0
- package/common/utils/createRealtimeFilters.d.ts.map +1 -0
- package/common/utils/createRealtimeFilters.js +74 -0
- package/common/utils/debounceDeparturesMessages.d.ts +12 -0
- package/common/utils/debounceDeparturesMessages.d.ts.map +1 -0
- package/common/utils/debounceDeparturesMessages.js +24 -0
- package/common/utils/debounceWebsocketMessages.d.ts +11 -0
- package/common/utils/debounceWebsocketMessages.d.ts.map +1 -0
- package/common/utils/debounceWebsocketMessages.js +29 -0
- package/common/utils/getLayersAsFlatArray.d.ts +3 -0
- package/common/utils/getLayersAsFlatArray.d.ts.map +1 -0
- package/common/utils/getLayersAsFlatArray.js +15 -0
- package/common/utils/getMapboxMapCopyrights.d.ts +18 -0
- package/common/utils/getMapboxMapCopyrights.d.ts.map +1 -0
- package/common/utils/getMapboxMapCopyrights.js +26 -15
- package/common/utils/getMapboxRender.d.ts +7 -0
- package/common/utils/getMapboxRender.d.ts.map +1 -0
- package/common/utils/getMapboxRender.js +87 -0
- package/common/utils/getMaplibreRender.d.ts +7 -0
- package/common/utils/getMaplibreRender.d.ts.map +1 -0
- package/common/utils/getMaplibreRender.js +38 -0
- package/common/utils/getRealtimeModeSuffix.d.ts +10 -0
- package/common/utils/getRealtimeModeSuffix.d.ts.map +1 -0
- package/common/utils/getRealtimeModeSuffix.js +7 -0
- package/common/utils/getUrlWithParams.d.ts +9 -0
- package/common/utils/getUrlWithParams.d.ts.map +1 -0
- package/common/utils/getUrlWithParams.js +18 -0
- package/common/utils/getVehiclePosition.d.ts +16 -0
- package/common/utils/getVehiclePosition.d.ts.map +1 -0
- package/common/utils/getVehiclePosition.js +67 -37
- package/common/utils/index.d.ts +17 -0
- package/common/utils/index.d.ts.map +1 -0
- package/common/utils/index.js +17 -5
- package/common/utils/realtimeConfig.d.ts +49 -0
- package/common/utils/realtimeConfig.d.ts.map +1 -0
- package/common/utils/realtimeConfig.js +173 -0
- package/common/utils/removeDuplicate.d.ts +10 -0
- package/common/utils/removeDuplicate.d.ts.map +1 -0
- package/common/utils/removeDuplicate.js +12 -5
- package/common/utils/renderTrajectories.d.ts +17 -0
- package/common/utils/renderTrajectories.d.ts.map +1 -0
- package/common/utils/renderTrajectories.js +110 -0
- package/common/utils/sortAndFilterDepartures.d.ts +16 -0
- package/common/utils/sortAndFilterDepartures.d.ts.map +1 -0
- package/common/utils/sortAndFilterDepartures.js +58 -0
- package/common/utils/sortByDelay.d.ts +3 -0
- package/common/utils/sortByDelay.d.ts.map +1 -0
- package/common/utils/sortByDelay.js +17 -15
- package/common/utils/timeUtils.d.ts +24 -0
- package/common/utils/timeUtils.d.ts.map +1 -0
- package/common/utils/timeUtils.js +34 -15
- package/iife.d.ts +3 -0
- package/iife.d.ts.map +1 -0
- package/iife.js +5 -0
- package/index.d.ts +10 -0
- package/index.d.ts.map +1 -0
- package/index.js +8 -6
- package/mapbox/controls/CopyrightControl.d.ts +29 -0
- package/mapbox/controls/CopyrightControl.d.ts.map +1 -0
- package/mapbox/controls/CopyrightControl.js +44 -25
- package/mapbox/controls/index.d.ts +2 -0
- package/mapbox/controls/index.d.ts.map +1 -0
- package/mapbox/controls/index.js +2 -1
- package/mapbox/index.d.ts +6 -0
- package/mapbox/index.d.ts.map +1 -0
- package/mapbox/index.js +5 -4
- package/mapbox/layers/Layer.d.ts +59 -0
- package/mapbox/layers/Layer.d.ts.map +1 -0
- package/mapbox/layers/Layer.js +99 -55
- package/mapbox/layers/RealtimeLayer.d.ts +181 -0
- package/mapbox/layers/RealtimeLayer.d.ts.map +1 -0
- package/mapbox/layers/RealtimeLayer.js +276 -0
- package/mapbox/layers/index.d.ts +3 -0
- package/mapbox/layers/index.d.ts.map +1 -0
- package/mapbox/layers/index.js +2 -2
- package/mapbox/utils/getMercatorResolution.d.ts +9 -0
- package/mapbox/utils/getMercatorResolution.d.ts.map +1 -0
- package/mapbox/utils/getMercatorResolution.js +18 -0
- package/mapbox/utils/getSourceCoordinates.d.ts +9 -0
- package/mapbox/utils/getSourceCoordinates.d.ts.map +1 -0
- package/mapbox/utils/getSourceCoordinates.js +27 -0
- package/mapbox/utils/index.d.ts +3 -0
- package/mapbox/utils/index.d.ts.map +1 -0
- package/mapbox/utils/index.js +2 -0
- package/mbt.js +26061 -16500
- package/mbt.js.map +4 -4
- package/mbt.min.js +205 -126
- package/mbt.min.js.map +4 -4
- package/ol/controls/CopyrightControl.d.ts +31 -0
- package/ol/controls/CopyrightControl.d.ts.map +1 -0
- package/ol/controls/CopyrightControl.js +62 -36
- package/ol/controls/RoutingControl.d.ts +193 -0
- package/ol/controls/RoutingControl.d.ts.map +1 -0
- package/ol/controls/RoutingControl.js +601 -357
- package/ol/controls/StopFinderControl.d.ts +30 -0
- package/ol/controls/StopFinderControl.d.ts.map +1 -0
- package/ol/controls/StopFinderControl.js +30 -8
- package/ol/controls/index.d.ts +4 -0
- package/ol/controls/index.d.ts.map +1 -0
- package/ol/controls/index.js +3 -3
- package/ol/index.d.ts +6 -0
- package/ol/index.d.ts.map +1 -0
- package/ol/index.js +5 -5
- package/ol/layers/Layer.d.ts +86 -0
- package/ol/layers/Layer.d.ts.map +1 -0
- package/ol/layers/Layer.js +163 -77
- package/ol/layers/MapGlLayer.d.ts +67 -0
- package/ol/layers/MapGlLayer.d.ts.map +1 -0
- package/ol/layers/MapGlLayer.js +218 -0
- package/ol/layers/MapboxLayer.d.ts +50 -0
- package/ol/layers/MapboxLayer.d.ts.map +1 -0
- package/ol/layers/MapboxLayer.js +99 -193
- package/ol/layers/MapboxStyleLayer.d.ts +129 -0
- package/ol/layers/MapboxStyleLayer.d.ts.map +1 -0
- package/ol/layers/MapboxStyleLayer.js +362 -171
- package/ol/layers/MaplibreLayer.d.ts +28 -0
- package/ol/layers/MaplibreLayer.d.ts.map +1 -0
- package/ol/layers/MaplibreLayer.js +30 -135
- package/ol/layers/RealtimeLayer.d.ts +202 -0
- package/ol/layers/RealtimeLayer.d.ts.map +1 -0
- package/ol/layers/RealtimeLayer.js +340 -0
- package/ol/layers/RoutingLayer.d.ts +34 -0
- package/ol/layers/RoutingLayer.d.ts.map +1 -0
- package/ol/layers/RoutingLayer.js +72 -48
- package/ol/layers/VectorLayer.d.ts +25 -0
- package/ol/layers/VectorLayer.d.ts.map +1 -0
- package/ol/layers/VectorLayer.js +34 -18
- package/ol/layers/WMSLayer.d.ts +42 -0
- package/ol/layers/WMSLayer.d.ts.map +1 -0
- package/ol/layers/WMSLayer.js +84 -34
- package/ol/layers/index.d.ts +9 -0
- package/ol/layers/index.d.ts.map +1 -0
- package/ol/layers/index.js +8 -8
- package/ol/styles/fullTrajectoryDelayStyle.d.ts +4 -0
- package/ol/styles/fullTrajectoryDelayStyle.d.ts.map +1 -0
- package/ol/styles/fullTrajectoryDelayStyle.js +26 -24
- package/ol/styles/fullTrajectoryStyle.d.ts +5 -0
- package/ol/styles/fullTrajectoryStyle.d.ts.map +1 -0
- package/ol/styles/fullTrajectoryStyle.js +40 -39
- package/ol/styles/index.d.ts +3 -0
- package/ol/styles/index.d.ts.map +1 -0
- package/ol/styles/index.js +2 -2
- package/package.json +81 -133
- package/setupTests.d.ts +2 -0
- package/setupTests.d.ts.map +1 -0
- package/setupTests.js +26 -0
- package/types/common.d.ts +122 -0
- package/types/index.d.ts +11 -0
- package/types/realtime.d.ts +320 -0
- package/types/routing.d.ts +206 -0
- package/types/stops.d.ts +143 -0
- package/README.md +0 -23
- package/api/RoutingAPI.test.js +0 -25
- package/api/StopsAPI.test.js +0 -22
- package/api/TralisAPI.js +0 -359
- package/api/TralisAPI.test.js +0 -67
- package/api/TralisAPIUtils.js +0 -43
- package/common/Tracker.js +0 -93
- package/common/api/HttpAPI.test.js +0 -50
- package/common/api/WebSocketAPI.test.js +0 -311
- package/common/controls/Control.js +0 -81
- package/common/controls/Control.test.js +0 -87
- package/common/layers/Layer.js +0 -213
- package/common/layers/Layer.test.js +0 -526
- package/common/mixins/CopyrightMixin.js +0 -24
- package/common/mixins/SearchMixin.js +0 -110
- package/common/mixins/TralisLayerMixin.js +0 -479
- package/common/styles/trackerDefaultStyle.js +0 -197
- package/common/styles/trackerDelayStyle.js +0 -8
- package/common/styles/trackerSimpleStyle.js +0 -18
- package/common/trackerConfig.js +0 -152
- package/common/trackerConfig.test.js +0 -23
- package/common/utils/createTrackerFilters.js +0 -56
- package/common/utils/createTrackerFilters.test.js +0 -79
- package/common/utils/getMapboxMapCopyrights.test.js +0 -40
- package/common/utils/getMapboxStyleUrl.js +0 -22
- package/common/utils/removeDuplicate.test.js +0 -19
- package/common/utils/timeUtils.test.js +0 -10
- package/mapbox/layers/Layer.test.js +0 -182
- package/mapbox/layers/TralisLayer.js +0 -182
- package/mapbox/layers/TralisLayer.test.js +0 -38
- package/mapbox/utils.js +0 -32
- package/ol/controls/CopyrightControl.test.js +0 -165
- package/ol/controls/RoutingControl.test.js +0 -151
- package/ol/controls/StopFinderControl.test.js +0 -48
- package/ol/layers/Layer.test.js +0 -174
- package/ol/layers/MapboxLayer.test.js +0 -160
- package/ol/layers/MapboxStyleLayer.test.js +0 -231
- package/ol/layers/RoutingLayer.test.js +0 -40
- package/ol/layers/TralisLayer.js +0 -185
- package/ol/layers/TralisLayer.test.js +0 -79
- package/ol/layers/VectorLayer.test.js +0 -87
- package/ol/layers/WMSLayer.test.js +0 -76
|
@@ -1,387 +1,631 @@
|
|
|
1
|
-
import { Feature } from
|
|
2
|
-
import { LineString, Point } from
|
|
3
|
-
import { Modify } from
|
|
4
|
-
import { unByKey } from
|
|
5
|
-
import { click } from
|
|
6
|
-
import { GeoJSON } from
|
|
7
|
-
import { buffer } from
|
|
8
|
-
import { fromLonLat, toLonLat } from
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
1
|
+
import { Feature } from 'ol';
|
|
2
|
+
import { LineString, Point } from 'ol/geom';
|
|
3
|
+
import { Modify } from 'ol/interaction';
|
|
4
|
+
import { unByKey } from 'ol/Observable';
|
|
5
|
+
import { click } from 'ol/events/condition';
|
|
6
|
+
import { GeoJSON } from 'ol/format';
|
|
7
|
+
import { buffer } from 'ol/extent';
|
|
8
|
+
import { fromLonLat, toLonLat } from 'ol/proj';
|
|
9
|
+
import BaseEvent from 'ol/events/Event';
|
|
10
|
+
import { RoutingAPI } from '../../api';
|
|
11
|
+
import ControlCommon from '../../common/controls/ControlCommon';
|
|
12
|
+
import RoutingLayer from '../layers/RoutingLayer';
|
|
13
|
+
// Examples for a single hop:
|
|
14
|
+
// basel sbb a station named "basel sbb"
|
|
15
|
+
// ZUE, station "Zürich HB" by its common abbreviation
|
|
16
|
+
// Zürich Hauptbahnhof or HBF Zürich are all valid synonyms für "Zürich HB"
|
|
17
|
+
// @47.37811,8.53935 a station at position 47.37811, 8.53935
|
|
18
|
+
// @47.37811,8.53935$4 track 4 in a station at position 47.37811, 8.53935
|
|
19
|
+
// zürich hb@47.37811,8.53935$8 track 8 in station "Zürich HB" at position 47.37811, 8.53935
|
|
20
|
+
/** @private */
|
|
12
21
|
const REGEX_VIA_POINT = /^([^@$!\n]*)(@?([\d.]+),([\d.]+))?(\$?([a-zA-Z0-9]{0,2}))$/;
|
|
22
|
+
// Examples for a single hop:
|
|
23
|
+
//
|
|
24
|
+
// 47.37811,8.53935 a position 47.37811, 8.53935
|
|
25
|
+
/** @private */
|
|
13
26
|
const REGEX_VIA_POINT_COORD = /^([\d.]+),([\d.]+)$/;
|
|
27
|
+
// Examples for a single hop:
|
|
28
|
+
//
|
|
29
|
+
// !8596126 a station with id 8596126
|
|
30
|
+
// !8596126$4 a station with id 8596126
|
|
31
|
+
/** @private */
|
|
14
32
|
const REGEX_VIA_POINT_STATION_ID = /^!([^$]*)(\$?([a-zA-Z0-9]{0,2}))$/;
|
|
15
|
-
|
|
33
|
+
/** @private */
|
|
34
|
+
const STOP_FETCH_ABORT_CONTROLLER_KEY = 'stop-fetch';
|
|
35
|
+
/** @private */
|
|
16
36
|
const getFlatCoordinatesFromSegments = (segmentArray) => {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
constructor(options = {}) {
|
|
25
|
-
super(options);
|
|
26
|
-
Object.defineProperties(this, {
|
|
27
|
-
mot: {
|
|
28
|
-
get: () => this.get("mot"),
|
|
29
|
-
set: (newMot) => {
|
|
30
|
-
if (newMot) {
|
|
31
|
-
this.set("mot", newMot);
|
|
32
|
-
if (this.viaPoints) {
|
|
33
|
-
this.drawRoute();
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
loading: {
|
|
39
|
-
get: () => this.get("loading"),
|
|
40
|
-
set: (newLoading) => {
|
|
41
|
-
this.set("loading", newLoading);
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
modify: {
|
|
45
|
-
get: () => this.get("modify"),
|
|
46
|
-
set: (modify) => {
|
|
47
|
-
this.set("modify", modify);
|
|
37
|
+
const coords = [];
|
|
38
|
+
segmentArray.forEach((seg) => {
|
|
39
|
+
var _a;
|
|
40
|
+
// @ts-ignore
|
|
41
|
+
const coordArr = (_a = seg.getGeometry()) === null || _a === void 0 ? void 0 : _a.getCoordinates();
|
|
42
|
+
if (coordArr === null || coordArr === void 0 ? void 0 : coordArr.length) {
|
|
43
|
+
coords.push(...coordArr);
|
|
48
44
|
}
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
this.loading = false;
|
|
52
|
-
this.graphs = options.graphs || [["osm", 0, 99]];
|
|
53
|
-
this.mot = options.mot || "bus";
|
|
54
|
-
this.modify = options.modify !== false;
|
|
55
|
-
this.routingApiParams = options.routingApiParams || {};
|
|
56
|
-
this.useRawViaPoints = options.useRawViaPoints || false;
|
|
57
|
-
this.snapToClosestStation = options.snapToClosestStation || false;
|
|
58
|
-
this.cacheStationData = {};
|
|
59
|
-
this.abortControllers = [];
|
|
60
|
-
this.apiKey = options.apiKey;
|
|
61
|
-
this.stopsApiKey = options.stopsApiKey || this.apiKey;
|
|
62
|
-
this.segments = [];
|
|
63
|
-
this.stopsApiUrl = options.stopsApiUrl || "https://api.geops.io/stops/v1/";
|
|
64
|
-
this.api = new RoutingAPI({
|
|
65
|
-
...options
|
|
66
|
-
});
|
|
67
|
-
this.routingLayer = options.routingLayer || new RoutingLayer({
|
|
68
|
-
name: "routing-layer",
|
|
69
|
-
style: options.style
|
|
70
|
-
});
|
|
71
|
-
this.onRouteError = options.onRouteError || ((error) => {
|
|
72
|
-
this.dispatchEvent({
|
|
73
|
-
type: "change:route",
|
|
74
|
-
target: this
|
|
75
|
-
});
|
|
76
|
-
this.reset();
|
|
77
|
-
console.error(error);
|
|
78
|
-
});
|
|
79
|
-
this.viaPoints = [];
|
|
80
|
-
this.onMapClick = this.onMapClick.bind(this);
|
|
81
|
-
this.onModifyEnd = this.onModifyEnd.bind(this);
|
|
82
|
-
this.onModifyStart = this.onModifyStart.bind(this);
|
|
83
|
-
this.apiChangeListener = () => this.drawRoute();
|
|
84
|
-
this.createModifyInteraction();
|
|
85
|
-
}
|
|
86
|
-
static getGraphsResolutions(graphs, map) {
|
|
87
|
-
const view = map.getView();
|
|
88
|
-
return graphs.map(([, minZoom, maxZoom]) => [
|
|
89
|
-
view.getResolutionForZoom(minZoom),
|
|
90
|
-
view.getResolutionForZoom(maxZoom || minZoom + 1)
|
|
91
|
-
]);
|
|
92
|
-
}
|
|
93
|
-
addViaPoint(coordinatesOrString, index = this.viaPoints.length, overwrite = 0) {
|
|
94
|
-
this.viaPoints.splice(index, overwrite, coordinatesOrString);
|
|
95
|
-
this.drawRoute();
|
|
96
|
-
this.dispatchEvent({
|
|
97
|
-
type: "change:route",
|
|
98
|
-
target: this
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
removeViaPoint(index = this.viaPoints.length - 1) {
|
|
102
|
-
if (this.viaPoints.length && this.viaPoints[index]) {
|
|
103
|
-
this.viaPoints.splice(index, 1);
|
|
104
|
-
}
|
|
105
|
-
this.drawRoute();
|
|
106
|
-
this.dispatchEvent({
|
|
107
|
-
type: "change:route",
|
|
108
|
-
target: this
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
setViaPoints(coordinateArray) {
|
|
112
|
-
this.viaPoints = [...coordinateArray];
|
|
113
|
-
this.drawRoute();
|
|
114
|
-
this.dispatchEvent({
|
|
115
|
-
type: "change:route",
|
|
116
|
-
target: this
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
reset() {
|
|
120
|
-
this.abortRequests();
|
|
121
|
-
this.viaPoints = [];
|
|
122
|
-
this.routingLayer.olLayer.getSource().clear();
|
|
123
|
-
this.dispatchEvent({
|
|
124
|
-
type: "change:route",
|
|
125
|
-
target: this
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
abortRequests() {
|
|
129
|
-
this.graphs.forEach(([graph]) => {
|
|
130
|
-
if (this.abortControllers[graph]) {
|
|
131
|
-
this.abortControllers[graph].abort();
|
|
132
|
-
}
|
|
133
|
-
this.abortControllers[graph] = new AbortController();
|
|
134
|
-
});
|
|
135
|
-
this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]?.abort();
|
|
136
|
-
this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY] = new AbortController();
|
|
137
|
-
this.loading = false;
|
|
138
|
-
}
|
|
139
|
-
drawRoute() {
|
|
140
|
-
this.abortRequests();
|
|
141
|
-
this.routingLayer.olLayer.getSource().clear();
|
|
142
|
-
if (!this.viaPoints.length) {
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
if (this.viaPoints.length === 1) {
|
|
146
|
-
return this.drawViaPoint(this.viaPoints[0], 0, this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]);
|
|
147
|
-
}
|
|
148
|
-
const formattedViaPoints = this.viaPoints.map((viaPoint) => {
|
|
149
|
-
if (Array.isArray(viaPoint)) {
|
|
150
|
-
const projection = this.map.getView().getProjection();
|
|
151
|
-
const [lon, lat] = toLonLat(viaPoint, projection);
|
|
152
|
-
return this.snapToClosestStation ? [`@${lat}`, lon] : [lat, lon];
|
|
153
|
-
}
|
|
154
|
-
return this.useRawViaPoints ? viaPoint : `!${viaPoint}`;
|
|
155
45
|
});
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
routeFeature.set("minResolution", this.graphsResolutions[index][0]);
|
|
194
|
-
routeFeature.set("maxResolution", this.graphsResolutions[index][1]);
|
|
195
|
-
this.routingLayer.olLayer.getSource().addFeature(routeFeature);
|
|
46
|
+
return coords;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Display a route of a specified mean of transport.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* import { Map } from 'ol';
|
|
53
|
+
* import { RoutingControl } from 'mobility-toolbox-js/ol';
|
|
54
|
+
*
|
|
55
|
+
* const map = new Map({
|
|
56
|
+
* target: 'map'
|
|
57
|
+
* });
|
|
58
|
+
*
|
|
59
|
+
* const control = new RoutingControl();
|
|
60
|
+
*
|
|
61
|
+
* control.attachToMap(map)
|
|
62
|
+
*
|
|
63
|
+
* @classproperty {string} apiKey - Key used for RoutingApi requests.
|
|
64
|
+
* @classproperty {string} stopsApiKey - Key used for Stop lookup requests (defaults to apiKey).
|
|
65
|
+
* @classproperty {string} stopsApiUrl - Url used for Stop lookup requests (defaults to https://api.geops.io/stops/v1/lookup/).
|
|
66
|
+
* @classproperty {Array.<Array<graph="osm", minZoom=0, maxZoom=99>>} graphs - Array of routing graphs and min/max zoom levels. If you use the control in combination with the [geOps Maps API](https://developer.geops.io/apis/maps/), you may want to use the optimal level of generalizations: "[['gen4', 0, 8], ['gen3', 8, 9], ['gen2', 9, 11], ['gen1', 11, 13], ['osm', 13, 99]]"
|
|
67
|
+
* @classproperty {string} mot - Mean of transport to be used for routing.
|
|
68
|
+
* @classproperty {object} routingApiParams - object of additional parameters to pass to the routing api request.
|
|
69
|
+
* @classproperty {object} snapToClosestStation - If true, the routing will snap the coordinate to the closest station. Default to false.
|
|
70
|
+
* @classproperty {boolean} useRawViaPoints - Experimental property. Wen true, it allows the user to add via points using different kind of string. See "via" parameter defined by the [geOps Routing API](https://developer.geops.io/apis/routing/). Default to false, only array of coordinates and station's id are supported as via points.
|
|
71
|
+
* @classproperty {RoutingLayer|Layer} routingLayer - Layer for adding route features.
|
|
72
|
+
* @classproperty {function} onRouteError - Callback on error.
|
|
73
|
+
* @classproperty {boolean} loading - True if the control is requesting the backend.
|
|
74
|
+
* @see <a href="/example/ol-routing">Openlayers routing example</a>
|
|
75
|
+
*
|
|
76
|
+
* @extends {Control}
|
|
77
|
+
* @implements {RoutingInterface}
|
|
78
|
+
*/
|
|
79
|
+
class RoutingControl extends ControlCommon {
|
|
80
|
+
constructor(options = {}) {
|
|
81
|
+
super(options);
|
|
82
|
+
this.viaPoints = [];
|
|
196
83
|
this.loading = false;
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
84
|
+
this.graphs = [];
|
|
85
|
+
this.modify = true;
|
|
86
|
+
this.useRawViaPoints = false;
|
|
87
|
+
this.snapToClosestStation = false;
|
|
88
|
+
this.cacheStationData = {};
|
|
89
|
+
this.abortControllers = {};
|
|
201
90
|
this.segments = [];
|
|
202
|
-
this.
|
|
203
|
-
|
|
204
|
-
|
|
91
|
+
this.format = new GeoJSON({ featureProjection: 'EPSG:3857' });
|
|
92
|
+
this.initialRouteDrag = {};
|
|
93
|
+
Object.defineProperties(this, {
|
|
94
|
+
mot: {
|
|
95
|
+
get: () => this.get('mot'),
|
|
96
|
+
set: (newMot) => {
|
|
97
|
+
if (newMot) {
|
|
98
|
+
this.set('mot', newMot);
|
|
99
|
+
if (this.viaPoints) {
|
|
100
|
+
this.drawRoute();
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
loading: {
|
|
106
|
+
get: () => this.get('loading'),
|
|
107
|
+
set: (newLoading) => {
|
|
108
|
+
this.set('loading', newLoading);
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
modify: {
|
|
112
|
+
get: () => this.get('modify'),
|
|
113
|
+
set: (modify) => {
|
|
114
|
+
this.set('modify', modify);
|
|
115
|
+
},
|
|
116
|
+
},
|
|
205
117
|
});
|
|
206
|
-
|
|
118
|
+
/** True if the control is requesting the backend. */
|
|
207
119
|
this.loading = false;
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
120
|
+
/** @ignore */
|
|
121
|
+
this.graphs = options.graphs || [['osm', 0, 99]];
|
|
122
|
+
/** @ignore */
|
|
123
|
+
this.mot = options.mot || 'bus';
|
|
124
|
+
/** @ignore */
|
|
125
|
+
this.modify = options.modify !== false;
|
|
126
|
+
/** @ignore */
|
|
127
|
+
this.routingApiParams = options.routingApiParams;
|
|
128
|
+
/** @ignore */
|
|
129
|
+
this.useRawViaPoints = options.useRawViaPoints || false;
|
|
130
|
+
/** @ignore */
|
|
131
|
+
this.snapToClosestStation = options.snapToClosestStation || false;
|
|
132
|
+
/** @ignore */
|
|
133
|
+
this.apiKey = options.apiKey;
|
|
134
|
+
/** @ignore */
|
|
135
|
+
this.stopsApiKey = options.stopsApiKey || this.apiKey;
|
|
136
|
+
/** @ignore */
|
|
137
|
+
this.stopsApiUrl = options.stopsApiUrl || 'https://api.geops.io/stops/v1/';
|
|
138
|
+
/** @ignore */
|
|
139
|
+
this.api = new RoutingAPI(Object.assign({}, options));
|
|
140
|
+
/** @ignore */
|
|
141
|
+
this.routingLayer =
|
|
142
|
+
options.routingLayer ||
|
|
143
|
+
new RoutingLayer({
|
|
144
|
+
name: 'routing-layer',
|
|
145
|
+
style: options.style,
|
|
146
|
+
});
|
|
147
|
+
/** @ignore */
|
|
148
|
+
this.onRouteError =
|
|
149
|
+
options.onRouteError ||
|
|
150
|
+
((error) => {
|
|
151
|
+
this.dispatchEvent(new BaseEvent('change:route'));
|
|
152
|
+
this.reset();
|
|
153
|
+
// eslint-disable-next-line no-console
|
|
154
|
+
console.error(error);
|
|
155
|
+
});
|
|
156
|
+
/** @ignore */
|
|
157
|
+
this.onMapClick = this.onMapClick.bind(this);
|
|
158
|
+
/** @ignore */
|
|
159
|
+
this.onModifyEnd = this.onModifyEnd.bind(this);
|
|
160
|
+
/** @ignore */
|
|
161
|
+
this.onModifyStart = this.onModifyStart.bind(this);
|
|
162
|
+
/** @ignore */
|
|
163
|
+
this.createModifyInteraction();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Calculate at which resolutions corresponds each generalizations.
|
|
167
|
+
*
|
|
168
|
+
* @private
|
|
169
|
+
*/
|
|
170
|
+
static getGraphsResolutions(graphs, map) {
|
|
171
|
+
const view = map.getView();
|
|
172
|
+
return graphs.map(([, minZoom, maxZoom]) => [
|
|
173
|
+
view.getResolutionForZoom(minZoom),
|
|
174
|
+
view.getResolutionForZoom(maxZoom || minZoom + 1),
|
|
175
|
+
]);
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Adds/Replaces a viaPoint to the viaPoints array and redraws route:
|
|
179
|
+
* Adds a viaPoint at end of array by default.
|
|
180
|
+
* If an index is passed a viaPoint is added at the specified index.
|
|
181
|
+
* If an index is passed and overwrite x is > 0, x viaPoints at the specified
|
|
182
|
+
* index are replaced with a single new viaPoint.
|
|
183
|
+
* @param {number[]|string} coordinates Array of coordinates
|
|
184
|
+
* @param {number} [index=-1] Integer representing the index of the added viaPoint. If not specified, the viaPoint is added at the end of the array.
|
|
185
|
+
* @param {number} [overwrite=0] Marks the number of viaPoints that are removed at the specified index on add.
|
|
186
|
+
*/
|
|
187
|
+
addViaPoint(coordinatesOrString, index = -1, overwrite = 0) {
|
|
188
|
+
/* Add/Insert/Overwrite viapoint and redraw route */
|
|
189
|
+
this.viaPoints.splice(index === -1 ? this.viaPoints.length : index, overwrite, coordinatesOrString);
|
|
190
|
+
this.drawRoute();
|
|
191
|
+
this.dispatchEvent(new BaseEvent('change:route'));
|
|
218
192
|
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
const { coordinates } = stationData.features[0].geometry;
|
|
229
|
-
this.cacheStationData[viaPoint] = fromLonLat(coordinates);
|
|
230
|
-
pointFeature.set("viaPointTrack", track2);
|
|
231
|
-
pointFeature.setGeometry(new Point(fromLonLat(coordinates)));
|
|
232
|
-
this.routingLayer.olLayer.getSource().addFeature(pointFeature);
|
|
233
|
-
return pointFeature;
|
|
234
|
-
}).catch((error) => {
|
|
235
|
-
if (error.name === "AbortError") {
|
|
236
|
-
return;
|
|
193
|
+
/**
|
|
194
|
+
* Removes a viaPoint at the passed array index and redraws route
|
|
195
|
+
* By default the last viaPoint is removed.
|
|
196
|
+
* @param {number} index Integer representing the index of the viaPoint to delete.
|
|
197
|
+
*/
|
|
198
|
+
removeViaPoint(index = (this.viaPoints || []).length - 1) {
|
|
199
|
+
/* Remove viapoint and redraw route */
|
|
200
|
+
if (this.viaPoints.length && this.viaPoints[index]) {
|
|
201
|
+
this.viaPoints.splice(index, 1);
|
|
237
202
|
}
|
|
238
|
-
this.
|
|
239
|
-
|
|
240
|
-
target: this
|
|
241
|
-
});
|
|
242
|
-
this.onRouteError(error, this);
|
|
243
|
-
this.loading = false;
|
|
244
|
-
});
|
|
203
|
+
this.drawRoute();
|
|
204
|
+
this.dispatchEvent(new BaseEvent('change:route'));
|
|
245
205
|
}
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
206
|
+
/**
|
|
207
|
+
* Replaces the current viaPoints with a new coordinate array.
|
|
208
|
+
* @param {Array<Array<number>>} coordinateArray Array of nested coordinates
|
|
209
|
+
*/
|
|
210
|
+
setViaPoints(coordinateArray) {
|
|
211
|
+
this.viaPoints = [...coordinateArray];
|
|
212
|
+
this.drawRoute();
|
|
213
|
+
this.dispatchEvent(new BaseEvent('change:route'));
|
|
252
214
|
}
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
215
|
+
/**
|
|
216
|
+
* Removes all viaPoints, clears the source and triggers a change event
|
|
217
|
+
*/
|
|
218
|
+
reset() {
|
|
219
|
+
var _a, _b, _c;
|
|
220
|
+
// Clear viaPoints and source
|
|
221
|
+
this.abortRequests();
|
|
222
|
+
this.viaPoints = [];
|
|
223
|
+
(_c = (_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.olLayer) === null || _b === void 0 ? void 0 : _b.getSource()) === null || _c === void 0 ? void 0 : _c.clear();
|
|
224
|
+
this.dispatchEvent(new BaseEvent('change:route'));
|
|
260
225
|
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
226
|
+
/**
|
|
227
|
+
* Aborts viapoint and route requests
|
|
228
|
+
* @private
|
|
229
|
+
*/
|
|
230
|
+
abortRequests() {
|
|
231
|
+
var _a;
|
|
232
|
+
// Abort Routing API requests
|
|
233
|
+
this.graphs.forEach((graph) => {
|
|
234
|
+
const graphName = graph[0];
|
|
235
|
+
if (this.abortControllers[graphName]) {
|
|
236
|
+
this.abortControllers[graphName].abort();
|
|
237
|
+
}
|
|
238
|
+
this.abortControllers[graphName] = new AbortController();
|
|
273
239
|
});
|
|
274
|
-
|
|
240
|
+
// Abort Stops API requests
|
|
241
|
+
(_a = this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]) === null || _a === void 0 ? void 0 : _a.abort();
|
|
242
|
+
this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY] =
|
|
243
|
+
new AbortController();
|
|
275
244
|
this.loading = false;
|
|
276
|
-
return null;
|
|
277
|
-
});
|
|
278
245
|
}
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
246
|
+
/**
|
|
247
|
+
* Draws route on map using an array of coordinates:
|
|
248
|
+
* If a single coordinate is passed a single point feature is added to map.
|
|
249
|
+
* If two or more coordinates are passed a request to the RoutingAPI fetches
|
|
250
|
+
* the route using the passed coordinates and the current mot.
|
|
251
|
+
* @private
|
|
252
|
+
*/
|
|
253
|
+
drawRoute() {
|
|
254
|
+
var _a, _b, _c, _d, _e, _f;
|
|
255
|
+
/* Calls RoutingAPI to draw a route using the viaPoints array */
|
|
256
|
+
this.abortRequests();
|
|
257
|
+
(_c = (_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.olLayer) === null || _b === void 0 ? void 0 : _b.getSource()) === null || _c === void 0 ? void 0 : _c.clear();
|
|
258
|
+
if (!this.viaPoints.length) {
|
|
259
|
+
return null;
|
|
260
|
+
}
|
|
261
|
+
if (this.viaPoints.length === 1) {
|
|
262
|
+
// Add point for first node
|
|
263
|
+
return this.drawViaPoint(this.viaPoints[0], 0, this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]);
|
|
264
|
+
}
|
|
265
|
+
const formattedViaPoints = this.viaPoints.map((viaPoint) => {
|
|
266
|
+
var _a;
|
|
267
|
+
if (Array.isArray(viaPoint)) {
|
|
268
|
+
const projection = (_a = this.map) === null || _a === void 0 ? void 0 : _a.getView().getProjection();
|
|
269
|
+
// viaPoint is a coordinate
|
|
270
|
+
// Coordinates need to be reversed as required by the backend RoutingAPI
|
|
271
|
+
const [lon, lat] = toLonLat(viaPoint, projection);
|
|
272
|
+
return this.snapToClosestStation ? [`@${lat}`, lon] : [lat, lon];
|
|
273
|
+
}
|
|
274
|
+
// viaPoint is a string to use as it is
|
|
275
|
+
return this.useRawViaPoints ? viaPoint : `!${viaPoint}`;
|
|
276
|
+
});
|
|
277
|
+
this.loading = true;
|
|
278
|
+
// Clear source
|
|
279
|
+
(_f = (_e = (_d = this.routingLayer) === null || _d === void 0 ? void 0 : _d.olLayer) === null || _e === void 0 ? void 0 : _e.getSource()) === null || _f === void 0 ? void 0 : _f.clear();
|
|
280
|
+
// Create point features for the viaPoints
|
|
281
|
+
this.viaPoints.forEach((viaPoint, idx) => this.drawViaPoint(viaPoint, idx, this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]));
|
|
282
|
+
return Promise.all(this.graphs.map(([graph], index) => {
|
|
283
|
+
const { signal } = this.abortControllers[graph];
|
|
284
|
+
if (!this.api) {
|
|
285
|
+
return Promise.resolve([]);
|
|
286
|
+
}
|
|
287
|
+
return this.api
|
|
288
|
+
.route(Object.assign({ graph, via: `${formattedViaPoints.join('|')}`, mot: this.mot,
|
|
289
|
+
// @ts-ignore missing property in swagger
|
|
290
|
+
'resolve-hops': false, elevation: false, 'coord-radius': 100.0, 'coord-punish': 1000.0 }, (this.routingApiParams || {})), { signal })
|
|
291
|
+
.then((featureCollection) => {
|
|
292
|
+
var _a, _b, _c, _d;
|
|
293
|
+
this.segments = this.format.readFeatures(featureCollection);
|
|
294
|
+
if (this.mot === 'foot') {
|
|
295
|
+
// Extract unique values from viaPoint target value
|
|
296
|
+
const uniqueVias = this.segments.reduce((resultVias, currentFeat) => {
|
|
297
|
+
const segTrg = currentFeat.get('trg');
|
|
298
|
+
return resultVias.find((via) => via[0] === segTrg[0] && via[1] === segTrg[1])
|
|
299
|
+
? resultVias
|
|
300
|
+
: [...resultVias, segTrg];
|
|
301
|
+
}, []);
|
|
302
|
+
// Create LineString features from segments with same unique value
|
|
303
|
+
this.segments = uniqueVias.map((via) => {
|
|
304
|
+
const viaSegments = this.segments.filter((seg) => {
|
|
305
|
+
const segTrg = seg.get('trg');
|
|
306
|
+
return segTrg[0] === via[0] && segTrg[1] === via[1];
|
|
307
|
+
});
|
|
308
|
+
const coords = getFlatCoordinatesFromSegments(viaSegments);
|
|
309
|
+
return new Feature({
|
|
310
|
+
geometry: new LineString(coords),
|
|
311
|
+
});
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
// Create the new route. This route will be modifiable by the Modifiy interaction.
|
|
315
|
+
const coords = getFlatCoordinatesFromSegments(this.segments);
|
|
316
|
+
const routeFeature = new Feature({
|
|
317
|
+
geometry: new LineString(coords),
|
|
318
|
+
});
|
|
319
|
+
routeFeature.set('graph', graph);
|
|
320
|
+
routeFeature.set('mot', this.mot);
|
|
321
|
+
if (this.graphsResolutions &&
|
|
322
|
+
((_a = this.graphsResolutions[index]) === null || _a === void 0 ? void 0 : _a.length) >= 2) {
|
|
323
|
+
routeFeature.set('minResolution', this.graphsResolutions[index][0]);
|
|
324
|
+
routeFeature.set('maxResolution', this.graphsResolutions[index][1]);
|
|
325
|
+
}
|
|
326
|
+
(_d = (_c = (_b = this.routingLayer) === null || _b === void 0 ? void 0 : _b.olLayer) === null || _c === void 0 ? void 0 : _c.getSource()) === null || _d === void 0 ? void 0 : _d.addFeature(routeFeature);
|
|
327
|
+
this.loading = false;
|
|
328
|
+
})
|
|
329
|
+
.catch((error) => {
|
|
330
|
+
if (error.name === 'AbortError') {
|
|
331
|
+
// Ignore abort error
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
this.segments = [];
|
|
335
|
+
// Dispatch error event and execute error function
|
|
336
|
+
this.dispatchEvent(new BaseEvent('error'));
|
|
337
|
+
this.onRouteError(error, this);
|
|
338
|
+
this.loading = false;
|
|
339
|
+
});
|
|
340
|
+
}));
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Draw a via point. This function can parse all the possibilitiies
|
|
344
|
+
*
|
|
345
|
+
* @private
|
|
346
|
+
*/
|
|
347
|
+
drawViaPoint(viaPoint, idx, abortController) {
|
|
348
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
|
|
349
|
+
const pointFeature = new Feature();
|
|
350
|
+
pointFeature.set('viaPointIdx', idx);
|
|
351
|
+
// The via point is a coordinate using the current map's projection
|
|
352
|
+
if (Array.isArray(viaPoint)) {
|
|
353
|
+
pointFeature.setGeometry(new Point(viaPoint));
|
|
354
|
+
(_c = (_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.olLayer) === null || _b === void 0 ? void 0 : _b.getSource()) === null || _c === void 0 ? void 0 : _c.addFeature(pointFeature);
|
|
355
|
+
return Promise.resolve(pointFeature);
|
|
356
|
+
}
|
|
357
|
+
// Possibility to parse:
|
|
358
|
+
//
|
|
359
|
+
// !8596126 a station with id 8596126
|
|
360
|
+
// !8596126$4 a station with id 8596126
|
|
361
|
+
if (!this.useRawViaPoints || REGEX_VIA_POINT_STATION_ID.test(viaPoint)) {
|
|
362
|
+
let stationId;
|
|
363
|
+
let track;
|
|
364
|
+
if (this.useRawViaPoints) {
|
|
365
|
+
[, stationId, , track] =
|
|
366
|
+
REGEX_VIA_POINT_STATION_ID.exec(viaPoint) || [];
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
[stationId, track] = viaPoint.split('$');
|
|
370
|
+
}
|
|
371
|
+
return fetch(`${this.stopsApiUrl}lookup/${stationId}?key=${this.stopsApiKey}`, { signal: abortController.signal })
|
|
372
|
+
.then((res) => res.json())
|
|
373
|
+
.then((stationData) => {
|
|
374
|
+
var _a, _b, _c;
|
|
375
|
+
const { coordinates } = stationData.features[0].geometry;
|
|
376
|
+
this.cacheStationData[viaPoint] = fromLonLat(coordinates);
|
|
377
|
+
pointFeature.set('viaPointTrack', track);
|
|
378
|
+
pointFeature.setGeometry(new Point(fromLonLat(coordinates)));
|
|
379
|
+
(_c = (_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.olLayer) === null || _b === void 0 ? void 0 : _b.getSource()) === null || _c === void 0 ? void 0 : _c.addFeature(pointFeature);
|
|
380
|
+
return pointFeature;
|
|
381
|
+
})
|
|
382
|
+
.catch((error) => {
|
|
383
|
+
if (error.name === 'AbortError') {
|
|
384
|
+
// Ignore abort error
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
// Dispatch error event and execute error function
|
|
388
|
+
this.dispatchEvent(new BaseEvent('error'));
|
|
389
|
+
this.onRouteError(error, this);
|
|
390
|
+
this.loading = false;
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
// Only when this.useRawViaPoints is true.
|
|
394
|
+
// Possibility to parse:
|
|
395
|
+
//
|
|
396
|
+
// 47.37811,8.53935 a position 47.37811, 8.53935
|
|
397
|
+
if (this.useRawViaPoints && REGEX_VIA_POINT_COORD.test(viaPoint)) {
|
|
398
|
+
const [lat, lon] = REGEX_VIA_POINT_COORD.exec(viaPoint) || [];
|
|
399
|
+
if (lon && lat) {
|
|
400
|
+
const floatLon = parseFloat(lon);
|
|
401
|
+
const floatLat = parseFloat(lat);
|
|
402
|
+
const coordinates = fromLonLat([floatLon, floatLat], (_d = this.map) === null || _d === void 0 ? void 0 : _d.getView().getProjection());
|
|
403
|
+
pointFeature.setGeometry(new Point(coordinates));
|
|
404
|
+
(_g = (_f = (_e = this.routingLayer) === null || _e === void 0 ? void 0 : _e.olLayer) === null || _f === void 0 ? void 0 : _f.getSource()) === null || _g === void 0 ? void 0 : _g.addFeature(pointFeature);
|
|
405
|
+
return Promise.resolve(pointFeature);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
// Only when this.useRawViaPoints is true.
|
|
409
|
+
// It will parse the via point to find some name, id, track coordinates.
|
|
410
|
+
//
|
|
411
|
+
// Possibility to parse:
|
|
412
|
+
//
|
|
413
|
+
// @47.37811,8.53935 a station at position 47.37811, 8.53935
|
|
414
|
+
// @47.37811,8.53935$4 track 4 in a station at position 47.37811, 8.53935
|
|
415
|
+
// zürich hb@47.37811,8.53935$8 track 8 in station "Zürich HB" at position 47.37811, 8.53935
|
|
416
|
+
const [, stationName, , lat, lon, , track] = REGEX_VIA_POINT.exec(viaPoint) || [];
|
|
417
|
+
if (lon && lat) {
|
|
418
|
+
const coordinates = fromLonLat([parseFloat(lon), parseFloat(lat)], (_h = this.map) === null || _h === void 0 ? void 0 : _h.getView().getProjection());
|
|
419
|
+
pointFeature.set('viaPointTrack', track);
|
|
420
|
+
pointFeature.setGeometry(new Point(coordinates));
|
|
421
|
+
(_l = (_k = (_j = this.routingLayer) === null || _j === void 0 ? void 0 : _j.olLayer) === null || _k === void 0 ? void 0 : _k.getSource()) === null || _l === void 0 ? void 0 : _l.addFeature(pointFeature);
|
|
422
|
+
return Promise.resolve(pointFeature);
|
|
423
|
+
}
|
|
424
|
+
if (stationName) {
|
|
425
|
+
return fetch(`${this.stopsApiUrl}?key=${this.stopsApiKey}&q=${stationName}&limit=1`, { signal: abortController.signal })
|
|
426
|
+
.then((res) => res.json())
|
|
427
|
+
.then((stationData) => {
|
|
428
|
+
var _a, _b, _c;
|
|
429
|
+
const { coordinates } = stationData.features[0].geometry;
|
|
430
|
+
this.cacheStationData[viaPoint] = fromLonLat(coordinates);
|
|
431
|
+
pointFeature.set('viaPointTrack', track);
|
|
432
|
+
pointFeature.setGeometry(new Point(fromLonLat(coordinates)));
|
|
433
|
+
(_c = (_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.olLayer) === null || _b === void 0 ? void 0 : _b.getSource()) === null || _c === void 0 ? void 0 : _c.addFeature(pointFeature);
|
|
434
|
+
return pointFeature;
|
|
435
|
+
})
|
|
436
|
+
.catch((error) => {
|
|
437
|
+
// Dispatch error event and execute error function
|
|
438
|
+
this.dispatchEvent(new BaseEvent('error'));
|
|
439
|
+
this.onRouteError(error, this);
|
|
440
|
+
this.loading = false;
|
|
441
|
+
return null;
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
return Promise.resolve(null);
|
|
287
445
|
}
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
446
|
+
/**
|
|
447
|
+
* Used on click on map while control is active:
|
|
448
|
+
* By default adds a viaPoint to the end of array.
|
|
449
|
+
* If an existing viaPoint is clicked removes the clicked viaPoint.
|
|
450
|
+
* @private
|
|
451
|
+
*/
|
|
452
|
+
onMapClick(evt) {
|
|
453
|
+
const feats = evt.target.getFeaturesAtPixel(evt.pixel);
|
|
454
|
+
const viaPoint = feats.find((feat) => {
|
|
455
|
+
var _a;
|
|
456
|
+
return ((_a = feat.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType()) === 'Point' &&
|
|
457
|
+
feat.get('viaPointIdx') !== undefined;
|
|
458
|
+
});
|
|
459
|
+
if (viaPoint) {
|
|
460
|
+
// Remove existing viaPoint on click and abort viaPoint add
|
|
461
|
+
this.removeViaPoint(viaPoint.get('viaPointIdx'));
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
this.addViaPoint(evt.coordinate);
|
|
296
465
|
}
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
466
|
+
/**
|
|
467
|
+
* Used on start of the modify interaction. Stores relevant data
|
|
468
|
+
* in this.initialRouteDrag object
|
|
469
|
+
* @private
|
|
470
|
+
*/
|
|
471
|
+
onModifyStart(evt) {
|
|
472
|
+
var _a;
|
|
473
|
+
// When modify start, we search the index of the segment that is modifying.
|
|
474
|
+
let segmentIndex = -1;
|
|
475
|
+
const route = evt.features
|
|
476
|
+
.getArray()
|
|
477
|
+
.find((feat) => { var _a; return ((_a = feat.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType()) === 'LineString'; });
|
|
478
|
+
// Find the segment index that is being modified
|
|
479
|
+
if (route && route.getGeometry() && evt.mapBrowserEvent.coordinate) {
|
|
480
|
+
// We use a buff extent to fix floating issues , see https://github.com/openlayers/openlayers/issues/7130#issuecomment-535856422
|
|
481
|
+
const closestExtent = buffer(new Point(
|
|
482
|
+
// @ts-ignore
|
|
483
|
+
(_a = route.getGeometry()) === null || _a === void 0 ? void 0 : _a.getClosestPoint(evt.mapBrowserEvent.coordinate)).getExtent(), 0.001);
|
|
484
|
+
segmentIndex = this.segments.findIndex((segment) => { var _a; return (_a = segment.getGeometry()) === null || _a === void 0 ? void 0 : _a.intersectsExtent(closestExtent); });
|
|
485
|
+
}
|
|
486
|
+
// Find the viaPoint that is being modified
|
|
487
|
+
const viaPoint = (evt.features
|
|
488
|
+
.getArray()
|
|
489
|
+
.filter((feat) => { var _a; return ((_a = feat.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType()) === 'Point'; }) ||
|
|
490
|
+
[])[0];
|
|
491
|
+
// Write object with modify info
|
|
492
|
+
/** @ignore */
|
|
493
|
+
this.initialRouteDrag = {
|
|
494
|
+
viaPoint,
|
|
495
|
+
oldRoute: route && route.clone(),
|
|
496
|
+
segmentIndex,
|
|
497
|
+
};
|
|
309
498
|
}
|
|
310
|
-
|
|
311
|
-
|
|
499
|
+
/**
|
|
500
|
+
* Used on end of the modify interaction. Resolves feature modification:
|
|
501
|
+
* Line drag creates new viaPoint at the final coordinate of drag.
|
|
502
|
+
* Point drag replaces old viaPoint.
|
|
503
|
+
* @private
|
|
504
|
+
*/
|
|
505
|
+
onModifyEnd(evt) {
|
|
506
|
+
const coord = evt.mapBrowserEvent.coordinate;
|
|
507
|
+
const { oldRoute, viaPoint, segmentIndex } = this.initialRouteDrag || {};
|
|
508
|
+
// If viaPoint is being relocated overwrite the old viaPoint
|
|
509
|
+
if (viaPoint) {
|
|
510
|
+
return this.addViaPoint(coord, viaPoint.get('viaPointIdx'), 1);
|
|
511
|
+
}
|
|
512
|
+
// In case there is no route overwrite first coordinate
|
|
513
|
+
if (!oldRoute) {
|
|
514
|
+
return this.addViaPoint(coord, 0, 1);
|
|
515
|
+
}
|
|
516
|
+
// We can't add a via point because we haven't found which segment has been modified.
|
|
517
|
+
if (segmentIndex === -1) {
|
|
518
|
+
return Promise.reject(new Error('No segment found'));
|
|
519
|
+
}
|
|
520
|
+
// Insert new viaPoint at the modified segment index + 1
|
|
521
|
+
return this.addViaPoint(coord, (segmentIndex || 0) + 1);
|
|
312
522
|
}
|
|
313
|
-
|
|
314
|
-
|
|
523
|
+
/**
|
|
524
|
+
* Define a default element.
|
|
525
|
+
*
|
|
526
|
+
* @private
|
|
527
|
+
*/
|
|
528
|
+
createDefaultElement() {
|
|
529
|
+
/** @ignore */
|
|
530
|
+
this.element = document.createElement('button');
|
|
531
|
+
this.element.id = 'ol-toggle-routing';
|
|
532
|
+
this.element.innerHTML = 'Toggle Route Control';
|
|
533
|
+
this.element.onclick = () => this.active ? this.deactivate() : this.activate();
|
|
534
|
+
Object.assign(this.element.style, {
|
|
535
|
+
position: 'absolute',
|
|
536
|
+
right: '10px',
|
|
537
|
+
top: '10px',
|
|
538
|
+
});
|
|
315
539
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
540
|
+
/**
|
|
541
|
+
* Create the interaction used to modify vertexes of features.
|
|
542
|
+
* @private
|
|
543
|
+
*/
|
|
544
|
+
createModifyInteraction() {
|
|
545
|
+
var _a, _b, _c;
|
|
546
|
+
/**
|
|
547
|
+
* @type {ol.interaction.Modify}
|
|
548
|
+
* @private
|
|
549
|
+
*/
|
|
550
|
+
// Define and add modify interaction
|
|
551
|
+
this.modifyInteraction = new Modify({
|
|
552
|
+
source: ((_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.olLayer) === null || _b === void 0 ? void 0 : _b.getSource()) || undefined,
|
|
553
|
+
pixelTolerance: 4,
|
|
554
|
+
hitDetection: (_c = this.routingLayer) === null || _c === void 0 ? void 0 : _c.olLayer,
|
|
555
|
+
deleteCondition: (e) => {
|
|
556
|
+
const feats = e.target.getFeaturesAtPixel(e.pixel, {
|
|
557
|
+
hitTolerance: 5,
|
|
558
|
+
});
|
|
559
|
+
const viaPoint = feats.find((feat) => { var _a; return ((_a = feat.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType()) === 'Point' && feat.get('index'); });
|
|
560
|
+
if (click(e) && viaPoint) {
|
|
561
|
+
// Remove node & viaPoint if an existing viaPoint was clicked
|
|
562
|
+
this.removeViaPoint(viaPoint.get('index'));
|
|
563
|
+
return true;
|
|
564
|
+
}
|
|
565
|
+
return false;
|
|
566
|
+
},
|
|
337
567
|
});
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
568
|
+
this.modifyInteraction.on('modifystart', this.onModifyStart);
|
|
569
|
+
this.modifyInteraction.on('modifyend', this.onModifyEnd);
|
|
570
|
+
this.modifyInteraction.setActive(false);
|
|
571
|
+
}
|
|
572
|
+
/**
|
|
573
|
+
* Add click listener to map.
|
|
574
|
+
* @private
|
|
575
|
+
*/
|
|
576
|
+
addListeners() {
|
|
577
|
+
var _a;
|
|
578
|
+
if (!this.modify) {
|
|
579
|
+
return;
|
|
342
580
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
this.modifyInteraction.on("modifystart", this.onModifyStart);
|
|
347
|
-
this.modifyInteraction.on("modifyend", this.onModifyEnd);
|
|
348
|
-
this.modifyInteraction.setActive(false);
|
|
349
|
-
}
|
|
350
|
-
addListeners() {
|
|
351
|
-
if (!this.modify) {
|
|
352
|
-
return;
|
|
581
|
+
this.removeListeners();
|
|
582
|
+
/** @ignore */
|
|
583
|
+
this.onMapClickKey = (_a = this.map) === null || _a === void 0 ? void 0 : _a.on('singleclick', this.onMapClick);
|
|
353
584
|
}
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
if (this.map) {
|
|
363
|
-
this.format = new GeoJSON({
|
|
364
|
-
featureProjection: this.map.getView().getProjection()
|
|
365
|
-
});
|
|
366
|
-
this.graphsResolutions = RoutingControl.getGraphsResolutions(this.graphs, this.map);
|
|
367
|
-
this.map.removeInteraction(this.modifyInteraction);
|
|
368
|
-
this.routingLayer.attachToMap(this.map);
|
|
369
|
-
this.map.addInteraction(this.modifyInteraction);
|
|
370
|
-
this.modifyInteraction.setActive(this.modify);
|
|
371
|
-
this.addListeners();
|
|
372
|
-
} else {
|
|
373
|
-
this.format = new GeoJSON({ featureProjection: "EPSG:3857" });
|
|
374
|
-
this.graphsResolutions = this.graphs;
|
|
585
|
+
/**
|
|
586
|
+
* Remove click listener from map.
|
|
587
|
+
* @private
|
|
588
|
+
*/
|
|
589
|
+
removeListeners() {
|
|
590
|
+
if (this.onMapClickKey) {
|
|
591
|
+
unByKey(this.onMapClickKey);
|
|
592
|
+
}
|
|
375
593
|
}
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
594
|
+
activate() {
|
|
595
|
+
var _a, _b;
|
|
596
|
+
super.activate();
|
|
597
|
+
if (this.map) {
|
|
598
|
+
/** @ignore */
|
|
599
|
+
this.format = new GeoJSON({
|
|
600
|
+
featureProjection: this.map.getView().getProjection(),
|
|
601
|
+
});
|
|
602
|
+
/** @ignore */
|
|
603
|
+
this.graphsResolutions = RoutingControl.getGraphsResolutions(this.graphs, this.map);
|
|
604
|
+
// Clean the modifyInteraction if present
|
|
605
|
+
if (this.modifyInteraction) {
|
|
606
|
+
this.map.removeInteraction(this.modifyInteraction);
|
|
607
|
+
}
|
|
608
|
+
// Add modify interaction, RoutingLayer and listeners
|
|
609
|
+
(_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.attachToMap(this.map);
|
|
610
|
+
if (this.modifyInteraction) {
|
|
611
|
+
this.map.addInteraction(this.modifyInteraction);
|
|
612
|
+
}
|
|
613
|
+
(_b = this.modifyInteraction) === null || _b === void 0 ? void 0 : _b.setActive(this.modify);
|
|
614
|
+
this.addListeners();
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
deactivate() {
|
|
618
|
+
var _a;
|
|
619
|
+
if (this.map) {
|
|
620
|
+
// Remove modify interaction, RoutingLayer, listeners and viaPoints
|
|
621
|
+
(_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.detachFromMap();
|
|
622
|
+
if (this.modifyInteraction) {
|
|
623
|
+
this.map.removeInteraction(this.modifyInteraction);
|
|
624
|
+
}
|
|
625
|
+
this.removeListeners();
|
|
626
|
+
this.reset();
|
|
627
|
+
}
|
|
383
628
|
}
|
|
384
|
-
|
|
385
|
-
}
|
|
629
|
+
render() { }
|
|
386
630
|
}
|
|
387
631
|
export default RoutingControl;
|