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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (304) hide show
  1. package/api/RoutingAPI.js +15 -0
  2. package/api/RoutingAPI.test.js +25 -0
  3. package/api/StopsAPI.js +12 -0
  4. package/api/StopsAPI.test.js +22 -0
  5. package/api/TralisAPI.js +359 -0
  6. package/api/TralisAPI.test.js +67 -0
  7. package/{src/api/tralis → api}/TralisAPIUtils.js +2 -32
  8. package/api/index.js +3 -0
  9. package/{index.html → api/typedefs.js} +0 -0
  10. package/common/Tracker.js +93 -0
  11. package/common/api/HttpAPI.js +30 -0
  12. package/common/api/HttpAPI.test.js +50 -0
  13. package/common/api/WebSocketAPI.js +175 -0
  14. package/{src/api/tralis/WebSocketConnector.test.js → common/api/WebSocketAPI.test.js} +100 -145
  15. package/common/controls/Control.js +81 -0
  16. package/{src/common → common}/controls/Control.test.js +32 -43
  17. package/common/index.js +4 -0
  18. package/common/layers/Layer.js +213 -0
  19. package/{src/common → common}/layers/Layer.test.js +185 -244
  20. package/common/mixins/CopyrightMixin.js +24 -0
  21. package/common/mixins/SearchMixin.js +110 -0
  22. package/common/mixins/TralisLayerMixin.js +479 -0
  23. package/common/styles/index.js +4 -0
  24. package/{src/common → common}/styles/trackerDefaultStyle.js +39 -175
  25. package/common/styles/trackerDelayStyle.js +8 -0
  26. package/{src/common → common}/styles/trackerSimpleStyle.js +4 -8
  27. package/{src/common → common}/trackerConfig.js +61 -99
  28. package/common/trackerConfig.test.js +23 -0
  29. package/{src/doc/examples/ol-mapbox-layer.md → common/typedefs.js} +0 -0
  30. package/common/utils/createTrackerFilters.js +56 -0
  31. package/common/utils/createTrackerFilters.test.js +79 -0
  32. package/{src/common → common}/utils/getMapboxMapCopyrights.js +3 -16
  33. package/common/utils/getMapboxMapCopyrights.test.js +40 -0
  34. package/{src/common → common}/utils/getMapboxStyleUrl.js +3 -13
  35. package/{src/common → common}/utils/getVehiclePosition.js +3 -33
  36. package/common/utils/index.js +5 -0
  37. package/common/utils/removeDuplicate.js +8 -0
  38. package/common/utils/removeDuplicate.test.js +19 -0
  39. package/{src/common → common}/utils/sortByDelay.js +2 -7
  40. package/common/utils/timeUtils.js +20 -0
  41. package/common/utils/timeUtils.test.js +10 -0
  42. package/index.js +8 -0
  43. package/mapbox/controls/CopyrightControl.js +29 -0
  44. package/mapbox/controls/index.js +1 -0
  45. package/mapbox/index.js +4 -0
  46. package/mapbox/layers/Layer.js +57 -0
  47. package/mapbox/layers/Layer.test.js +182 -0
  48. package/mapbox/layers/TralisLayer.js +182 -0
  49. package/{src/mapbox → mapbox}/layers/TralisLayer.test.js +12 -14
  50. package/mapbox/layers/index.js +2 -0
  51. package/{src/mapbox → mapbox}/utils.js +7 -21
  52. package/mbt.js +50444 -0
  53. package/mbt.js.map +7 -0
  54. package/mbt.min.js +1005 -0
  55. package/mbt.min.js.map +7 -0
  56. package/ol/controls/CopyrightControl.js +42 -0
  57. package/ol/controls/CopyrightControl.test.js +165 -0
  58. package/ol/controls/RoutingControl.js +387 -0
  59. package/ol/controls/RoutingControl.test.js +151 -0
  60. package/ol/controls/StopFinderControl.js +10 -0
  61. package/ol/controls/StopFinderControl.test.js +48 -0
  62. package/ol/controls/index.js +3 -0
  63. package/ol/index.js +5 -0
  64. package/ol/layers/Layer.js +88 -0
  65. package/ol/layers/Layer.test.js +174 -0
  66. package/ol/layers/MapboxLayer.js +203 -0
  67. package/{src/ol → ol}/layers/MapboxLayer.test.js +58 -84
  68. package/ol/layers/MapboxStyleLayer.js +187 -0
  69. package/{src/ol → ol}/layers/MapboxStyleLayer.test.js +97 -128
  70. package/ol/layers/MaplibreLayer.js +139 -0
  71. package/ol/layers/RoutingLayer.js +61 -0
  72. package/{src/ol → ol}/layers/RoutingLayer.test.js +15 -24
  73. package/ol/layers/TralisLayer.js +185 -0
  74. package/ol/layers/TralisLayer.test.js +79 -0
  75. package/ol/layers/VectorLayer.js +22 -0
  76. package/{src/ol → ol}/layers/VectorLayer.test.js +34 -45
  77. package/ol/layers/WMSLayer.js +38 -0
  78. package/ol/layers/WMSLayer.test.js +76 -0
  79. package/ol/layers/index.js +8 -0
  80. package/{src/ol → ol}/styles/fullTrajectoryDelayStyle.js +11 -15
  81. package/ol/styles/fullTrajectoryStyle.js +43 -0
  82. package/ol/styles/index.js +2 -0
  83. package/package.json +34 -74
  84. package/.babelrc +0 -6
  85. package/.esdoc.json +0 -17
  86. package/.eslintignore +0 -1
  87. package/.github/workflows/conventional-pr-title.yml +0 -21
  88. package/.github/workflows/cypress.yml +0 -29
  89. package/.github/workflows/nodejs.yml +0 -28
  90. package/.husky/commit-msg +0 -4
  91. package/.husky/post-checkout +0 -4
  92. package/.husky/post-merge +0 -4
  93. package/.husky/post-rebase +0 -4
  94. package/.husky/pre-commit +0 -4
  95. package/.neutrinorc.js +0 -176
  96. package/.nvmrc +0 -1
  97. package/CHANGELOG.md +0 -10
  98. package/LICENSE +0 -21
  99. package/__mocks__/mapbox-gl.js +0 -81
  100. package/__mocks__/maplibre-gl.js +0 -81
  101. package/commitlint.config.js +0 -1
  102. package/cypress/fixtures/example.json +0 -5
  103. package/cypress/integration/examples/api.spec.js +0 -7
  104. package/cypress/integration/examples/examples.spec.js +0 -7
  105. package/cypress/integration/examples/navigation.spec.js +0 -29
  106. package/cypress/plugins/index.js +0 -21
  107. package/cypress/support/commands.js +0 -25
  108. package/cypress/support/index.js +0 -20
  109. package/cypress.json +0 -4
  110. package/data/fetchRoute.json +0 -292
  111. package/data/fetchTrajectories.json +0 -18
  112. package/data/fetchTrajectoryById.json +0 -3
  113. package/data/fetchTrajectoryStations.json +0 -18
  114. package/data/stopsSearch.json +0 -15
  115. package/documentation.yml +0 -4
  116. package/esdoc/README.md +0 -27
  117. package/esdoc/plugins/MyPlugin.js +0 -69
  118. package/esdoc/plugins/dynamic-property-plugin/Plugin.js +0 -50
  119. package/esdoc/plugins/externals-plugin/Plugin.js +0 -45
  120. package/esdoc/plugins/externals-plugin/externals.js +0 -96
  121. package/global-setup.js +0 -3
  122. package/indexweb.html +0 -49
  123. package/jest.config.js +0 -5
  124. package/pull_request_template.md +0 -17
  125. package/renovate.json +0 -4
  126. package/scripts/read-pkg-json.js +0 -22
  127. package/src/api/index.js +0 -3
  128. package/src/api/routing/RoutingAPI.js +0 -44
  129. package/src/api/routing/RoutingAPI.test.js +0 -41
  130. package/src/api/stops/StopsAPI.js +0 -41
  131. package/src/api/stops/StopsAPI.test.js +0 -34
  132. package/src/api/tralis/TralisAPI.js +0 -731
  133. package/src/api/tralis/TralisAPI.test.js +0 -75
  134. package/src/api/tralis/WebSocketConnector.js +0 -338
  135. package/src/api/tralis/typedefs.js +0 -81
  136. package/src/assets/Lato-Black.ttf +0 -0
  137. package/src/assets/Lato-BlackItalic.ttf +0 -0
  138. package/src/assets/Lato-Bold.ttf +0 -0
  139. package/src/assets/Lato-BoldItalic.ttf +0 -0
  140. package/src/assets/Lato-Italic.ttf +0 -0
  141. package/src/assets/Lato-Light.ttf +0 -0
  142. package/src/assets/Lato-LightItalic.ttf +0 -0
  143. package/src/assets/Lato-Regular.ttf +0 -0
  144. package/src/assets/Lato-Thin.ttf +0 -0
  145. package/src/assets/Lato-ThinItalic.ttf +0 -0
  146. package/src/assets/OFL.txt +0 -93
  147. package/src/common/Tracker.js +0 -197
  148. package/src/common/api/api.js +0 -64
  149. package/src/common/api/api.test.js +0 -68
  150. package/src/common/controls/Control.js +0 -146
  151. package/src/common/index.js +0 -5
  152. package/src/common/layers/Layer.js +0 -404
  153. package/src/common/mixins/CopyrightMixin.js +0 -48
  154. package/src/common/mixins/SearchMixin.js +0 -176
  155. package/src/common/mixins/TralisLayerMixin.js +0 -930
  156. package/src/common/styles/index.js +0 -4
  157. package/src/common/styles/trackerDelayStyle.js +0 -17
  158. package/src/common/trackerConfig.test.js +0 -25
  159. package/src/common/typedefs.js +0 -23
  160. package/src/common/utils/createTrackerFilters.js +0 -87
  161. package/src/common/utils/createTrackerFilters.test.js +0 -95
  162. package/src/common/utils/getMapboxMapCopyrights.test.js +0 -47
  163. package/src/common/utils/index.js +0 -5
  164. package/src/common/utils/removeDuplicate.js +0 -22
  165. package/src/common/utils/removeDuplicate.test.js +0 -22
  166. package/src/common/utils/timeUtils.js +0 -44
  167. package/src/common/utils/timeUtils.test.js +0 -16
  168. package/src/doc/App.js +0 -116
  169. package/src/doc/App.scss +0 -51
  170. package/src/doc/_redirects +0 -2
  171. package/src/doc/components/CodeSandboxButton.js +0 -103
  172. package/src/doc/components/Documentation.js +0 -40
  173. package/src/doc/components/Esdoc/Anchor.js +0 -57
  174. package/src/doc/components/Esdoc/ClassDoc.js +0 -272
  175. package/src/doc/components/Esdoc/DeprecatedHTML.js +0 -16
  176. package/src/doc/components/Esdoc/DetailDocs.js +0 -281
  177. package/src/doc/components/Esdoc/DetailHTML.js +0 -33
  178. package/src/doc/components/Esdoc/DirectSubclassHTML.js +0 -30
  179. package/src/doc/components/Esdoc/DocBuilderUtils.js +0 -694
  180. package/src/doc/components/Esdoc/DocLinkHTML.js +0 -62
  181. package/src/doc/components/Esdoc/DocsLinkHTML.js +0 -38
  182. package/src/doc/components/Esdoc/Esdoc.js +0 -63
  183. package/src/doc/components/Esdoc/EsdocContent.js +0 -51
  184. package/src/doc/components/Esdoc/EsdocNavigation.js +0 -13
  185. package/src/doc/components/Esdoc/EsdocSearch.js +0 -81
  186. package/src/doc/components/Esdoc/ExperimentalHTML.js +0 -17
  187. package/src/doc/components/Esdoc/ExtendsChainHTML.js +0 -32
  188. package/src/doc/components/Esdoc/FileDocLinkHTML.js +0 -60
  189. package/src/doc/components/Esdoc/IdentifiersDoc.js +0 -113
  190. package/src/doc/components/Esdoc/IndirectSubclassHTML.js +0 -30
  191. package/src/doc/components/Esdoc/InheritedSummaryDoc.js +0 -70
  192. package/src/doc/components/Esdoc/InheritedSummaryHTML.js +0 -38
  193. package/src/doc/components/Esdoc/MixinClassesHTML.js +0 -29
  194. package/src/doc/components/Esdoc/NavDoc.js +0 -112
  195. package/src/doc/components/Esdoc/OverrideMethod.js +0 -44
  196. package/src/doc/components/Esdoc/OverrideMethodDescription.js +0 -35
  197. package/src/doc/components/Esdoc/Properties.js +0 -89
  198. package/src/doc/components/Esdoc/README.md +0 -45
  199. package/src/doc/components/Esdoc/SignatureHTML.js +0 -123
  200. package/src/doc/components/Esdoc/SingleDoc.js +0 -31
  201. package/src/doc/components/Esdoc/SummaryDoc.js +0 -160
  202. package/src/doc/components/Esdoc/SummaryHTML.js +0 -96
  203. package/src/doc/components/Esdoc/TypeDocLinkHTML.js +0 -249
  204. package/src/doc/components/Esdoc/css/identifiers.css +0 -38
  205. package/src/doc/components/Esdoc/css/search.css +0 -76
  206. package/src/doc/components/Esdoc/css/style.css +0 -603
  207. package/src/doc/components/Esdoc/index.js +0 -7
  208. package/src/doc/components/Example.js +0 -153
  209. package/src/doc/components/Examples.js +0 -183
  210. package/src/doc/components/Home.js +0 -106
  211. package/src/doc/components/TrackerExample.js +0 -38
  212. package/src/doc/examples/assets/tralis-live-map/index.js +0 -11
  213. package/src/doc/examples/assets/tralis-live-map/s1kreis.svg +0 -105
  214. package/src/doc/examples/assets/tralis-live-map/s20kreis.svg +0 -101
  215. package/src/doc/examples/assets/tralis-live-map/s2kreis.svg +0 -95
  216. package/src/doc/examples/assets/tralis-live-map/s3kreis.svg +0 -95
  217. package/src/doc/examples/assets/tralis-live-map/s4kreis.svg +0 -95
  218. package/src/doc/examples/assets/tralis-live-map/s6kreis.svg +0 -95
  219. package/src/doc/examples/assets/tralis-live-map/s7kreis.svg +0 -95
  220. package/src/doc/examples/assets/tralis-live-map/s8kreis.svg +0 -93
  221. package/src/doc/examples/assets/tralis-live-map/unknown.svg +0 -107
  222. package/src/doc/examples/mb-copyright.html +0 -26
  223. package/src/doc/examples/mb-copyright.js +0 -37
  224. package/src/doc/examples/mb-tracker.html +0 -1
  225. package/src/doc/examples/mb-tracker.js +0 -39
  226. package/src/doc/examples/mb-tracker.md +0 -1
  227. package/src/doc/examples/mb-tralis.html +0 -1
  228. package/src/doc/examples/mb-tralis.js +0 -34
  229. package/src/doc/examples/ol-copyright.html +0 -26
  230. package/src/doc/examples/ol-copyright.js +0 -43
  231. package/src/doc/examples/ol-mapbox-layer.html +0 -1
  232. package/src/doc/examples/ol-mapbox-layer.js +0 -28
  233. package/src/doc/examples/ol-mapbox-style-layer.html +0 -12
  234. package/src/doc/examples/ol-mapbox-style-layer.js +0 -44
  235. package/src/doc/examples/ol-query.html +0 -32
  236. package/src/doc/examples/ol-query.js +0 -83
  237. package/src/doc/examples/ol-routing.html +0 -26
  238. package/src/doc/examples/ol-routing.js +0 -59
  239. package/src/doc/examples/ol-routing.md +0 -1
  240. package/src/doc/examples/ol-stop-finder.html +0 -15
  241. package/src/doc/examples/ol-stop-finder.js +0 -31
  242. package/src/doc/examples/ol-stop-finder.md +0 -1
  243. package/src/doc/examples/ol-tracker.html +0 -1
  244. package/src/doc/examples/ol-tracker.js +0 -44
  245. package/src/doc/examples/ol-tracker.md +0 -1
  246. package/src/doc/examples/ol-tralis.html +0 -5
  247. package/src/doc/examples/ol-tralis.js +0 -57
  248. package/src/doc/examples/tralis-live-map.html +0 -1
  249. package/src/doc/examples/tralis-live-map.js +0 -51
  250. package/src/doc/examples/tralis-live-map.md +0 -3
  251. package/src/doc/examples.js +0 -107
  252. package/src/doc/img/examples/live_tracker_mb.jpg +0 -0
  253. package/src/doc/img/examples/live_tracker_munich.jpg +0 -0
  254. package/src/doc/img/examples/live_tracker_ol.jpg +0 -0
  255. package/src/doc/img/examples/mapbox.jpg +0 -0
  256. package/src/doc/img/examples/mapbox_style.jpg +0 -0
  257. package/src/doc/img/examples/ol-copyright.png +0 -0
  258. package/src/doc/img/examples/query_objects.jpg +0 -0
  259. package/src/doc/img/examples/routing.jpg +0 -0
  260. package/src/doc/img/examples/simple_map.jpg +0 -0
  261. package/src/doc/img/examples/stops.jpg +0 -0
  262. package/src/doc/img/favico.ico +0 -0
  263. package/src/doc/index.js +0 -21
  264. package/src/iife.js +0 -7
  265. package/src/index.js +0 -10
  266. package/src/mapbox/controls/CopyrightControl.js +0 -58
  267. package/src/mapbox/controls/index.js +0 -2
  268. package/src/mapbox/index.js +0 -4
  269. package/src/mapbox/layers/Layer.js +0 -118
  270. package/src/mapbox/layers/Layer.test.js +0 -202
  271. package/src/mapbox/layers/TralisLayer.js +0 -329
  272. package/src/mapbox/layers/index.js +0 -2
  273. package/src/ol/README.md +0 -0
  274. package/src/ol/controls/CopyrightControl.js +0 -80
  275. package/src/ol/controls/CopyrightControl.test.js +0 -211
  276. package/src/ol/controls/RoutingControl.js +0 -752
  277. package/src/ol/controls/RoutingControl.test.js +0 -216
  278. package/src/ol/controls/StopFinderControl.js +0 -38
  279. package/src/ol/controls/StopFinderControl.test.js +0 -59
  280. package/src/ol/controls/index.js +0 -3
  281. package/src/ol/controls/snapshots/RoutingControlRouteGen10.json +0 -58
  282. package/src/ol/controls/snapshots/RoutingControlRouteGen100.json +0 -292
  283. package/src/ol/controls/snapshots/RoutingControlRouteGen30.json +0 -69
  284. package/src/ol/controls/snapshots/RoutingControlRouteGen5.json +0 -58
  285. package/src/ol/controls/snapshots/RoutingControlRouteOSM.json +0 -759
  286. package/src/ol/controls/snapshots/RoutingControlStation1.json +0 -60
  287. package/src/ol/controls/snapshots/RoutingControlStation2.json +0 -49
  288. package/src/ol/index.js +0 -5
  289. package/src/ol/layers/Layer.js +0 -193
  290. package/src/ol/layers/Layer.test.js +0 -197
  291. package/src/ol/layers/MapboxLayer.js +0 -378
  292. package/src/ol/layers/MapboxStyleLayer.js +0 -417
  293. package/src/ol/layers/MaplibreLayer.js +0 -280
  294. package/src/ol/layers/RoutingLayer.js +0 -91
  295. package/src/ol/layers/TralisLayer.js +0 -359
  296. package/src/ol/layers/TralisLayer.test.js +0 -97
  297. package/src/ol/layers/VectorLayer.js +0 -43
  298. package/src/ol/layers/WMSLayer.js +0 -80
  299. package/src/ol/layers/WMSLayer.test.js +0 -84
  300. package/src/ol/layers/index.js +0 -8
  301. package/src/ol/styles/fullTrajectoryStyle.js +0 -51
  302. package/src/ol/styles/index.js +0 -2
  303. package/src/setupTests.js +0 -15
  304. package/webpack.config.js +0 -6
