mobility-toolbox-js 2.0.0-beta.1 → 2.0.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.
Files changed (67) hide show
  1. package/README.md +7 -4
  2. package/api/index.js +0 -1
  3. package/api/tralis/TralisAPI.js +1 -1
  4. package/common/controls/Control.js +4 -1
  5. package/common/layers/Layer.js +18 -49
  6. package/common/layers/Layer.test.js +2 -106
  7. package/common/mixins/SearchMixin.js +1 -1
  8. package/common/mixins/TralisLayerMixin.js +549 -21
  9. package/common/styles/index.js +4 -0
  10. package/common/{utils/delayTrackerStyle.js → styles/trackerDefaultStyle.js} +8 -8
  11. package/common/styles/trackerDelayStyle.js +17 -0
  12. package/common/styles/trackerSimpleStyle.js +22 -0
  13. package/common/trackerConfig.test.js +0 -13
  14. package/common/utils/getMapboxMapCopyrights.js +1 -0
  15. package/common/utils/index.js +2 -3
  16. package/common/utils/sortByDelay.js +23 -0
  17. package/index.js +1 -1
  18. package/index.js.map +1 -1
  19. package/mapbox/controls/CopyrightControl.js +5 -1
  20. package/mapbox/index.js +0 -2
  21. package/mapbox/layers/Layer.test.js +2 -2
  22. package/mapbox/layers/TralisLayer.js +270 -5
  23. package/mapbox/layers/TralisLayer.test.js +40 -0
  24. package/module.js +1 -9
  25. package/ol/controls/CopyrightControl.js +4 -4
  26. package/ol/controls/CopyrightControl.test.js +16 -16
  27. package/ol/controls/RoutingControl.js +9 -7
  28. package/ol/controls/RoutingControl.test.js +1 -1
  29. package/ol/controls/StopFinderControl.js +8 -6
  30. package/ol/controls/StopFinderControl.test.js +1 -1
  31. package/ol/index.js +3 -3
  32. package/ol/layers/Layer.js +9 -0
  33. package/ol/layers/Layer.test.js +22 -7
  34. package/ol/layers/MapboxLayer.js +39 -44
  35. package/ol/layers/MapboxLayer.test.js +5 -5
  36. package/ol/layers/MapboxStyleLayer.js +0 -6
  37. package/ol/layers/MapboxStyleLayer.test.js +22 -6
  38. package/ol/layers/MaplibreLayer.js +280 -0
  39. package/ol/layers/RoutingLayer.test.js +1 -1
  40. package/ol/layers/TralisLayer.js +258 -76
  41. package/ol/layers/TralisLayer.test.js +1 -49
  42. package/ol/layers/VectorLayer.test.js +1 -1
  43. package/ol/layers/WMSLayer.test.js +6 -2
  44. package/ol/styles/fullTrajectoryDelayStyle.js +35 -0
  45. package/ol/styles/fullTrajectoryStyle.js +51 -0
  46. package/ol/styles/index.js +2 -0
  47. package/package.json +16 -8
  48. package/api/trajserv/TrajservAPI.js +0 -71
  49. package/api/trajserv/TrajservAPI.test.js +0 -171
  50. package/api/trajserv/TrajservAPIUtils.js +0 -191
  51. package/api/trajserv/TrajservAPIUtils.test.js +0 -40
  52. package/api/trajserv/typedefs.js +0 -44
  53. package/common/mixins/MapMixin.js +0 -103
  54. package/common/mixins/TrackerLayerMixin.js +0 -745
  55. package/common/mixins/TrajservLayerMixin.js +0 -544
  56. package/common/utils/simpleTrackerStyle.js +0 -18
  57. package/mapbox/Map.js +0 -87
  58. package/mapbox/layers/TrackerLayer.js +0 -282
  59. package/mapbox/layers/TrackerLayer.test.js +0 -68
  60. package/mapbox/layers/TrajservLayer.js +0 -114
  61. package/mapbox/layers/TrajservLayer.test.js +0 -90
  62. package/ol/Map.js +0 -109
  63. package/ol/Map.test.js +0 -34
  64. package/ol/layers/TrackerLayer.js +0 -296
  65. package/ol/layers/TrackerLayer.test.js +0 -70
  66. package/ol/layers/TrajservLayer.js +0 -190
  67. package/ol/layers/TrajservLayer.test.js +0 -113
