mobility-toolbox-js 2.3.9 → 2.3.10

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 (471) hide show
  1. package/.esdoc.js +18 -0
  2. package/.eslintignore +1 -0
  3. package/.eslintrc.js +25 -0
  4. package/.fixpackrc +20 -0
  5. package/.github/workflows/build.yml +16 -0
  6. package/.github/workflows/conventional-pr-title.yml +16 -0
  7. package/.github/workflows/cypress.yml +101 -0
  8. package/.github/workflows/test.yml +17 -0
  9. package/.husky/commit-msg +4 -0
  10. package/.husky/post-checkout +4 -0
  11. package/.husky/post-merge +4 -0
  12. package/.husky/post-rebase +4 -0
  13. package/.husky/pre-commit +4 -0
  14. package/.lintstagedrc.js +10 -0
  15. package/.nvmrc +1 -0
  16. package/.prettierrc.js +5 -0
  17. package/.stylelintrc.js +4 -0
  18. package/CHANGELOG.md +132 -0
  19. package/LICENSE +21 -0
  20. package/MIGRATION-V2.md +248 -0
  21. package/README.md +42 -0
  22. package/__mocks__/mapbox-gl.js +81 -0
  23. package/__mocks__/maplibre-gl.js +81 -0
  24. package/babel.config.js +9 -0
  25. package/commitlint.config.js +1 -0
  26. package/cypress/e2e/examples/api.cy.js +7 -0
  27. package/cypress/e2e/examples/examples.cy.js +7 -0
  28. package/cypress/e2e/examples/navigation.cy.js +29 -0
  29. package/cypress/fixtures/example.json +5 -0
  30. package/cypress/plugins/index.js +21 -0
  31. package/cypress/support/commands.js +25 -0
  32. package/cypress/support/e2e.js +20 -0
  33. package/cypress.config.ts +15 -0
  34. package/data/fetchRoute.json +292 -0
  35. package/data/fetchTrajectories.json +18 -0
  36. package/data/fetchTrajectoryById.json +3 -0
  37. package/data/fetchTrajectoryStations.json +18 -0
  38. package/data/stopsSearch.json +15 -0
  39. package/dependabot.yml +15 -0
  40. package/doc/.eslintrc.json +1 -0
  41. package/doc/README.md +34 -0
  42. package/doc/next.config.js +16 -0
  43. package/doc/package.json +41 -0
  44. package/doc/pages/404.js +5 -0
  45. package/doc/pages/_app.js +61 -0
  46. package/doc/pages/_document.js +64 -0
  47. package/doc/pages/doc/[...slug].js +23 -0
  48. package/doc/pages/doc.js +23 -0
  49. package/doc/pages/example/[example].js +52 -0
  50. package/doc/pages/examples.js +34 -0
  51. package/doc/pages/index.js +25 -0
  52. package/doc/public/README.md +15 -0
  53. package/doc/public/favicon.ico +0 -0
  54. package/doc/public/static/assets/Lato-Black.ttf +0 -0
  55. package/doc/public/static/assets/Lato-BlackItalic.ttf +0 -0
  56. package/doc/public/static/assets/Lato-Bold.ttf +0 -0
  57. package/doc/public/static/assets/Lato-BoldItalic.ttf +0 -0
  58. package/doc/public/static/assets/Lato-Italic.ttf +0 -0
  59. package/doc/public/static/assets/Lato-Light.ttf +0 -0
  60. package/doc/public/static/assets/Lato-LightItalic.ttf +0 -0
  61. package/doc/public/static/assets/Lato-Regular.ttf +0 -0
  62. package/doc/public/static/assets/Lato-Thin.ttf +0 -0
  63. package/doc/public/static/assets/Lato-ThinItalic.ttf +0 -0
  64. package/doc/public/static/assets/OFL.txt +93 -0
  65. package/doc/public/static/examples/assets/tralis-live-map/index.js +11 -0
  66. package/doc/public/static/examples/assets/tralis-live-map/s1kreis.svg +105 -0
  67. package/doc/public/static/examples/assets/tralis-live-map/s20kreis.svg +101 -0
  68. package/doc/public/static/examples/assets/tralis-live-map/s2kreis.svg +95 -0
  69. package/doc/public/static/examples/assets/tralis-live-map/s3kreis.svg +95 -0
  70. package/doc/public/static/examples/assets/tralis-live-map/s4kreis.svg +95 -0
  71. package/doc/public/static/examples/assets/tralis-live-map/s6kreis.svg +95 -0
  72. package/doc/public/static/examples/assets/tralis-live-map/s7kreis.svg +95 -0
  73. package/doc/public/static/examples/assets/tralis-live-map/s8kreis.svg +93 -0
  74. package/doc/public/static/examples/assets/tralis-live-map/unknown.svg +107 -0
  75. package/doc/public/static/examples/layers.html +11 -0
  76. package/doc/public/static/examples/layers.js +97 -0
  77. package/doc/public/static/examples/mb-copyright.html +26 -0
  78. package/doc/public/static/examples/mb-copyright.js +37 -0
  79. package/doc/public/static/examples/mb-tracker.html +1 -0
  80. package/doc/public/static/examples/mb-tracker.js +40 -0
  81. package/doc/public/static/examples/mb-tracker.md +1 -0
  82. package/doc/public/static/examples/mb-tralis.html +1 -0
  83. package/doc/public/static/examples/mb-tralis.js +34 -0
  84. package/doc/public/static/examples/ol-copyright.html +26 -0
  85. package/doc/public/static/examples/ol-copyright.js +43 -0
  86. package/doc/public/static/examples/ol-mapbox-layer.html +1 -0
  87. package/doc/public/static/examples/ol-mapbox-layer.js +28 -0
  88. package/doc/public/static/examples/ol-mapbox-style-layer.html +12 -0
  89. package/doc/public/static/examples/ol-mapbox-style-layer.js +48 -0
  90. package/doc/public/static/examples/ol-query.html +32 -0
  91. package/doc/public/static/examples/ol-query.js +83 -0
  92. package/doc/public/static/examples/ol-routing.html +26 -0
  93. package/doc/public/static/examples/ol-routing.js +65 -0
  94. package/doc/public/static/examples/ol-routing.md +1 -0
  95. package/doc/public/static/examples/ol-stop-finder.html +15 -0
  96. package/doc/public/static/examples/ol-stop-finder.js +35 -0
  97. package/doc/public/static/examples/ol-stop-finder.md +1 -0
  98. package/doc/public/static/examples/ol-tracker.html +1 -0
  99. package/doc/public/static/examples/ol-tracker.js +41 -0
  100. package/doc/public/static/examples/ol-tracker.md +1 -0
  101. package/doc/public/static/examples/ol-tralis.html +5 -0
  102. package/doc/public/static/examples/ol-tralis.js +62 -0
  103. package/doc/public/static/examples/tralis-live-map.html +1 -0
  104. package/doc/public/static/examples/tralis-live-map.js +67 -0
  105. package/doc/public/static/examples/tralis-live-map.md +3 -0
  106. package/doc/public/static/img/live_tracker_mb.jpg +0 -0
  107. package/doc/public/static/img/live_tracker_munich.jpg +0 -0
  108. package/doc/public/static/img/live_tracker_ol.jpg +0 -0
  109. package/doc/public/static/img/mapbox.jpg +0 -0
  110. package/doc/public/static/img/mapbox_style.jpg +0 -0
  111. package/doc/public/static/img/ol-copyright.png +0 -0
  112. package/doc/public/static/img/query_objects.jpg +0 -0
  113. package/doc/public/static/img/routing.jpg +0 -0
  114. package/doc/public/static/img/simple_map.jpg +0 -0
  115. package/doc/public/static/img/stops.jpg +0 -0
  116. package/doc/public/vercel.svg +4 -0
  117. package/doc/src/components/CodeSandboxButton.js +102 -0
  118. package/doc/src/components/Documentation.js +42 -0
  119. package/doc/src/components/Esdoc/Anchor.js +57 -0
  120. package/doc/src/components/Esdoc/ClassDoc.js +272 -0
  121. package/doc/src/components/Esdoc/DeprecatedHTML.js +16 -0
  122. package/doc/src/components/Esdoc/DetailDocs.js +279 -0
  123. package/doc/src/components/Esdoc/DetailHTML.js +33 -0
  124. package/doc/src/components/Esdoc/DirectSubclassHTML.js +30 -0
  125. package/doc/src/components/Esdoc/DocBuilderUtils.js +697 -0
  126. package/doc/src/components/Esdoc/DocLinkHTML.js +63 -0
  127. package/doc/src/components/Esdoc/DocsLinkHTML.js +38 -0
  128. package/doc/src/components/Esdoc/Esdoc.js +63 -0
  129. package/doc/src/components/Esdoc/EsdocContent.js +56 -0
  130. package/doc/src/components/Esdoc/EsdocNavigation.js +13 -0
  131. package/doc/src/components/Esdoc/EsdocSearch.js +78 -0
  132. package/doc/src/components/Esdoc/ExperimentalHTML.js +17 -0
  133. package/doc/src/components/Esdoc/ExtendsChainHTML.js +32 -0
  134. package/doc/src/components/Esdoc/FileDocLinkHTML.js +62 -0
  135. package/doc/src/components/Esdoc/IdentifiersDoc.js +113 -0
  136. package/doc/src/components/Esdoc/IndirectSubclassHTML.js +30 -0
  137. package/doc/src/components/Esdoc/InheritedSummaryDoc.js +70 -0
  138. package/doc/src/components/Esdoc/InheritedSummaryHTML.js +38 -0
  139. package/doc/src/components/Esdoc/MixinClassesHTML.js +29 -0
  140. package/doc/src/components/Esdoc/NavDoc.js +112 -0
  141. package/doc/src/components/Esdoc/OverrideMethod.js +44 -0
  142. package/doc/src/components/Esdoc/OverrideMethodDescription.js +35 -0
  143. package/doc/src/components/Esdoc/Properties.js +89 -0
  144. package/doc/src/components/Esdoc/README.md +45 -0
  145. package/doc/src/components/Esdoc/SignatureHTML.js +123 -0
  146. package/doc/src/components/Esdoc/SingleDoc.js +31 -0
  147. package/doc/src/components/Esdoc/SummaryDoc.js +160 -0
  148. package/doc/src/components/Esdoc/SummaryHTML.js +96 -0
  149. package/doc/src/components/Esdoc/TypeDocLinkHTML.js +251 -0
  150. package/doc/src/components/Esdoc/index.js +7 -0
  151. package/doc/src/components/Esdoc/taffydb.js +2070 -0
  152. package/doc/src/components/Example.js +200 -0
  153. package/doc/src/components/ExampleCard.js +126 -0
  154. package/doc/src/components/Examples.js +78 -0
  155. package/doc/src/components/Home.js +121 -0
  156. package/doc/src/components/TrackerExample.js +39 -0
  157. package/doc/src/examples.js +117 -0
  158. package/doc/styles/App.scss +53 -0
  159. package/doc/styles/identifiers.css +38 -0
  160. package/doc/styles/search.css +76 -0
  161. package/doc/styles/style.css +603 -0
  162. package/esdoc/README.md +27 -0
  163. package/esdoc/plugins/MyPlugin.js +69 -0
  164. package/esdoc/plugins/dynamic-property-plugin/Plugin.js +50 -0
  165. package/esdoc/plugins/externals-plugin/Plugin.js +45 -0
  166. package/esdoc/plugins/externals-plugin/externals.js +93 -0
  167. package/esdoc/plugins/optional-chaining-plugin/Plugin.js +8 -0
  168. package/global-setup.js +3 -0
  169. package/jest.config.js +24 -0
  170. package/package.json +18 -18
  171. package/pull_request_template.md +17 -0
  172. package/scripts/read-pkg-json.js +22 -0
  173. package/src/api/RealtimeAPI.test.js +144 -0
  174. package/src/api/RealtimeAPI.ts +712 -0
  175. package/src/api/RoutingAPI.test.js +41 -0
  176. package/src/api/RoutingAPI.ts +47 -0
  177. package/src/api/StopsAPI.test.js +34 -0
  178. package/src/api/StopsAPI.ts +45 -0
  179. package/{api → src/api}/typedefs.js +11 -1
  180. package/src/common/api/HttpAPI.test.js +68 -0
  181. package/src/common/api/HttpAPI.ts +77 -0
  182. package/src/common/api/WebSocketAPI.test.js +421 -0
  183. package/src/common/api/WebSocketAPI.ts +515 -0
  184. package/src/common/controls/ControlCommon.test.js +106 -0
  185. package/src/common/controls/ControlCommon.ts +194 -0
  186. package/src/common/controls/CopyrightControlCommon.ts +41 -0
  187. package/src/common/controls/StopFinderControlCommon.ts +192 -0
  188. package/src/common/layers/LayerCommon.test.js +158 -0
  189. package/src/common/layers/LayerCommon.ts +321 -0
  190. package/src/common/mixins/RealtimeLayerMixin.ts +1168 -0
  191. package/src/common/mixins/UserInteractionsLayerMixin.test.js +227 -0
  192. package/src/common/mixins/UserInteractionsLayerMixin.ts +352 -0
  193. package/src/common/styles/realtimeDefaultStyle.ts +436 -0
  194. package/src/common/styles/realtimeDelayStyle.ts +27 -0
  195. package/src/common/styles/realtimeHeadingStyle.ts +138 -0
  196. package/src/common/styles/realtimeSimpleStyle.ts +25 -0
  197. package/{common → src/common}/typedefs.js +1 -1
  198. package/src/common/utils/compareDepartures.ts +46 -0
  199. package/src/common/utils/createCanvas.ts +33 -0
  200. package/src/common/utils/createRealtimeFilters.test.js +100 -0
  201. package/src/common/utils/createRealtimeFilters.ts +96 -0
  202. package/src/common/utils/debounceDeparturesMessages.ts +52 -0
  203. package/src/common/utils/debounceWebsocketMessages.ts +47 -0
  204. package/src/common/utils/getLayersAsFlatArray.ts +17 -0
  205. package/src/common/utils/getMapboxMapCopyrights.test.js +47 -0
  206. package/src/common/utils/getMapboxMapCopyrights.ts +52 -0
  207. package/src/common/utils/getMapboxRender.ts +104 -0
  208. package/src/common/utils/getMaplibreRender.ts +54 -0
  209. package/{common/utils/getRealtimeModeSuffix.d.ts → src/common/utils/getRealtimeModeSuffix.ts} +4 -2
  210. package/src/common/utils/getUrlWithParams.ts +21 -0
  211. package/src/common/utils/getVehiclePosition.ts +92 -0
  212. package/{common → src/common}/utils/index.js +1 -2
  213. package/src/common/utils/realtimeConfig.test.js +57 -0
  214. package/src/common/utils/realtimeConfig.ts +228 -0
  215. package/src/common/utils/removeDuplicate.test.js +22 -0
  216. package/src/common/utils/removeDuplicate.ts +22 -0
  217. package/src/common/utils/renderTrajectories.ts +194 -0
  218. package/src/common/utils/sortAndFilterDepartures.ts +78 -0
  219. package/src/common/utils/sortByDelay.ts +29 -0
  220. package/src/common/utils/timeUtils.test.js +16 -0
  221. package/src/common/utils/timeUtils.ts +45 -0
  222. package/{iife.js → src/iife.js} +3 -1
  223. package/src/index.js +10 -0
  224. package/{mapbox/controls/CopyrightControl.js → src/mapbox/controls/CopyrightControl.ts} +26 -21
  225. package/src/mapbox/layers/Layer.test.js +217 -0
  226. package/src/mapbox/layers/Layer.ts +144 -0
  227. package/src/mapbox/layers/RealtimeLayer.test.js +13 -0
  228. package/src/mapbox/layers/RealtimeLayer.ts +350 -0
  229. package/src/mapbox/utils/getMercatorResolution.ts +21 -0
  230. package/src/mapbox/utils/getSourceCoordinates.ts +34 -0
  231. package/src/ol/README.md +0 -0
  232. package/src/ol/controls/CopyrightControl.test.js +211 -0
  233. package/src/ol/controls/CopyrightControl.ts +82 -0
  234. package/src/ol/controls/RoutingControl.test.js +205 -0
  235. package/src/ol/controls/RoutingControl.ts +869 -0
  236. package/src/ol/controls/StopFinderControl.test.js +59 -0
  237. package/{ol/controls/StopFinderControl.js → src/ol/controls/StopFinderControl.ts} +10 -7
  238. package/src/ol/controls/snapshots/RoutingControlRouteGen10.json +58 -0
  239. package/src/ol/controls/snapshots/RoutingControlRouteGen100.json +292 -0
  240. package/src/ol/controls/snapshots/RoutingControlRouteGen30.json +69 -0
  241. package/src/ol/controls/snapshots/RoutingControlRouteGen5.json +58 -0
  242. package/src/ol/controls/snapshots/RoutingControlRouteOSM.json +759 -0
  243. package/src/ol/controls/snapshots/RoutingControlStation1.json +60 -0
  244. package/src/ol/controls/snapshots/RoutingControlStation2.json +49 -0
  245. package/src/ol/layers/Layer.test.js +212 -0
  246. package/src/ol/layers/Layer.ts +252 -0
  247. package/src/ol/layers/MapGlLayer.ts +294 -0
  248. package/src/ol/layers/MapboxLayer.test.js +190 -0
  249. package/src/ol/layers/MapboxLayer.ts +136 -0
  250. package/src/ol/layers/MapboxStyleLayer.test.js +258 -0
  251. package/src/ol/layers/MapboxStyleLayer.ts +466 -0
  252. package/{ol/layers/MaplibreLayer.d.ts → src/ol/layers/MaplibreLayer.ts} +21 -10
  253. package/src/ol/layers/RealtimeLayer.test.js +84 -0
  254. package/src/ol/layers/RealtimeLayer.ts +465 -0
  255. package/src/ol/layers/RoutingLayer.test.js +48 -0
  256. package/src/ol/layers/RoutingLayer.ts +113 -0
  257. package/src/ol/layers/VectorLayer.test.js +87 -0
  258. package/src/ol/layers/VectorLayer.ts +48 -0
  259. package/src/ol/layers/WMSLayer.test.js +65 -0
  260. package/src/ol/layers/WMSLayer.ts +114 -0
  261. package/src/ol/styles/fullTrajectoryDelayStyle.ts +37 -0
  262. package/src/ol/styles/fullTrajectoryStyle.ts +56 -0
  263. package/{setupTests.js → src/setupTests.js} +12 -7
  264. package/tsconfig.json +23 -0
  265. package/api/RealtimeAPI.d.ts +0 -290
  266. package/api/RealtimeAPI.d.ts.map +0 -1
  267. package/api/RealtimeAPI.js +0 -483
  268. package/api/RoutingAPI.d.ts +0 -37
  269. package/api/RoutingAPI.d.ts.map +0 -1
  270. package/api/RoutingAPI.js +0 -35
  271. package/api/StopsAPI.d.ts +0 -38
  272. package/api/StopsAPI.d.ts.map +0 -1
  273. package/api/StopsAPI.js +0 -36
  274. package/api/index.d.ts +0 -4
  275. package/api/index.d.ts.map +0 -1
  276. package/api/typedefs.d.ts +0 -179
  277. package/api/typedefs.d.ts.map +0 -1
  278. package/common/api/HttpAPI.d.ts +0 -31
  279. package/common/api/HttpAPI.d.ts.map +0 -1
  280. package/common/api/HttpAPI.js +0 -57
  281. package/common/api/WebSocketAPI.d.ts +0 -153
  282. package/common/api/WebSocketAPI.d.ts.map +0 -1
  283. package/common/api/WebSocketAPI.js +0 -341
  284. package/common/controls/ControlCommon.d.ts +0 -76
  285. package/common/controls/ControlCommon.d.ts.map +0 -1
  286. package/common/controls/ControlCommon.js +0 -150
  287. package/common/controls/CopyrightControlCommon.d.ts +0 -13
  288. package/common/controls/CopyrightControlCommon.d.ts.map +0 -1
  289. package/common/controls/CopyrightControlCommon.js +0 -34
  290. package/common/controls/StopFinderControlCommon.d.ts +0 -55
  291. package/common/controls/StopFinderControlCommon.d.ts.map +0 -1
  292. package/common/controls/StopFinderControlCommon.js +0 -144
  293. package/common/index.d.ts +0 -3
  294. package/common/index.d.ts.map +0 -1
  295. package/common/layers/LayerCommon.d.ts +0 -94
  296. package/common/layers/LayerCommon.d.ts.map +0 -1
  297. package/common/layers/LayerCommon.js +0 -244
  298. package/common/mixins/RealtimeLayerMixin.d.ts +0 -288
  299. package/common/mixins/RealtimeLayerMixin.d.ts.map +0 -1
  300. package/common/mixins/RealtimeLayerMixin.js +0 -779
  301. package/common/mixins/UserInteractionsLayerMixin.d.ts +0 -60
  302. package/common/mixins/UserInteractionsLayerMixin.d.ts.map +0 -1
  303. package/common/mixins/UserInteractionsLayerMixin.js +0 -241
  304. package/common/styles/index.d.ts +0 -5
  305. package/common/styles/index.d.ts.map +0 -1
  306. package/common/styles/realtimeDefaultStyle.d.ts +0 -36
  307. package/common/styles/realtimeDefaultStyle.d.ts.map +0 -1
  308. package/common/styles/realtimeDefaultStyle.js +0 -276
  309. package/common/styles/realtimeDelayStyle.d.ts +0 -12
  310. package/common/styles/realtimeDelayStyle.d.ts.map +0 -1
  311. package/common/styles/realtimeDelayStyle.js +0 -13
  312. package/common/styles/realtimeHeadingStyle.d.ts +0 -12
  313. package/common/styles/realtimeHeadingStyle.d.ts.map +0 -1
  314. package/common/styles/realtimeHeadingStyle.js +0 -87
  315. package/common/styles/realtimeSimpleStyle.d.ts +0 -4
  316. package/common/styles/realtimeSimpleStyle.d.ts.map +0 -1
  317. package/common/styles/realtimeSimpleStyle.js +0 -23
  318. package/common/typedefs.d.ts +0 -183
  319. package/common/typedefs.d.ts.map +0 -1
  320. package/common/utils/compareDepartures.d.ts +0 -11
  321. package/common/utils/compareDepartures.d.ts.map +0 -1
  322. package/common/utils/compareDepartures.js +0 -35
  323. package/common/utils/createCanvas.d.ts +0 -11
  324. package/common/utils/createCanvas.d.ts.map +0 -1
  325. package/common/utils/createCanvas.js +0 -28
  326. package/common/utils/createRealtimeFilters.d.ts +0 -13
  327. package/common/utils/createRealtimeFilters.d.ts.map +0 -1
  328. package/common/utils/createRealtimeFilters.js +0 -74
  329. package/common/utils/debounceDeparturesMessages.d.ts +0 -13
  330. package/common/utils/debounceDeparturesMessages.d.ts.map +0 -1
  331. package/common/utils/debounceDeparturesMessages.js +0 -28
  332. package/common/utils/debounceWebsocketMessages.d.ts +0 -12
  333. package/common/utils/debounceWebsocketMessages.d.ts.map +0 -1
  334. package/common/utils/debounceWebsocketMessages.js +0 -30
  335. package/common/utils/getLayersAsFlatArray.d.ts +0 -4
  336. package/common/utils/getLayersAsFlatArray.d.ts.map +0 -1
  337. package/common/utils/getLayersAsFlatArray.js +0 -16
  338. package/common/utils/getMapboxMapCopyrights.d.ts +0 -18
  339. package/common/utils/getMapboxMapCopyrights.d.ts.map +0 -1
  340. package/common/utils/getMapboxMapCopyrights.js +0 -30
  341. package/common/utils/getMapboxRender.d.ts +0 -8
  342. package/common/utils/getMapboxRender.d.ts.map +0 -1
  343. package/common/utils/getMapboxRender.js +0 -88
  344. package/common/utils/getMaplibreRender.d.ts +0 -9
  345. package/common/utils/getMaplibreRender.d.ts.map +0 -1
  346. package/common/utils/getMaplibreRender.js +0 -40
  347. package/common/utils/getRealtimeModeSuffix.d.ts.map +0 -1
  348. package/common/utils/getRealtimeModeSuffix.js +0 -7
  349. package/common/utils/getUrlWithParams.d.ts +0 -9
  350. package/common/utils/getUrlWithParams.d.ts.map +0 -1
  351. package/common/utils/getUrlWithParams.js +0 -18
  352. package/common/utils/getVehiclePosition.d.ts +0 -16
  353. package/common/utils/getVehiclePosition.d.ts.map +0 -1
  354. package/common/utils/getVehiclePosition.js +0 -72
  355. package/common/utils/index.d.ts +0 -18
  356. package/common/utils/index.d.ts.map +0 -1
  357. package/common/utils/realtimeConfig.d.ts +0 -53
  358. package/common/utils/realtimeConfig.d.ts.map +0 -1
  359. package/common/utils/realtimeConfig.js +0 -202
  360. package/common/utils/removeDuplicate.d.ts +0 -10
  361. package/common/utils/removeDuplicate.d.ts.map +0 -1
  362. package/common/utils/removeDuplicate.js +0 -15
  363. package/common/utils/renderTrajectories.d.ts +0 -17
  364. package/common/utils/renderTrajectories.d.ts.map +0 -1
  365. package/common/utils/renderTrajectories.js +0 -110
  366. package/common/utils/sortAndFilterDepartures.d.ts +0 -16
  367. package/common/utils/sortAndFilterDepartures.d.ts.map +0 -1
  368. package/common/utils/sortAndFilterDepartures.js +0 -58
  369. package/common/utils/sortByDelay.d.ts +0 -4
  370. package/common/utils/sortByDelay.d.ts.map +0 -1
  371. package/common/utils/sortByDelay.js +0 -21
  372. package/common/utils/timeUtils.d.ts +0 -24
  373. package/common/utils/timeUtils.d.ts.map +0 -1
  374. package/common/utils/timeUtils.js +0 -39
  375. package/iife.d.ts +0 -3
  376. package/iife.d.ts.map +0 -1
  377. package/index.d.ts +0 -10
  378. package/index.d.ts.map +0 -1
  379. package/index.js +0 -10
  380. package/mapbox/controls/CopyrightControl.d.ts +0 -29
  381. package/mapbox/controls/CopyrightControl.d.ts.map +0 -1
  382. package/mapbox/controls/index.d.ts +0 -2
  383. package/mapbox/controls/index.d.ts.map +0 -1
  384. package/mapbox/index.d.ts +0 -6
  385. package/mapbox/index.d.ts.map +0 -1
  386. package/mapbox/layers/Layer.d.ts +0 -59
  387. package/mapbox/layers/Layer.d.ts.map +0 -1
  388. package/mapbox/layers/Layer.js +0 -101
  389. package/mapbox/layers/RealtimeLayer.d.ts +0 -180
  390. package/mapbox/layers/RealtimeLayer.d.ts.map +0 -1
  391. package/mapbox/layers/RealtimeLayer.js +0 -270
  392. package/mapbox/layers/index.d.ts +0 -3
  393. package/mapbox/layers/index.d.ts.map +0 -1
  394. package/mapbox/utils/getMercatorResolution.d.ts +0 -9
  395. package/mapbox/utils/getMercatorResolution.d.ts.map +0 -1
  396. package/mapbox/utils/getMercatorResolution.js +0 -18
  397. package/mapbox/utils/getSourceCoordinates.d.ts +0 -9
  398. package/mapbox/utils/getSourceCoordinates.d.ts.map +0 -1
  399. package/mapbox/utils/getSourceCoordinates.js +0 -27
  400. package/mapbox/utils/index.d.ts +0 -3
  401. package/mapbox/utils/index.d.ts.map +0 -1
  402. package/mbt.js +0 -64706
  403. package/mbt.js.map +0 -7
  404. package/mbt.min.js +0 -1090
  405. package/mbt.min.js.map +0 -7
  406. package/ol/controls/CopyrightControl.d.ts +0 -31
  407. package/ol/controls/CopyrightControl.d.ts.map +0 -1
  408. package/ol/controls/CopyrightControl.js +0 -68
  409. package/ol/controls/RoutingControl.d.ts +0 -193
  410. package/ol/controls/RoutingControl.d.ts.map +0 -1
  411. package/ol/controls/RoutingControl.js +0 -631
  412. package/ol/controls/StopFinderControl.d.ts +0 -30
  413. package/ol/controls/StopFinderControl.d.ts.map +0 -1
  414. package/ol/controls/index.d.ts +0 -4
  415. package/ol/controls/index.d.ts.map +0 -1
  416. package/ol/index.d.ts +0 -6
  417. package/ol/index.d.ts.map +0 -1
  418. package/ol/layers/Layer.d.ts +0 -86
  419. package/ol/layers/Layer.d.ts.map +0 -1
  420. package/ol/layers/Layer.js +0 -174
  421. package/ol/layers/MapGlLayer.d.ts +0 -67
  422. package/ol/layers/MapGlLayer.d.ts.map +0 -1
  423. package/ol/layers/MapGlLayer.js +0 -218
  424. package/ol/layers/MapboxLayer.d.ts +0 -50
  425. package/ol/layers/MapboxLayer.d.ts.map +0 -1
  426. package/ol/layers/MapboxLayer.js +0 -109
  427. package/ol/layers/MapboxStyleLayer.d.ts +0 -130
  428. package/ol/layers/MapboxStyleLayer.d.ts.map +0 -1
  429. package/ol/layers/MapboxStyleLayer.js +0 -378
  430. package/ol/layers/MaplibreLayer.d.ts.map +0 -1
  431. package/ol/layers/MaplibreLayer.js +0 -34
  432. package/ol/layers/RealtimeLayer.d.ts +0 -202
  433. package/ol/layers/RealtimeLayer.d.ts.map +0 -1
  434. package/ol/layers/RealtimeLayer.js +0 -332
  435. package/ol/layers/RoutingLayer.d.ts +0 -35
  436. package/ol/layers/RoutingLayer.d.ts.map +0 -1
  437. package/ol/layers/RoutingLayer.js +0 -85
  438. package/ol/layers/VectorLayer.d.ts +0 -25
  439. package/ol/layers/VectorLayer.d.ts.map +0 -1
  440. package/ol/layers/VectorLayer.js +0 -38
  441. package/ol/layers/WMSLayer.d.ts +0 -42
  442. package/ol/layers/WMSLayer.d.ts.map +0 -1
  443. package/ol/layers/WMSLayer.js +0 -88
  444. package/ol/layers/index.d.ts +0 -9
  445. package/ol/layers/index.d.ts.map +0 -1
  446. package/ol/styles/fullTrajectoryDelayStyle.d.ts +0 -4
  447. package/ol/styles/fullTrajectoryDelayStyle.d.ts.map +0 -1
  448. package/ol/styles/fullTrajectoryDelayStyle.js +0 -33
  449. package/ol/styles/fullTrajectoryStyle.d.ts +0 -5
  450. package/ol/styles/fullTrajectoryStyle.d.ts.map +0 -1
  451. package/ol/styles/fullTrajectoryStyle.js +0 -44
  452. package/ol/styles/index.d.ts +0 -3
  453. package/ol/styles/index.d.ts.map +0 -1
  454. package/setupTests.d.ts +0 -2
  455. package/setupTests.d.ts.map +0 -1
  456. /package/{api → src/api}/index.js +0 -0
  457. /package/{common → src/common}/index.js +0 -0
  458. /package/{common → src/common}/styles/index.js +0 -0
  459. /package/{mapbox → src/mapbox}/controls/index.js +0 -0
  460. /package/{mapbox → src/mapbox}/index.js +0 -0
  461. /package/{mapbox → src/mapbox}/layers/index.js +0 -0
  462. /package/{mapbox → src/mapbox}/utils/index.js +0 -0
  463. /package/{ol → src/ol}/controls/index.js +0 -0
  464. /package/{ol → src/ol}/index.js +0 -0
  465. /package/{ol → src/ol}/layers/index.js +0 -0
  466. /package/{ol → src/ol}/styles/index.js +0 -0
  467. /package/{types → src/types}/common.d.ts +0 -0
  468. /package/{types → src/types}/index.d.ts +0 -0
  469. /package/{types → src/types}/realtime.d.ts +0 -0
  470. /package/{types → src/types}/routing.d.ts +0 -0
  471. /package/{types → src/types}/stops.d.ts +0 -0
