mobility-toolbox-js 2.0.0-beta.1 → 2.0.0-beta.6

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 (303) hide show
  1. package/.babelrc +6 -0
  2. package/.esdoc.json +17 -0
  3. package/.eslintignore +1 -0
  4. package/.github/workflows/conventional-pr-title.yml +21 -0
  5. package/.github/workflows/cypress.yml +29 -0
  6. package/.github/workflows/nodejs.yml +28 -0
  7. package/.husky/commit-msg +4 -0
  8. package/.husky/post-checkout +4 -0
  9. package/.husky/post-merge +4 -0
  10. package/.husky/post-rebase +4 -0
  11. package/.husky/pre-commit +4 -0
  12. package/.neutrinorc.js +176 -0
  13. package/.nvmrc +1 -0
  14. package/CHANGELOG.md +10 -0
  15. package/LICENSE +21 -0
  16. package/Layer.js +2 -0
  17. package/Layer.js.map +7 -0
  18. package/README.md +7 -4
  19. package/__mocks__/mapbox-gl.js +81 -0
  20. package/__mocks__/maplibre-gl.js +81 -0
  21. package/commitlint.config.js +1 -0
  22. package/cypress/fixtures/example.json +5 -0
  23. package/cypress/integration/examples/api.spec.js +7 -0
  24. package/cypress/integration/examples/examples.spec.js +7 -0
  25. package/cypress/integration/examples/navigation.spec.js +29 -0
  26. package/cypress/plugins/index.js +21 -0
  27. package/cypress/support/commands.js +25 -0
  28. package/cypress/support/index.js +20 -0
  29. package/cypress.json +4 -0
  30. package/data/fetchRoute.json +292 -0
  31. package/data/fetchTrajectories.json +18 -0
  32. package/data/fetchTrajectoryById.json +3 -0
  33. package/data/fetchTrajectoryStations.json +18 -0
  34. package/data/stopsSearch.json +15 -0
  35. package/documentation.yml +4 -0
  36. package/esdoc/README.md +27 -0
  37. package/esdoc/plugins/MyPlugin.js +69 -0
  38. package/esdoc/plugins/dynamic-property-plugin/Plugin.js +50 -0
  39. package/esdoc/plugins/externals-plugin/Plugin.js +45 -0
  40. package/esdoc/plugins/externals-plugin/externals.js +96 -0
  41. package/global-setup.js +3 -0
  42. package/{ol/README.md → index.html} +0 -0
  43. package/indexweb.html +49 -0
  44. package/jest.config.js +5 -0
  45. package/package.json +34 -13
  46. package/pull_request_template.md +17 -0
  47. package/renovate.json +4 -0
  48. package/scripts/read-pkg-json.js +22 -0
  49. package/{api → src/api}/index.js +0 -1
  50. package/{api → src/api}/routing/RoutingAPI.js +0 -0
  51. package/{api → src/api}/routing/RoutingAPI.test.js +0 -0
  52. package/{api → src/api}/stops/StopsAPI.js +0 -0
  53. package/{api → src/api}/stops/StopsAPI.test.js +0 -0
  54. package/{api → src/api}/tralis/TralisAPI.js +1 -1
  55. package/{api → src/api}/tralis/TralisAPI.test.js +0 -0
  56. package/{api → src/api}/tralis/TralisAPIUtils.js +0 -0
  57. package/{api → src/api}/tralis/WebSocketConnector.js +0 -0
  58. package/{api → src/api}/tralis/WebSocketConnector.test.js +0 -0
  59. package/{api → src/api}/tralis/typedefs.js +0 -0
  60. package/src/assets/Lato-Black.ttf +0 -0
  61. package/src/assets/Lato-BlackItalic.ttf +0 -0
  62. package/src/assets/Lato-Bold.ttf +0 -0
  63. package/src/assets/Lato-BoldItalic.ttf +0 -0
  64. package/src/assets/Lato-Italic.ttf +0 -0
  65. package/src/assets/Lato-Light.ttf +0 -0
  66. package/src/assets/Lato-LightItalic.ttf +0 -0
  67. package/src/assets/Lato-Regular.ttf +0 -0
  68. package/src/assets/Lato-Thin.ttf +0 -0
  69. package/src/assets/Lato-ThinItalic.ttf +0 -0
  70. package/src/assets/OFL.txt +93 -0
  71. package/{common → src/common}/Tracker.js +0 -0
  72. package/{common → src/common}/api/api.js +0 -0
  73. package/{common → src/common}/api/api.test.js +0 -0
  74. package/{common → src/common}/controls/Control.js +4 -1
  75. package/{common → src/common}/controls/Control.test.js +0 -0
  76. package/{common → src/common}/layers/Layer.js +18 -49
  77. package/{common → src/common}/layers/Layer.test.js +2 -106
  78. package/{common → src/common}/mixins/CopyrightMixin.js +0 -0
  79. package/{common → src/common}/mixins/SearchMixin.js +1 -1
  80. package/{common/mixins/TrackerLayerMixin.js → src/common/mixins/TralisLayerMixin.js} +380 -195
  81. package/src/common/styles/index.js +4 -0
  82. package/{common/utils/delayTrackerStyle.js → src/common/styles/trackerDefaultStyle.js} +8 -8
  83. package/src/common/styles/trackerDelayStyle.js +17 -0
  84. package/src/common/styles/trackerSimpleStyle.js +22 -0
  85. package/{common → src/common}/trackerConfig.js +0 -0
  86. package/{common → src/common}/trackerConfig.test.js +0 -13
  87. package/{common → src/common}/typedefs.js +0 -0
  88. package/{common → src/common}/utils/createTrackerFilters.js +0 -0
  89. package/{common → src/common}/utils/createTrackerFilters.test.js +0 -0
  90. package/{common → src/common}/utils/getMapboxMapCopyrights.js +1 -0
  91. package/{common → src/common}/utils/getMapboxMapCopyrights.test.js +0 -0
  92. package/{common → src/common}/utils/getMapboxStyleUrl.js +0 -0
  93. package/{common → src/common}/utils/getVehiclePosition.js +0 -0
  94. package/{common → src/common}/utils/index.js +2 -3
  95. package/{common → src/common}/utils/removeDuplicate.js +0 -0
  96. package/{common → src/common}/utils/removeDuplicate.test.js +0 -0
  97. package/src/common/utils/sortByDelay.js +23 -0
  98. package/{common → src/common}/utils/timeUtils.js +0 -0
  99. package/{common → src/common}/utils/timeUtils.test.js +0 -0
  100. package/src/doc/App.js +116 -0
  101. package/src/doc/App.scss +51 -0
  102. package/src/doc/_redirects +2 -0
  103. package/src/doc/components/CodeSandboxButton.js +103 -0
  104. package/src/doc/components/Documentation.js +40 -0
  105. package/src/doc/components/Esdoc/Anchor.js +57 -0
  106. package/src/doc/components/Esdoc/ClassDoc.js +272 -0
  107. package/src/doc/components/Esdoc/DeprecatedHTML.js +16 -0
  108. package/src/doc/components/Esdoc/DetailDocs.js +281 -0
  109. package/src/doc/components/Esdoc/DetailHTML.js +33 -0
  110. package/src/doc/components/Esdoc/DirectSubclassHTML.js +30 -0
  111. package/src/doc/components/Esdoc/DocBuilderUtils.js +694 -0
  112. package/src/doc/components/Esdoc/DocLinkHTML.js +62 -0
  113. package/src/doc/components/Esdoc/DocsLinkHTML.js +38 -0
  114. package/src/doc/components/Esdoc/Esdoc.js +63 -0
  115. package/src/doc/components/Esdoc/EsdocContent.js +51 -0
  116. package/src/doc/components/Esdoc/EsdocNavigation.js +13 -0
  117. package/src/doc/components/Esdoc/EsdocSearch.js +81 -0
  118. package/src/doc/components/Esdoc/ExperimentalHTML.js +17 -0
  119. package/src/doc/components/Esdoc/ExtendsChainHTML.js +32 -0
  120. package/src/doc/components/Esdoc/FileDocLinkHTML.js +60 -0
  121. package/src/doc/components/Esdoc/IdentifiersDoc.js +113 -0
  122. package/src/doc/components/Esdoc/IndirectSubclassHTML.js +30 -0
  123. package/src/doc/components/Esdoc/InheritedSummaryDoc.js +70 -0
  124. package/src/doc/components/Esdoc/InheritedSummaryHTML.js +38 -0
  125. package/src/doc/components/Esdoc/MixinClassesHTML.js +29 -0
  126. package/src/doc/components/Esdoc/NavDoc.js +112 -0
  127. package/src/doc/components/Esdoc/OverrideMethod.js +44 -0
  128. package/src/doc/components/Esdoc/OverrideMethodDescription.js +35 -0
  129. package/src/doc/components/Esdoc/Properties.js +89 -0
  130. package/src/doc/components/Esdoc/README.md +45 -0
  131. package/src/doc/components/Esdoc/SignatureHTML.js +123 -0
  132. package/src/doc/components/Esdoc/SingleDoc.js +31 -0
  133. package/src/doc/components/Esdoc/SummaryDoc.js +160 -0
  134. package/src/doc/components/Esdoc/SummaryHTML.js +96 -0
  135. package/src/doc/components/Esdoc/TypeDocLinkHTML.js +249 -0
  136. package/src/doc/components/Esdoc/css/identifiers.css +38 -0
  137. package/src/doc/components/Esdoc/css/search.css +76 -0
  138. package/src/doc/components/Esdoc/css/style.css +603 -0
  139. package/src/doc/components/Esdoc/index.js +7 -0
  140. package/src/doc/components/Example.js +153 -0
  141. package/src/doc/components/Examples.js +183 -0
  142. package/src/doc/components/Home.js +106 -0
  143. package/src/doc/components/TrackerExample.js +38 -0
  144. package/src/doc/components/esm.min.js +2 -0
  145. package/src/doc/components/examples/assets/tralis-live-map/index.js +11 -0
  146. package/src/doc/components/examples/assets/tralis-live-map/s1kreis.svg +105 -0
  147. package/src/doc/components/examples/assets/tralis-live-map/s20kreis.svg +101 -0
  148. package/src/doc/components/examples/assets/tralis-live-map/s2kreis.svg +95 -0
  149. package/src/doc/components/examples/assets/tralis-live-map/s3kreis.svg +95 -0
  150. package/src/doc/components/examples/assets/tralis-live-map/s4kreis.svg +95 -0
  151. package/src/doc/components/examples/assets/tralis-live-map/s6kreis.svg +95 -0
  152. package/src/doc/components/examples/assets/tralis-live-map/s7kreis.svg +95 -0
  153. package/src/doc/components/examples/assets/tralis-live-map/s8kreis.svg +93 -0
  154. package/src/doc/components/examples/assets/tralis-live-map/unknown.svg +107 -0
  155. package/src/doc/components/examples/mb-copyright.html +26 -0
  156. package/src/doc/components/examples/mb-copyright.js +37 -0
  157. package/src/doc/components/examples/mb-tracker.html +1 -0
  158. package/src/doc/components/examples/mb-tracker.js +39 -0
  159. package/src/doc/components/examples/mb-tracker.md +1 -0
  160. package/src/doc/components/examples/mb-tralis.html +1 -0
  161. package/src/doc/components/examples/mb-tralis.js +34 -0
  162. package/src/doc/components/examples/ol-copyright.html +26 -0
  163. package/src/doc/components/examples/ol-copyright.js +43 -0
  164. package/src/doc/components/examples/ol-mapbox-layer.html +1 -0
  165. package/src/doc/components/examples/ol-mapbox-layer.js +28 -0
  166. package/src/doc/components/examples/ol-mapbox-layer.md +0 -0
  167. package/src/doc/components/examples/ol-mapbox-style-layer.html +12 -0
  168. package/src/doc/components/examples/ol-mapbox-style-layer.js +44 -0
  169. package/src/doc/components/examples/ol-query.html +32 -0
  170. package/src/doc/components/examples/ol-query.js +83 -0
  171. package/src/doc/components/examples/ol-routing.html +26 -0
  172. package/src/doc/components/examples/ol-routing.js +59 -0
  173. package/src/doc/components/examples/ol-routing.md +1 -0
  174. package/src/doc/components/examples/ol-stop-finder.html +15 -0
  175. package/src/doc/components/examples/ol-stop-finder.js +31 -0
  176. package/src/doc/components/examples/ol-stop-finder.md +1 -0
  177. package/src/doc/components/examples/ol-tracker.html +1 -0
  178. package/src/doc/components/examples/ol-tracker.js +44 -0
  179. package/src/doc/components/examples/ol-tracker.md +1 -0
  180. package/src/doc/components/examples/ol-tralis.html +5 -0
  181. package/src/doc/components/examples/ol-tralis.js +57 -0
  182. package/src/doc/components/examples/tralis-live-map.html +1 -0
  183. package/src/doc/components/examples/tralis-live-map.js +51 -0
  184. package/src/doc/components/examples/tralis-live-map.md +3 -0
  185. package/src/doc/examples/assets/tralis-live-map/index.js +11 -0
  186. package/src/doc/examples/assets/tralis-live-map/s1kreis.svg +105 -0
  187. package/src/doc/examples/assets/tralis-live-map/s20kreis.svg +101 -0
  188. package/src/doc/examples/assets/tralis-live-map/s2kreis.svg +95 -0
  189. package/src/doc/examples/assets/tralis-live-map/s3kreis.svg +95 -0
  190. package/src/doc/examples/assets/tralis-live-map/s4kreis.svg +95 -0
  191. package/src/doc/examples/assets/tralis-live-map/s6kreis.svg +95 -0
  192. package/src/doc/examples/assets/tralis-live-map/s7kreis.svg +95 -0
  193. package/src/doc/examples/assets/tralis-live-map/s8kreis.svg +93 -0
  194. package/src/doc/examples/assets/tralis-live-map/unknown.svg +107 -0
  195. package/src/doc/examples/mb-copyright.html +26 -0
  196. package/src/doc/examples/mb-copyright.js +37 -0
  197. package/src/doc/examples/mb-tracker.html +1 -0
  198. package/src/doc/examples/mb-tracker.js +39 -0
  199. package/src/doc/examples/mb-tracker.md +1 -0
  200. package/src/doc/examples/mb-tralis.html +1 -0
  201. package/src/doc/examples/mb-tralis.js +34 -0
  202. package/src/doc/examples/ol-copyright.html +26 -0
  203. package/src/doc/examples/ol-copyright.js +43 -0
  204. package/src/doc/examples/ol-mapbox-layer.html +1 -0
  205. package/src/doc/examples/ol-mapbox-layer.js +28 -0
  206. package/src/doc/examples/ol-mapbox-layer.md +0 -0
  207. package/src/doc/examples/ol-mapbox-style-layer.html +12 -0
  208. package/src/doc/examples/ol-mapbox-style-layer.js +44 -0
  209. package/src/doc/examples/ol-query.html +32 -0
  210. package/src/doc/examples/ol-query.js +83 -0
  211. package/src/doc/examples/ol-routing.html +26 -0
  212. package/src/doc/examples/ol-routing.js +59 -0
  213. package/src/doc/examples/ol-routing.md +1 -0
  214. package/src/doc/examples/ol-stop-finder.html +15 -0
  215. package/src/doc/examples/ol-stop-finder.js +31 -0
  216. package/src/doc/examples/ol-stop-finder.md +1 -0
  217. package/src/doc/examples/ol-tracker.html +1 -0
  218. package/src/doc/examples/ol-tracker.js +44 -0
  219. package/src/doc/examples/ol-tracker.md +1 -0
  220. package/src/doc/examples/ol-tralis.html +5 -0
  221. package/src/doc/examples/ol-tralis.js +57 -0
  222. package/src/doc/examples/tralis-live-map.html +1 -0
  223. package/src/doc/examples/tralis-live-map.js +51 -0
  224. package/src/doc/examples/tralis-live-map.md +3 -0
  225. package/src/doc/examples.js +107 -0
  226. package/src/doc/img/examples/live_tracker_mb.jpg +0 -0
  227. package/src/doc/img/examples/live_tracker_munich.jpg +0 -0
  228. package/src/doc/img/examples/live_tracker_ol.jpg +0 -0
  229. package/src/doc/img/examples/mapbox.jpg +0 -0
  230. package/src/doc/img/examples/mapbox_style.jpg +0 -0
  231. package/src/doc/img/examples/ol-copyright.png +0 -0
  232. package/src/doc/img/examples/query_objects.jpg +0 -0
  233. package/src/doc/img/examples/routing.jpg +0 -0
  234. package/src/doc/img/examples/simple_map.jpg +0 -0
  235. package/src/doc/img/examples/stops.jpg +0 -0
  236. package/src/doc/img/favico.ico +0 -0
  237. package/src/doc/index.js +21 -0
  238. package/src/iife.js +7 -0
  239. package/{module.js → src/index.js} +3 -9
  240. package/{mapbox → src/mapbox}/controls/CopyrightControl.js +5 -1
  241. package/{mapbox → src/mapbox}/index.js +0 -2
  242. package/{mapbox → src/mapbox}/layers/Layer.js +0 -0
  243. package/{mapbox → src/mapbox}/layers/Layer.test.js +2 -2
  244. package/{mapbox/layers/TrackerLayer.js → src/mapbox/layers/TralisLayer.js} +71 -24
  245. package/src/mapbox/layers/TralisLayer.test.js +40 -0
  246. package/{mapbox → src/mapbox}/utils.js +0 -0
  247. package/src/ol/README.md +0 -0
  248. package/{ol → src/ol}/controls/CopyrightControl.js +4 -4
  249. package/{ol → src/ol}/controls/CopyrightControl.test.js +16 -16
  250. package/{ol → src/ol}/controls/RoutingControl.js +9 -7
  251. package/{ol → src/ol}/controls/RoutingControl.test.js +1 -1
  252. package/{ol → src/ol}/controls/StopFinderControl.js +8 -6
  253. package/{ol → src/ol}/controls/StopFinderControl.test.js +1 -1
  254. package/{ol → src/ol}/controls/snapshots/RoutingControlRouteGen10.json +0 -0
  255. package/{ol → src/ol}/controls/snapshots/RoutingControlRouteGen100.json +0 -0
  256. package/{ol → src/ol}/controls/snapshots/RoutingControlRouteGen30.json +0 -0
  257. package/{ol → src/ol}/controls/snapshots/RoutingControlRouteGen5.json +0 -0
  258. package/{ol → src/ol}/controls/snapshots/RoutingControlRouteOSM.json +0 -0
  259. package/{ol → src/ol}/controls/snapshots/RoutingControlStation1.json +0 -0
  260. package/{ol → src/ol}/controls/snapshots/RoutingControlStation2.json +0 -0
  261. package/{ol → src/ol}/index.js +3 -3
  262. package/{ol → src/ol}/layers/Layer.js +9 -0
  263. package/{ol → src/ol}/layers/Layer.test.js +22 -7
  264. package/{ol → src/ol}/layers/MapboxLayer.js +39 -44
  265. package/{ol → src/ol}/layers/MapboxLayer.test.js +5 -5
  266. package/{ol → src/ol}/layers/MapboxStyleLayer.js +0 -6
  267. package/{ol → src/ol}/layers/MapboxStyleLayer.test.js +22 -6
  268. package/src/ol/layers/MaplibreLayer.js +280 -0
  269. package/{ol → src/ol}/layers/RoutingLayer.js +0 -0
  270. package/{ol → src/ol}/layers/RoutingLayer.test.js +1 -1
  271. package/{ol/layers/TrackerLayer.js → src/ol/layers/TralisLayer.js} +96 -33
  272. package/{ol → src/ol}/layers/TralisLayer.test.js +1 -49
  273. package/{ol → src/ol}/layers/VectorLayer.js +0 -0
  274. package/{ol → src/ol}/layers/VectorLayer.test.js +1 -1
  275. package/{ol → src/ol}/layers/WMSLayer.js +0 -0
  276. package/{ol → src/ol}/layers/WMSLayer.test.js +6 -2
  277. package/src/ol/styles/fullTrajectoryDelayStyle.js +35 -0
  278. package/src/ol/styles/fullTrajectoryStyle.js +51 -0
  279. package/src/ol/styles/index.js +2 -0
  280. package/src/setupTests.js +15 -0
  281. package/webpack.config.js +6 -0
  282. package/api/trajserv/TrajservAPI.js +0 -71
  283. package/api/trajserv/TrajservAPI.test.js +0 -171
  284. package/api/trajserv/TrajservAPIUtils.js +0 -191
  285. package/api/trajserv/TrajservAPIUtils.test.js +0 -40
  286. package/api/trajserv/typedefs.js +0 -44
  287. package/common/mixins/MapMixin.js +0 -103
  288. package/common/mixins/TrajservLayerMixin.js +0 -544
  289. package/common/mixins/TralisLayerMixin.js +0 -402
  290. package/common/utils/simpleTrackerStyle.js +0 -18
  291. package/index.js +0 -2
  292. package/index.js.map +0 -1
  293. package/mapbox/Map.js +0 -87
  294. package/mapbox/layers/TrackerLayer.test.js +0 -68
  295. package/mapbox/layers/TrajservLayer.js +0 -114
  296. package/mapbox/layers/TrajservLayer.test.js +0 -90
  297. package/mapbox/layers/TralisLayer.js +0 -64
  298. package/ol/Map.js +0 -109
  299. package/ol/Map.test.js +0 -34
  300. package/ol/layers/TrackerLayer.test.js +0 -70
  301. package/ol/layers/TrajservLayer.js +0 -190
  302. package/ol/layers/TrajservLayer.test.js +0 -113
  303. package/ol/layers/TralisLayer.js +0 -177
