mobility-toolbox-js 3.0.0-beta.2 → 3.0.0-beta.21

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.
Files changed (125) hide show
  1. package/api/HttpAPI.d.ts +20 -0
  2. package/api/HttpAPI.js +0 -11
  3. package/api/RealtimeAPI.d.ts +404 -0
  4. package/api/RealtimeAPI.js +342 -276
  5. package/api/RoutingAPI.d.ts +47 -0
  6. package/api/RoutingAPI.js +17 -7
  7. package/api/StopsAPI.d.ts +44 -0
  8. package/api/StopsAPI.js +16 -10
  9. package/api/WebSocketAPI.d.ts +147 -0
  10. package/api/WebSocketAPI.js +164 -164
  11. package/api/index.d.ts +3 -0
  12. package/api/index.js +1 -1
  13. package/api/typedefs.d.ts +76 -0
  14. package/api/typedefs.js +27 -42
  15. package/common/controls/StopFinderControlCommon.d.ts +53 -0
  16. package/common/controls/StopFinderControlCommon.js +31 -31
  17. package/common/index.d.ts +2 -0
  18. package/common/index.js +1 -1
  19. package/common/mixins/RealtimeLayerMixin.d.ts +267 -0
  20. package/common/mixins/RealtimeLayerMixin.js +401 -393
  21. package/common/styles/index.d.ts +4 -0
  22. package/common/styles/realtimeDefaultStyle.d.ts +36 -0
  23. package/common/styles/realtimeDefaultStyle.js +6 -6
  24. package/common/styles/realtimeDelayStyle.d.ts +12 -0
  25. package/common/styles/realtimeHeadingStyle.d.ts +12 -0
  26. package/common/styles/realtimeHeadingStyle.js +5 -5
  27. package/common/styles/realtimeSimpleStyle.d.ts +4 -0
  28. package/common/typedefs.d.ts +219 -0
  29. package/common/typedefs.js +7 -1
  30. package/common/utils/compareDepartures.d.ts +10 -0
  31. package/common/utils/compareDepartures.js +2 -2
  32. package/common/utils/constants.d.ts +5 -0
  33. package/common/utils/createCanvas.d.ts +10 -0
  34. package/common/utils/createDefaultCopyrightElt.d.ts +5 -0
  35. package/common/utils/createDefaultStopFinderElt.d.ts +5 -0
  36. package/common/utils/createRealtimeFilters.d.ts +12 -0
  37. package/common/utils/debounceDeparturesMessages.d.ts +12 -0
  38. package/common/utils/debounceWebsocketMessages.d.ts +11 -0
  39. package/common/utils/getLayersAsFlatArray.d.ts +3 -0
  40. package/common/utils/getLayersAsFlatArray.js +5 -1
  41. package/common/utils/getMapGlCopyrights.d.ts +17 -0
  42. package/common/utils/getMapGlCopyrights.js +3 -3
  43. package/common/utils/getRealtimeModeSuffix.d.ts +10 -0
  44. package/common/utils/getRealtimeModeSuffix.js +1 -0
  45. package/common/utils/getUrlWithParams.d.ts +8 -0
  46. package/common/utils/getVehiclePosition.d.ts +17 -0
  47. package/common/utils/getVehiclePosition.js +9 -3
  48. package/common/utils/index.d.ts +16 -0
  49. package/common/utils/realtimeConfig.d.ts +64 -0
  50. package/common/utils/removeDuplicate.d.ts +9 -0
  51. package/common/utils/renderTrajectories.d.ts +16 -0
  52. package/common/utils/renderTrajectories.js +6 -6
  53. package/common/utils/sortAndFilterDepartures.d.ts +15 -0
  54. package/common/utils/sortAndFilterDepartures.js +1 -1
  55. package/common/utils/sortByDelay.d.ts +3 -0
  56. package/common/utils/sortByDelay.js +5 -1
  57. package/common/utils/timeUtils.d.ts +23 -0
  58. package/common/utils/toMercatorExtent.d.ts +5 -0
  59. package/iife.d.ts +2 -0
  60. package/index.d.ts +9 -0
  61. package/maplibre/controls/CopyrightControl.d.ts +35 -0
  62. package/maplibre/controls/index.d.ts +1 -0
  63. package/maplibre/index.d.ts +5 -0
  64. package/maplibre/layers/Layer.d.ts +28 -0
  65. package/maplibre/layers/Layer.js +1 -1
  66. package/maplibre/layers/RealtimeLayer.d.ts +181 -0
  67. package/maplibre/layers/RealtimeLayer.js +29 -5
  68. package/maplibre/layers/index.d.ts +2 -0
  69. package/maplibre/utils/getMercatorResolution.d.ts +7 -0
  70. package/maplibre/utils/getSourceCoordinates.d.ts +7 -0
  71. package/maplibre/utils/getSourceCoordinates.js +5 -5
  72. package/maplibre/utils/index.d.ts +2 -0
  73. package/mbt.js +22103 -14430
  74. package/mbt.js.map +4 -4
  75. package/mbt.min.js +61 -58
  76. package/mbt.min.js.map +4 -4
  77. package/ol/controls/CopyrightControl.d.ts +31 -0
  78. package/ol/controls/CopyrightControl.js +18 -8
  79. package/ol/controls/RoutingControl.d.ts +202 -0
  80. package/ol/controls/RoutingControl.js +220 -219
  81. package/ol/controls/StopFinderControl.d.ts +37 -0
  82. package/ol/controls/StopFinderControl.js +4 -1
  83. package/ol/controls/index.d.ts +3 -0
  84. package/ol/index.d.ts +7 -0
  85. package/ol/index.js +1 -0
  86. package/ol/layers/Layer.d.ts +101 -0
  87. package/ol/layers/Layer.js +25 -0
  88. package/ol/layers/MaplibreLayer.d.ts +160 -0
  89. package/ol/layers/MaplibreLayer.js +97 -27
  90. package/ol/layers/MaplibreStyleLayer.d.ts +237 -0
  91. package/ol/layers/MaplibreStyleLayer.js +291 -267
  92. package/ol/layers/RealtimeLayer.d.ts +283 -0
  93. package/ol/layers/RealtimeLayer.js +143 -128
  94. package/ol/layers/VectorLayer.d.ts +18 -0
  95. package/ol/layers/VectorLayer.js +31 -0
  96. package/ol/layers/index.d.ts +5 -0
  97. package/ol/layers/index.js +3 -0
  98. package/ol/mixins/MobilityLayerMixin.d.ts +96 -0
  99. package/ol/mixins/MobilityLayerMixin.js +1 -4
  100. package/ol/mixins/PropertiesLayerMixin.d.ts +135 -0
  101. package/ol/mixins/PropertiesLayerMixin.js +112 -140
  102. package/ol/mixins/index.d.ts +1 -0
  103. package/ol/mixins/index.js +2 -0
  104. package/ol/renderers/MaplibreLayerRenderer.d.ts +0 -0
  105. package/ol/renderers/MaplibreLayerRenderer.js +142 -114
  106. package/ol/renderers/MaplibreStyleLayerRenderer.d.ts +20 -0
  107. package/ol/renderers/MaplibreStyleLayerRenderer.js +20 -23
  108. package/ol/renderers/RealtimeLayerRenderer.d.ts +22 -0
  109. package/ol/renderers/RealtimeLayerRenderer.js +58 -53
  110. package/ol/styles/fullTrajectoryDelayStyle.d.ts +6 -0
  111. package/ol/styles/fullTrajectoryStyle.d.ts +5 -0
  112. package/ol/styles/index.d.ts +3 -0
  113. package/ol/styles/routingStyle.d.ts +4 -0
  114. package/ol/utils/getFeatureInfoAtCoordinate.d.ts +8 -0
  115. package/ol/utils/getFeatureInfoAtCoordinate.js +12 -18
  116. package/ol/utils/index.d.ts +1 -0
  117. package/package.json +31 -31
  118. package/setupTests.d.ts +1 -0
  119. package/setupTests.js +3 -4
  120. package/types/common.d.ts +55 -48
  121. package/types/index.d.ts +1 -1
  122. package/types/realtime.d.ts +91 -93
  123. package/types/routing.d.ts +60 -60
  124. package/types/stops.d.ts +62 -62
  125. package/ol/layers/MapGlLayer.js +0 -142
