mobility-toolbox-js 2.0.0 → 2.0.1-beta.13

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 (102) hide show
  1. package/api/RoutingAPI.js +15 -0
  2. package/api/RoutingAPI.test.js +25 -0
  3. package/api/StopsAPI.js +12 -0
  4. package/api/StopsAPI.test.js +22 -0
  5. package/api/TralisAPI.js +359 -0
  6. package/api/TralisAPI.test.js +67 -0
  7. package/api/{tralis/TralisAPIUtils.js → TralisAPIUtils.js} +2 -32
  8. package/api/index.js +3 -3
  9. package/{ol/README.md → api/typedefs.js} +0 -0
  10. package/common/Tracker.js +14 -118
  11. package/common/api/HttpAPI.js +30 -0
  12. package/common/api/HttpAPI.test.js +50 -0
  13. package/common/api/WebSocketAPI.js +175 -0
  14. package/{api/tralis/WebSocketConnector.test.js → common/api/WebSocketAPI.test.js} +100 -145
  15. package/common/controls/Control.js +26 -91
  16. package/common/controls/Control.test.js +32 -43
  17. package/common/index.js +4 -0
  18. package/common/layers/Layer.js +53 -244
  19. package/common/layers/Layer.test.js +185 -244
  20. package/common/mixins/CopyrightMixin.js +20 -44
  21. package/common/mixins/SearchMixin.js +100 -166
  22. package/common/mixins/TralisLayerMixin.js +443 -894
  23. package/common/styles/index.js +4 -4
  24. package/common/styles/trackerDefaultStyle.js +39 -175
  25. package/common/styles/trackerDelayStyle.js +2 -11
  26. package/common/styles/trackerSimpleStyle.js +4 -8
  27. package/common/trackerConfig.js +61 -99
  28. package/common/trackerConfig.test.js +15 -17
  29. package/common/typedefs.js +0 -23
  30. package/common/utils/createTrackerFilters.js +10 -41
  31. package/common/utils/createTrackerFilters.test.js +40 -56
  32. package/common/utils/getMapboxMapCopyrights.js +3 -16
  33. package/common/utils/getMapboxMapCopyrights.test.js +32 -39
  34. package/common/utils/getMapboxStyleUrl.js +3 -13
  35. package/common/utils/getVehiclePosition.js +3 -33
  36. package/common/utils/index.js +5 -6
  37. package/common/utils/removeDuplicate.js +3 -17
  38. package/common/utils/removeDuplicate.test.js +17 -20
  39. package/common/utils/sortByDelay.js +2 -7
  40. package/common/utils/timeUtils.js +8 -32
  41. package/common/utils/timeUtils.test.js +7 -13
  42. package/index.js +8 -2
  43. package/mapbox/controls/CopyrightControl.js +9 -38
  44. package/mapbox/controls/index.js +1 -0
  45. package/mapbox/index.js +4 -3
  46. package/mapbox/layers/Layer.js +15 -76
  47. package/mapbox/layers/Layer.test.js +81 -101
  48. package/mapbox/layers/TralisLayer.js +46 -193
  49. package/mapbox/layers/TralisLayer.test.js +12 -14
  50. package/mapbox/layers/index.js +2 -0
  51. package/mapbox/utils.js +7 -21
  52. package/mbt.js +50444 -0
  53. package/mbt.js.map +7 -0
  54. package/mbt.min.js +1005 -0
  55. package/mbt.min.js.map +7 -0
  56. package/ol/controls/CopyrightControl.js +8 -46
  57. package/ol/controls/CopyrightControl.test.js +75 -121
  58. package/ol/controls/RoutingControl.js +167 -532
  59. package/ol/controls/RoutingControl.test.js +99 -164
  60. package/ol/controls/StopFinderControl.js +3 -31
  61. package/ol/controls/StopFinderControl.test.js +18 -29
  62. package/ol/controls/index.js +3 -0
  63. package/ol/index.js +5 -13
  64. package/ol/layers/Layer.js +23 -128
  65. package/ol/layers/Layer.test.js +79 -102
  66. package/ol/layers/MapboxLayer.js +62 -237
  67. package/ol/layers/MapboxLayer.test.js +58 -84
  68. package/ol/layers/MapboxStyleLayer.js +38 -268
  69. package/ol/layers/MapboxStyleLayer.test.js +97 -128
  70. package/ol/layers/MaplibreLayer.js +46 -187
  71. package/ol/layers/RoutingLayer.js +21 -51
  72. package/ol/layers/RoutingLayer.test.js +15 -24
  73. package/ol/layers/TralisLayer.js +102 -276
  74. package/ol/layers/TralisLayer.test.js +32 -50
  75. package/ol/layers/VectorLayer.js +3 -24
  76. package/ol/layers/VectorLayer.test.js +34 -45
  77. package/ol/layers/WMSLayer.js +15 -57
  78. package/ol/layers/WMSLayer.test.js +35 -43
  79. package/ol/layers/index.js +8 -0
  80. package/ol/styles/fullTrajectoryDelayStyle.js +11 -15
  81. package/ol/styles/fullTrajectoryStyle.js +17 -25
  82. package/ol/styles/index.js +2 -2
  83. package/package.json +35 -62
  84. package/api/routing/RoutingAPI.js +0 -44
  85. package/api/routing/RoutingAPI.test.js +0 -41
  86. package/api/stops/StopsAPI.js +0 -41
  87. package/api/stops/StopsAPI.test.js +0 -34
  88. package/api/tralis/TralisAPI.js +0 -731
  89. package/api/tralis/TralisAPI.test.js +0 -75
  90. package/api/tralis/WebSocketConnector.js +0 -338
  91. package/api/tralis/typedefs.js +0 -81
  92. package/common/api/api.js +0 -64
  93. package/common/api/api.test.js +0 -68
  94. package/index.js.map +0 -1
  95. package/module.js +0 -23
  96. package/ol/controls/snapshots/RoutingControlRouteGen10.json +0 -58
  97. package/ol/controls/snapshots/RoutingControlRouteGen100.json +0 -292
  98. package/ol/controls/snapshots/RoutingControlRouteGen30.json +0 -69
  99. package/ol/controls/snapshots/RoutingControlRouteGen5.json +0 -58
  100. package/ol/controls/snapshots/RoutingControlRouteOSM.json +0 -759
  101. package/ol/controls/snapshots/RoutingControlStation1.json +0 -60
  102. package/ol/controls/snapshots/RoutingControlStation2.json +0 -49