@@ -1,14 +1,21 @@
1
+ /* eslint-disable no-empty-function */
2
+ /* eslint-disable no-useless-constructor */
3
+ /* eslint-disable no-unused-vars */
1
4
  /* eslint-disable class-methods-use-this */
2
5
  /* eslint-disable max-classes-per-file */
3
- import { buffer, containsCoordinate } from 'ol/extent';
4
- import { unByKey } from 'ol/Observable';
5
6
  import qs from 'query-string';
7
+ import { buffer, containsCoordinate, intersects } from 'ol/extent';
8
+ import { unByKey } from 'ol/Observable';
9
+ import GeoJSON from 'ol/format/GeoJSON';
10
+ import Point from 'ol/geom/Point';
6
11
  import debounce from 'lodash.debounce';
7
12
  import throttle from 'lodash.throttle';
13
+ import { fromLonLat } from 'ol/proj';
8
14
  import Tracker from '../Tracker';
9
15
  import { timeSteps } from '../trackerConfig';
10
16
  import createFilters from '../utils/createTrackerFilters';
11
- import { delayTrackerStyle } from '../utils';
17
+ import trackerDefaultStyle from '../styles/trackerDefaultStyle';
18
+ import { TralisAPI, TralisModes } from '../../api';
12
19
 
13
20
  /* Permalink parameter used to filters vehicles */