@@ -1,15 +1,15 @@
1
1
  import { Feature } from 'ol';
2
+ import Control from 'ol/control/Control';
3
+ import { click } from 'ol/events/condition';
4
+ import BaseEvent from 'ol/events/Event';
5
+ import { buffer } from 'ol/extent';
6
+ import { GeoJSON } from 'ol/format';
2
7
  import { LineString, Point } from 'ol/geom';
3
8
  import { Modify } from 'ol/interaction';
9
+ import VectorLayer from 'ol/layer/Vector';
4
10
  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
11
  import { fromLonLat, toLonLat } from 'ol/proj';
9
- import BaseEvent from 'ol/events/Event';
10
- import VectorLayer from 'ol/layer/Vector';
11
12
  import VectorSource from 'ol/source/Vector';
12
- import Control from 'ol/control/Control';
13
13
  import { RoutingAPI } from '../../api';
14
14
  // Examples for a single hop:
15
15
  // basel sbb a station named "basel sbb"
@@ -38,7 +38,7 @@ const getFlatCoordinatesFromSegments = (segmentArray) => {
38
38
  const coords = [];
39
39
  segmentArray.forEach((seg) => {
40
40
  var _a;
41
- // @ts-ignore
41
+ // @ts-expect-error
42
42
  const coordArr = (_a = seg.getGeometry()) === null || _a === void 0 ? void 0 : _a.getCoordinates();
43
43
  if (coordArr === null || coordArr === void 0 ? void 0 : coordArr.length) {
44
44
  coords.push(...coordArr);
@@ -47,7 +47,7 @@ const getFlatCoordinatesFromSegments = (segmentArray) => {
47
47
  return coords;
48
48
  };
49
49
  /**
50
- * Display a route of a specified mean of transport.
50
+ * This OpenLayers control allows the user to add and modifiy via points to a map and request a route from the [geOps Routing API](https://developer.geops.io/apis/routing/).
51
51
  *
52
52
  * @example
53
53
  * import { Map } from 'ol';
@@ -79,41 +79,20 @@ const getFlatCoordinatesFromSegments = (segmentArray) => {
79
79
  * @public
80
80
  */
81
81
  class RoutingControl extends Control {
82
- get active() {
83
- return this.get('active');
84
- }
85
- set active(newValue) {
86
- this.set('active', newValue);
87
- }
88
- get loading() {
89
- return this.get('loading');
90
- }
91
- set loading(newValue) {
92
- this.set('loading', newValue);
93
- }
94
- get modify() {
95
- return this.get('modify');
96
- }
97
- set modify(newValue) {
98
- this.set('modify', newValue);
99
- }
100
- get mot() {
101
- return this.get('mot');
102
- }
103
- set mot(newValue) {
104
- this.set('mot', newValue);
105
- }
106
82
  constructor(options = {}) {
107
83
  super(options);
108
- this.viaPoints = [];
109
- this.graphs = [];
110
- this.useRawViaPoints = false;
111
- this.snapToClosestStation = false;
112
- this.cacheStationData = {};
113
84
  this.abortControllers = {};
114
- this.segments = [];
85
+ this.cacheStationData = {};
115
86
  this.format = new GeoJSON({ featureProjection: 'EPSG:3857' });
87
+ this.graphs = [];
116
88
  this.initialRouteDrag = {};
89
+ this.segments = [];
90
+ this.snapToClosestStation = false;
91
+ this.useRawViaPoints = false;
92
+ this.viaPoints = [];
93
+ if (!this.element) {
94
+ this.createDefaultElement();
95
+ }
117
96
  /** True if the control is requesting the backend. */
118
97
  this.loading = false;
119
98
  /** @private */
@@ -186,17 +165,60 @@ class RoutingControl extends Control {
186
165
  ]);
187
166
  }
188
167
  /**
189
- * Activet7deactivate the control when activ eproperty changes
168
+ * Aborts viapoint and route requests
190
169
  * @private
191
170
  */
192
- onActiveChange() {
193
- if (this.get('active')) {
194
- this.activate();
171
+ abortRequests() {
172
+ var _a;
173
+ // Abort Routing API requests
174
+ this.graphs.forEach((graph) => {
175
+ const graphName = graph[0];
176
+ if (this.abortControllers[graphName]) {
177
+ this.abortControllers[graphName].abort();
178
+ }
179
+ this.abortControllers[graphName] = new AbortController();
180
+ });
181
+ // Abort Stops API requests
182
+ (_a = this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]) === null || _a === void 0 ? void 0 : _a.abort();
183
+ this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY] =
184
+ new AbortController();
185
+ this.loading = false;
186
+ }
187
+ activate() {
188
+ var _a;
189
+ const map = this.getMap();
190
+ if (map) {
191
+ /** @private */
192
+ this.format = new GeoJSON({
193
+ featureProjection: map.getView().getProjection(),
194
+ });
195
+ /** @private */
196
+ this.graphsResolutions = RoutingControl.getGraphsResolutions(this.graphs, map);
197
+ // Clean the modifyInteraction if present
198
+ if (this.modifyInteraction) {
199
+ map.removeInteraction(this.modifyInteraction);
200
+ }
201
+ // Add modify interaction, RoutingLayer and listeners
202
+ // this.routingLayer?.attachToMap(this.getMap());
203
+ if (this.modifyInteraction) {
204
+ map.addInteraction(this.modifyInteraction);
205
+ }
206
+ (_a = this.modifyInteraction) === null || _a === void 0 ? void 0 : _a.setActive(this.modify);
207
+ this.addListeners();
195
208
  }
196
- else {
197
- this.deactivate();
209
+ }
210
+ /**
211
+ * Add click listener to map.
212
+ * @private
213
+ */
214
+ addListeners() {
215
+ var _a;
216
+ if (!this.modify) {
217
+ return;
198
218
  }
199
- this.render();
219
+ this.removeListeners();
220
+ /** @private */
221
+ this.onMapClickKey = (_a = this.getMap()) === null || _a === void 0 ? void 0 : _a.on('singleclick', this.onMapClick);
200
222
  }
201
223
  /**
202
224
  * Adds/Replaces a viaPoint to the viaPoints array and redraws route:
@@ -216,60 +238,66 @@ class RoutingControl extends Control {
216
238
  this.dispatchEvent(new BaseEvent('change:route'));
217
239
  }
218
240
  /**
219
- * Removes a viaPoint at the passed array index and redraws route
220
- * By default the last viaPoint is removed.
221
- * @param {number} index Integer representing the index of the viaPoint to delete.
222
- * @public
223
- */
224
- removeViaPoint(index = (this.viaPoints || []).length - 1) {
225
- /* Remove viapoint and redraw route */
226
- if (this.viaPoints.length && this.viaPoints[index]) {
227
- this.viaPoints.splice(index, 1);
228
- }
229
- this.drawRoute();
230
- this.dispatchEvent(new BaseEvent('change:route'));
231
- }
232
- /**
233
- * Replaces the current viaPoints with a new coordinate array.
234
- * @param {Array<Array<number>>} coordinateArray Array of nested coordinates
235
- * @public
236
- */
237
- setViaPoints(coordinateArray) {
238
- this.viaPoints = [...coordinateArray];
239
- this.drawRoute();
240
- this.dispatchEvent(new BaseEvent('change:route'));
241
- }
242
- /**
243
- * Removes all viaPoints, clears the source and triggers a change event
244
- * @public
241
+ * Define a default element.
242
+ *
243
+ * @private
245
244
  */
246
- reset() {
247
- var _a, _b;
248
- // Clear viaPoints and source
249
- this.abortRequests();
250
- this.viaPoints = [];
251
- (_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.getSource()) === null || _b === void 0 ? void 0 : _b.clear();
252
- this.dispatchEvent(new BaseEvent('change:route'));
245
+ createDefaultElement() {
246
+ /** @private */
247
+ this.element = document.createElement('button');
248
+ this.element.id = 'ol-toggle-routing';
249
+ this.element.innerHTML = 'Toggle Route Control';
250
+ this.element.onclick = () => this.active ? this.deactivate() : this.activate();
251
+ Object.assign(this.element.style, {
252
+ position: 'absolute',
253
+ right: '10px',
254
+ top: '10px',
255
+ });
253
256
  }
254
257
  /**
255
- * Aborts viapoint and route requests
258
+ * Create the interaction used to modify vertexes of features.
256
259
  * @private
257
260
  */
258
- abortRequests() {
261
+ createModifyInteraction() {
259
262
  var _a;
260
- // Abort Routing API requests
261
- this.graphs.forEach((graph) => {
262
- const graphName = graph[0];
263
- if (this.abortControllers[graphName]) {
264
- this.abortControllers[graphName].abort();
265
- }
266
- this.abortControllers[graphName] = new AbortController();
263
+ /**
264
+ * @type {ol.interaction.Modify}
265
+ * @private
266
+ */
267
+ // Define and add modify interaction
268
+ this.modifyInteraction = new Modify({
269
+ // hitDetection: this.routingLayer, // Create a bug, the first point is always selected even if the mous eis far away
270
+ deleteCondition: (e) => {
271
+ var _a;
272
+ const feats = (_a = e.target) === null || _a === void 0 ? void 0 : _a.getFeaturesAtPixel(e.pixel, {
273
+ hitTolerance: 5,
274
+ } || []);
275
+ const viaPoint = feats.find((feat) => { var _a; return ((_a = feat.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType()) === 'Point' && feat.get('index'); });
276
+ if (click(e) && viaPoint) {
277
+ // Remove node & viaPoint if an existing viaPoint was clicked
278
+ this.removeViaPoint(viaPoint.get('index'));
279
+ return true;
280
+ }
281
+ return false;
282
+ },
283
+ pixelTolerance: 6,
284
+ source: ((_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.getSource()) || undefined,
267
285
  });
268
- // Abort Stops API requests
269
- (_a = this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]) === null || _a === void 0 ? void 0 : _a.abort();
270
- this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY] =
271
- new AbortController();
272
- this.loading = false;
286
+ this.modifyInteraction.on('modifystart', this.onModifyStart);
287
+ this.modifyInteraction.on('modifyend', this.onModifyEnd);
288
+ this.modifyInteraction.setActive(false);
289
+ }
290
+ deactivate() {
291
+ const map = this.getMap();
292
+ if (map) {
293
+ // Remove modify interaction, RoutingLayer, listeners and viaPoints
294
+ // this.routingLayer?.detachFromMap();
295
+ if (this.modifyInteraction) {
296
+ map.removeInteraction(this.modifyInteraction);
297
+ }
298
+ this.removeListeners();
299
+ this.reset();
300
+ }
273
301
  }
274
302
  /**
275
303
  * Draws route on map using an array of coordinates:
@@ -311,9 +339,9 @@ class RoutingControl extends Control {
311
339
  return Promise.resolve([]);
312
340
  }
313
341
  return this.api
314
- .route(Object.assign({ graph, via: `${formattedViaPoints.join('|')}`, mot: this.mot,
315
- // @ts-ignore missing property in swagger
316
- 'resolve-hops': false, elevation: false, 'coord-radius': 100.0, 'coord-punish': 1000.0 }, (this.routingApiParams || {})), { signal })
342
+ .route(Object.assign({ 'coord-punish': 1000.0, 'coord-radius': 100.0,
343
+ // @ts-expect-error missing property in swagger
344
+ elevation: false, graph, mot: this.mot, 'resolve-hops': false, via: `${formattedViaPoints.join('|')}` }, (this.routingApiParams || {})), { signal })
317
345
  .then((featureCollection) => {
318
346
  var _a, _b, _c;
319
347
  this.segments = this.format.readFeatures(featureCollection);
@@ -471,6 +499,19 @@ class RoutingControl extends Control {
471
499
  }
472
500
  return Promise.resolve(null);
473
501
  }
502
+ /**
503
+ * Activet7deactivate the control when activ eproperty changes
504
+ * @private
505
+ */
506
+ onActiveChange() {
507
+ if (this.get('active')) {
508
+ this.activate();
509
+ }
510
+ else {
511
+ this.deactivate();
512
+ }
513
+ this.render();
514
+ }
474
515
  /**
475
516
  * Used on click on map while control is active:
476
517
  * By default adds a viaPoint to the end of array.
@@ -479,8 +520,8 @@ class RoutingControl extends Control {
479
520
  */
480
521
  onMapClick(evt) {
481
522
  const feats = evt.target.getFeaturesAtPixel(evt.pixel, {
482
- layerFilter: (layer) => layer === this.routingLayer,
483
523
  hitTolerance: 5,
524
+ layerFilter: (layer) => layer === this.routingLayer,
484
525
  });
485
526
  const viaPoint = feats.find((feat) => {
486
527
  var _a;
@@ -494,6 +535,30 @@ class RoutingControl extends Control {
494
535
  }
495
536
  this.addViaPoint(evt.coordinate);
496
537
  }
538
+ /**
539
+ * Used on end of the modify interaction. Resolves feature modification:
540
+ * Line drag creates new viaPoint at the final coordinate of drag.
541
+ * Point drag replaces old viaPoint.
542
+ * @private
543
+ */
544
+ onModifyEnd(evt) {
545
+ const coord = evt.mapBrowserEvent.coordinate;
546
+ const { oldRoute, segmentIndex, viaPoint } = this.initialRouteDrag || {};
547
+ // If viaPoint is being relocated overwrite the old viaPoint
548
+ if (viaPoint) {
549
+ return this.addViaPoint(coord, viaPoint.get('viaPointIdx'), 1);
550
+ }
551
+ // In case there is no route overwrite first coordinate
552
+ if (!oldRoute) {
553
+ return this.addViaPoint(coord, 0, 1);
554
+ }
555
+ // We can't add a via point because we haven't found which segment has been modified.
556
+ if (segmentIndex === -1) {
557
+ return Promise.reject(new Error('No segment found'));
558
+ }
559
+ // Insert new viaPoint at the modified segment index + 1
560
+ return this.addViaPoint(coord, (segmentIndex || 0) + 1);
561
+ }
497
562
  /**
498
563
  * Used on start of the modify interaction. Stores relevant data
499
564
  * in this.initialRouteDrag object
@@ -507,10 +572,10 @@ class RoutingControl extends Control {
507
572
  .getArray()
508
573
  .find((feat) => { var _a; return ((_a = feat.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType()) === 'LineString'; });
509
574
  // Find the segment index that is being modified
510
- if (route && route.getGeometry() && evt.mapBrowserEvent.coordinate) {
575
+ if ((route === null || route === void 0 ? void 0 : route.getGeometry()) && evt.mapBrowserEvent.coordinate) {
511
576
  // We use a buff extent to fix floating issues , see https://github.com/openlayers/openlayers/issues/7130#issuecomment-535856422
512
577
  const closestExtent = buffer(new Point(
513
- // @ts-ignore
578
+ // @ts-expect-error
514
579
  (_a = route.getGeometry()) === null || _a === void 0 ? void 0 : _a.getClosestPoint(evt.mapBrowserEvent.coordinate)).getExtent(), 0.001);
515
580
  segmentIndex = this.segments.findIndex((segment) => { var _a; return (_a = segment.getGeometry()) === null || _a === void 0 ? void 0 : _a.intersectsExtent(closestExtent); });
516
581
  }
@@ -522,106 +587,46 @@ class RoutingControl extends Control {
522
587
  // Write object with modify info
523
588
  /** @private */
524
589
  this.initialRouteDrag = {
525
- viaPoint,
526
590
  oldRoute: route && route.clone(),
527
591
  segmentIndex,
592
+ viaPoint,
528
593
  };
529
594
  }
530
595
  /**
531
- * Used on end of the modify interaction. Resolves feature modification:
532
- * Line drag creates new viaPoint at the final coordinate of drag.
533
- * Point drag replaces old viaPoint.
596
+ * Remove click listener from map.
534
597
  * @private
535
598
  */
536
- onModifyEnd(evt) {
537
- const coord = evt.mapBrowserEvent.coordinate;
538
- const { oldRoute, viaPoint, segmentIndex } = this.initialRouteDrag || {};
539
- // If viaPoint is being relocated overwrite the old viaPoint
540
- if (viaPoint) {
541
- return this.addViaPoint(coord, viaPoint.get('viaPointIdx'), 1);
542
- }
543
- // In case there is no route overwrite first coordinate
544
- if (!oldRoute) {
545
- return this.addViaPoint(coord, 0, 1);
546
- }
547
- // We can't add a via point because we haven't found which segment has been modified.
548
- if (segmentIndex === -1) {
549
- return Promise.reject(new Error('No segment found'));
599
+ removeListeners() {
600
+ if (this.onMapClickKey) {
601
+ unByKey(this.onMapClickKey);
550
602
  }
551
- // Insert new viaPoint at the modified segment index + 1
552
- return this.addViaPoint(coord, (segmentIndex || 0) + 1);
553
- }
554
- /**
555
- * Define a default element.
556
- *
557
- * @private
558
- */
559
- createDefaultElement() {
560
- /** @private */
561
- this.element = document.createElement('button');
562
- this.element.id = 'ol-toggle-routing';
563
- this.element.innerHTML = 'Toggle Route Control';
564
- this.element.onclick = () => this.active ? this.deactivate() : this.activate();
565
- Object.assign(this.element.style, {
566
- position: 'absolute',
567
- right: '10px',
568
- top: '10px',
569
- });
570
603
  }
571
604
  /**
572
- * Create the interaction used to modify vertexes of features.
573
- * @private
574
- */
575
- createModifyInteraction() {
576
- var _a;
577
- /**
578
- * @type {ol.interaction.Modify}
579
- * @private
580
- */
581
- // Define and add modify interaction
582
- this.modifyInteraction = new Modify({
583
- source: ((_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.getSource()) || undefined,
584
- pixelTolerance: 6,
585
- // hitDetection: this.routingLayer, // Create a bug, the first point is always selected even if the mous eis far away
586
- deleteCondition: (e) => {
587
- var _a;
588
- const feats = (_a = e.target) === null || _a === void 0 ? void 0 : _a.getFeaturesAtPixel(e.pixel, {
589
- hitTolerance: 5,
590
- } || []);
591
- const viaPoint = feats.find((feat) => { var _a; return ((_a = feat.getGeometry()) === null || _a === void 0 ? void 0 : _a.getType()) === 'Point' && feat.get('index'); });
592
- if (click(e) && viaPoint) {
593
- // Remove node & viaPoint if an existing viaPoint was clicked
594
- this.removeViaPoint(viaPoint.get('index'));
595
- return true;
596
- }
597
- return false;
598
- },
599
- });
600
- this.modifyInteraction.on('modifystart', this.onModifyStart);
601
- this.modifyInteraction.on('modifyend', this.onModifyEnd);
602
- this.modifyInteraction.setActive(false);
603
- }
604
- /**
605
- * Add click listener to map.
606
- * @private
605
+ * Removes a viaPoint at the passed array index and redraws route
606
+ * By default the last viaPoint is removed.
607
+ * @param {number} index Integer representing the index of the viaPoint to delete.
608
+ * @public
607
609
  */
608
- addListeners() {
609
- var _a;
610
- if (!this.modify) {
611
- return;
610
+ removeViaPoint(index = (this.viaPoints || []).length - 1) {
611
+ /* Remove viapoint and redraw route */
612
+ if (this.viaPoints.length && this.viaPoints[index]) {
613
+ this.viaPoints.splice(index, 1);
612
614
  }
613
- this.removeListeners();
614
- /** @private */
615
- this.onMapClickKey = (_a = this.getMap()) === null || _a === void 0 ? void 0 : _a.on('singleclick', this.onMapClick);
615
+ this.drawRoute();
616
+ this.dispatchEvent(new BaseEvent('change:route'));
616
617
  }
618
+ render() { }
617
619
  /**
618
- * Remove click listener from map.
619
- * @private
620
+ * Removes all viaPoints, clears the source and triggers a change event
621
+ * @public
620
622
  */
621
- removeListeners() {
622
- if (this.onMapClickKey) {
623
- unByKey(this.onMapClickKey);
624
- }
623
+ reset() {
624
+ var _a, _b;
625
+ // Clear viaPoints and source
626
+ this.abortRequests();
627
+ this.viaPoints = [];
628
+ (_b = (_a = this.routingLayer) === null || _a === void 0 ? void 0 : _a.getSource()) === null || _b === void 0 ? void 0 : _b.clear();
629
+ this.dispatchEvent(new BaseEvent('change:route'));
625
630
  }
626
631
  setMap(map) {
627
632
  super.setMap(map);
@@ -632,43 +637,39 @@ class RoutingControl extends Control {
632
637
  this.active = false;
633
638
  }
634
639
  }
635
- activate() {
636
- var _a;
637
- const map = this.getMap();
638
- if (map) {
639
- /** @private */
640
- this.format = new GeoJSON({
641
- featureProjection: map.getView().getProjection(),
642
- });
643
- /** @private */
644
- this.graphsResolutions = RoutingControl.getGraphsResolutions(this.graphs, map);
645
- // Clean the modifyInteraction if present
646
- if (this.modifyInteraction) {
647
- map.removeInteraction(this.modifyInteraction);
648
- }
649
- // Add modify interaction, RoutingLayer and listeners
650
- // @ts-ignore
651
- // this.routingLayer?.attachToMap(this.getMap());
652
- if (this.modifyInteraction) {
653
- map.addInteraction(this.modifyInteraction);
654
- }
655
- (_a = this.modifyInteraction) === null || _a === void 0 ? void 0 : _a.setActive(this.modify);
656
- this.addListeners();
657
- }
640
+ /**
641
+ * Replaces the current viaPoints with a new coordinate array.
642
+ * @param {Array<Array<number>>} coordinateArray Array of nested coordinates
643
+ * @public
644
+ */
645
+ setViaPoints(coordinateArray) {
646
+ this.viaPoints = [...coordinateArray];
647
+ this.drawRoute();
648
+ this.dispatchEvent(new BaseEvent('change:route'));
658
649
  }
659
- deactivate() {
660
- const map = this.getMap();
661
- if (map) {
662
- // Remove modify interaction, RoutingLayer, listeners and viaPoints
663
- // @ts-ignore
664
- // this.routingLayer?.detachFromMap();
665
- if (this.modifyInteraction) {
666
- map.removeInteraction(this.modifyInteraction);
667
- }
668
- this.removeListeners();
669
- this.reset();
670
- }
650
+ get active() {
651
+ return this.get('active');
652
+ }
653
+ set active(newValue) {
654
+ this.set('active', newValue);
655
+ }
656
+ get loading() {
657
+ return this.get('loading');
658
+ }
659
+ set loading(newValue) {
660
+ this.set('loading', newValue);
661
+ }
662
+ get modify() {
663
+ return this.get('modify');
664
+ }
665
+ set modify(newValue) {
666
+ this.set('modify', newValue);
667
+ }
668
+ get mot() {
669
+ return this.get('mot');
670
+ }
671
+ set mot(newValue) {
672
+ this.set('mot', newValue);
671
673
  }
672
- render() { }
673
674
  }
674
675
  export default RoutingControl;
@@ -0,0 +1,37 @@
1
+ import { Feature } from 'geojson';
2
+ import Control, { Options } from 'ol/control/Control';
3
+ import StopFinderControlCommon from '../../common/controls/StopFinderControlCommon';
4
+ export type StopFinderControlOptions = Options & StopFinderControlCommon & {
5
+ className?: string;
6
+ };
7
+ /**
8
+ * This OpenLayers control allows to search stations from the [geOps Stops API](https://developer.geops.io/apis/stops/).
9
+ *
10
+ * @example
11
+ * import { Map } from 'ol';
12
+ * import { StopFinderControl } from 'mobility-toolbox-js/ol';
13
+ *
14
+ * const map = new Map({
15
+ * target: 'map',
16
+ * });
17
+ *
18
+ * const control = new StopFinderControl({
19
+ * apiKey: [yourApiKey]
20
+ * });
21
+ *
22
+ * map.addControl(control);
23
+ *
24
+ *
25
+ * @see <a href="/example/ol-search">Openlayers search example</a>
26
+ * @public
27
+ */
28
+ declare class StopFinderControl extends Control {
29
+ controller: StopFinderControlCommon;
30
+ constructor(options: StopFinderControlOptions);
31
+ /**
32
+ * @private
33
+ */
34
+ onSuggestionClick(suggestion: Feature): void;
35
+ search(q: string, abortController: AbortController): Promise<void>;
36
+ }
37
+ export default StopFinderControl;
@@ -3,7 +3,7 @@ import Control from 'ol/control/Control';
3
3
  import StopFinderControlCommon from '../../common/controls/StopFinderControlCommon';
4
4
  import createDefaultStopFinderElement from '../../common/utils/createDefaultStopFinderElt';
5
5
  /**
6
- * Search stations.
6
+ * This OpenLayers control allows to search stations from the [geOps Stops API](https://developer.geops.io/apis/stops/).
7
7
  *
8
8
  * @example
9
9
  * import { Map } from 'ol';
@@ -39,5 +39,8 @@ class StopFinderControl extends Control {
39
39
  const coord = fromLonLat(suggestion.geometry.coordinates);
40
40
  (_a = this.getMap()) === null || _a === void 0 ? void 0 : _a.getView().setCenter(coord);
41
41
  }
42
+ search(q, abortController) {
43
+ return this.controller.search(q, abortController);
44
+ }
42
45
  }
43
46
  export default StopFinderControl;
@@ -0,0 +1,3 @@
1
+ export { default as CopyrightControl } from "./CopyrightControl";
2
+ export { default as RoutingControl } from "./RoutingControl";
3
+ export { default as StopFinderControl } from "./StopFinderControl";
package/ol/index.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export * from "../api";
2
+ export * from "../common";
3
+ export * from "./controls";
4
+ export * from "./layers";
5
+ export * from "./mixins";
6
+ export * from "./styles";
7
+ export * from "./utils";
package/ol/index.js CHANGED
@@ -2,5 +2,6 @@ export * from '../api';
2
2
  export * from '../common';
3
3
  export * from './controls';
4
4
  export * from './layers';
5
+ export * from './mixins';
5
6
  export * from './styles';
6
7
  export * from './utils';