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
@@ -0,0 +1,185 @@
1
+ import GeoJSON from "ol/format/GeoJSON";
2
+ import { Layer as OLLayer, Group, Vector as VectorLayer } from "ol/layer";
3
+ import Source from "ol/source/Source";
4
+ import { composeCssTransform } from "ol/transform";
5
+ import { Vector as VectorSource } from "ol/source";
6
+ import Layer from "./Layer";
7
+ import mixin from "../../common/mixins/TralisLayerMixin";
8
+ import { fullTrajectoryStyle } from "../styles";
9
+ const format = new GeoJSON();
10
+ class TralisLayer extends mixin(Layer) {
11
+ constructor(options = {}) {
12
+ super({
13
+ ...options
14
+ });
15
+ this.olLayer = options.olLayer || new Group({
16
+ layers: [
17
+ new VectorLayer({
18
+ source: new VectorSource({ features: [] }),
19
+ style: options.fullTrajectoryStyle || fullTrajectoryStyle
20
+ }),
21
+ new OLLayer({
22
+ source: new Source({}),
23
+ render: (frameState) => {
24
+ if (!this.tracker || !this.tracker.canvas) {
25
+ return null;
26
+ }
27
+ if (!this.container) {
28
+ this.container = document.createElement("div");
29
+ this.container.style.position = "absolute";
30
+ this.container.style.width = "100%";
31
+ this.container.style.height = "100%";
32
+ this.transformContainer = document.createElement("div");
33
+ this.transformContainer.style.position = "absolute";
34
+ this.transformContainer.style.width = "100%";
35
+ this.transformContainer.style.height = "100%";
36
+ this.container.appendChild(this.transformContainer);
37
+ this.tracker.canvas.style.position = "absolute";
38
+ this.tracker.canvas.style.top = "0";
39
+ this.tracker.canvas.style.left = "0";
40
+ this.tracker.canvas.style.transformOrigin = "top left";
41
+ this.transformContainer.appendChild(this.tracker.canvas);
42
+ }
43
+ if (this.renderedViewState) {
44
+ const { center, resolution, rotation } = frameState.viewState;
45
+ const {
46
+ center: renderedCenter,
47
+ resolution: renderedResolution,
48
+ rotation: renderedRotation
49
+ } = this.renderedViewState;
50
+ if (renderedResolution / resolution >= 3) {
51
+ const { canvas } = this.tracker;
52
+ const context = canvas.getContext("2d");
53
+ context.clearRect(0, 0, canvas.width, canvas.height);
54
+ } else {
55
+ const pixelCenterRendered = this.map.getPixelFromCoordinate(renderedCenter);
56
+ const pixelCenter = this.map.getPixelFromCoordinate(center);
57
+ this.transformContainer.style.transform = composeCssTransform(pixelCenterRendered[0] - pixelCenter[0], pixelCenterRendered[1] - pixelCenter[1], renderedResolution / resolution, renderedResolution / resolution, rotation - renderedRotation, 0, 0);
58
+ }
59
+ }
60
+ return this.container;
61
+ }
62
+ })
63
+ ]
64
+ });
65
+ this.vectorLayer = this.olLayer.getLayers().item(0);
66
+ this.renderState = {
67
+ center: [0, 0],
68
+ zoom: null,
69
+ rotation: 0
70
+ };
71
+ }
72
+ attachToMap(map) {
73
+ super.attachToMap(map);
74
+ if (this.map) {
75
+ this.olListenersKeys.push(this.map.on(["moveend", "change:target"], (evt) => {
76
+ const view = this.map.getView();
77
+ if (view.getAnimating() || view.getInteracting()) {
78
+ return;
79
+ }
80
+ const zoom = view.getZoom();
81
+ if (this.currentZoom !== zoom) {
82
+ this.onZoomEnd(evt);
83
+ }
84
+ this.currentZoom = zoom;
85
+ this.onMoveEnd(evt);
86
+ }));
87
+ }
88
+ }
89
+ detachFromMap() {
90
+ super.detachFromMap();
91
+ this.container = null;
92
+ }
93
+ hasFeatureInfoAtCoordinate(coordinate) {
94
+ if (this.map && this.tracker && this.tracker.canvas) {
95
+ const context = this.tracker.canvas.getContext("2d");
96
+ const pixel = this.map.getPixelFromCoordinate(coordinate);
97
+ return !!context.getImageData(pixel[0] * this.pixelRatio, pixel[1] * this.pixelRatio, 1, 1).data[3];
98
+ }
99
+ return false;
100
+ }
101
+ renderTrajectories(noInterpolate) {
102
+ const view = this.map.getView();
103
+ super.renderTrajectories({
104
+ size: this.map.getSize(),
105
+ center: this.map.getView().getCenter(),
106
+ extent: view.calculateExtent(),
107
+ resolution: view.getResolution(),
108
+ rotation: view.getRotation(),
109
+ zoom: view.getZoom(),
110
+ pixelRatio: this.pixelRatio
111
+ }, noInterpolate);
112
+ }
113
+ renderTrajectoriesInternal(viewState, noInterpolate) {
114
+ let isRendered = false;
115
+ const blockRendering = this.map.getView().getAnimating() || this.map.getView().getInteracting();
116
+ isRendered = blockRendering ? false : super.renderTrajectoriesInternal(viewState, noInterpolate);
117
+ if (isRendered) {
118
+ this.renderedViewState = { ...viewState };
119
+ if (this.transformContainer) {
120
+ this.transformContainer.style.transform = "";
121
+ }
122
+ }
123
+ }
124
+ getRefreshTimeInMs() {
125
+ return super.getRefreshTimeInMs(this.map.getView().getZoom());
126
+ }
127
+ getFeatureInfoAtCoordinate(coordinate, options = {}) {
128
+ const resolution = this.map.getView().getResolution();
129
+ return super.getFeatureInfoAtCoordinate(coordinate, {
130
+ resolution,
131
+ ...options
132
+ });
133
+ }
134
+ onMoveEnd() {
135
+ if (this.visible && this.isUpdateBboxOnMoveEnd) {
136
+ this.setBbox();
137
+ }
138
+ if (this.visible && this.isUpdateBboxOnMoveEnd && this.isClickActive && this.selectedVehicleId) {
139
+ this.highlightTrajectory(this.selectedVehicleId);
140
+ }
141
+ }
142
+ onZoomEnd(evt) {
143
+ super.onZoomEnd(evt);
144
+ }
145
+ onFeatureHover(features, layer, coordinate) {
146
+ super.onFeatureHover(features, layer, coordinate);
147
+ this.map.getTargetElement().style.cursor = features.length ? "pointer" : "auto";
148
+ }
149
+ onFeatureClick(features, layer, coordinate) {
150
+ super.onFeatureClick(features, layer, coordinate);
151
+ if (!features.length && this.vectorLayer) {
152
+ this.vectorLayer.getSource().clear();
153
+ }
154
+ if (this.selectedVehicleId) {
155
+ this.highlightTrajectory(this.selectedVehicleId);
156
+ }
157
+ }
158
+ purgeTrajectory(trajectory, extent, zoom) {
159
+ return super.purgeTrajectory(trajectory, extent || this.map.getView().calculateExtent(), zoom || this.map.getView().getZoom());
160
+ }
161
+ setBbox(extent, zoom) {
162
+ let newExtent = extent;
163
+ let newZoom = zoom;
164
+ if (!newExtent && this.isUpdateBboxOnMoveEnd) {
165
+ newExtent = extent || this.map.getView().calculateExtent();
166
+ newZoom = Math.floor(this.map.getView().getZoom());
167
+ }
168
+ super.setBbox(newExtent, newZoom);
169
+ }
170
+ highlightTrajectory(id) {
171
+ this.api.getFullTrajectory(id, this.mode, this.generalizationLevel).then((fullTrajectory) => {
172
+ const vectorSource = this.vectorLayer.getSource();
173
+ vectorSource.clear();
174
+ if (!fullTrajectory || !fullTrajectory.features || !fullTrajectory.features.length) {
175
+ return;
176
+ }
177
+ const features = format.readFeatures(fullTrajectory);
178
+ this.vectorLayer.getSource().addFeatures(features);
179
+ });
180
+ }
181
+ clone(newOptions) {
182
+ return new TralisLayer({ ...this.options, ...newOptions });
183
+ }
184
+ }
185
+ export default TralisLayer;
@@ -0,0 +1,79 @@
1
+ import fetch from "jest-fetch-mock";
2
+ import Map from "ol/Map";
3
+ import View from "ol/View";
4
+ import WS from "jest-websocket-mock";
5
+ import TralisLayer from "./TralisLayer";
6
+ let layer;
7
+ let onClick;
8
+ let olMap;
9
+ let server;
10
+ describe("TralisLayer", () => {
11
+ beforeEach(() => {
12
+ server = new WS("ws://localhost:1234");
13
+ global.fetch = fetch;
14
+ fetch.resetMocks();
15
+ onClick = jest.fn();
16
+ layer = new TralisLayer({
17
+ url: "ws://localhost:1234",
18
+ apiKey: "apiKey",
19
+ onClick
20
+ });
21
+ olMap = new Map({
22
+ view: new View({
23
+ center: [831634, 5933959],
24
+ zoom: 9
25
+ })
26
+ });
27
+ });
28
+ afterEach(() => {
29
+ server.close();
30
+ WS.clean();
31
+ });
32
+ test("should be instanced.", () => {
33
+ expect(layer).toBeInstanceOf(TralisLayer);
34
+ expect(layer.clickCallbacks[0]).toBe(onClick);
35
+ });
36
+ test("should called terminate on initalization.", () => {
37
+ const spy = jest.spyOn(layer, "detachFromMap");
38
+ fetch.mockResponseOnce(JSON.stringify(global.fetchTrajectoriesResponse));
39
+ layer.attachToMap(olMap);
40
+ expect(spy).toHaveBeenCalledTimes(1);
41
+ });
42
+ test("should clone", () => {
43
+ const clone = layer.clone({ name: "clone" });
44
+ expect(clone).not.toBe(layer);
45
+ expect(clone.name).toBe("clone");
46
+ expect(clone).toBeInstanceOf(TralisLayer);
47
+ });
48
+ test("should use the sort function.", () => {
49
+ const fn = () => true;
50
+ const laye = new TralisLayer({
51
+ url: "ws://localhost:1234",
52
+ apiKey: "apiKey",
53
+ sort: fn
54
+ });
55
+ expect(laye).toBeInstanceOf(TralisLayer);
56
+ expect(laye.sort).toBe(fn);
57
+ });
58
+ test("should use filter function.", () => {
59
+ const fn = () => true;
60
+ const laye = new TralisLayer({
61
+ url: "ws://localhost:1234",
62
+ apiKey: "apiKey",
63
+ filter: fn
64
+ });
65
+ expect(laye).toBeInstanceOf(TralisLayer);
66
+ expect(laye.filter).toBe(fn);
67
+ });
68
+ test("should override filter function if operator, tripNumber, regexPublishedLineName is set.", () => {
69
+ const fn = () => true;
70
+ const laye = new TralisLayer({
71
+ url: "ws://localhost:1234",
72
+ apiKey: "apiKey",
73
+ filter: fn,
74
+ publishedLineName: ".*"
75
+ });
76
+ expect(laye).toBeInstanceOf(TralisLayer);
77
+ expect(laye.filter).not.toBe(fn);
78
+ });
79
+ });
@@ -0,0 +1,22 @@
1
+ import Layer from "./Layer";
2
+ class VectorLayer extends Layer {
3
+ getFeatureInfoAtCoordinate(coordinate) {
4
+ let features = [];
5
+ if (this.map) {
6
+ const pixel = this.map.getPixelFromCoordinate(coordinate);
7
+ features = this.map.getFeaturesAtPixel(pixel, {
8
+ layerFilter: (l) => l === this.olLayer,
9
+ hitTolerance: this.hitTolerance
10
+ });
11
+ }
12
+ return Promise.resolve({
13
+ features,
14
+ layer: this,
15
+ coordinate
16
+ });
17
+ }
18
+ clone(newOptions) {
19
+ return new VectorLayer({ ...this.options, ...newOptions });
20
+ }
21
+ }
22
+ export default VectorLayer;
@@ -1,80 +1,70 @@
1
- import OLVectorLayer from 'ol/layer/Vector';
2
- import VectorSource from 'ol/source/Vector';
3
- import View from 'ol/View';
4
- import Feature from 'ol/Feature';
5
- import Point from 'ol/geom/Point';
6
- import Map from 'ol/Map';
7
- import VectorLayer from './VectorLayer';
8
-
1
+ import OLVectorLayer from "ol/layer/Vector";
2
+ import VectorSource from "ol/source/Vector";
3
+ import View from "ol/View";
4
+ import Feature from "ol/Feature";
5
+ import Point from "ol/geom/Point";
6
+ import Map from "ol/Map";
7
+ import VectorLayer from "./VectorLayer";
9
8
  const feature1 = new Feature({
10
- attribute: 'bar',
11
- geometry: new Point([500, 500]),
9
+ attribute: "bar",
10
+ geometry: new Point([500, 500])
12
11
  });