14
21
  const LINE_FILTER = 'publishedlinename';
@@ -16,34 +23,31 @@ const ROUTE_FILTER = 'tripnumber';
16
23
  const OPERATOR_FILTER = 'operator';
17
24
 
18
25
  /**
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.
26
+ * TralisLayerInterface.
33
27
  */
34
- export class TrackerLayerInterface {
28
+ export class TralisLayerInterface {
29
+ /*
30
+ * Constructor
31
+
32
+ * @param {Object} options Layer options.
33
+ * @param {string} options.url Tralis service url.
34
+ * @param {string} options.apiKey Access key for [geOps services](https://developer.geops.io/).
35
+ * @param {boolean} [options.debug=false] Display additional debug informations.
36
+ * @param {TralisMode} [options.mode=TralisMode.TOPOGRAPHIC] Tralis's Mode.
37
+ * @param {number} [options.minZoomInterpolation=8] Minimal zoom when trains positions start to be interpolated.
38
+ * @param {number} [options.minZoomNonTrain=9] Minimal zoom when non trains vehicles are allowed to be displayed.
39
+ */
40
+ constructor(options = {}) {}
41
+
35
42
  /**
36
- * Initalize the Tracker.
43
+ * Initialize the layer subscribing to the Tralis api.
44
+ *
37
45
  * @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
46
  */
42
- // eslint-disable-next-line no-unused-vars
43
- init(map, options) {}
47
+ init(map) {}
44
48
 
45
49
  /**
46
- * Destroy the Tracker.
50
+ * Terminate the layer unsubscribing to the Tralis api.
47
51
  */
48
52
  terminate() {}
49
53
 
@@ -52,73 +56,76 @@ export class TrackerLayerInterface {
52
56
  */
53
57
  start() {}
54
58
 
55
- /**
56
- * Start the timeout for the next update.
57
- * @private
58
- */
59
- startUpdateTime() {}
60
-
61
59
  /**
62
60
  * Stop the clock.
63
61
  */
64
62
  stop() {}
65
63
 
66
64
  /**
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.
65
+ * Set the Tralis api's bbox.
77
66
  *
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.
67
+ * @param {Array<number>} extent Extent to request, [minX, minY, maxX, maxY, zoom].
68
+ * @param {number} zoom Zoom level to request. Must be an integer.
82
69
  */
83
- // eslint-disable-next-line no-unused-vars
84
- getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {}
70
+ setBbox(extent, zoom) {}
85
71
 
86
72
  /**
87
- * Get the duration before the next update depending on zoom level.
88
- * @private
89
- * @param {number} zoom
73
+ * Set the Tralis api's mode.
74
+ *
75
+ * @param {TralisMode} mode Tralis mode
90
76
  */
91
- // eslint-disable-next-line no-unused-vars
92
- getRefreshTimeInMs(zoom) {}
77
+ setMode(mode) {}
93
78
 
94
79
  /**
95
- * Define a default style of vehicles.
96
- * Draw a blue circle with the id of the props parameter.
80
+ * Request the stopSequence and the fullTrajectory informations for a vehicle.
97
81
  *
98
- * @param {Object} trajectory A trajectory
99
- * @param {ViewState} viewState Map's view state (zoom, resolution, center, ...)
100
- * @private
82
+ * @param {string} id The vehicle identifier (the train_id property).
83
+ * @param {TralisMode} mode The mode to request. If not defined, the layer´s mode propetrty will be used.
84
+ * @return {Promise<{stopSequence: StopSequence, fullTrajectory: FullTrajectory>} A promise that will be resolved with the trajectory informations.
101
85
  */
102
- // eslint-disable-next-line no-unused-vars
103
- defaultStyle(trajectory, viewState) {}
86
+ getTrajectoryInfos(id, mode) {}
104
87
  }
105
88
 
106
89
  /**
107
- * Mixin for TrackeLayerInterface.
90
+ * Mixin for TralisLayerInterface.
108
91
  *
109
- * @param {Class} Base A class to extend with {TrackerLayerInterface} functionnalities.
110
- * @return {Class} A class that implements <TrackerLayerInterface> class and extends Base;
92
+ * @param {Class} Base A class to extend with {TralisLayerInterface} functionnalities.
93
+ * @return {Class} A class that implements {TralisLayerInterface} class and extends Base;
111
94
  * @private
112
95
  */
113
- const TrackerLayerMixin = (Base) =>
96
+ const TralisLayerMixin = (Base) =>
114
97
  class extends Base {
115
- constructor(options) {
98
+ constructor(options = {}) {
116
99
  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
100
 
101
+ this.debug = options.debug;
102
+ this.mode = options.mode || TralisModes.TOPOGRAPHIC;
103
+ this.api = options.api || new TralisAPI(options);
104
+ this.tenant = options.tenant || ''; // sbb,sbh or sbm
105
+ this.minZoomNonTrain = options.minZoomNonTrain || 9; // Min zoom level from which non trains are allowed to be displayed. Min value is 9 (as configured by the server
106
+ this.minZoomInterpolation = options.minZoomInterpolation || 8; // Min zoom level from which trains positions are not interpolated.
107
+ this.format = new GeoJSON();
108
+ this.generalizationLevelByZoom = options.generalizationLevelByZoom || {
109
+ 0: 5,
110
+ 1: 5,
111
+ 2: 5,
112
+ 3: 5,
113
+ 4: 5,
114
+ 5: 5,
115
+ 6: 5,
116
+ 7: 5,
117
+ 8: 10,
118
+ 9: 30,
119
+ 10: 30,
120
+ 11: 100,
121
+ 12: 100,
122
+ 13: 100,
123
+ };
124
+
125
+ // This property will call api.setBbox on each movend event
126
+ this.isUpdateBboxOnMoveEnd = options.isUpdateBboxOnMoveEnd !== false;
127
+
128
+ // Define throttling nad debounce render function
122
129
  this.throttleRenderTrajectories = throttle(
123
130
  this.renderTrajectoriesInternal,
124
131
  50,
@@ -130,6 +137,17 @@ const TrackerLayerMixin = (Base) =>
130
137
  50,
131
138
  { leading: true, trailing: true, maxWait: 5000 },
132
139
  );
140
+
141
+ // Bind callbacks
142
+ this.onFeatureHover = this.onFeatureHover.bind(this);
143
+ this.onFeatureClick = this.onFeatureClick.bind(this);
144
+ this.renderTrajectoriesInternal =
145
+ this.renderTrajectoriesInternal.bind(this);
146
+ this.onTrajectoryMessage = this.onTrajectoryMessage.bind(this);
147
+ this.onDeleteTrajectoryMessage =
148
+ this.onDeleteTrajectoryMessage.bind(this);
149
+ this.onDocumentVisibilityChange =
150
+ this.onDocumentVisibilityChange.bind(this);
133
151
  }
134
152
 
135
153
  /**
@@ -175,7 +193,8 @@ const TrackerLayerMixin = (Base) =>
175
193
  * Style function used to render a vehicle.
176
194
  */
177
195
  style: {
178
- value: style || this.defaultStyle,
196
+ value: (trajectory, viewState) =>
197
+ (style || trackerDefaultStyle)(trajectory, viewState, this),
179
198
  },
180
199
 
181
200
  /**
@@ -272,7 +291,9 @@ const TrackerLayerMixin = (Base) =>
272
291
  * Id of the selected vehicle.
273
292
  */
274
293
  pixelRatio: {
275
- value: pixelRatio || window.devicePixelRatio || 1,
294
+ value:
295
+ pixelRatio ||
296
+ (typeof window !== 'undefined' ? window.devicePixelRatio : 1),
276
297
  writable: true,
277
298
  },
278
299
 
@@ -351,10 +372,6 @@ const TrackerLayerMixin = (Base) =>
351
372
  value: options.delayOutlineColor || '#000000',
352
373
  writable: true,
353
374
  },
354
- useDelayStyle: {
355
- value: options.useDelayStyle || false,
356
- writable: true,
357
- },
358
375
 
359
376
  /**
360
377
  * Debug properties.
@@ -369,61 +386,24 @@ const TrackerLayerMixin = (Base) =>
369
386
  // },
370
387
  });
371
388
 
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
389
  // Update filter function based on convenient properties
398
390
  this.updateFilters();
399
391
  }
400
392
 
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 = {}) {
393
+ init(map) {
415
394
  super.init(map);
416
395
 
417
396
  this.tracker = new Tracker({
418
397
  style: (...args) => this.style(...args),
419
398
  ...this.initTrackerOptions,
420
- ...options,
421
399
  });
422
400
 
401
+ // If the layer is visible we start the rendering clock
423
402
  if (this.visible) {
424
403
  this.start();
425
404
  }
426
405
 
406
+ // On change of visibility we start/stop the rendering clock
427
407
  this.visibilityRef = this.on('change:visible', (evt) => {
428
408
  if (evt.target.visible) {
429
409
  this.start();
@@ -431,12 +411,21 @@ const TrackerLayerMixin = (Base) =>
431
411
  this.stop();
432
412
  }
433
413
  });
414
+
415
+ // To avoid browser hanging when the tab is not visible for a certain amount of time,
416
+ // We stop the rendering and the websocket when hide and start again when show.
417
+ document.addEventListener(
418
+ 'visibilitychange',
419
+ this.onDocumentVisibilityChange,
420
+ );
434
421
  }
435
422
 
436
- /**
437
- * Destroy the Tracker.
438
- */
439
423
  terminate() {
424
+ document.removeEventListener(
425
+ 'visibilitychange',
426
+ this.onDocumentVisibilityChange,
427
+ );
428
+
440
429
  this.stop();
441
430
  unByKey(this.visibilityRef);
442
431
  if (this.tracker) {
@@ -448,14 +437,6 @@ const TrackerLayerMixin = (Base) =>
448
437
  super.terminate();
449
438
  }
450
439
 
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
440
  start() {
460
441
  this.stop();
461
442
  this.renderTrajectories();
@@ -468,6 +449,23 @@ const TrackerLayerMixin = (Base) =>
468
449
  if (this.isHoverActive) {
469
450
  this.onHover(this.onFeatureHover);
470
451
  }
452
+
453
+ this.api.open();
454
+ this.api.subscribeTrajectory(
455
+ this.mode,
456
+ this.onTrajectoryMessage,
457
+ this.isUpdateBboxOnMoveEnd,
458
+ );
459
+ this.api.subscribeDeletedVehicles(
460
+ this.mode,
461
+ this.onDeleteTrajectoryMessage,
462
+ this.isUpdateBboxOnMoveEnd,
463
+ );
464
+
465
+ if (this.isUpdateBboxOnMoveEnd) {
466
+ // Update the bbox on each move end
467
+ this.setBbox();
468
+ }
471
469
  }
472
470
 
473
471
  /**
@@ -485,16 +483,10 @@ const TrackerLayerMixin = (Base) =>
485
483
  }, this.updateTimeDelay);
486
484
  }
487
485
 
488
- /**
489
- * Stop the trajectories rendering.
490
- */
491
486
  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
- }
487
+ this.api.unsubscribeTrajectory(this.onTrajectoryMessage);
488
+ this.api.unsubscribeDeletedVehicles(this.onDeleteTrajectoryMessage);
489
+ this.api.close();
498
490
  }
499
491
 
500
492
  /**
@@ -548,7 +540,6 @@ const TrackerLayerMixin = (Base) =>
548
540
  iconScale: this.iconScale,
549
541
  delayDisplay: this.delayDisplay,
550
542
  delayOutlineColor: this.delayOutlineColor,
551
- useDelayStyle: this.useDelayStyle,
552
543
  },
553
544
  );
554
545
 
@@ -590,6 +581,84 @@ const TrackerLayerMixin = (Base) =>
590
581
  }
591
582
  }
592
583
 
584
+ setBbox(extent, zoom) {
585
+ // Clean trajectories before sending the new bbox
586
+ // Purge trajectories:
587
+ // - which are outside the extent
588
+ // - when it's bus and zoom level is too low for them
589
+ const keys = Object.keys(this.trajectories);
590
+ for (let i = keys.length - 1; i >= 0; i -= 1) {
591
+ this.purgeTrajectory(this.trajectories[keys[i]], extent, zoom);
592
+ }
593
+
594
+ const bbox = [...extent];
595
+
596
+ if (this.isUpdateBboxOnMoveEnd) {
597
+ bbox.push(zoom);
598
+
599
+ if (this.tenant) {
600
+ bbox.push(`tenant=${this.tenant}`);
601
+ }
602
+
603
+ /* @ignore */
604
+ this.generalizationLevel = this.generalizationLevelByZoom[zoom];
605
+ if (this.generalizationLevel) {
606
+ bbox.push(`gen=${this.generalizationLevel}`);
607
+ }
608
+ }
609
+
610
+ this.api.bbox = bbox;
611
+ }
612
+
613
+ setMode(mode) {
614
+ if (this.mode === mode) {
615
+ return;
616
+ }
617
+ this.mode = mode;
618
+ this.api.subscribeTrajectory(
619
+ this.mode,
620
+ this.onTrajectoryMessage,
621
+ this.isUpdateBboxOnMoveEnd,
622
+ );
623
+ this.api.subscribeDeletedVehicles(
624
+ this.mode,
625
+ this.onDeleteTrajectoryMessage,
626
+ this.isUpdateBboxOnMoveEnd,
627
+ );
628
+ }
629
+
630
+ /**
631
+ * Get the duration before the next update depending on zoom level.
632
+ *
633
+ * @private
634
+ * @param {number} zoom
635
+ */
636
+ getRefreshTimeInMs(zoom) {
637
+ const roundedZoom = Math.round(zoom);
638
+ const timeStep = timeSteps[roundedZoom] || 25;
639
+ const nextTick = Math.max(25, timeStep / this.speed);
640
+ const nextThrottleTick = Math.min(nextTick, 500);
641
+ // TODO: see if this should go elsewhere.
642
+ if (this.useThrottle) {
643
+ this.throttleRenderTrajectories = throttle(
644
+ this.renderTrajectoriesInternal,
645
+ nextThrottleTick,
646
+ { leading: true, trailing: true },
647
+ );
648
+ } else if (this.useDebounce) {
649
+ this.debounceRenderTrajectories = debounce(
650
+ this.renderTrajectoriesInternal,
651
+ nextThrottleTick,
652
+ { leading: true, trailing: true, maxWait: 5000 },
653
+ );
654
+ }
655
+ if (this.api?.buffer) {
656
+ const [, size] = this.api.buffer;
657
+ this.api.buffer = [nextThrottleTick, size];
658
+ }
659
+ return nextTick;
660
+ }
661
+
593
662
  /**
594
663
  * Get vehicle.
595
664
  * @param {function} filterFc A function use to filter results.
@@ -600,19 +669,26 @@ const TrackerLayerMixin = (Base) =>
600
669
  }
601
670
 
602
671
  /**
603
- * Returns an array of vehicles located at the given coordinates and resolution.
672
+ * Request feature information for a given coordinate.
604
673
  *
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.
674
+ * @param {ol/coordinate~Coordinate} coordinate Coordinate.
675
+ * @param {Object} options Options See child classes to see which options are supported.
676
+ * @param {number} [options.resolution=1] The resolution of the map.
677
+ * @param {number} [options.nb=Infinity] The max number of vehicles to return.
678
+ * @return {Promise<FeatureInfo>} Promise with features, layer and coordinate.
609
679
  */