@@ -0,0 +1,92 @@
1
+ import { Coordinate } from 'ol/coordinate';
2
+ import { LineString } from 'ol/geom';
3
+ import type { RealtimeTrajectory } from '../../api/typedefs';
4
+
5
+ export type VehiclePosition = {
6
+ coord: Coordinate;
7
+ rotation: number;
8
+ };
9
+
10
+ /**
11
+ * Interpolate or not the vehicle position from a trajectory at a specific date.
12
+ *
13
+ * @param {number} now Current date to interpolate a position with. In ms.
14
+ * @param {RealtimeTrajectory} trajectory The trajectory to interpolate.
15
+ * @param {boolean} noInterpolate If true, the vehicle position is not interpolated on each render but only once.
16
+ * @returns {VehiclePosition}
17
+ */
18
+ const getVehiclePosition = (
19
+ now: number,
20
+ trajectory: RealtimeTrajectory,
21
+ noInterpolate: boolean,
22
+ ): VehiclePosition => {
23
+ const {
24
+ time_intervals: timeIntervals,
25
+ olGeometry,
26
+ coordinate,
27
+ } = trajectory.properties;
28
+ const { coordinates } = trajectory.geometry;
29
+ let { type } = trajectory.geometry;
30
+ let geometry = olGeometry;
31
+ let coord;
32
+ let rotation;
33
+
34
+ if (olGeometry) {
35
+ type = geometry.getType();
36
+ }
37
+
38
+ if (noInterpolate && coordinate) {
39
+ coord = coordinate;
40
+ } else if (type === 'Point') {
41
+ coord = coordinates;
42
+ } else if (type === 'LineString') {
43
+ if (!geometry) {
44
+ geometry = new LineString(coordinates);
45
+ }
46
+ const intervals = timeIntervals || [[]];
47
+ const firstInterval = intervals[0];
48
+ const lastInterval = intervals[intervals.length - 1];
49
+
50
+ // Between the last time interval of a trajectory event and the beginning
51
+ // of the new trajectory event, there is few seconds, can be 6 to 30
52
+ // seconds (that's why the vehicle jumps sometimes).
53
+ // So we make the choice here to display the last (or the first) position
54
+ // of an trajectory event instead of removing them, if the current date is
55
+ // outside the time intervals we display the vehicle at the last (or first) position known.
56
+ if (now < firstInterval[0]) {
57
+ // Display first position known.
58
+ [, , rotation] = firstInterval;
59
+ coord = geometry.getFirstCoordinate();
60
+ } else if (now > lastInterval[0]) {
61
+ // Display last position known.
62
+ [, , rotation] = lastInterval;
63
+ coord = geometry.getLastCoordinate();
64
+ } else {
65
+ // Interpolate position using time intervals.
66
+ for (let j = 0; j < intervals.length - 1; j += 1) {
67
+ // Rotation only available in realtime layer.
68
+ const [start, startFrac] = intervals[j];
69
+ const [end, endFrac] = intervals[j + 1];
70
+
71
+ if (start <= now && now <= end) {
72
+ // interpolate position inside the time interval.
73
+ const timeFrac = Math.min((now - start) / (end - start), 1);
74
+ const geomFrac = timeFrac * (endFrac - startFrac) + startFrac;
75
+ coord = geometry.getCoordinateAt(geomFrac);
76
+ [, , rotation] = intervals[j];
77
+ break;
78
+ }
79
+ }
80
+ }
81
+ } else {
82
+ // eslint-disable-next-line no-console
83
+ console.error(
84
+ 'This geometry type is not supported. Only Point or LineString are. Current geometry: ',
85
+ geometry,
86
+ );
87
+ }
88
+
89
+ return { coord, rotation };
90
+ };
91
+
92
+ export default getVehiclePosition;
@@ -14,5 +14,4 @@ export { default as sortAndFilterDepartures } from './sortAndFilterDepartures';
14
14
  export { default as compareDepartures } from './compareDepartures';