@@ -1,201 +1,68 @@
1
- /* eslint-disable no-param-reassign */
2
- import Layer from './Layer';
3
-
4
- /**
5
- * Layer for visualizing a specific set of layer from a MapboxLayer.
6
- *
7
- * @example
8
- * import { MapboxLayer, MapboxStyleLayer } from 'mobility-toolbox-js/ol';
9
- *
10
- * const mapboxLayer = new MapboxLayer({
11
- * url: 'https://maps.geops.io/styles/travic_v2/style.json?key=[yourApiKey]',
12
- * });
13
- *
14
- * const layer = new MapboxStyleLayer({
15
- * mapboxLayer: mapboxLayer,
16
- * styleLayersFilter: () => {},
17
- * });
18
- *
19
- * @classproperty {ol/Map~Map} map - The map where the layer is displayed.
20
- * @extends {Layer}
21
- */
1
+ import Layer from "./Layer";
22
2
  class MapboxStyleLayer extends Layer {
23
- /**
24
- * Constructor.
25
- *
26
- * @param {Object} options
27
- * @param {MapboxLayer} [options.mapboxLayer] The MapboxLayer to use.
28
- * @param {Function} [options.styleLayersFilter] Filter function to decide which style layer to display.
29
- */
30
3
  constructor(options = {}) {
31
4
  super(options);
32
-
33
- /**
34
- * MapboxLayer provided for the style Layer.
35
- * @type {MapboxLayer}
36
- * @private
37
- */
38
5
  this.mapboxLayer = options.mapboxLayer;
39
-
40
- /**
41
- * Define if the layer has data to display in the current mapbox layer.
42
- */
43
6
  this.disabled = false;
44
-
45
- /**
46
- * Function to filter features to be displayed.
47
- * @type {function}
48
- * @private
49
- */
50
7
  this.styleLayersFilter = options.styleLayersFilter;
51
-
52
- /**
53
- * Mapbox style layer id where to add the style layers.
54
- * See [mapbox.map.addLayer](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer) documentation.
55
- * @type {String}
56
- * @private
57
- */
58
8
  this.beforeId = options.beforeId;
59
-
60
- /**
61
- * Function to filter features for getFeatureInfoAtCoordinate method.
62
- * @type {function}
63
- * @private
64
- */
65
9
  this.featureInfoFilter = options.featureInfoFilter || ((obj) => obj);
66
-
67
- /**
68
- * Function to query the rendered features.
69
- * @type {function}
70
- * @private
71
- */
72
10
  this.queryRenderedLayersFilter = options.queryRenderedLayersFilter;
73
-
74
- /**
75
- * Array of features to highlight.
76
- * @type {Array<ol/Feature~Feature>}
77
- * @private
78
- */
79
11
  this.highlightedFeatures = [];
80
-
81
- /**
82
- * Array of selected features.
83
- * @type {Array<ol/Feature~Feature>}
84
- * @private
85
- */
86
12
  this.selectedFeatures = [];
87
-
88
- /**
89
- * Array of mapbox style layers to add.
90
- * @type {Array<mapboxgl.styleLayer>}
91
- * @private
92
- */
93
- this.styleLayers =
94
- (options.styleLayer ? [options.styleLayer] : options.styleLayers) || [];
95
-
96
- /**
97
- * @private
98
- */
13
+ this.styleLayers = (options.styleLayer ? [options.styleLayer] : options.styleLayers) || [];
99
14
  this.addStyleLayers = this.addStyleLayers.bind(this);
100
-
101
- /**
102
- * @private
103
- */
104
15
  this.onLoad = this.onLoad.bind(this);
105
16
  if (options.filters) {
106
- /** @private */
107
17
  this.addDynamicFilters = () => {
108
- this.setFilter(
109
- typeof options.filters === 'function'
110
- ? options.filters(this)
111
- : options.filters,
112
- );
18
+ this.setFilter(typeof options.filters === "function" ? options.filters(this) : options.filters);
113
19
  };
114
20
  }
115
-
116
21
  if (!this.styleLayersFilter && this.styleLayers) {
117
22
  const ids = this.styleLayers.map((s) => s.id);
118
23
  this.styleLayersFilter = (styleLayer) => ids.includes(styleLayer.id);
119
24
  }
120
25
  }
121
-
122
- /**
123
- * Initialize the layer.
124
- * @param {mapboxgl.Map} map the mapbox map.
125
- * @override
126
- */
127
- init(map) {
26
+ attachToMap(map) {
128
27
  if (!this.mapboxLayer.map) {
129
- this.mapboxLayer.init(map);
28
+ this.mapboxLayer.attachToMap(map);
130
29
  }
131
- super.init(map);
132
-
30
+ super.attachToMap(map);
133
31
  if (!this.map) {
134
32
  return;
135
33
  }
136
-
137
- // Apply the initial visibiltity.
138
34
  const { mbMap } = this.mapboxLayer;
139
35
  if (!mbMap) {
140
- // If the mbMap is not yet created because the map has no target yet, we
141
- // relaunch the initialisation when it's the case.
142
- this.olListenersKeys.push(
143
- this.map.on('change:target', () => {
144
- this.init(map);
145
- }),
146
- );
147
-
36
+ this.olListenersKeys.push(this.map.on("change:target", () => {
37
+ this.attachToMap(map);
38
+ }));
148
39
  return;
149
40
  }
150
-
151
- // mbMap.loaded() and mbMap.isStyleLoaded() are reliable only on the first call of init.
152
- // On the next call (when a topic change for example), these functions returns false because
153
- // the style is being modified.
154
- // That's why we rely on a property instead for the next calls.
155
41
  if (this.mapboxLayer.loaded || mbMap.isStyleLoaded() || mbMap.loaded()) {
156
42
  this.onLoad();
157
43
  } else {
158
- mbMap.once('load', this.onLoad);
44
+ mbMap.once("load", this.onLoad);
159
45
  }
160
-
161
- // Apply the visibiltity when layer's visibility change.
162
- this.olListenersKeys.push(
163
- this.on('change:visible', (evt) => {
164
- // Once the map is loaded we can apply vsiiblity without waiting
165
- // the style. Mapbox take care of the application of style changes.
166
- this.applyLayoutVisibility(evt);
167
- }),
168
- );
169
-
170
- this.olListenersKeys.push(
171
- this.mapboxLayer.on('load', () => {
172
- this.onLoad();
173
- }),
174
- );
46
+ this.olListenersKeys.push(this.on("change:visible", (evt) => {
47
+ this.applyLayoutVisibility(evt);
48
+ }));
49
+ this.olListenersKeys.push(this.mapboxLayer.on("load", () => {
50
+ this.onLoad();
51
+ }));
175
52
  }
176
-
177
- /**
178
- * Terminate the layer.
179
- * @param {mapboxgl.Map} map the mapbox map.
180
- * @override
181
- */
182
- terminate(map) {
53
+ detachFromMap(map) {
183
54
  const { mbMap } = this.mapboxLayer;
184
55
  if (mbMap) {
185
- mbMap.off('load', this.onLoad);
56
+ mbMap.off("load", this.onLoad);
186
57
  this.removeStyleLayers();
187
58
  }
188
- super.terminate(map);
59
+ super.detachFromMap(map);
189
60
  }
190
-
191
- /** @ignore */
192
61
  addStyleLayers() {
193
62
  const { mbMap } = this.mapboxLayer;
194
-
195
63
  if (!mbMap) {
196
64
  return;
197
65
  }
198
-
199
66
  this.styleLayers.forEach((styleLayer) => {
200
67
  const { id, source } = styleLayer;
201
68
  if (mbMap.getSource(source) && !mbMap.getLayer(id)) {
@@ -204,33 +71,22 @@ class MapboxStyleLayer extends Layer {
204
71
  });
205
72
  this.applyLayoutVisibility();
206
73
  }
207
-
208
- /** @ignore */
209
74
  removeStyleLayers() {
210
75
  const { mbMap } = this.mapboxLayer;
211
-
212
76
  if (!mbMap) {
213
77
  return;
214
78
  }
215
-
216
79
  this.styleLayers.forEach((styleLayer) => {
217
80
  if (mbMap.getLayer(styleLayer.id)) {
218
81
  mbMap.removeLayer(styleLayer.id);
219
82
  }
220
83
  });
221
84
  }
222
-
223
- /**
224
- * On Mapbox map load callback function. Add style layers and dynaimc filters.
225
- * @ignore
226
- */
227
85
  onLoad() {
228
86
  this.addStyleLayers();
229
-
230
87
  if (this.addDynamicFilters) {
231
88
  this.addDynamicFilters();
232
89
  }
233
-
234
90
  const { mbMap } = this.mapboxLayer;
235
91
  const style = mbMap.getStyle();
236
92
  if (style && this.styleLayersFilter) {
@@ -238,180 +94,94 @@ class MapboxStyleLayer extends Layer {
238
94
  this.disabled = !styles.length;
239
95
  }
240
96
  }
241
-
242
- /**
243
- * Request feature information for a given coordinate.
244
- * @param {ol/coordinate~Coordinate} coordinate Coordinate to request the information at.
245
- * @return {Promise<FeatureInfo>} Promise with features, layer and coordinate.
246
- */
247
97
  getFeatureInfoAtCoordinate(coordinate) {
248
98
  const { mbMap } = this.mapboxLayer;
249
-
250
- // Ignore the getFeatureInfo until the mapbox map is loaded
251
99
  if (!mbMap || !mbMap.isStyleLoaded()) {
252
100
  return Promise.resolve({ coordinate, features: [], layer: this });
253
101
  }
254
-
255
- // We query features only on style layers used by this layer.
256
102
  let layers = this.styleLayers || [];
257
-
258
103
  if (this.styleLayersFilter) {
259
104
  layers = mbMap.getStyle().layers.filter(this.styleLayersFilter);
260
105
  }
261
-
262
106
  if (this.queryRenderedLayersFilter) {
263
107
  layers = mbMap.getStyle().layers.filter(this.queryRenderedLayersFilter);
264
108
  }
265
-
266
- return this.mapboxLayer
267
- .getFeatureInfoAtCoordinate(coordinate, {
268
- layers: layers.map((layer) => layer && layer.id),
269
- validate: false,
270
- })
271
- .then((featureInfo) => {
272
- const features = featureInfo.features.filter((feature) =>
273
- this.featureInfoFilter(feature, this.map.getView().getResolution()),
274
- );
275
- this.highlight(features);
276
- return { ...featureInfo, features, layer: this };
277
- });
109
+ return this.mapboxLayer.getFeatureInfoAtCoordinate(coordinate, {
110
+ layers: layers.map((layer) => layer && layer.id),
111
+ validate: false
112
+ }).then((featureInfo) => {
113
+ const features = featureInfo.features.filter((feature) => this.featureInfoFilter(feature, this.map.getView().getResolution()));
114
+ this.highlight(features);
115
+ return { ...featureInfo, features, layer: this };
116
+ });
278
117
  }
279
-
280
- /**
281
- * Set filter that determines which features should be rendered in a style layer.
282
- * @param {mapboxgl.filter} filter Determines which features should be rendered in a style layer.
283
- */
284
118
  setFilter(filter) {
285
119
  const { mbMap } = this.mapboxLayer;
286
-
287
120
  if (!mbMap) {
288
121
  return;
289
122
  }
290
-
291
123
  this.styleLayers.forEach(({ id }) => {
292
124
  if (mbMap.getLayer(id)) {
293
125
  mbMap.setFilter(id, filter);
294
126
  }
295
127
  });
296
128
  }
297
-
298
- /**
299
- * Set if features are hovered or not.
300
- * @param {Array<ol/Feature~Feature>} features
301
- * @param {boolean} state Is the feature hovered
302
- * @private
303
- */
304
129
  setHoverState(features, state) {
305
130
  const { mbMap } = this.mapboxLayer;
306
-
307
131
  if (!features || !mbMap) {
308
132
  return;
309
133
  }
310
-
311
134
  features.forEach((feature) => {
312
- const { source, sourceLayer } = feature.get('mapboxFeature') || {};
313
- if ((!source && !sourceLayer) || !feature.getId()) {
135
+ const { source, sourceLayer } = feature.get("mapboxFeature") || {};
136
+ if (!source && !sourceLayer || !feature.getId()) {
314
137
  if (!feature.getId()) {
315
- // eslint-disable-next-line no-console
316
- console.warn(
317
- "No feature's id found. To use the feature state functionnality, tiles must be generated with --generate-ids. See https://github.com/mapbox/tippecanoe#adding-calculated-attributes.",
318
- feature.getId(),
319
- feature.getProperties(),
320
- );
138
+ console.warn("No feature's id found. To use the feature state functionnality, tiles must be generated with --generate-ids. See https://github.com/mapbox/tippecanoe#adding-calculated-attributes.", feature.getId(), feature.getProperties());
321
139
  }
322
140
  return;
323
141
  }
324
-
325
- mbMap.setFeatureState(
326
- {
327
- id: feature.getId(),
328
- source,
329
- sourceLayer,
330
- },
331
- { hover: state },
332
- );
142
+ mbMap.setFeatureState({
143
+ id: feature.getId(),
144
+ source,
145
+ sourceLayer
146
+ }, { hover: state });
333
147
  });
334
148
  }
335
-
336
- /**
337
- * Select a list of features.
338
- * @param {Array<ol/Feature~Feature>} [features=[]] Features to select.
339
- * @private
340
- */
341
149
  select(features = []) {
342
150
  this.setHoverState(this.selectedFeatures, false);
343
151
  this.selectedFeatures = features;
344
152
  this.setHoverState(this.selectedFeatures, true);
345
153
  }
346
-
347
- /**
348
- * Highlight a list of features.
349
- * @param {Array<ol/Feature~Feature>} [features=[]] Features to highlight.
350
- * @private
351
- */
352
154
  highlight(features = []) {
353
- // Filter out selected features
354
- const filtered = this.highlightedFeatures.filter(
355
- (feature) =>
356
- !this.selectedFeatures
357
- .map((feat) => feat.getId())
358
- .includes(feature.getId()),
359
- );
360
-
361
- // Remove previous highlight
155
+ const filtered = this.highlightedFeatures.filter((feature) => !this.selectedFeatures.map((feat) => feat.getId()).includes(feature.getId()));
362
156
  this.setHoverState(filtered, false);
363
157
  this.highlightedFeatures = features;
364
-
365
- // Add highlight
366
158
  this.setHoverState(this.highlightedFeatures, true);
367
159
  }
368
-
369
- /**
370
- * Apply visibility to style layers that fits the styleLayersFilter function.
371
- * @param {Event} evt Layer's event that has called the function.
372
- * @private
373
- */
374
- // eslint-disable-next-line no-unused-vars
375
160
  applyLayoutVisibility(evt) {
376
161
  const { visible } = this;
377
162
  const { mbMap } = this.mapboxLayer;
378
163
  const filterFunc = this.styleLayersFilter;
379
-
380
164
  if (!mbMap) {
381
165
  return;
382
166
  }
383
-
384
167
  const style = mbMap.getStyle();
385
-
386
168
  if (!style) {
387
169
  return;
388
170
  }
389
-
390
171
  if (filterFunc) {
391
- const visibilityValue = visible ? 'visible' : 'none';
172
+ const visibilityValue = visible ? "visible" : "none";
392
173
  for (let i = 0; i < style.layers.length; i += 1) {
393
174
  const styleLayer = style.layers[i];
394
175
  if (filterFunc(styleLayer)) {
395
176
  if (mbMap.getLayer(styleLayer.id)) {
396
- mbMap.setLayoutProperty(
397
- styleLayer.id,
398
- 'visibility',
399
- visibilityValue,
400
- );
177
+ mbMap.setLayoutProperty(styleLayer.id, "visibility", visibilityValue);
401
178
  }
402
179
  }
403
180
  }
404
181
  }
405
182
  }
406
-
407
- /**
408
- * Create a copy of the MapboxStyleLayer.
409
- * @param {Object} newOptions Options to override.
410
- * @return {MapboxStyleLayer} A MapboxStyleLayer.
411
- */
412
183
  clone(newOptions) {
413
184
  return new MapboxStyleLayer({ ...this.options, ...newOptions });
414
185
  }
415
186
  }
416
-
417
187
  export default MapboxStyleLayer;