@@ -1,752 +0,0 @@
1
- import { Feature } from 'ol';
2
- import { LineString, Point } from 'ol/geom';
3
- import { Modify } from 'ol/interaction';
4
- import { unByKey } from 'ol/Observable';
5
- import { click } from 'ol/events/condition';
6
- import { GeoJSON } from 'ol/format';
7
- import { buffer } from 'ol/extent';
8
- import { fromLonLat, toLonLat } from 'ol/proj';
9
- import RoutingAPI from '../../api/routing/RoutingAPI';
10
- import Control from '../../common/controls/Control';
11
- import RoutingLayer from '../layers/RoutingLayer';
12
-
13
- // Examples for a single hop:
14
- // basel sbb a station named "basel sbb"
15
- // ZUE, station "Zürich HB" by its common abbreviation
16
- // Zürich Hauptbahnhof or HBF Zürich are all valid synonyms für "Zürich HB"
17
- // @47.37811,8.53935 a station at position 47.37811, 8.53935
18
- // @47.37811,8.53935$4 track 4 in a station at position 47.37811, 8.53935
19
- // zürich hb@47.37811,8.53935$8 track 8 in station "Zürich HB" at position 47.37811, 8.53935
20
- const REGEX_VIA_POINT =
21
- /^([^@$!\n]*)(@?([\d.]+),([\d.]+))?(\$?([a-zA-Z0-9]{0,2}))$/;
22
-
23
- // Examples for a single hop:
24
- //
25
- // 47.37811,8.53935 a position 47.37811, 8.53935
26
- const REGEX_VIA_POINT_COORD = /^([\d.]+),([\d.]+)$/;
27
-
28
- // Examples for a single hop:
29
- //
30
- // !8596126 a station with id 8596126
31
- // !8596126$4 a station with id 8596126
32
- const REGEX_VIA_POINT_STATION_ID = /^!([^$]*)(\$?([a-zA-Z0-9]{0,2}))$/;
33
-
34
- const STOP_FETCH_ABORT_CONTROLLER_KEY = 'stop-fetch';
35
-
36
- const getFlatCoordinatesFromSegments = (segmentArray) => {
37
- const coords = [];
38
- segmentArray.forEach((seg) => {
39
- coords.push(...seg.getGeometry().getCoordinates());
40
- });
41
- return coords;
42
- };
43
-
44
- /**
45
- * Display a route of a specified mean of transport.
46
- *
47
- * @example
48
- * import { Map } from 'ol';
49
- * import { RoutingControl } from 'mobility-toolbox-js/ol';
50
- *
51
- * const map = new Map({
52
- * target: 'map'
53
- * });
54
- *
55
- * const control = new RoutingControl();
56
- *
57
- * control.map = map
58
- *
59
- * @classproperty {string} apiKey - Key used for RoutingApi requests.
60
- * @classproperty {string} stopsApiKey - Key used for Stop lookup requests (defaults to apiKey).
61
- * @classproperty {string} stopsApiUrl - Url used for Stop lookup requests (defaults to https://api.geops.io/stops/v1/lookup/).
62
- * @classproperty {Array.<Array<graph="osm", minZoom=0, maxZoom=99>>} graphs - Array of routing graphs and min/max zoom levels. If you use the control in combination with the [geOps Maps API](https://developer.geops.io/apis/maps/), you may want to use the optimal level of generalizations: "[['gen4', 0, 8], ['gen3', 8, 9], ['gen2', 9, 11], ['gen1', 11, 13], ['osm', 13, 99]]"
63
- * @classproperty {string} mot - Mean of transport to be used for routing.
64
- * @classproperty {object} routingApiParams - object of additional parameters to pass to the routing api request.
65
- * @classproperty {object} snapToClosestStation - If true, the routing will snap the coordinate to the closest station. Default to false.
66
- * @classproperty {boolean} useRawViaPoints - Experimental property. Wen true, it allows the user to add via points using different kind of string. See "via" parameter defined by the [geOps Routing API](https://developer.geops.io/apis/routing/). Default to false, only array of coordinates and station's id are supported as via points.
67
- * @classproperty {RoutingLayer|Layer} routingLayer - Layer for adding route features.
68
- * @classproperty {function} onRouteError - Callback on error.
69
- * @classproperty {boolean} loading - True if the control is requesting the backend.
70
- * @see <a href="/example/ol-routing">Openlayers routing example</a>
71
- *
72
- * @extends {Control}
73
- * @implements {RoutingInterface}
74
- */
75
- class RoutingControl extends Control {
76
- constructor(options = {}) {
77
- super(options);
78
-
79
- Object.defineProperties(this, {
80
- mot: {
81
- get: () => this.get('mot'),
82
- set: (newMot) => {
83
- if (newMot) {
84
- this.set('mot', newMot);
85
- if (this.viaPoints) {
86
- this.drawRoute();
87
- }
88
- }
89
- },
90
- },
91
- loading: {
92
- get: () => this.get('loading'),
93
- set: (newLoading) => {
94
- this.set('loading', newLoading);
95
- },
96
- },
97
- modify: {
98
- get: () => this.get('modify'),
99
- set: (modify) => {
100
- this.set('modify', modify);
101
- },
102
- },
103
- });
104
-
105
- /** True if the control is requesting the backend. */
106
- this.loading = false;
107
-
108
- /** @ignore */
109
- this.graphs = options.graphs || [['osm', 0, 99]];
110
-
111
- /** @ignore */
112
- this.mot = options.mot || 'bus';
113
-
114
- /** @ignore */
115
- this.modify = options.modify !== false;
116
-
117
- /** @ignore */
118
- this.routingApiParams = options.routingApiParams || {};
119
-
120
- /** @ignore */
121
- this.useRawViaPoints = options.useRawViaPoints || false;
122
-
123
- /** @ignore */
124
- this.snapToClosestStation = options.snapToClosestStation || false;
125
-
126
- /** @ignore */
127
- this.cacheStationData = {};
128
-
129
- /** @ignore */
130
- this.abortControllers = [];
131
-
132
- /** @ignore */
133
- this.apiKey = options.apiKey;
134
-
135
- /** @ignore */
136
- this.stopsApiKey = options.stopsApiKey || this.apiKey;
137
-
138
- /** @ignore */
139
- this.segments = [];
140
-
141
- /** @ignore */
142
- this.stopsApiUrl = options.stopsApiUrl || 'https://api.geops.io/stops/v1/';
143
-
144
- /** @ignore */
145
- this.api = new RoutingAPI({
146
- url: options.url,
147
- apiKey: this.apiKey,
148
- mot: options.mot,
149
- });
150
-
151
- /** @ignore */
152
- this.routingLayer =
153
- options.routingLayer ||
154
- new RoutingLayer({
155
- name: 'routing-layer',
156
- style: options.style,
157
- });
158
-
159
- /** @ignore */
160
- this.onRouteError =
161
- options.onRouteError ||
162
- ((error) => {
163
- this.dispatchEvent({
164
- type: 'change:route',
165
- target: this,
166
- });
167
- this.reset();
168
- // eslint-disable-next-line no-console
169
- console.error(error);
170
- });
171
-
172
- /** @ignore */
173
- this.viaPoints = [];
174
-
175
- /** @ignore */
176
- this.onMapClick = this.onMapClick.bind(this);
177
-
178
- /** @ignore */
179
- this.onModifyEnd = this.onModifyEnd.bind(this);
180
-
181
- /** @ignore */
182
- this.onModifyStart = this.onModifyStart.bind(this);
183
-
184
- /** @ignore */
185
- this.apiChangeListener = () => this.drawRoute();
186
-
187
- /** @ignore */
188
- this.createModifyInteraction();
189
- }
190
-
191
- /**
192
- * Calculate at which resolutions corresponds each generalizations.
193
- *
194
- * @private
195
- */
196
- static getGraphsResolutions(graphs, map) {
197
- const view = map.getView();
198
- return graphs.map(([, minZoom, maxZoom]) => [
199
- view.getResolutionForZoom(minZoom),
200
- view.getResolutionForZoom(maxZoom || minZoom + 1),
201
- ]);
202
- }
203
-
204
- /**
205
- * Adds/Replaces a viaPoint to the viaPoints array and redraws route:
206
- * Adds a viaPoint at end of array by default.
207
- * If an index is passed a viaPoint is added at the specified index.
208
- * If an index is passed and overwrite x is > 0, x viaPoints at the specified
209
- * index are replaced with a single new viaPoint.
210
- * @param {Array<number>} coordinates Array of coordinates
211
- * @param {number} index Integer representing the index of the added viaPoint.
212
- * @param {number} [overwrite=0] Marks the number of viaPoints that are removed at the specified index on add.
213
- */
214
- addViaPoint(
215
- coordinatesOrString,
216
- index = this.viaPoints.length,
217
- overwrite = 0,
218
- ) {
219
- /* Add/Insert/Overwrite viapoint and redraw route */
220
- this.viaPoints.splice(index, overwrite, coordinatesOrString);
221
- this.drawRoute();
222
- this.dispatchEvent({
223
- type: 'change:route',
224
- target: this,
225
- });
226
- }
227
-
228
- /**
229
- * Removes a viaPoint at the passed array index and redraws route
230
- * By default the last viaPoint is removed.
231
- * @param {number} index Integer representing the index of the viaPoint to delete.
232
- */
233
- removeViaPoint(index = this.viaPoints.length - 1) {
234
- /* Remove viapoint and redraw route */
235
- if (this.viaPoints.length && this.viaPoints[index]) {
236
- this.viaPoints.splice(index, 1);
237
- }
238
- this.drawRoute();
239
- this.dispatchEvent({
240
- type: 'change:route',
241
- target: this,
242
- });
243
- }
244
-
245
- /**
246
- * Replaces the current viaPoints with a new coordinate array.
247
- * @param {Array<Array<number>>} coordinateArray Array of nested coordinates
248
- */
249
- setViaPoints(coordinateArray) {
250
- this.viaPoints = [...coordinateArray];
251
- this.drawRoute();
252
- this.dispatchEvent({
253
- type: 'change:route',
254
- target: this,
255
- });
256
- }
257
-
258
- /**
259
- * Removes all viaPoints, clears the source and triggers a change event
260
- */
261
- reset() {
262
- // Clear viaPoints and source
263
- this.abortRequests();
264
- this.viaPoints = [];
265
- this.routingLayer.olLayer.getSource().clear();
266
- this.dispatchEvent({
267
- type: 'change:route',
268
- target: this,
269
- });
270
- }
271
-
272
- /**
273
- * Aborts viapoint and route requests
274
- * @private
275
- */
276
- abortRequests() {
277
- // Abort Routing API requests
278
- this.graphs.forEach(([graph]) => {
279
- if (this.abortControllers[graph]) {
280
- this.abortControllers[graph].abort();
281
- }
282
- this.abortControllers[graph] = new AbortController();
283
- });
284
-
285
- // Abort Stops API requests
286
- this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY]?.abort();
287
- this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY] =
288
- new AbortController();
289
-
290
- this.loading = false;
291
- }
292
-
293
- /**
294
- * Draws route on map using an array of coordinates:
295
- * If a single coordinate is passed a single point feature is added to map.
296
- * If two or more coordinates are passed a request to the RoutingAPI fetches
297
- * the route using the passed coordinates and the current mot.
298
- * @private
299
- */
300
- drawRoute() {
301
- /* Calls RoutingAPI to draw a route using the viaPoints array */
302
- this.abortRequests();
303
- this.routingLayer.olLayer.getSource().clear();
304
-
305
- if (!this.viaPoints.length) {
306
- return null;
307
- }
308
-
309
- if (this.viaPoints.length === 1) {
310
- // Add point for first node
311
- return this.drawViaPoint(
312
- this.viaPoints[0],
313
- 0,
314
- this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY],
315
- );
316
- }
317
-
318
- const formattedViaPoints = this.viaPoints.map((viaPoint) => {
319
- if (Array.isArray(viaPoint)) {
320
- const projection = this.map.getView().getProjection();
321
- // viaPoint is a coordinate
322
- // Coordinates need to be reversed as required by the backend RoutingAPI
323
- const [lon, lat] = toLonLat(viaPoint, projection);
324
- return this.snapToClosestStation ? [`@${lat}`, lon] : [lat, lon];
325
- }
326
-
327
- // viaPoint is a string to use as it is
328
- return this.useRawViaPoints ? viaPoint : `!${viaPoint}`;
329
- });
330
-
331
- this.loading = true;
332
-
333
- // Clear source
334
- this.routingLayer.olLayer.getSource().clear();
335
-
336
- // Create point features for the viaPoints
337
- this.viaPoints.forEach((viaPoint, idx) =>
338
- this.drawViaPoint(
339
- viaPoint,
340
- idx,
341
- this.abortControllers[STOP_FETCH_ABORT_CONTROLLER_KEY],
342
- ),
343
- );
344
-
345
- return Promise.all(
346
- this.graphs.map(([graph], index) => {
347
- return this.api
348
- .route(
349
- {
350
- graph,
351
- via: `${formattedViaPoints.join('|')}`,
352
- mot: `${this.mot}`,
353
- 'resolve-hops': false,
354
- elevation: false,
355
- 'coord-radius': 100.0,
356
- 'coord-punish': 1000.0,
357
- ...this.routingApiParams,
358
- },
359
- this.abortControllers[graph],
360
- )
361
- .then((featureCollection) => {
362
- this.segments = this.format.readFeatures(featureCollection);
363
-
364
- if (this.mot === 'foot') {
365
- // Extract unique values from viaPoint target value
366
- const uniqueVias = this.segments.reduce(
367
- (resultVias, currentFeat) => {
368
- const segTrg = currentFeat.get('trg');
369
- return resultVias.find(
370
- (via) => via[0] === segTrg[0] && via[1] === segTrg[1],
371
- )
372
- ? resultVias
373
- : [...resultVias, segTrg];
374
- },
375
- [],
376
- );
377
-
378
- // Create LineString features from segments with same unique value
379
- this.segments = uniqueVias.map((via) => {
380
- const viaSegments = this.segments.filter((seg) => {
381
- const segTrg = seg.get('trg');
382
- return segTrg[0] === via[0] && segTrg[1] === via[1];
383
- });
384
-
385
- const coords = getFlatCoordinatesFromSegments(viaSegments);
386
- return new Feature({
387
- geometry: new LineString(coords),
388
- });
389
- });
390
- }
391
-
392
- // Create the new route. This route will be modifiable by the Modifiy interaction.
393
- const coords = getFlatCoordinatesFromSegments(this.segments);
394
-
395
- const routeFeature = new Feature({
396
- geometry: new LineString(coords),
397
- });
398
- routeFeature.set('graph', graph);
399
- routeFeature.set('mot', this.mot);
400
- routeFeature.set('minResolution', this.graphsResolutions[index][0]);
401
- routeFeature.set('maxResolution', this.graphsResolutions[index][1]);
402
- this.routingLayer.olLayer.getSource().addFeature(routeFeature);
403
- this.loading = false;
404
- })
405
- .catch((error) => {
406
- if (error.name === 'AbortError') {
407
- // Ignore abort error
408
- return;
409
- }
410
- this.segments = [];
411
- // Dispatch error event and execute error function
412
- this.dispatchEvent({
413
- type: 'error',
414
- target: this,
415
- });
416
- this.onRouteError(error, this);
417
- this.loading = false;
418
- });
419
- }),
420
- );
421
- }
422
-
423
- /**
424
- * Draw a via point. This function can parse all the possibilitiies
425
- *
426
- * @private
427
- */
428
- drawViaPoint(viaPoint, idx, abortController) {
429
- const pointFeature = new Feature();
430
- pointFeature.set('viaPointIdx', idx);
431
-
432
- // The via point is a coordinate using the current map's projection
433
- if (Array.isArray(viaPoint)) {
434
- pointFeature.setGeometry(new Point(viaPoint));
435
- this.routingLayer.olLayer.getSource().addFeature(pointFeature);
436
- return Promise.resolve(pointFeature);
437
- }
438
-
439
- // Possibility to parse:
440
- //
441
- // !8596126 a station with id 8596126
442
- // !8596126$4 a station with id 8596126
443
- if (!this.useRawViaPoints || REGEX_VIA_POINT_STATION_ID.test(viaPoint)) {
444
- let stationId;
445
- let track;
446
- if (this.useRawViaPoints) {
447
- [, stationId, , track] = REGEX_VIA_POINT_STATION_ID.exec(viaPoint);
448
- } else {
449
- [stationId, track] = viaPoint.split('$');
450
- }
451
-
452
- return fetch(
453
- `${this.stopsApiUrl}lookup/${stationId}?key=${this.stopsApiKey}`,
454
- { signal: abortController.signal },
455
- )
456
- .then((res) => res.json())
457
- .then((stationData) => {
458
- const { coordinates } = stationData.features[0].geometry;
459
- this.cacheStationData[viaPoint] = fromLonLat(coordinates);
460
- pointFeature.set('viaPointTrack', track);
461
- pointFeature.setGeometry(new Point(fromLonLat(coordinates)));
462
- this.routingLayer.olLayer.getSource().addFeature(pointFeature);
463
- return pointFeature;
464
- })
465
- .catch((error) => {
466
- if (error.name === 'AbortError') {
467
- // Ignore abort error
468
- return;
469
- }
470
- // Dispatch error event and execute error function
471
- this.dispatchEvent({
472
- type: 'error',
473
- target: this,
474
- });
475
- this.onRouteError(error, this);
476
- this.loading = false;
477
- });
478
- }
479
-
480
- // Only when this.useRawViaPoints is true.
481
- // Possibility to parse:
482
- //
483
- // 47.37811,8.53935 a position 47.37811, 8.53935
484
- if (this.useRawViaPoints && REGEX_VIA_POINT_COORD.test(viaPoint)) {
485
- const [lat, lon] = REGEX_VIA_POINT_COORD.exec(viaPoint);
486
- const coordinates = fromLonLat(
487
- [parseFloat(lon), parseFloat(lat)],
488
- this.map.getView().getProjection(),
489
- );
490
- pointFeature.setGeometry(new Point(coordinates));
491
- this.routingLayer.olLayer.getSource().addFeature(pointFeature);
492
- return Promise.resolve(pointFeature);
493
- }
494
-
495
- // Only when this.useRawViaPoints is true.
496
- // It will parse the via point to find some name, id, track coordinates.
497
- //
498
- // Possibility to parse:
499
- //
500
- // @47.37811,8.53935 a station at position 47.37811, 8.53935
501
- // @47.37811,8.53935$4 track 4 in a station at position 47.37811, 8.53935
502
- // zürich hb@47.37811,8.53935$8 track 8 in station "Zürich HB" at position 47.37811, 8.53935
503
- const [, stationName, , lat, lon, , track] = REGEX_VIA_POINT.exec(viaPoint);
504
-
505
- if (lon && lat) {
506
- const coordinates = fromLonLat(
507
- [parseFloat(lon), parseFloat(lat)],
508
- this.map.getView().getProjection(),
509
- );
510
- pointFeature.set('viaPointTrack', track);
511
- pointFeature.setGeometry(new Point(coordinates));
512
- this.routingLayer.olLayer.getSource().addFeature(pointFeature);
513
- return Promise.resolve(pointFeature);
514
- }
515
-
516
- if (stationName) {
517
- return fetch(
518
- `${this.stopsApiUrl}?key=${this.stopsApiKey}&q=${stationName}&limit=1`,
519
- { signal: abortController.signal },
520
- )
521
- .then((res) => res.json())
522
- .then((stationData) => {
523
- const { coordinates } = stationData.features[0].geometry;
524
- this.cacheStationData[viaPoint] = fromLonLat(coordinates);
525
- pointFeature.set('viaPointTrack', track);
526
- pointFeature.setGeometry(new Point(fromLonLat(coordinates)));
527
- this.routingLayer.olLayer.getSource().addFeature(pointFeature);
528
- return pointFeature;
529
- })
530
- .catch((error) => {
531
- // Dispatch error event and execute error function
532
- this.dispatchEvent({
533
- type: 'error',
534
- target: this,
535
- });
536
- this.onRouteError(error, this);
537
- this.loading = false;
538
- return null;
539
- });
540
- }
541
- return Promise.resolve(null);
542
- }
543
-
544
- /**
545
- * Used on click on map while control is active:
546
- * By default adds a viaPoint to the end of array.
547
- * If an existing viaPoint is clicked removes the clicked viaPoint.
548
- * @private
549
- */
550
- onMapClick(e) {
551
- const feats = e.target.getFeaturesAtPixel(e.pixel);
552
- const viaPoint = feats.find(
553
- (feat) =>
554
- feat.getGeometry() instanceof Point &&
555
- feat.get('viaPointIdx') !== undefined,
556
- );
557
-
558
- if (viaPoint) {
559
- // Remove existing viaPoint on click and abort viaPoint add
560
- this.removeViaPoint(viaPoint.get('viaPointIdx'));
561
- return;
562
- }
563
-
564
- this.addViaPoint(e.coordinate);
565
- }
566
-
567
- /**
568
- * Used on start of the modify interaction. Stores relevant data
569
- * in this.initialRouteDrag object
570
- * @private
571
- */
572
- onModifyStart(evt) {
573
- // When modify start, we search the index of the segment that is modifying.
574
- let segmentIndex = -1;
575
- const route = evt.features
576
- .getArray()
577
- .find((feat) => feat.getGeometry() instanceof LineString);
578
-
579
- // Find the segment index that is being modified
580
- if (route) {
581
- // We use a buff extent to fix floating issues , see https://github.com/openlayers/openlayers/issues/7130#issuecomment-535856422
582
- const closestExtent = buffer(
583
- new Point(
584
- route.getGeometry().getClosestPoint(evt.mapBrowserEvent.coordinate),
585
- ).getExtent(),
586
- 0.001,
587
- );
588
-
589
- segmentIndex = this.segments.findIndex((segment) =>
590
- segment.getGeometry().intersectsExtent(closestExtent),
591
- );
592
- }
593
-
594
- // Find the viaPoint that is being modified
595
- const viaPoint = (evt.features
596
- .getArray()
597
- .filter((feat) => feat.getGeometry() instanceof Point) || [])[0];
598
-
599
- // Write object with modify info
600
- /** @ignore */
601
- this.initialRouteDrag = {
602
- viaPoint,
603
- oldRoute: route && route.clone(),
604
- segmentIndex,
605
- };
606
- }
607
-
608
- /**
609
- * Used on end of the modify interaction. Resolves feature modification:
610
- * Line drag creates new viaPoint at the final coordinate of drag.
611
- * Point drag replaces old viaPoint.
612
- * @private
613
- */
614
- onModifyEnd(evt) {
615
- const coord = evt.mapBrowserEvent.coordinate;
616
- const { oldRoute, viaPoint, segmentIndex } = this.initialRouteDrag;
617
-
618
- // If viaPoint is being relocated overwrite the old viaPoint
619
- if (viaPoint) {
620
- return this.addViaPoint(coord, viaPoint.get('viaPointIdx'), 1);
621
- }
622
-
623
- // In case there is no route overwrite first coordinate
624
- if (!oldRoute) {
625
- return this.addViaPoint(coord, 0, 1);
626
- }
627
-
628
- // We can't add a via point because we haven't found which segment has been modified.
629
- if (segmentIndex === -1) {
630
- return Promise.reject(new Error('No segment found'));
631
- }
632
-
633
- // Insert new viaPoint at the modified segment index + 1
634
- return this.addViaPoint(coord, segmentIndex + 1);
635
- }
636
-
637
- /**
638
- * Define a default element.
639
- *
640
- * @private
641
- */
642
- createDefaultElement() {
643
- /** @ignore */
644
- this.element = document.createElement('button');
645
- this.element.id = 'ol-toggle-routing';
646
- this.element.innerHTML = 'Toggle Route Control';
647
- this.element.onclick = () =>
648
- this.active ? this.deactivate() : this.activate();
649
- Object.assign(this.element.style, {
650
- position: 'absolute',
651
- right: '10px',
652
- top: '10px',
653
- });
654
- }
655
-
656
- /**
657
- * Create the interaction used to modify vertexes of features.
658
- * @private
659
- */
660
- createModifyInteraction() {
661
- /**
662
- * @type {ol.interaction.Modify}
663
- * @private
664
- */
665
- // Define and add modify interaction
666
- this.modifyInteraction = new Modify({
667
- source: this.routingLayer.olLayer.getSource(),
668
- pixelTolerance: 4,
669
- hitDetection: this.routingLayer.olLayer,
670
- deleteCondition: (e) => {
671
- const feats = e.target.getFeaturesAtPixel(e.pixel, {
672
- hitTolerance: 5,
673
- });
674
- const viaPoint = feats.find(
675
- (feat) => feat.getGeometry() instanceof Point && feat.get('index'),
676
- );
677
- if (click(e) && viaPoint) {
678
- // Remove node & viaPoint if an existing viaPoint was clicked
679
- this.removeViaPoint(viaPoint.get('index'));
680
- return true;
681
- }
682
- return false;
683
- },
684
- });
685
- this.modifyInteraction.on('modifystart', this.onModifyStart);
686
- this.modifyInteraction.on('modifyend', this.onModifyEnd);
687
- this.modifyInteraction.setActive(false);
688
- }
689
-
690
- /**
691
- * Add click listener to map.
692
- * @private
693
- */
694
- addListeners() {
695
- if (!this.modify) {
696
- return;
697
- }
698
- this.removeListeners();
699
- /** @ignore */
700
- this.onMapClickKey = this.map.on('singleclick', this.onMapClick);
701
- }
702
-
703
- /**
704
- * Remove click listener from map.
705
- * @private
706
- */
707
- removeListeners() {
708
- unByKey(this.onMapClickKey);
709
- }
710
-
711
- activate() {
712
- super.activate();
713
- if (this.map) {
714
- /** @ignore */
715
- this.format = new GeoJSON({
716
- featureProjection: this.map.getView().getProjection(),
717
- });
718
-
719
- /** @ignore */
720
- this.graphsResolutions = RoutingControl.getGraphsResolutions(
721
- this.graphs,
722
- this.map,
723
- );
724
-
725
- // Clean the modifyInteraction if present
726
- this.map.removeInteraction(this.modifyInteraction);
727
-
728
- // Add modify interaction, RoutingLayer and listeners
729
- this.routingLayer.init(this.map);
730
- this.map.addInteraction(this.modifyInteraction);
731
- this.modifyInteraction.setActive(this.modify);
732
- this.addListeners();
733
- } else {
734
- // fall back to some default values if map is not available
735
- this.format = new GeoJSON({ featureProjection: 'EPSG:3857' });
736
- this.graphsResolutions = this.graphs;
737
- }
738
- }
739
-
740
- deactivate() {
741
- if (this.map) {
742
- // Remove modify interaction, RoutingLayer, listeners and viaPoints
743
- this.routingLayer.terminate(this.map);
744
- this.map.removeInteraction(this.modifyInteraction);
745
- this.removeListeners();
746
- this.reset();
747
- }
748
- super.deactivate();
749
- }
750
- }
751
-
752
- export default RoutingControl;