15
15
  export { default as createCanvas } from './createCanvas';
16
16
  export { default as getVehiclePosition } from './getVehiclePosition';
17
- import * as realtimeConfig_1 from './realtimeConfig';
18
- export { realtimeConfig_1 as realtimeConfig };
17
+ export * as realtimeConfig from './realtimeConfig';
@@ -0,0 +1,57 @@
1
+ import { getDelayText, getTypeIndex } from './realtimeConfig';
2
+
3
+ describe('trackerConfig', () => {
4
+ describe('#getTypeIndex()', () => {
5
+ test("returns the type is it's not a string", () => {
6
+ const obj = { foo: 'foo' };
7
+ expect(getTypeIndex(obj)).toBe(obj);
8
+ expect(getTypeIndex(0)).toBe(0);
9
+ expect(getTypeIndex(null)).toBe(null);
10
+ expect(getTypeIndex(undefined)).toBe(undefined);
11
+ });
12
+
13
+ test('find good index for new tracker values', () => {
14
+ expect(getTypeIndex('tram')).toBe(0);
15
+ expect(getTypeIndex('subway')).toBe(1);
16
+ expect(getTypeIndex('bus')).toBe(3);
17
+ expect(getTypeIndex('ferry')).toBe(4);
18
+ expect(getTypeIndex('cablecar')).toBe(5);
19
+ expect(getTypeIndex('gondola')).toBe(6);
20
+ expect(getTypeIndex('funicular')).toBe(7);
21
+ expect(getTypeIndex('coach')).toBe(8);
22
+ expect(getTypeIndex('rail')).toBe(9);
23
+ });
24
+ });
25
+
26
+ describe('#getDelayText()', () => {
27
+ test('returns hours', () => {
28
+ expect(getDelayText(6400000)).toBe('+2h');
29
+ expect(getDelayText(4500000)).toBe('+1h');
30
+ expect(getDelayText(3600000)).toBe('+1h');
31
+ });
32
+
33
+ test('returns minutes', () => {
34
+ expect(getDelayText(100000)).toBe('+2m');
35
+ expect(getDelayText(68000)).toBe('+1m');
36
+ expect(getDelayText(60000)).toBe('+1m');
37
+ });
38
+
39
+ test('returns seconds', () => {
40
+ expect(getDelayText(1800)).toBe('+2s');
41
+ expect(getDelayText(1400)).toBe('+1s');
42
+ expect(getDelayText(1000)).toBe('+1s');
43
+ });
44
+
45
+ test('returns milliseconds', () => {
46
+ expect(getDelayText(100)).toBe('+100ms');
47
+ expect(getDelayText(999)).toBe('+999ms');
48
+ });
49
+
50
+ test('returns empty string', () => {
51
+ expect(getDelayText(-45)).toBe('');
52
+ expect(getDelayText('lalal')).toBe('');
53
+ expect(getDelayText(null)).toBe('');
54
+ expect(getDelayText()).toBe('');
55
+ });
56
+ });
57
+ });
@@ -0,0 +1,228 @@
1
+ import { AnyCanvasContext, RealtimeMot } from '../../types';
2
+
3
+ /** @private */
4
+ const radiusMapping: number[][] = [
5
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
6
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
7
+ [0, 0, 0, 0, 0, 2, 2, 3, 7, 7, 7, 12, 15, 15, 15, 15, 15],
8
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
9
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
10
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
11
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
12
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
13
+ [0, 0, 0, 0, 0, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7],
14
+ [0, 0, 0, 0, 0, 2, 2, 3, 7, 7, 7, 12, 15, 15, 15, 15, 15],
15
+ ];
16
+
17
+ export const MOTS_ONLY_RAIL: RealtimeMot[] = ['rail'];
18
+ export const MOTS_WITH_CABLE: RealtimeMot[] = [
19
+ 'cablecar',
20
+ 'gondola',
21
+ 'funicular',
22
+ 'coach',
23
+ ];
24
+ export const MOTS_WITHOUT_CABLE: RealtimeMot[] = [
25
+ 'tram',
26
+ 'subway',
27
+ 'rail',
28
+ 'bus',
29
+ ];
30
+ export const MOTS_ALL: RealtimeMot[] = [
31
+ 'tram',
32
+ 'subway',
33
+ 'rail',
34
+ 'bus',
35
+ 'ferry',
36
+ 'cablecar',
37
+ 'gondola',
38
+ 'funicular',
39
+ 'coach',
40
+ ];
41
+
42
+ /**
43
+ * Trajserv value: 'Tram', 'Subway / Metro / S-Bahn', 'Train', 'Bus', 'Ferry', 'Cable Car', 'Gondola', 'Funicular', 'Long distance bus', 'Rail',
44
+ * New endpoint use Rail instead of Train.
45
+ * New tracker values: null, "tram", "subway", "rail", "bus", "ferry", "cablecar", "gondola", "funicular", "coach".
46
+ *
47
+ * @private
48
+ */
49
+ export const types: RegExp[] = [
50
+ /^Tram/i,
51
+ /^Subway( \/ Metro \/ S-Bahn)?/i,
52
+ /^Train/i,
53
+ /^Bus/i,
54
+ /^Ferry/i,
55
+ /^Cable ?Car/i,
56
+ /^Gondola/i,
57
+ /^Funicular/i,
58
+ /^(Long distance bus|coach)/i,
59
+ /^Rail/i, // New endpoint use Rail instead of Train.
60
+ ];
61
+
62
+ /**
63
+ * @private
64
+ */
65
+ export const bgColors: string[] = [
66
+ '#ffb400',
67
+ '#ff5400',
68
+ '#ff8080',
69
+ '#ea0000',
70
+ '#3000ff',
71
+ '#ffb400',
72
+ '#41a27b',
73
+ '#00d237',
74
+ '#b5b5b5',
75
+ '#ff8080',
76
+ ];
77
+
78
+ /**
79
+ * @private
80
+ */
81
+ export const textColors: string[] = [
82
+ '#000000',
83
+ '#ffffff',
84
+ '#000000',
85
+ '#ffffff',
86
+ '#ffffff',
87
+ '#000000',
88
+ '#ffffff',
89
+ '#000000',
90
+ '#000000',
91
+ '#000000',
92
+ ];
93
+
94
+ /**
95
+ * @private
96
+ */
97
+ export const getTypeIndex = (type: RealtimeMot): number => {
98
+ if (typeof type === 'string') {
99
+ return types.findIndex((t) => t.test(type));
100
+ }
101
+ return type;
102
+ };
103
+
104
+ /**
105
+ * @private
106
+ */
107
+ export const getRadius = (type: RealtimeMot, zoom: number): number => {
108
+ try {
109
+ const typeIdx = getTypeIndex(type || 0);
110
+ return radiusMapping[typeIdx][zoom];
111
+ } catch (e) {
112
+ return 1;
113
+ }
114
+ };
115
+
116
+ /**
117
+ * @private
118
+ */
119
+ export const getBgColor = (type: RealtimeMot): string => {
120
+ try {
121
+ const typeIdx = getTypeIndex(type);
122
+ return bgColors[typeIdx];
123
+ } catch (e) {
124
+ return '#ffffff';
125
+ }
126
+ };
127
+
128
+ /**
129
+ * @private
130
+ */
131
+ export const getTextColor = (type: RealtimeMot): string => {
132
+ try {
133
+ const typeIdx = getTypeIndex(type);
134
+ return textColors[typeIdx];
135
+ } catch (e) {
136
+ return '#ffffff';
137
+ }
138
+ };
139
+
140
+ /**
141
+ * @private
142
+ */
143
+ export const getTextSize = (
144
+ ctx: AnyCanvasContext,
145
+ markerSize: number,
146
+ text: string,
147
+ fontSize: number,
148
+ getTextFont: (fontSize: number, text?: string) => string,
149
+ ): number => {
150
+ if (!ctx) {
151
+ return 0;
152
+ }
153
+ ctx.font = getTextFont(fontSize, text);
154
+ let newText = ctx.measureText(text);
155
+
156
+ const maxiter = 25;
157
+ let i = 0;
158
+
159
+ while (newText.width > markerSize - 6 && i < maxiter) {
160
+ // eslint-disable-next-line no-param-reassign
161
+ fontSize -= 0.5;
162
+ ctx.font = getTextFont(fontSize, text);
163
+ newText = ctx.measureText(text);
164
+ i += 1;
165
+ }
166
+ return fontSize;
167
+ };
168
+
169
+ /**
170
+ * @private
171
+ * @param {number} delayInMs Delay in milliseconds.
172
+ * @param {boolean} cancelled true if the journey is cancelled.
173
+ * @param {boolean} isDelayText true if the color is used for delay text of the symbol.
174
+ */
175
+ export const getDelayColor = (
176
+ delayInMs: number | null,
177
+ cancelled?: boolean,
178
+ isDelayText?: boolean,
179
+ ): string => {
180
+ if (cancelled) {
181
+ return isDelayText ? '#ff0000' : '#a0a0a0'; // red or gray
182
+ }
183
+ if (delayInMs === null) {
184
+ return '#a0a0a0'; // grey { r: 160, g: 160, b: 160, s: '160,160,160' };
185
+ }
186
+ if (delayInMs >= 3600000) {
187
+ return '#ed004c'; // pink { r: 237, g: 0, b: 76, s: '237,0,76' };
188
+ }
189
+ if (delayInMs >= 500000) {
190
+ return '#e80000'; // red { r: 232, g: 0, b: 0, s: '232,0,0' };
191
+ }
192
+ if (delayInMs >= 300000) {
193
+ return '#ff4a00'; // orange { r: 255, g: 74, b: 0, s: '255,74,0' };
194
+ }
195
+ if (delayInMs >= 180000) {
196
+ return '#f7bf00'; // yellow { r: 247, g: 191, b: 0, s: '247,191,0' };
197
+ }
198
+ return '#00a00c'; // green { r: 0, g: 160, b: 12, s: '0,160,12' };
199
+ };
200
+
201
+ /**
202
+ * @private
203
+ */
204
+ export const getDelayText = (delayInMs: number, cancelled: boolean): string => {
205
+ if (cancelled) {
206
+ return String.fromCodePoint(0x00d7);
207
+ }
208
+ if (delayInMs >= 3600000) {
209
+ const rounded = Math.round(delayInMs / 3600000);
210
+ return `+${rounded}h`;
211
+ }
212
+
213
+ if (delayInMs >= 60000) {
214
+ const rounded = Math.round(delayInMs / 60000);
215
+ return `+${rounded}m`;
216
+ }
217
+
218
+ if (delayInMs >= 1000) {
219
+ const rounded = Math.round(delayInMs / 1000);
220
+ return `+${rounded}s`;
221
+ }
222
+
223
+ if (delayInMs > 0) {
224
+ return `+${delayInMs}ms`;
225
+ }
226
+
227
+ return '';
228
+ };
@@ -0,0 +1,22 @@
1
+ import removeDuplicate from './removeDuplicate';
2
+
3
+ describe('removeDuplicate()', () => {
4
+ test('removes duplicates', () => {
5
+ expect(
6
+ removeDuplicate([
7
+ 'a',
8
+ ' ',
9
+ ' ',
10
+ 'b',
11
+ 'a',
12
+ undefined,
13
+ null,
14
+ 'A',
15
+ 0,
16
+ 'c',
17
+ 'b',
18
+ 'B',
19
+ ]),
20
+ ).toEqual(['a', 'b', 'c']);
21
+ });
22
+ });
@@ -0,0 +1,22 @@
1
+ /**
2
+ * This function remove duplicates lower case string value of an array.
3
+ * It removes also null, undefined or non string values.
4
+ *
5
+ * @param {array} array Array of values.
6
+ * @private
7
+ */
8
+ const removeDuplicate = (array: any[]) => {
9
+ const arrWithoutEmptyValues = array.filter(
10
+ (val) => val !== undefined && val !== null && val.trim && val.trim(),
11
+ );
12
+ const lowerCasesValues = arrWithoutEmptyValues.map((str) =>
13
+ str.toLowerCase(),
14
+ );
15
+ const uniqueLowerCaseValues = [...new Set(lowerCasesValues)];
16
+ const uniqueValues = uniqueLowerCaseValues.map((uniqueStr) =>
17
+ arrWithoutEmptyValues.find((str) => str.toLowerCase() === uniqueStr),
18
+ );
19
+ return uniqueValues;
20
+ };
21
+
22
+ export default removeDuplicate;
@@ -0,0 +1,194 @@
1
+ /* eslint-disable no-param-reassign */
2
+ import { Pixel } from 'ol/pixel';
3
+ import { compose, apply, create } from 'ol/transform';
4
+ import {
5
+ AnyCanvas,
6
+ RealtimeRenderState,
7
+ RealtimeStyleFunction,
8
+ RealtimeStyleOptions,
9
+ RealtimeTrajectories,
10
+ ViewState,
11
+ } from '../../types';
12
+ import getVehiclePosition from './getVehiclePosition';
13
+
14
+ /**
15
+ * Draw all the trajectories available in a canvas.
16
+ * @param {HTMLCanvas|HTMLOffscreenCanvas} The canvas where to draw the trajectories.
17
+ * @param {ViewState} trajectories An array of trajectories.
18
+ * @param {Function} style A function that returns a canvas representing a vehicle of a specific trajectory.
19
+ * @param {ViewState} viewState The view state of the map.
20
+ * @param {boolean} options.hoverVehicleId The id of the vehicle to highlight.
21
+ * @param {boolean} options.selectedVehicleId The id of the vehicle to select.
22
+ * @param {boolean} options.noInterpolate If true trajectories are not interpolated but
23
+ * drawn at the last known coordinate. Use this for performance optimization
24
+ * during map navigation.
25
+ * @private
26
+ */
27
+ const renderTrajectories = (
28
+ canvas: AnyCanvas,
29
+ trajectories: RealtimeTrajectories,
30
+ style: RealtimeStyleFunction,
31
+ viewState: ViewState,
32
+ options: RealtimeStyleOptions,
33
+ ): RealtimeRenderState => {
34
+ if (!canvas) {
35
+ return { renderedTrajectories: [] };
36
+ }
37
+
38
+ const {
39
+ time = Date.now(),
40
+ size = [],
41
+ center,
42
+ resolution,
43
+ rotation = 0,
44
+ pixelRatio = 1,
45
+ } = viewState;
46
+
47
+ if (!resolution || !center) {
48
+ return { renderedTrajectories: [] };
49
+ }
50
+
51
+ const {
52
+ noInterpolate = false,
53
+ hoverVehicleId,
54
+ selectedVehicleId,
55
+ filter,
56
+ getScreenPixel = (pixel: Pixel, viewStat: ViewState): Pixel =>
57
+ (viewStat.zoom || 0) < 12
58
+ ? pixel.map((coord) => Math.floor(coord))
59
+ : pixel,
60
+ } = options;
61
+ const context = canvas.getContext('2d');
62
+ context?.clearRect(0, 0, canvas.width, canvas.height);
63
+
64
+ const [width, height] = size;
65
+ if (width && height && (canvas.width !== width || canvas.height !== height)) {
66
+ [canvas.width, canvas.height] = [width * pixelRatio, height * pixelRatio];
67
+ }
68
+
69
+ const coordinateToPixelTransform = compose(
70
+ create(),
71
+ size[0] / 2,
72
+ size[1] / 2,
73
+ 1 / resolution,
74
+ -1 / resolution,
75
+ -rotation,
76
+ -center[0],
77
+ -center[1],
78
+ );
79
+
80
+ // Offscreen canvas has not style attribute
81
+ if ((canvas as HTMLCanvasElement).style) {
82
+ (canvas as HTMLCanvasElement).style.width = `${
83
+ canvas.width / pixelRatio
84
+ }px`;
85
+ (canvas as HTMLCanvasElement).style.height = `${
86
+ canvas.height / pixelRatio
87
+ }px`;
88
+ }
89
+
90
+ let hoverVehicleImg;
91
+ let hoverVehiclePx;
92
+ let selectedVehicleImg;
93
+ let selectedVehiclePx;
94
+ const renderedTrajectories = [];
95
+
96
+ for (let i = trajectories.length - 1; i >= 0; i -= 1) {
97
+ const trajectory = trajectories[i];
98
+
99
+ // Filter out trajectories
100
+ if (filter && !filter(trajectory)) {
101
+ // eslint-disable-next-line no-continue
102
+ continue;
103
+ }
104
+
105
+ // We simplify the trajectory object
106
+ const { train_id: id, timeOffset } = trajectory.properties;
107
+ // We set the rotation and the timeFraction of the trajectory (used by tralis).
108
+ // if rotation === null that seems there is no rotation available.
109
+ const { coord, rotation: rotationIcon } = getVehiclePosition(
110
+ time - (timeOffset || 0),
111
+ trajectory,
112
+ noInterpolate,
113
+ );
114
+
115
+ // We store the current vehicle position to the trajectory.
116
+ trajectories[i].properties.coordinate = coord;
117
+ trajectories[i].properties.rotation = rotationIcon;
118
+
119
+ if (!coord) {
120
+ // eslint-disable-next-line no-continue
121
+ continue;
122
+ }
123
+
124
+ let px = apply(coordinateToPixelTransform, [...coord]);
125
+ if (!px) {
126
+ // eslint-disable-next-line no-continue
127
+ continue;
128
+ }
129
+
130
+ px = px.map((p) => p * pixelRatio);
131
+
132
+ if (
133
+ px[0] < 0 ||
134
+ px[0] > canvas.width ||
135
+ px[1] < 0 ||
136
+ px[1] > canvas.height
137
+ ) {
138
+ // eslint-disable-next-line no-continue
139
+ continue;
140
+ }
141
+
142
+ const vehicleImg = style(trajectory, viewState, options);
143
+ if (!vehicleImg) {
144
+ // eslint-disable-next-line no-continue
145
+ continue;
146
+ }
147
+
148
+ if (hoverVehicleId !== id && selectedVehicleId !== id) {
149
+ // To optimize the performance we use integer as pixel coordinate
150
+ // to avoid an additional work by the browser on zoom level < 12.
151
+ // See https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Optimizing_canvas?retiredLocale=de#avoid_floating-point_coordinates_and_use_integers_instead
152
+ const [x, y] = getScreenPixel(
153
+ [px[0] - vehicleImg.width / 2, px[1] - vehicleImg.height / 2],
154
+ viewState,
155
+ );
156
+ context?.drawImage(vehicleImg, x, y);
157
+ }
158
+
159
+ if (hoverVehicleId && hoverVehicleId === id) {
160
+ // Store the canvas to draw it at the end
161
+ hoverVehicleImg = vehicleImg;
162
+ hoverVehiclePx = px;
163
+ }
164
+
165
+ if (selectedVehicleId && selectedVehicleId === id) {
166
+ // Store the canvas to draw it at the end
167
+ selectedVehicleImg = vehicleImg;
168
+ selectedVehiclePx = px;
169
+ }
170
+
171
+ renderedTrajectories.push(trajectory);
172
+ }
173
+
174
+ if (selectedVehicleImg && selectedVehiclePx) {
175
+ context?.drawImage(
176
+ selectedVehicleImg,
177
+ Math.floor(selectedVehiclePx[0] - selectedVehicleImg.width / 2),
178
+ Math.floor(selectedVehiclePx[1] - selectedVehicleImg.height / 2),
179
+ );
180
+ }
181
+
182
+ if (hoverVehicleImg && hoverVehiclePx) {
183
+ context?.drawImage(
184
+ hoverVehicleImg,
185
+ Math.floor(hoverVehiclePx[0] - hoverVehicleImg.width / 2),
186
+ Math.floor(hoverVehiclePx[1] - hoverVehicleImg.height / 2),
187
+ );
188
+ }
189
+ return {
190
+ renderedTrajectories,
191
+ };
192
+ };
193
+
194
+ export default renderTrajectories;
@@ -0,0 +1,78 @@
1
+ import { RealtimeAPIDeparturesById } from '../../api/RealtimeAPI';
2
+ import type { RealtimeDepartureExtended } from '../../types';
3
+ import compareDepartures from './compareDepartures';
4
+
5
+ /**
6
+ * This function sort Departures by arrival time and filter out unwanted departures:
7
+ * - when dparture time is in the past
8
+ * - when departure are duplicated
9
+ * - when departure is not in the next 30 min
10
+ *
11
+ * @param {Object} depObject The object containing departures by id.
12
+ * @param {boolean} [sortByMinArrivalTime=false] If true sort departures by arrival time.
13
+ * @return {Array<Departure>} Return departures array.
14
+ * @private
15
+ */
16
+ const sortAndfilterDepartures = (
17
+ depObject: RealtimeAPIDeparturesById,
18
+ sortByMinArrivalTime: boolean = false,
19
+ maxDepartureAge: number = 30,
20
+ ): RealtimeDepartureExtended[] => {
21
+ const departures = Object.keys(depObject).map((k) => depObject[k]);
22
+ departures.sort((a, b) => compareDepartures(a, b, sortByMinArrivalTime));
23
+
24
+ const futureDate = new Date();
25
+ futureDate.setMinutes(futureDate.getMinutes() + maxDepartureAge);
26
+ const future = futureDate.getTime();
27
+
28
+ const pastDate = new Date();
29
+ pastDate.setMinutes(pastDate.getMinutes() - maxDepartureAge);
30
+ const past = pastDate.getTime();
31
+
32
+ const departureArray = [];
33
+ const platformsBoarding: string[] = [];
34
+ let previousDeparture = null;
35
+
36
+ for (let i = departures.length - 1; i >= 0; i -= 1) {
37
+ const departure: RealtimeDepartureExtended = {
38
+ ...departures[i],
39
+ };
40
+ const time = new Date(departure.time).getTime();
41
+
42
+ // Only show departures within the next 30 minutes
43
+ if (time > past && time < future) {
44
+ // If 2 trains are boarding at the same platform,
45
+ // remove the older one.
46
+ if (departure.state === 'BOARDING') {
47
+ if (!platformsBoarding.includes(departure.platform)) {
48
+ platformsBoarding.push(departure.platform);
49
+ } else {
50
+ departure.state = 'HIDDEN';
51
+ }
52
+ }
53
+
54
+ // If two trains with the same line number and destinatin
55
+ // and a departure difference < 1 minute, hide the second one.
56
+ if (
57
+ previousDeparture &&
58
+ departure.to[0] === previousDeparture.to[0] &&
59
+ Math.abs(time - previousDeparture.time) < 1000 &&
60
+ departure.line.name === previousDeparture.line.name
61
+ ) {
62
+ departure.state = 'HIDDEN';
63
+ }
64
+
65
+ if (/(STOP_CANCELLED|JOURNEY_CANCELLED)/.test(departure.state)) {
66
+ departure.cancelled = true;
67
+ }
68
+
69
+ previousDeparture = departure;
70
+ previousDeparture.time = time;
71
+ departureArray.unshift(departure);
72
+ }
73
+ }
74
+
75
+ return departureArray;
76
+ };
77
+
78
+ export default sortAndfilterDepartures;