@@ -1,745 +0,0 @@
1
- /* eslint-disable class-methods-use-this */
2
- /* eslint-disable max-classes-per-file */
3
- import { buffer, containsCoordinate } from 'ol/extent';
4
- import { unByKey } from 'ol/Observable';
5
- import qs from 'query-string';
6
- import debounce from 'lodash.debounce';
7
- import throttle from 'lodash.throttle';
8
- import Tracker from '../Tracker';
9
- import { timeSteps } from '../trackerConfig';
10
- import createFilters from '../utils/createTrackerFilters';
11
- import { delayTrackerStyle } from '../utils';
12
-
13
- /* Permalink parameter used to filters vehicles */
14
- const LINE_FILTER = 'publishedlinename';
15
- const ROUTE_FILTER = 'tripnumber';
16
- const OPERATOR_FILTER = 'operator';
17
-
18
- /**
19
- * TrackerLayerInterface.
20
- *
21
- * @classproperty {string} hoverVehicleId - Id of the hovered vehicle.
22
- * @classproperty {string} selectedVehicleId - Id of the selected vehicle.
23
- * @classproperty {number} pixelRatio - Pixel ratio use to render the trajectories. Default to window.devicePixelRatio.
24
- * @classproperty {boolean} live - If true, the layer will always use Date.now() to render trajectories. Default to true.
25
- * @classproperty {boolean} useRequestAnimationFrame - If true, encapsulates the renderTrajectories calls in a requestAnimationFrame. Experimental.
26
- * @classproperty {boolean} useThrottle - If true, encapsulates the renderTrajectories calls in a throttle function. Experimental.
27
- * @classproperty {boolean} useDebounce - If true, encapsulates the renderTrajectories calls in a debounce function. Experimental.
28
- * @classproperty {boolean} isTrackerLayer - Property for duck typing since `instanceof` is not working when the instance was created on different bundles.
29
- * @classproperty {function} sort - Sort the trajectories.
30
- * @classproperty {function} style - Style of a trajectory.
31
- * @classproperty {Date} time - Time used to display the trajectories. The setter manages a Date or a number in ms representing a Date. If `live` property is true. The setter does nothing..
32
- * @classproperty {FilterFunction} filter - Filter the trajectories.
33
- */
34
- export class TrackerLayerInterface {
35
- /**
36
- * Initalize the Tracker.
37
- * @param {ol/Map~Map} map
38
- * @param {Object} options
39
- * @param {number} [options.width] Canvas's width.
40
- * @param {number} [options.height] Canvas's height.
41
- */
42
- // eslint-disable-next-line no-unused-vars
43
- init(map, options) {}
44
-
45
- /**
46
- * Destroy the Tracker.
47
- */
48
- terminate() {}
49
-
50
- /**
51
- * Start the clock.
52
- */
53
- start() {}
54
-
55
- /**
56
- * Start the timeout for the next update.
57
- * @private
58
- */
59
- startUpdateTime() {}
60
-
61
- /**
62
- * Stop the clock.
63
- */
64
- stop() {}
65
-
66
- /**
67
- * Get vehicle.
68
- * @param {function} filterFc A function use to filter results.
69
- */
70
- // eslint-disable-next-line no-unused-vars
71
- getVehicle(filterFc) {}
72
-
73
- /**
74
- * Returns the list of vehicles which are at the given coordinates.
75
- * Returns an empty array when no vehicle is located at the given
76
- * coordinates.
77
- *
78
- * @param {number[2]} coordinate A coordinate ([x,y]).
79
- * @param {number} [resolution=1] The resolution of the map.
80
- * @param {number} [nb=Infinity] nb The max number of vehicles to return.
81
- * @return {Array<ol/Feature~Feature>} Array of vehicles.
82
- */
83
- // eslint-disable-next-line no-unused-vars
84
- getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {}
85
-
86
- /**
87
- * Get the duration before the next update depending on zoom level.
88
- * @private
89
- * @param {number} zoom
90
- */
91
- // eslint-disable-next-line no-unused-vars
92
- getRefreshTimeInMs(zoom) {}
93
-
94
- /**
95
- * Define a default style of vehicles.
96
- * Draw a blue circle with the id of the props parameter.
97
- *
98
- * @param {Object} trajectory A trajectory
99
- * @param {ViewState} viewState Map's view state (zoom, resolution, center, ...)
100
- * @private
101
- */
102
- // eslint-disable-next-line no-unused-vars
103
- defaultStyle(trajectory, viewState) {}
104
- }
105
-
106
- /**
107
- * Mixin for TrackeLayerInterface.
108
- *
109
- * @param {Class} Base A class to extend with {TrackerLayerInterface} functionnalities.
110
- * @return {Class} A class that implements <TrackerLayerInterface> class and extends Base;
111
- * @private
112
- */
113
- const TrackerLayerMixin = (Base) =>
114
- class extends Base {
115
- constructor(options) {
116
- super({ hitTolerance: 10, ...options });
117
- this.onFeatureHover = this.onFeatureHover.bind(this);
118
- this.onFeatureClick = this.onFeatureClick.bind(this);
119
- this.renderTrajectoriesInternal =
120
- this.renderTrajectoriesInternal.bind(this);
121
-
122
- this.throttleRenderTrajectories = throttle(
123
- this.renderTrajectoriesInternal,
124
- 50,
125
- { leading: false, trailing: true },
126
- );
127
-
128
- this.debounceRenderTrajectories = debounce(
129
- this.renderTrajectoriesInternal,
130
- 50,
131
- { leading: true, trailing: true, maxWait: 5000 },
132
- );
133
- }
134
-
135
- /**
136
- * Define layer's properties.
137
- *
138
- * @ignore
139
- */
140
- defineProperties(options) {
141
- // Tracker options use to build the tracker.
142
- let { regexPublishedLineName, publishedLineName, tripNumber, operator } =
143
- options;
144
- const {
145
- style,
146
- speed,
147
- pixelRatio,
148
- hoverVehicleId,
149
- selectedVehicleId,
150
- filter,
151
- sort,
152
- time,
153
- live,
154
- } = options;
155
-
156
- const initTrackerOptions = {
157
- style,
158
- };
159
-
160
- Object.keys(initTrackerOptions).forEach(
161
- (key) =>
162
- initTrackerOptions[key] === undefined &&
163
- delete initTrackerOptions[key],
164
- );
165
-
166
- let currSpeed = speed || 1;
167
- let currTime = time || new Date();
168
-
169
- super.defineProperties(options);
170
-
171
- Object.defineProperties(this, {
172
- isTrackerLayer: { value: true },
173
-
174
- /**
175
- * Style function used to render a vehicle.
176
- */
177
- style: {
178
- value: style || this.defaultStyle,
179
- },
180
-
181
- /**
182
- * Speed of the wheel of time.
183
- * If live property is true. The speed is ignored.
184
- */
185
- speed: {
186
- get: () => currSpeed,
187
- set: (newSpeed) => {
188
- currSpeed = newSpeed;
189
- this.start();
190
- },
191
- },
192
-
193
- /**
194
- * Function to filter which vehicles to display.
195
- */
196
- filter: {
197
- value: filter,
198
- writable: true,
199
- },
200
-
201
- /**
202
- * Function to sort the vehicles to display.
203
- */
204
- sort: {
205
- value: sort,
206
- writable: true,
207
- },
208
-
209
- /**
210
- * The tracker that renders the trajectories.
211
- */
212
- tracker: { value: null, writable: true },
213
-
214
- /**
215
- * Canvas cache object for trajectories drawn.
216
- */
217
- styleCache: { value: {} },
218
-
219
- /**
220
- * If true. The layer will always use Date.now() on the next tick to render the trajectories.
221
- * When true, setting the time property has no effect.
222
- */
223
- live: {
224
- value: live === false ? live : true,
225
- writable: true,
226
- },
227
-
228
- /**
229
- * Time used to display the trajectories. Can be a Date or a number in ms representing a Date.
230
- * If live property is true. The setter does nothing.
231
- */
232
- time: {
233
- get: () => currTime,
234
- set: (newTime) => {
235
- currTime = newTime && newTime.getTime ? newTime : new Date(newTime);
236
- this.renderTrajectories();
237
- },
238
- },
239
-
240
- /**
241
- * Keep track of which trajectories are stored.
242
- */
243
- trajectories: {
244
- value: {},
245
- writable: true,
246
- },
247
-
248
- /**
249
- * Keep track of which trajectories are currently drawn.
250
- */
251
- renderedTrajectories: {
252
- get: () => (this.tracker && this.tracker.renderedTrajectories) || [],
253
- },
254
-
255
- /**
256
- * Id of the hovered vehicle.
257
- */
258
- hoverVehicleId: {
259
- value: hoverVehicleId,
260
- writable: true,
261
- },
262
-
263
- /**
264
- * Id of the selected vehicle.
265
- */
266
- selectedVehicleId: {
267
- value: selectedVehicleId,
268
- writable: true,
269
- },
270
-
271
- /**
272
- * Id of the selected vehicle.
273
- */
274
- pixelRatio: {
275
- value: pixelRatio || window.devicePixelRatio || 1,
276
- writable: true,
277
- },
278
-
279
- /**
280
- * Options used by the constructor of the Tracker class.
281
- */
282
- initTrackerOptions: {
283
- value: initTrackerOptions,
284
- writable: false,
285
- },
286
-
287
- /**
288
- * If true, encapsulates the renderTrajectories calls in a requestAnimationFrame.
289
- */
290
- useRequestAnimationFrame: {
291
- value: options.useRequestAnimationFrame || false,
292
- writable: true,
293
- },
294
-
295
- /**
296
- * If true, encapsulates the renderTrajectories calls in a throttle function. Default to true.
297
- */
298
- useThrottle: {
299
- value: options.useThrottle || true,
300
- writable: true,
301
- },
302
-
303
- /**
304
- * If true, encapsulates the renderTrajectories calls in a debounce function.
305
- */
306
- useDebounce: {
307
- value: options.useDebounce || false,
308
- writable: true,
309
- },
310
-
311
- /**
312
- * Filter properties used in combination with permalink parameters.
313
- */
314
- publishedLineName: {
315
- get: () => publishedLineName,
316
- set: (newPublishedLineName) => {
317
- publishedLineName = newPublishedLineName;
318
- this.updateFilters();
319
- },
320
- },
321
- tripNumber: {
322
- get: () => tripNumber,
323
- set: (newTripNumber) => {
324
- tripNumber = newTripNumber;
325
- this.updateFilters();
326
- },
327
- },
328
- operator: {
329
- get: () => operator,
330
- set: (newOperator) => {
331
- operator = newOperator;
332
- this.updateFilters();
333
- },
334
- },
335
- regexPublishedLineName: {
336
- get: () => regexPublishedLineName,
337
- set: (newRegex) => {
338
- regexPublishedLineName = newRegex;
339
- this.updateFilters();
340
- },
341
- },
342
-
343
- /**
344
- * Style properties.
345
- */
346
- delayDisplay: {
347
- value: options.delayDisplay || 300000,
348
- writable: true,
349
- },
350
- delayOutlineColor: {
351
- value: options.delayOutlineColor || '#000000',
352
- writable: true,
353
- },
354
- useDelayStyle: {
355
- value: options.useDelayStyle || false,
356
- writable: true,
357
- },
358
-
359
- /**
360
- * Debug properties.
361
- */
362
- // Not used anymore, but could be useful for debugging.
363
- // showVehicleTraj: {
364
- // value:
365
- // options.showVehicleTraj !== undefined
366
- // ? options.showVehicleTraj
367
- // : true,
368
- // writable: true,
369
- // },
370
- });
371
-
372
- // When we use the delay style we want to display delayed train on top by default
373
- if (this.useDelayStyle && !this.sort) {
374
- this.sort = (traj1, traj2) => {
375
- const props1 = traj1.properties;
376
- const props2 = traj2.properties;
377
-
378
- if (props1.delay === null && props2.delay !== null) {
379
- return 1;
380
- }
381
- if (props2.delay === null && props1.delay !== null) {
382
- return -1;
383
- }
384
-
385
- // We put cancelled train inbetween green and yellow trains
386
- // >=180000ms corresponds to yellow train
387
- if (props1.cancelled && !props2.cancelled) {
388
- return props2.delay < 180000 ? -1 : 1;
389
- }
390
- if (props2.cancelled && !props1.cancelled) {
391
- return props1.delay < 180000 ? 1 : -1;
392
- }
393
- return props2.delay - props1.delay;
394
- };
395
- }
396
-
397
- // Update filter function based on convenient properties
398
- this.updateFilters();
399
- }
400
-
401
- /**
402
- * Initalize the Tracker.
403
- * @param {ol/Map~Map} map
404
- * @param {Object} options
405
- * @param {number} [options.width] Canvas's width.
406
- * @param {number} [options.height] Canvas's height.
407
- * @param {bool} [options.interpolate] Convert an EPSG:3857 coordinate to a canvas pixel (origin top-left).
408
- * @param {string} [options.hoverVehicleId] Id of the trajectory which is hovered.
409
- * @param {string} [options.selectedVehicleId] Id of the trajectory which is selected.
410
- * @param {function} [options.filter] Function use to filter the features displayed.
411
- * @param {function} [options.sort] Function use to sort the features displayed.
412
- * @param {function} [options.style] Function use to style the features displayed.
413
- */
414
- init(map, options = {}) {
415
- super.init(map);
416
-
417
- this.tracker = new Tracker({
418
- style: (...args) => this.style(...args),
419
- ...this.initTrackerOptions,
420
- ...options,
421
- });
422
-
423
- if (this.visible) {
424
- this.start();
425
- }
426
-
427
- this.visibilityRef = this.on('change:visible', (evt) => {
428
- if (evt.target.visible) {
429
- this.start();
430
- } else {
431
- this.stop();
432
- }
433
- });
434
- }
435
-
436
- /**
437
- * Destroy the Tracker.
438
- */
439
- terminate() {
440
- this.stop();
441
- unByKey(this.visibilityRef);
442
- if (this.tracker) {
443
- const { canvas } = this.tracker;
444
- const context = canvas.getContext('2d');
445
- context.clearRect(0, 0, canvas.width, canvas.height);
446
- this.tracker = null;
447
- }
448
- super.terminate();
449
- }
450
-
451
- /**
452
- * Start the trajectories rendering.
453
- *
454
- * @param {Array<Number>} size Map's size: [width, height].
455
- * @param {number} zoom Map's zoom level.
456
- * @param {number} resolution Map's resolution.
457
- * @param {number} rotation Map's rotation.
458
- */
459
- start() {
460
- this.stop();
461
- this.renderTrajectories();
462
- this.startUpdateTime();
463
-
464
- if (this.isClickActive) {
465
- this.onClick(this.onFeatureClick);
466
- }
467
-
468
- if (this.isHoverActive) {
469
- this.onHover(this.onFeatureHover);
470
- }
471
- }
472
-
473
- /**
474
- * Start the clock.
475
- * @private
476
- */
477
- startUpdateTime() {
478
- this.stopUpdateTime();
479
- this.updateTimeDelay = this.getRefreshTimeInMs();
480
- this.updateTimeInterval = setInterval(() => {
481
- // When live=true, we update the time with new Date();
482
- this.time = this.live
483
- ? new Date()
484
- : this.time.getTime() + this.updateTimeDelay * this.speed;
485
- }, this.updateTimeDelay);
486
- }
487
-
488
- /**
489
- * Stop the trajectories rendering.
490
- */
491
- stop() {
492
- this.stopUpdateTime();
493
- if (this.tracker) {
494
- const { canvas } = this.tracker;
495
- const context = canvas.getContext('2d');
496
- context.clearRect(0, 0, canvas.width, canvas.height);
497
- }
498
- }
499
-
500
- /**
501
- * Stop the clock.
502
- * @private
503
- */
504
- stopUpdateTime() {
505
- if (this.updateTimeInterval) {
506
- clearInterval(this.updateTimeInterval);
507
- }
508
- }
509
-
510
- /**
511
- * Launch renderTrajectories. it avoids duplicating code in renderTrajectories method.
512
- *
513
- * @param {object} viewState The view state of the map.
514
- * @param {number[2]} viewState.center Center coordinate of the map in mercator coordinate.
515
- * @param {number[4]} viewState.extent Extent of the map in mercator coordinates.
516
- * @param {number[2]} viewState.size Size ([width, height]) of the canvas to render.
517
- * @param {number} [viewState.rotation = 0] Rotation of the map to render.
518
- * @param {number} viewState.resolution Resolution of the map to render.
519
- * @param {boolean} noInterpolate If true trajectories are not interpolated but
520
- * drawn at the last known coordinate. Use this for performance optimization
521
- * during map navigation.
522
- * @private
523
- */
524
- renderTrajectoriesInternal(viewState, noInterpolate) {
525
- if (!this.tracker) {
526
- return false;
527
- }
528
-
529
- const time = this.live ? Date.now() : this.time;
530
-
531
- const trajectories = Object.values(this.trajectories);
532
-
533
- // console.time('sort');
534
- if (this.sort) {
535
- trajectories.sort(this.sort);
536
- }
537
- // console.timeEnd('sort');
538
-
539
- // console.time('render');
540
- this.renderState = this.tracker.renderTrajectories(
541
- trajectories,
542
- { ...viewState, pixelRatio: this.pixelRatio, time },
543
- {
544
- noInterpolate:
545
- viewState.zoom < this.minZoomInterpolation ? true : noInterpolate,
546
- hoverVehicleId: this.hoverVehicleId,
547
- selectedVehicleId: this.selectedVehicleId,
548
- iconScale: this.iconScale,
549
- delayDisplay: this.delayDisplay,
550
- delayOutlineColor: this.delayOutlineColor,
551
- useDelayStyle: this.useDelayStyle,
552
- },
553
- );
554
-
555
- // console.timeEnd('render');
556
- return true;
557
- }
558
-
559
- /**
560
- * Render the trajectories requesting an animation frame and cancelling the previous one.
561
- * This function must be overrided by children to provide the correct parameters.
562
- *
563
- * @param {object} viewState The view state of the map.
564
- * @param {number[2]} viewState.center Center coordinate of the map in mercator coordinate.
565
- * @param {number[4]} viewState.extent Extent of the map in mercator coordinates.
566
- * @param {number[2]} viewState.size Size ([width, height]) of the canvas to render.
567
- * @param {number} [viewState.rotation = 0] Rotation of the map to render.
568
- * @param {number} viewState.resolution Resolution of the map to render.
569
- * @param {boolean} noInterpolate If true trajectories are not interpolated but
570
- * drawn at the last known coordinate. Use this for performance optimization
571
- * during map navigation.
572
- * @private
573
- */
574
- renderTrajectories(viewState, noInterpolate) {
575
- if (this.requestId) {
576
- cancelAnimationFrame(this.requestId);
577
- this.requestId = null;
578
- }
579
-
580
- if (!noInterpolate && this.useRequestAnimationFrame) {
581
- this.requestId = requestAnimationFrame(() => {
582
- this.renderTrajectoriesInternal(viewState, noInterpolate);
583
- });
584
- } else if (!noInterpolate && this.useDebounce) {
585
- this.debounceRenderTrajectories(viewState, noInterpolate);
586
- } else if (!noInterpolate && this.useThrottle) {
587
- this.throttleRenderTrajectories(viewState, noInterpolate);
588
- } else {
589
- this.renderTrajectoriesInternal(viewState, noInterpolate);
590
- }
591
- }
592
-
593
- /**
594
- * Get vehicle.
595
- * @param {function} filterFc A function use to filter results.
596
- * @return {Array<Object>} Array of vehicle.
597
- */
598
- getVehicle(filterFc) {
599
- return Object.values(this.trajectories).filter(filterFc);
600
- }
601
-
602
- /**
603
- * Returns an array of vehicles located at the given coordinates and resolution.
604
- *
605
- * @param {number[2]} coordinate A coordinate ([x,y]).
606
- * @param {number} [resolution=1] The resolution of the map.
607
- * @param {number} [nb=Infinity] The max number of vehicles to return.
608
- * @return {Array<ol/Feature~Feature>} Array of vehicle.
609
- */
610
- getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {
611
- const ext = buffer(
612
- [...coordinate, ...coordinate],
613
- this.hitTolerance * resolution,
614
- );
615
- const trajectories = Object.values(this.trajectories);
616
- const vehicles = [];
617
- for (let i = 0; i < trajectories.length; i += 1) {
618
- if (
619
- trajectories[i].properties.coordinate &&
620
- containsCoordinate(ext, trajectories[i].properties.coordinate)
621
- ) {
622
- vehicles.push(trajectories[i]);
623
- }
624
- if (vehicles.length === nb) {
625
- break;
626
- }
627
- }
628
-
629
- return vehicles;
630
- }
631
-
632
- /**
633
- * Request feature information for a given coordinate.
634
- *
635
- * @param {ol/coordinate~Coordinate} coordinate Coordinate.
636
- * @param {Object} options Options See child classes to see which options are supported.
637
- * @param {number} [options.resolution=1] The resolution of the map.
638
- * @param {number} [options.nb=Infinity] The max number of vehicles to return.
639
- * @return {Promise<FeatureInfo>} Promise with features, layer and coordinate.
640
- */
641
- getFeatureInfoAtCoordinate(coordinate, options = {}) {
642
- const { resolution, nb } = options;
643
-
644
- const vehicles = this.getVehiclesAtCoordinate(coordinate, resolution, nb);
645
-
646
- return Promise.resolve({
647
- layer: this,
648
- features: vehicles.map((vehicle) => this.format.readFeature(vehicle)),
649
- coordinate,
650
- });
651
- }
652
-
653
- /**
654
- * On zoomend we adjust the time interval of the update of vehicles positions.
655
- *
656
- * @param evt Event that triggered the function.
657
- * @private
658
- */
659
- // eslint-disable-next-line no-unused-vars
660
- onZoomEnd(evt) {
661
- this.startUpdateTime();
662
- }
663
-
664
- /**
665
- * Define beahvior when a vehicle is clicked
666
- * To be defined in child classes.
667
- *
668
- * @private
669
- * @override
670
- */
671
- onFeatureClick() {}
672
-
673
- /**
674
- * Define behavior when a vehicle is hovered
675
- * To be defined in child classes.
676
- *
677
- * @private
678
- * @override
679
- */
680
- onFeatureHover() {}
681
-
682
- /**
683
- * Get the duration before the next update depending on zoom level.
684
- *
685
- * @private
686
- * @param {number} zoom
687
- */
688
- getRefreshTimeInMs(zoom) {
689
- const roundedZoom = Math.round(zoom);
690
- const timeStep = timeSteps[roundedZoom] || 25;
691
- const nextTick = Math.max(25, timeStep / this.speed);
692
- const nextThrottleTick = Math.min(nextTick, 500);
693
- // TODO: see if this should go elsewhere.
694
- if (this.useThrottle) {
695
- this.throttleRenderTrajectories = throttle(
696
- this.renderTrajectoriesInternal,
697
- nextThrottleTick,
698
- { leading: true, trailing: true },
699
- );
700
- } else if (this.useDebounce) {
701
- this.debounceRenderTrajectories = debounce(
702
- this.renderTrajectoriesInternal,
703
- nextThrottleTick,
704
- { leading: true, trailing: true, maxWait: 5000 },
705
- );
706
- }
707
- if (this.api?.buffer) {
708
- const [, size] = this.api.buffer;
709
- this.api.buffer = [nextThrottleTick, size];
710
- }
711
- return nextTick;
712
- }
713
-
714
- /**
715
- * Update filter provided by properties or permalink.
716
- */
717
- updateFilters() {
718
- // Setting filters from the permalink if no values defined by the layer.
719
- const parameters = qs.parse(window.location.search.toLowerCase());
720
- const publishedName = this.publishedLineName || parameters[LINE_FILTER];
721
- const tripNumber = this.tripNumber || parameters[ROUTE_FILTER];
722
- const operator = this.operator || parameters[OPERATOR_FILTER];
723
- const { regexPublishedLineName } = this;
724
-
725
- // Only overrides filter function if one of this property exists.
726
- if (publishedName || tripNumber || operator || regexPublishedLineName) {
727
- // filter is the property in TrackerLayerMixin.
728
- this.filter = createFilters(
729
- publishedName,
730
- tripNumber,
731
- operator,
732
- regexPublishedLineName,
733
- );
734
- }
735
- }
736
-
737
- /**
738
- * @private
739
- */
740
- defaultStyle(trajectory, viewState) {
741
- return delayTrackerStyle(trajectory, viewState, this);
742
- }
743
- };
744
-
745
- export default TrackerLayerMixin;