13
12
  const olLayer = new OLVectorLayer({
14
13
  source: new VectorSource({
15
14
  features: [
16
15
  feature1,
17
16
  new Feature({
18
- attribute: 'foo',
19
- geometry: new Point([50, 50]),
20
- }),
21
- ],
22
- }),
17
+ attribute: "foo",
18
+ geometry: new Point([50, 50])
19
+ })
20
+ ]
21
+ })
23
22
  });
24
-
25
23
  let layer;
26
24
  let map;
27
25
  let onClick;
28
-
29
- describe('VectorLayer', () => {
26
+ describe("VectorLayer", () => {
30
27
  beforeEach(() => {
31
28
  onClick = jest.fn();
32
29
  layer = new VectorLayer({
33
- name: 'Layer',
30
+ name: "Layer",
34
31
  olLayer,
35
- onClick,
32
+ onClick
36
33
  });
37
34
  map = new Map({
38
35
  view: new View({ resolution: 5 }),
39
- target: document.body,
36
+ target: document.body
40
37
  });
41
38
  });
42
-
43
- test('should be instanced.', () => {
39
+ test("should be instanced.", () => {
44
40
  expect(layer).toBeInstanceOf(VectorLayer);
45
41
  expect(layer.clickCallbacks[0]).toBe(onClick);
46
42
  expect(layer.hitTolerance).toBe(5);
47
43
  });
48
-
49
- test('should add onClick callback.', () => {
44
+ test("should add onClick callback.", () => {
50
45
  const onClick2 = jest.fn();
51
46
  layer.onClick(onClick2);
52
47
  expect(layer.clickCallbacks[1]).toBe(onClick2);
53
48
  });
54
-
55
- test('should onClick throw error.', () => {
49
+ test("should onClick throw error.", () => {
56
50
  expect(() => {
57
- layer.onClick('not of type function');
51
+ layer.onClick("not of type function");
58
52
  }).toThrow(Error);
59
53
  });
60
-
61
- test('should called terminate on initalization.', () => {
62
- const spy = jest.spyOn(layer, 'terminate');
63
- layer.init();
54
+ test("should called terminate on initalization.", () => {
55
+ const spy = jest.spyOn(layer, "detachFromMap");
56
+ layer.attachToMap();
64
57
  expect(spy).toHaveBeenCalledTimes(1);
65
58
  });
66
-
67
- test('should call getFeatureInfoAtCoordinate on click then the callback', async () => {
59
+ test("should call getFeatureInfoAtCoordinate on click then the callback", async () => {
68
60
  const coordinate = [500, 500];
69
61
  const px = [10, 10];
70
62
  const features = [feature1];
71
- const evt = { type: 'singleclick', map, coordinate };
72
- const spy = jest.spyOn(layer, 'getFeatureInfoAtCoordinate');
73
- const spy2 = jest.spyOn(map, 'getPixelFromCoordinate').mockReturnValue(px);
74
- const spy3 = jest
75
- .spyOn(map, 'getFeaturesAtPixel')
76
- .mockReturnValue(features);
77
- layer.init(map);
63
+ const evt = { type: "singleclick", map, coordinate };
64
+ const spy = jest.spyOn(layer, "getFeatureInfoAtCoordinate");
65
+ const spy2 = jest.spyOn(map, "getPixelFromCoordinate").mockReturnValue(px);
66
+ const spy3 = jest.spyOn(map, "getFeaturesAtPixel").mockReturnValue(features);
67
+ layer.attachToMap(map);
78
68
  expect(onClick).toHaveBeenCalledTimes(0);
79
69
  await map.dispatchEvent(evt);
80
70
  expect(spy).toHaveBeenCalledTimes(1);
@@ -88,11 +78,10 @@ describe('VectorLayer', () => {
88
78
  expect(onClick).toHaveBeenCalledTimes(1);
89
79
  expect(onClick).toHaveBeenCalledWith(features, layer, coordinate);
90
80
  });
91
-
92
- test('should clone', () => {
93
- const clone = layer.clone({ name: 'clone' });
81
+ test("should clone", () => {
82
+ const clone = layer.clone({ name: "clone" });
94
83
  expect(clone).not.toBe(layer);
95
- expect(clone.name).toBe('clone');
84
+ expect(clone.name).toBe("clone");
96
85
  expect(clone).toBeInstanceOf(VectorLayer);
97
86
  });
98
87
  });
@@ -0,0 +1,38 @@
1
+ import GeoJSON from "ol/format/GeoJSON";
2
+ import Layer from "./Layer";
3
+ class WMSLayer extends Layer {
4
+ constructor(options = {}) {
5
+ super(options);
6
+ this.abortController = new AbortController();
7
+ this.format = new GeoJSON();
8
+ }
9
+ getFeatureInfoUrl(coord) {
10
+ const projection = this.map.getView().getProjection();
11
+ const resolution = this.map.getView().getResolution();
12
+ if (this.olLayer.getSource().getFeatureInfoUrl) {
13
+ return this.olLayer.getSource().getFeatureInfoUrl(coord, resolution, projection, {
14
+ info_format: "application/json",
15
+ query_layers: this.olLayer.getSource().getParams().layers
16
+ });
17
+ }
18
+ return false;
19
+ }
20
+ getFeatureInfoAtCoordinate(coordinate) {
21
+ this.abortController.abort();
22
+ this.abortController = new AbortController();
23
+ const { signal } = this.abortController;
24
+ return fetch(this.getFeatureInfoUrl(coordinate), { signal }).then((resp) => resp.json()).then((r) => r.features).then((data) => ({
25
+ layer: this,
26
+ coordinate,
27
+ features: data.map((d) => this.format.readFeature(d))
28
+ })).catch(() => Promise.resolve({
29
+ features: [],
30
+ coordinate,
31
+ layer: this
32
+ }));
33
+ }
34
+ clone(newOptions) {
35
+ return new WMSLayer({ ...this.options, ...newOptions });
36
+ }
37
+ }
38
+ export default WMSLayer;
@@ -0,0 +1,76 @@
1
+ import OLView from "ol/View";
2
+ import ImageLayer from "ol/layer/Image";
3
+ import ImageWMS from "ol/source/ImageWMS";
4
+ import fetch from "jest-fetch-mock";
5
+ import qs from "query-string";
6
+ import Map from "ol/Map";
7
+ import WMSLayer from "./WMSLayer";
8
+ describe("WMSLayer", () => {
9
+ let map;
10
+ let layer;
11
+ beforeEach(() => {
12
+ map = new Map({
13
+ view: new OLView({ resolution: 5 }),
14
+ target: document.body
15
+ });
16
+ layer = new WMSLayer({
17
+ olLayer: new ImageLayer({
18
+ source: new ImageWMS({
19
+ url: "dummy",
20
+ params: { LAYERS: "layers" }
21
+ })
22
+ })
23
+ });
24
+ layer.attachToMap(map);
25
+ fetch.mockResponseOnce(JSON.stringify({ features: [] }));
26
+ global.fetch = fetch;
27
+ });
28
+ afterEach(() => {
29
+ layer.detachFromMap();
30
+ });
31
+ test("should initialize.", () => {
32
+ expect(layer).toBeInstanceOf(WMSLayer);
33
+ });
34
+ test("should called terminate on initalization.", () => {
35
+ const spy = jest.spyOn(layer, "detachFromMap");
36
+ layer.attachToMap();
37
+ expect(spy).toHaveBeenCalledTimes(1);
38
+ });
39
+ test("should return a promise resolving features.", async () => {
40
+ const data = await layer.getFeatureInfoAtCoordinate([50, 50]);
41
+ const params = qs.parse(fetch.mock.calls[0][0].split("?")[1]);
42
+ expect(params.REQUEST).toBe("GetFeatureInfo");
43
+ expect(params.I).toBe("50");
44
+ expect(params.J).toBe("50");
45
+ expect(data.features).toEqual([]);
46
+ });
47
+ test("should return a layer instance and a coordinate.", async () => {
48
+ const data = await layer.getFeatureInfoAtCoordinate([50, 50]);
49
+ expect(data.coordinate).toEqual([50, 50]);
50
+ expect(data.layer).toBeInstanceOf(WMSLayer);
51
+ });
52
+ test("#onClick", () => {
53
+ const f = () => {
54
+ };
55
+ const f2 = () => {
56
+ };
57
+ layer.onClick(f);
58
+ expect(layer.clickCallbacks[0]).toBe(f);
59
+ expect(layer.clickCallbacks.length).toBe(1);
60
+ layer.onClick(f);
61
+ expect(layer.clickCallbacks.length).toBe(1);
62
+ layer.onClick(f2);
63
+ expect(layer.clickCallbacks.length).toBe(2);
64
+ });
65
+ test("should onClick throw error.", () => {
66
+ expect(() => {
67
+ layer.onClick("not of type function");
68
+ }).toThrow(Error);
69
+ });
70
+ test("should clone", () => {
71
+ const clone = layer.clone({ name: "clone" });
72
+ expect(clone).not.toBe(layer);
73
+ expect(clone.name).toBe("clone");
74
+ expect(clone).toBeInstanceOf(WMSLayer);
75
+ });
76
+ });
@@ -0,0 +1,8 @@
1
+ export { default as Layer } from "./Layer";
2
+ export { default as MapboxLayer } from "./MapboxLayer";
3
+ export { default as MaplibreLayer } from "./MaplibreLayer";
4
+ export { default as MapboxStyleLayer } from "./MapboxStyleLayer";
5
+ export { default as RoutingLayer } from "./RoutingLayer";
6
+ export { default as TralisLayer } from "./TralisLayer";
7
+ export { default as VectorLayer } from "./VectorLayer";
8
+ export { default as WMSLayer } from "./WMSLayer";
@@ -1,35 +1,31 @@
1
- import { Style, Fill, Stroke, Circle } from 'ol/style';
2
-
1
+ import { Style, Fill, Stroke, Circle } from "ol/style";
3
2
  const stroke = new Style({
4
3
  zIndex: 2,
5
4
  image: new Circle({
6
5
  radius: 5,
7
6
  fill: new Fill({
8
- color: '#000000',
9
- }),
7
+ color: "#000000"
8
+ })
10
9
  }),
11
10
  stroke: new Stroke({
12
- color: '#000000',
13
- width: 6,
14
- }),
11
+ color: "#000000",
12
+ width: 6
13
+ })
15
14
  });
16
-
17
15
  const fill = new Style({
18
16
  zIndex: 3,
19
17
  image: new Circle({
20
18
  radius: 4,
21
19
  fill: new Fill({
22
- color: '#a0a0a0',
23
- }),
20
+ color: "#a0a0a0"
21
+ })
24
22
  }),
25
23
  stroke: new Stroke({
26
- color: '#a0a0a0',
27
- width: 4,
28
- }),
24
+ color: "#a0a0a0",
25
+ width: 4
26
+ })
29
27
  });
30
-
31
28
  const fullTrajectoryDelaystyle = () => {
32
29
  return [stroke, fill];
33
30
  };
34
-
35
31
  export default fullTrajectoryDelaystyle;
@@ -0,0 +1,43 @@
1
+ import { Style, Fill, Stroke, Circle } from "ol/style";
2
+ import { getBgColor } from "../../common/trackerConfig";
3
+ const borderStyle = new Style({
4
+ zIndex: 2,
5
+ image: new Circle({
6
+ radius: 5,
7
+ fill: new Fill({
8
+ color: "#000000"
9
+ })
10
+ }),
11
+ stroke: new Stroke({
12
+ color: "#000000",
13
+ width: 6
14
+ })
15
+ });
16
+ const fullTrajectorystyle = (feature) => {
17
+ let lineColor = "#ffffff";
18
+ const type = feature.get("type");
19
+ let stroke = feature.get("stroke");
20
+ if (stroke && stroke[0] !== "#") {
21
+ stroke = `#${stroke}`;
22
+ }
23
+ lineColor = stroke || getBgColor(type);
24
+ lineColor = /#ffffff/i.test(lineColor) ? "#ff0000" : lineColor;
25
+ const style = [
26
+ borderStyle,
27
+ new Style({
28
+ zIndex: 3,
29
+ image: new Circle({
30
+ radius: 4,
31
+ fill: new Fill({
32
+ color: lineColor
33
+ })
34
+ }),
35
+ stroke: new Stroke({
36
+ color: lineColor,
37
+ width: 4
38
+ })
39
+ })
40
+ ];
41
+ return style;
42
+ };
43
+ export default fullTrajectorystyle;
@@ -0,0 +1,2 @@
1
+ export { default as fullTrajectoryStyle } from "./fullTrajectoryStyle";
2
+ export { default as fullTrajectoryDelayStyle } from "./fullTrajectoryDelayStyle";