610
- getVehiclesAtCoordinate(coordinate, resolution = 1, nb = Infinity) {
680
+ getFeatureInfoAtCoordinate(coordinate, options = {}) {
681
+ const { resolution, nb } = options;
611
682
  const ext = buffer(
612
683
  [...coordinate, ...coordinate],
613
684
  this.hitTolerance * resolution,
614
685
  );
615
- const trajectories = Object.values(this.trajectories);
686
+ let trajectories = Object.values(this.trajectories);
687
+
688
+ if (this.sort) {
689
+ trajectories = trajectories.sort(this.sort);
690
+ }
691
+
616
692
  const vehicles = [];
617
693
  for (let i = 0; i < trajectories.length; i += 1) {
618
694
  if (
@@ -626,28 +702,75 @@ const TrackerLayerMixin = (Base) =>
626
702
  }
627
703
  }
628
704
 
629
- return vehicles;
705
+ return Promise.resolve({
706
+ layer: this,
707
+ features: vehicles.map((vehicle) => this.format.readFeature(vehicle)),
708
+ coordinate,
709
+ });
630
710
  }
631
711
 
632
712
  /**
633
- * Request feature information for a given coordinate.
713
+ * Request the stopSequence and the fullTrajectory informations for a vehicle.
634
714
  *
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.
715
+ * @param {string} id The vehicle identifier (the train_id property).
716
+ * @return {Promise<{stopSequence: StopSequence, fullTrajectory: FullTrajectory>} A promise that will be resolved with the trajectory informations.
640
717
  */
641
- getFeatureInfoAtCoordinate(coordinate, options = {}) {
642
- const { resolution, nb } = options;
718
+ getTrajectoryInfos(id) {
719
+ // When a vehicle is selected, we request the complete stop sequence and the complete full trajectory.
720
+ // Then we combine them in one response and send them to inherited layers.
721
+ const promises = [
722
+ this.api.getStopSequence(id, this.mode),
723
+ this.api.getFullTrajectory(id, this.mode, this.generalizationLevel),
724
+ ];
725
+
726
+ return Promise.all(promises).then(([stopSequence, fullTrajectory]) => {
727
+ const response = {
728
+ stopSequence,
729
+ fullTrajectory,
730
+ };
731
+ return response;
732
+ });
733
+ }
643
734
 
644
- const vehicles = this.getVehiclesAtCoordinate(coordinate, resolution, nb);
735
+ /**
736
+ * Determine if the trajectory is useless and should be removed from the list or not.
737
+ * By default, this function exclude vehicles:
738
+ * - that have their trajectory outside the current extent and
739
+ * - that are not a train and zoom level is lower than layer's minZoomNonTrain property.
740
+ *
741
+ * @param {TralisTrajectory} trajectory
742
+ * @param {Array<number>} extent
743
+ * @param {number} zoom
744
+ * @return {boolean} if the trajectory must be displayed or not.
745
+ * @ignore
746
+ */
747
+ purgeTrajectory(trajectory, extent, zoom) {
748
+ const { type, bounds, train_id: id } = trajectory.properties;
749
+ if (
750
+ !intersects(extent, bounds) ||
751
+ (type !== 'rail' && zoom < (this.minZoomNonTrain || 9))
752
+ ) {
753
+ this.removeTrajectory(id);
754
+ return true;
755
+ }
756
+ return false;
757
+ }
645
758
 
646
- return Promise.resolve({
647
- layer: this,
648
- features: vehicles.map((vehicle) => this.format.readFeature(vehicle)),
649
- coordinate,
650
- });
759
+ /**
760
+ * Add a trajectory to the tracker.
761
+ * @param {TralisTrajectory} trajectory The trajectory to add.
762
+ * @private
763
+ */
764
+ addTrajectory(trajectory) {
765
+ if (this.filter && !this.filter(trajectory)) {
766
+ return;
767
+ }
768
+ this.trajectories[trajectory.properties.train_id] = trajectory;
769
+ this.renderTrajectories();
770
+ }
771
+
772
+ removeTrajectory(id) {
773
+ delete this.trajectories[id];
651
774
  }
652
775
 
653
776
  /**
@@ -661,54 +784,123 @@ const TrackerLayerMixin = (Base) =>
661
784
  this.startUpdateTime();
662
785
  }
663
786
 
787
+ onDocumentVisibilityChange() {
788
+ if (!this.visible) {
789
+ return;
790
+ }
791
+ if (document.hidden) {
792
+ this.stop();
793
+ } else {
794
+ this.start();
795
+ }
796
+ }
797
+
664
798
  /**
665
- * Define beahvior when a vehicle is clicked
666
- * To be defined in child classes.
799
+ * Callback on websocket's trajectory channel events.
800
+ * It adds a trajectory to the list.
801
+ *
802
+ * @private
803
+ */
804
+ onTrajectoryMessage(data) {
805
+ if (!data.content) {
806
+ return;
807
+ }
808
+ const trajectory = data.content;
809
+
810
+ const {
811
+ geometry,
812
+ properties: {
813
+ train_id: id,
814
+ time_since_update: timeSinceUpdate,
815
+ raw_coordinates: rawCoordinates,
816
+ },
817
+ } = trajectory;
818
+
819
+ // ignore old events [SBAHNM-97]
820
+ if (timeSinceUpdate < 0) {
821
+ return;
822
+ }
823
+
824
+ // console.time(`onTrajectoryMessage${data.content.properties.train_id}`);
825
+ if (this.purgeTrajectory(trajectory)) {
826
+ return;
827
+ }
828
+
829
+ if (
830
+ this.debug &&
831
+ this.mode === TralisModes.TOPOGRAPHIC &&
832
+ rawCoordinates
833
+ ) {
834
+ trajectory.properties.olGeometry = {
835
+ type: 'Point',
836
+ coordinates: fromLonLat(
837
+ rawCoordinates,
838
+ this.map.getView().getProjection(),
839
+ ),
840
+ };
841
+ } else {
842
+ trajectory.properties.olGeometry = this.format.readGeometry(geometry);
843
+ }
844
+
845
+ // TODO Make sure the timeOffset is useful. May be we can remove it.
846
+ trajectory.properties.timeOffset = Date.now() - data.timestamp;
847
+ this.addTrajectory(trajectory);
848
+ }
849
+
850
+ /**
851
+ * Callback on websocket's deleted_vehicles channel events.
852
+ * It removes the trajectory from the list.
667
853
  *
668
854
  * @private
669
855
  * @override
670
856
  */
671
- onFeatureClick() {}
857
+ onDeleteTrajectoryMessage(data) {
858
+ if (!data.content) {
859
+ return;
860
+ }
861
+
862
+ this.removeTrajectory(data.content);
863
+ }
672
864
 
673
865
  /**
674
- * Define behavior when a vehicle is hovered
675
- * To be defined in child classes.
866
+ * Callback when user moves the mouse/pointer over the map.
867
+ * It sets the layer's hoverVehicleId property with the current hovered vehicle's id.
676
868
  *
677
869
  * @private
678
870
  * @override
679
871
  */
680
- onFeatureHover() {}
872
+ onFeatureHover(features, layer, coordinate) {
873
+ const [feature] = features;
874
+ let id = null;
875
+ if (feature) {
876
+ id = feature.get('train_id');
877
+ }
878
+ if (this.hoverVehicleId !== id) {
879
+ /** @ignore */
880
+ this.hoverVehicleId = id;
881
+ this.renderTrajectories(true);
882
+ }
883
+ }
681
884
 
682
885
  /**
683
- * Get the duration before the next update depending on zoom level.
886
+ * Callback when user clicks on the map.
887
+ * It sets the layer's selectedVehicleId property with the current selected vehicle's id.
684
888
  *
685
889
  * @private
686
- * @param {number} zoom
890
+ * @override
687
891
  */
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
- );
892
+ onFeatureClick(features, layer, coordinate) {
893
+ const [feature] = features;
894
+ let id = null;
895
+ if (feature) {
896
+ id = feature.get('train_id');
706
897
  }
707
- if (this.api?.buffer) {
708
- const [, size] = this.api.buffer;
709
- this.api.buffer = [nextThrottleTick, size];
898
+ if (this.selectedVehicleId !== id) {
899
+ /** @ignore */
900
+ this.selectedVehicleId = id;
901
+ this.selectedVehicle = feature;
902
+ this.renderTrajectories(true);
710
903
  }
711
- return nextTick;
712
904
  }
713
905
 
714
906
  /**
@@ -733,13 +925,6 @@ const TrackerLayerMixin = (Base) =>
733
925
  );
734
926
  }
735
927
  }
736
-
737
- /**
738
- * @private
739
- */
740
- defaultStyle(trajectory, viewState) {
741
- return delayTrackerStyle(trajectory, viewState, this);
742
- }
743
928
  };
744
929
 
745
- export default TrackerLayerMixin;
930
+ export default TralisLayerMixin;