mobility-toolbox-js 2.0.0 → 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.
- package/api/RoutingAPI.js +15 -0
- package/api/RoutingAPI.test.js +25 -0
- package/api/StopsAPI.js +12 -0
- package/api/StopsAPI.test.js +22 -0
- package/api/TralisAPI.js +359 -0
- package/api/TralisAPI.test.js +67 -0
- package/api/{tralis/TralisAPIUtils.js → TralisAPIUtils.js} +2 -32
- package/api/index.js +3 -3
- package/{ol/README.md → api/typedefs.js} +0 -0
- package/common/Tracker.js +14 -118
- package/common/api/HttpAPI.js +30 -0
- package/common/api/HttpAPI.test.js +50 -0
- package/common/api/WebSocketAPI.js +175 -0
- package/{api/tralis/WebSocketConnector.test.js → common/api/WebSocketAPI.test.js} +100 -145
- package/common/controls/Control.js +26 -91
- package/common/controls/Control.test.js +32 -43
- package/common/index.js +4 -0
- package/common/layers/Layer.js +53 -244
- package/common/layers/Layer.test.js +185 -244
- package/common/mixins/CopyrightMixin.js +20 -44
- package/common/mixins/SearchMixin.js +100 -166
- package/common/mixins/TralisLayerMixin.js +443 -894
- package/common/styles/index.js +4 -4
- package/common/styles/trackerDefaultStyle.js +39 -175
- package/common/styles/trackerDelayStyle.js +2 -11
- package/common/styles/trackerSimpleStyle.js +4 -8
- package/common/trackerConfig.js +61 -99
- package/common/trackerConfig.test.js +15 -17
- package/common/typedefs.js +0 -23
- package/common/utils/createTrackerFilters.js +10 -41
- package/common/utils/createTrackerFilters.test.js +40 -56
- package/common/utils/getMapboxMapCopyrights.js +3 -16
- package/common/utils/getMapboxMapCopyrights.test.js +32 -39
- package/common/utils/getMapboxStyleUrl.js +3 -13
- package/common/utils/getVehiclePosition.js +3 -33
- package/common/utils/index.js +5 -6
- package/common/utils/removeDuplicate.js +3 -17
- package/common/utils/removeDuplicate.test.js +17 -20
- package/common/utils/sortByDelay.js +2 -7
- package/common/utils/timeUtils.js +8 -32
- package/common/utils/timeUtils.test.js +7 -13
- package/index.js +8 -2
- package/mapbox/controls/CopyrightControl.js +9 -38
- package/mapbox/controls/index.js +1 -0
- package/mapbox/index.js +4 -3
- package/mapbox/layers/Layer.js +15 -76
- package/mapbox/layers/Layer.test.js +81 -101
- package/mapbox/layers/TralisLayer.js +46 -193
- package/mapbox/layers/TralisLayer.test.js +12 -14
- package/mapbox/layers/index.js +2 -0
- package/mapbox/utils.js +7 -21
- package/mbt.js +50444 -0
- package/mbt.js.map +7 -0
- package/mbt.min.js +1005 -0
- package/mbt.min.js.map +7 -0
- package/ol/controls/CopyrightControl.js +8 -46
- package/ol/controls/CopyrightControl.test.js +75 -121
- package/ol/controls/RoutingControl.js +167 -532
- package/ol/controls/RoutingControl.test.js +99 -164
- package/ol/controls/StopFinderControl.js +3 -31
- package/ol/controls/StopFinderControl.test.js +18 -29
- package/ol/controls/index.js +3 -0
- package/ol/index.js +5 -13
- package/ol/layers/Layer.js +23 -128
- package/ol/layers/Layer.test.js +79 -102
- package/ol/layers/MapboxLayer.js +62 -237
- package/ol/layers/MapboxLayer.test.js +58 -84
- package/ol/layers/MapboxStyleLayer.js +38 -268
- package/ol/layers/MapboxStyleLayer.test.js +97 -128
- package/ol/layers/MaplibreLayer.js +46 -187
- package/ol/layers/RoutingLayer.js +21 -51
- package/ol/layers/RoutingLayer.test.js +15 -24
- package/ol/layers/TralisLayer.js +102 -276
- package/ol/layers/TralisLayer.test.js +32 -50
- package/ol/layers/VectorLayer.js +3 -24
- package/ol/layers/VectorLayer.test.js +34 -45
- package/ol/layers/WMSLayer.js +15 -57
- package/ol/layers/WMSLayer.test.js +35 -43
- package/ol/layers/index.js +8 -0
- package/ol/styles/fullTrajectoryDelayStyle.js +11 -15
- package/ol/styles/fullTrajectoryStyle.js +17 -25
- package/ol/styles/index.js +2 -2
- package/package.json +35 -62
- package/api/routing/RoutingAPI.js +0 -44
- package/api/routing/RoutingAPI.test.js +0 -41
- package/api/stops/StopsAPI.js +0 -41
- package/api/stops/StopsAPI.test.js +0 -34
- package/api/tralis/TralisAPI.js +0 -731
- package/api/tralis/TralisAPI.test.js +0 -75
- package/api/tralis/WebSocketConnector.js +0 -338
- package/api/tralis/typedefs.js +0 -81
- package/common/api/api.js +0 -64
- package/common/api/api.test.js +0 -68
- package/index.js.map +0 -1
- package/module.js +0 -23
- package/ol/controls/snapshots/RoutingControlRouteGen10.json +0 -58
- package/ol/controls/snapshots/RoutingControlRouteGen100.json +0 -292
- package/ol/controls/snapshots/RoutingControlRouteGen30.json +0 -69
- package/ol/controls/snapshots/RoutingControlRouteGen5.json +0 -58
- package/ol/controls/snapshots/RoutingControlRouteOSM.json +0 -759
- package/ol/controls/snapshots/RoutingControlStation1.json +0 -60
- package/ol/controls/snapshots/RoutingControlStation2.json +0 -49
|
@@ -1,202 +1,182 @@
|
|
|
1
|
-
import { Map } from
|
|
2
|
-
import { toLonLat } from
|
|
3
|
-
import Layer from
|
|
4
|
-
|
|
1
|
+
import { Map } from "maplibre-gl";
|
|
2
|
+
import { toLonLat } from "ol/proj";
|
|
3
|
+
import Layer from "./Layer";
|
|
5
4
|
let map;
|
|
6
5
|
let mapElement;
|
|
7
|
-
|
|
8
|
-
describe('Layer', () => {
|
|
6
|
+
describe("Layer", () => {
|
|
9
7
|
beforeEach(() => {
|
|
10
|
-
mapElement = document.createElement(
|
|
8
|
+
mapElement = document.createElement("div");
|
|
11
9
|
const { style } = mapElement;
|
|
12
|
-
style.position =
|
|
13
|
-
style.left =
|
|
14
|
-
style.top =
|
|
15
|
-
style.width =
|
|
16
|
-
style.height =
|
|
17
|
-
mapElement.setAttribute(
|
|
10
|
+
style.position = "absolute";
|
|
11
|
+
style.left = "0px";
|
|
12
|
+
style.top = "0px";
|
|
13
|
+
style.width = "400px";
|
|
14
|
+
style.height = "400px";
|
|
15
|
+
mapElement.setAttribute("id", "map");
|
|
18
16
|
document.body.appendChild(mapElement);
|
|
19
17
|
map = new Map({
|
|
20
|
-
container: document.getElementById(
|
|
18
|
+
container: document.getElementById("map"),
|
|
21
19
|
style: `path/to/style`,
|
|
22
20
|
center: toLonLat([831634, 5933959]),
|
|
23
|
-
zoom: 9
|
|
21
|
+
zoom: 9
|
|
24
22
|
});
|
|
25
23
|
});
|
|
26
|
-
|
|
27
24
|
afterEach(() => {
|
|
28
25
|
document.body.removeChild(mapElement);
|
|
29
26
|
});
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const layer = new Layer({ name: 'Layer' });
|
|
27
|
+
test("should initialize.", () => {
|
|
28
|
+
const layer = new Layer({ name: "Layer" });
|
|
33
29
|
expect(layer).toBeInstanceOf(Layer);
|
|
34
30
|
});
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const layer = new Layer({ name: 'Layer' });
|
|
31
|
+
test("should be visible by default.", () => {
|
|
32
|
+
const layer = new Layer({ name: "Layer" });
|
|
38
33
|
expect(layer.visible).toBe(true);
|
|
39
34
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const layer = new Layer({ name: 'Layer', visible: false });
|
|
35
|
+
test("should be invisible if defined.", () => {
|
|
36
|
+
const layer = new Layer({ name: "Layer", visible: false });
|
|
43
37
|
expect(layer.visible).toBe(false);
|
|
44
38
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
const layer = new Layer({ name: 'Layer' });
|
|
39
|
+
test("should be invisible if set.", () => {
|
|
40
|
+
const layer = new Layer({ name: "Layer" });
|
|
48
41
|
layer.setVisible(false);
|
|
49
42
|
expect(layer.visible).toBe(false);
|
|
50
43
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const layer = new Layer({ name: 'Layer', visible: false });
|
|
44
|
+
test("should visibility stay unchanged", () => {
|
|
45
|
+
const layer = new Layer({ name: "Layer", visible: false });
|
|
54
46
|
layer.setVisible(false);
|
|
55
47
|
expect(layer.visible).toBe(false);
|
|
56
48
|
});
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
expect(layer.name).toEqual('Layer');
|
|
49
|
+
test("should return its name.", () => {
|
|
50
|
+
const layer = new Layer({ name: "Layer", visible: false });
|
|
51
|
+
expect(layer.name).toEqual("Layer");
|
|
61
52
|
});
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
layer.init(map);
|
|
53
|
+
test("should call terminate on initialization.", () => {
|
|
54
|
+
const layer = new Layer({ name: "Layer" });
|
|
55
|
+
const spy = jest.spyOn(layer, "detachFromMap");
|
|
56
|
+
layer.attachToMap(map);
|
|
67
57
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
68
58
|
});
|
|
69
|
-
|
|
70
|
-
test('should listen for click/hover events when layer is visible by default then should not when hidden.', async () => {
|
|
59
|
+
test("should listen for click/hover events when layer is visible by default then should not when hidden.", async () => {
|
|
71
60
|
global.console.error = jest.fn();
|
|
72
|
-
const layer = new Layer({ name:
|
|
61
|
+
const layer = new Layer({ name: "Layer" });
|
|
73
62
|
expect(layer.visible).toBe(true);
|
|
74
63
|
const spy = jest.fn();
|
|
75
64
|
const spy2 = jest.fn();
|
|
76
|
-
layer.
|
|
65
|
+
layer.attachToMap(map);
|
|
77
66
|
layer.onHover(spy);
|
|
78
67
|
layer.onClick(spy2);
|
|
79
68
|
expect(spy).toHaveBeenCalledTimes(0);
|
|
80
69
|
expect(spy2).toHaveBeenCalledTimes(0);
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
type: 'mousemove',
|
|
70
|
+
await map.fire("mousemove", {
|
|
71
|
+
type: "mousemove",
|
|
84
72
|
lngLat: { toArray: () => [0, 0] },
|
|
85
|
-
coordinate: [0, 0]
|
|
73
|
+
coordinate: [0, 0]
|
|
86
74
|
});
|
|
87
|
-
await map.fire(
|
|
88
|
-
type:
|
|
89
|
-
lngLat: { toArray: () => [0, 0] }
|
|
75
|
+
await map.fire("click", {
|
|
76
|
+
type: "click",
|
|
77
|
+
lngLat: { toArray: () => [0, 0] }
|
|
90
78
|
});
|
|
91
79
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
92
80
|
expect(spy2).toHaveBeenCalledTimes(1);
|
|
93
81
|
spy.mockReset();
|
|
94
82
|
spy2.mockReset();
|
|
95
|
-
|
|
96
83
|
layer.setVisible(false);
|
|
97
|
-
await map.fire(
|
|
98
|
-
type:
|
|
99
|
-
lngLat: { toArray: () => [0, 0] }
|
|
84
|
+
await map.fire("mousemove", {
|
|
85
|
+
type: "mousemove",
|
|
86
|
+
lngLat: { toArray: () => [0, 0] }
|
|
100
87
|
});
|
|
101
|
-
await map.fire(
|
|
102
|
-
type:
|
|
103
|
-
lngLat: { toArray: () => [0, 0] }
|
|
88
|
+
await map.fire("click", {
|
|
89
|
+
type: "click",
|
|
90
|
+
lngLat: { toArray: () => [0, 0] }
|
|
104
91
|
});
|
|
105
92
|
expect(spy).toHaveBeenCalledTimes(0);
|
|
106
93
|
expect(spy2).toHaveBeenCalledTimes(0);
|
|
107
94
|
global.console.error.mockRestore();
|
|
108
95
|
});
|
|
109
|
-
|
|
110
|
-
test('should not listen for click/hover events when layer is not visible by default then should not when visible.', async () => {
|
|
96
|
+
test("should not listen for click/hover events when layer is not visible by default then should not when visible.", async () => {
|
|
111
97
|
global.console.error = jest.fn();
|
|
112
|
-
const layer = new Layer({ name:
|
|
98
|
+
const layer = new Layer({ name: "Layer", visible: false });
|
|
113
99
|
expect(layer.visible).toBe(false);
|
|
114
100
|
const spy = jest.fn();
|
|
115
101
|
const spy2 = jest.fn();
|
|
116
|
-
layer.
|
|
102
|
+
layer.attachToMap(map);
|
|
117
103
|
layer.onHover(spy);
|
|
118
104
|
layer.onClick(spy2);
|
|
119
105
|
expect(spy).toHaveBeenCalledTimes(0);
|
|
120
106
|
expect(spy2).toHaveBeenCalledTimes(0);
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
type: 'mousemove',
|
|
107
|
+
await map.fire("mousemove", {
|
|
108
|
+
type: "mousemove",
|
|
124
109
|
lngLat: { toArray: () => [0, 0] },
|
|
125
|
-
coordinate: [0, 0]
|
|
110
|
+
coordinate: [0, 0]
|
|
126
111
|
});
|
|
127
|
-
await map.fire(
|
|
128
|
-
type:
|
|
129
|
-
lngLat: { toArray: () => [0, 0] }
|
|
112
|
+
await map.fire("click", {
|
|
113
|
+
type: "click",
|
|
114
|
+
lngLat: { toArray: () => [0, 0] }
|
|
130
115
|
});
|
|
131
116
|
expect(spy).toHaveBeenCalledTimes(0);
|
|
132
117
|
expect(spy2).toHaveBeenCalledTimes(0);
|
|
133
118
|
spy.mockReset();
|
|
134
119
|
spy2.mockReset();
|
|
135
|
-
|
|
136
120
|
layer.setVisible(true);
|
|
137
|
-
await map.fire(
|
|
138
|
-
type:
|
|
121
|
+
await map.fire("mousemove", {
|
|
122
|
+
type: "mousemove",
|
|
139
123
|
lngLat: { toArray: () => [0, 0] },
|
|
140
|
-
coordinate: [0, 0]
|
|
124
|
+
coordinate: [0, 0]
|
|
141
125
|
});
|
|
142
|
-
await map.fire(
|
|
143
|
-
type:
|
|
144
|
-
lngLat: { toArray: () => [0, 0] }
|
|
126
|
+
await map.fire("click", {
|
|
127
|
+
type: "click",
|
|
128
|
+
lngLat: { toArray: () => [0, 0] }
|
|
145
129
|
});
|
|
146
130
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
147
131
|
expect(spy2).toHaveBeenCalledTimes(1);
|
|
148
132
|
global.console.error.mockRestore();
|
|
149
133
|
});
|
|
150
|
-
|
|
151
|
-
test('should not listen for click/hover events after layer.terminate()', async () => {
|
|
134
|
+
test("should not listen for click/hover events after layer.detachFromMap()", async () => {
|
|
152
135
|
global.console.error = jest.fn();
|
|
153
|
-
const layer = new Layer({ name:
|
|
136
|
+
const layer = new Layer({ name: "Layer", visible: true });
|
|
154
137
|
expect(layer.visible).toBe(true);
|
|
155
138
|
const spy = jest.fn();
|
|
156
139
|
const spy2 = jest.fn();
|
|
157
|
-
layer.
|
|
140
|
+
layer.attachToMap(map);
|
|
158
141
|
layer.onHover(spy);
|
|
159
142
|
layer.onClick(spy2);
|
|
160
143
|
expect(spy).toHaveBeenCalledTimes(0);
|
|
161
144
|
expect(spy2).toHaveBeenCalledTimes(0);
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
type: 'mousemove',
|
|
145
|
+
await map.fire("mousemove", {
|
|
146
|
+
type: "mousemove",
|
|
165
147
|
lngLat: { toArray: () => [0, 0] },
|
|
166
|
-
coordinate: [0, 0]
|
|
148
|
+
coordinate: [0, 0]
|
|
167
149
|
});
|
|
168
|
-
await map.fire(
|
|
169
|
-
type:
|
|
170
|
-
lngLat: { toArray: () => [0, 0] }
|
|
150
|
+
await map.fire("click", {
|
|
151
|
+
type: "click",
|
|
152
|
+
lngLat: { toArray: () => [0, 0] }
|
|
171
153
|
});
|
|
172
154
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
173
155
|
expect(spy2).toHaveBeenCalledTimes(1);
|
|
174
156
|
spy.mockReset();
|
|
175
157
|
spy2.mockReset();
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
type: 'mousemove',
|
|
158
|
+
layer.detachFromMap(map);
|
|
159
|
+
await map.fire("mousemove", {
|
|
160
|
+
type: "mousemove",
|
|
180
161
|
lngLat: { toArray: () => [0, 0] },
|
|
181
|
-
coordinate: [0, 0]
|
|
162
|
+
coordinate: [0, 0]
|
|
182
163
|
});
|
|
183
|
-
await map.fire(
|
|
184
|
-
type:
|
|
185
|
-
lngLat: { toArray: () => [0, 0] }
|
|
164
|
+
await map.fire("click", {
|
|
165
|
+
type: "click",
|
|
166
|
+
lngLat: { toArray: () => [0, 0] }
|
|
186
167
|
});
|
|
187
168
|
expect(spy).toHaveBeenCalledTimes(0);
|
|
188
169
|
expect(spy2).toHaveBeenCalledTimes(0);
|
|
189
170
|
global.console.error.mockRestore();
|
|
190
171
|
});
|
|
191
|
-
|
|
192
|
-
test('should clone', () => {
|
|
172
|
+
test("should clone", () => {
|
|
193
173
|
const layer = new Layer({
|
|
194
|
-
name:
|
|
195
|
-
copyrights: [
|
|
174
|
+
name: "Layer",
|
|
175
|
+
copyrights: ["bar"]
|
|
196
176
|
});
|
|
197
|
-
const clone = layer.clone({ name:
|
|
177
|
+
const clone = layer.clone({ name: "clone" });
|
|
198
178
|
expect(clone).not.toBe(layer);
|
|
199
|
-
expect(clone.name).toBe(
|
|
179
|
+
expect(clone.name).toBe("clone");
|
|
200
180
|
expect(clone).toBeInstanceOf(Layer);
|
|
201
181
|
});
|
|
202
182
|
});
|
|
@@ -1,110 +1,61 @@
|
|
|
1
|
-
import { fromLonLat } from
|
|
2
|
-
import { unByKey } from
|
|
3
|
-
import { getWidth, getHeight } from
|
|
4
|
-
import transformRotate from
|
|
5
|
-
import { point } from
|
|
6
|
-
import mixin from
|
|
7
|
-
import Layer from
|
|
8
|
-
import { getSourceCoordinates, getMercatorResolution } from
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Responsible for loading and display data from a Tralis service.
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* import { TralisLayer } from 'mobility-toolbox-js/mapbox';
|
|
15
|
-
*
|
|
16
|
-
* const layer = new TralisLayer({
|
|
17
|
-
* url: [yourUrl],
|
|
18
|
-
* apiKey: [yourApiKey],
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
* @see <a href="/api/class/src/api/tralis/TralisAPI%20js~TralisAPI%20html">TralisAPI</a>
|
|
23
|
-
*
|
|
24
|
-
* @extends {Layer}
|
|
25
|
-
* @implements {TralisLayerInterface}
|
|
26
|
-
*/
|
|
1
|
+
import { fromLonLat } from "ol/proj";
|
|
2
|
+
import { unByKey } from "ol/Observable";
|
|
3
|
+
import { getWidth, getHeight } from "ol/extent";
|
|
4
|
+
import transformRotate from "@turf/transform-rotate";
|
|
5
|
+
import { point } from "@turf/helpers";
|
|
6
|
+
import mixin from "../../common/mixins/TralisLayerMixin";
|
|
7
|
+
import Layer from "./Layer";
|
|
8
|
+
import { getSourceCoordinates, getMercatorResolution } from "../utils";
|
|
27
9
|
class TralisLayer extends mixin(Layer) {
|
|
28
10
|
constructor(options = {}) {
|
|
29
11
|
super({
|
|
30
|
-
...options
|
|
12
|
+
...options
|
|
31
13
|
});
|
|
32
|
-
|
|
33
|
-
/** @ignore */
|
|
34
14
|
this.onLoad = this.onLoad.bind(this);
|
|
35
|
-
|
|
36
|
-
/** @ignore */
|
|
37
15
|
this.onMove = this.onMove.bind(this);
|
|
38
|
-
|
|
39
|
-
/** @ignore */
|
|
40
16
|
this.onMoveEnd = this.onMoveEnd.bind(this);
|
|
41
|
-
|
|
42
|
-
/** @ignore */
|
|
43
17
|
this.onZoomEnd = this.onZoomEnd.bind(this);
|
|
44
|
-
|
|
45
|
-
/** @ignore */
|
|
46
18
|
this.onVisibilityChange = this.onVisibilityChange.bind(this);
|
|
47
19
|
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Initialize the layer.
|
|
51
|
-
*
|
|
52
|
-
* @param {mapboxgl.Map} map A [mapbox Map](https://docs.mapbox.com/mapbox-gl-js/api/map/).
|
|
53
|
-
* @param {string} beforeId Layer's id before which we want to add the new layer.
|
|
54
|
-
* @override
|
|
55
|
-
*/
|
|
56
|
-
init(map, beforeId) {
|
|
20
|
+
attachToMap(map, beforeId) {
|
|
57
21
|
if (!map) {
|
|
58
22
|
return;
|
|
59
23
|
}
|
|
60
|
-
|
|
61
24
|
const canvas = map.getCanvas();
|
|
62
|
-
|
|
63
|
-
super.init(map, {
|
|
25
|
+
super.attachToMap(map, {
|
|
64
26
|
width: canvas.width / this.pixelRatio,
|
|
65
|
-
height: canvas.height / this.pixelRatio
|
|
27
|
+
height: canvas.height / this.pixelRatio
|
|
66
28
|
});
|
|
67
|
-
|
|
68
29
|
this.source = {
|
|
69
|
-
type:
|
|
30
|
+
type: "canvas",
|
|
70
31
|
canvas: this.tracker.canvas,
|
|
71
32
|
coordinates: getSourceCoordinates(map, this.pixelRatio),
|
|
72
|
-
// Set to true if the canvas source is animated. If the canvas is static, animate should be set to false to improve performance.
|
|
73
33
|
animate: true,
|
|
74
|
-
attribution: this.copyrights && this.copyrights.join(
|
|
34
|
+
attribution: this.copyrights && this.copyrights.join(", ")
|
|
75
35
|
};
|
|
76
|
-
|
|
77
36
|
this.beforeId = beforeId;
|
|
78
37
|
this.layer = {
|
|
79
38
|
id: this.key,
|
|
80
|
-
type:
|
|
39
|
+
type: "raster",
|
|
81
40
|
source: this.key,
|
|
82
41
|
layout: {
|
|
83
|
-
visibility: this.visible ?
|
|
42
|
+
visibility: this.visible ? "visible" : "none"
|
|
84
43
|
},
|
|
85
44
|
paint: {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
45
|
+
"raster-opacity": 1,
|
|
46
|
+
"raster-fade-duration": 0,
|
|
47
|
+
"raster-resampling": "nearest"
|
|
48
|
+
}
|
|
90
49
|
};
|
|
91
|
-
|
|
92
50
|
if (map.isStyleLoaded()) {
|
|
93
51
|
this.onLoad();
|
|
94
52
|
}
|
|
95
|
-
|
|
96
|
-
this.
|
|
97
|
-
|
|
98
|
-
this.listeners = [this.on('change:visible', this.onVisibilityChange)];
|
|
53
|
+
this.map.on("load", this.onLoad);
|
|
54
|
+
this.listeners = [this.on("change:visible", this.onVisibilityChange)];
|
|
99
55
|
}
|
|
100
|
-
|
|
101
|
-
/**
|
|
102
|
-
* Remove listeners from the Mapbox Map.
|
|
103
|
-
*/
|
|
104
|
-
terminate() {
|
|
56
|
+
detachFromMap() {
|
|
105
57
|
if (this.map) {
|
|
106
|
-
this.map.off(
|
|
107
|
-
|
|
58
|
+
this.map.off("load", this.onLoad);
|
|
108
59
|
this.listeners.forEach((listener) => {
|
|
109
60
|
unByKey(listener);
|
|
110
61
|
});
|
|
@@ -115,38 +66,22 @@ class TralisLayer extends mixin(Layer) {
|
|
|
115
66
|
this.map.removeSource(this.key);
|
|
116
67
|
}
|
|
117
68
|
}
|
|
118
|
-
super.
|
|
69
|
+
super.detachFromMap();
|
|
119
70
|
}
|
|
120
|
-
|
|
121
|
-
/**
|
|
122
|
-
* Start updating vehicles position.
|
|
123
|
-
*
|
|
124
|
-
* @listens {mapboxgl.map.event:zoomend} Listen to zoom end event.
|
|
125
|
-
* @listens {mapboxgl.map.event:mousemove} Listen to mousemove end.
|
|
126
|
-
* @override
|
|
127
|
-
*/
|
|
128
71
|
start() {
|
|
129
72
|
super.start();
|
|
130
|
-
|
|
131
|
-
this.map.on(
|
|
132
|
-
this.map.on(
|
|
133
|
-
this.map.on('zoomend', this.onZoomEnd);
|
|
73
|
+
this.map.on("move", this.onMove);
|
|
74
|
+
this.map.on("moveend", this.onMoveEnd);
|
|
75
|
+
this.map.on("zoomend", this.onZoomEnd);
|
|
134
76
|
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Stop updating vehicles position, and unlisten events.
|
|
138
|
-
*
|
|
139
|
-
* @override
|
|
140
|
-
*/
|
|
141
77
|
stop() {
|
|
142
78
|
super.stop();
|
|
143
79
|
if (this.map) {
|
|
144
|
-
this.map.off(
|
|
145
|
-
this.map.off(
|
|
146
|
-
this.map.off(
|
|
80
|
+
this.map.off("move", this.onMove);
|
|
81
|
+
this.map.off("moveend", this.onMoveEnd);
|
|
82
|
+
this.map.off("zoomend", this.onZoomEnd);
|
|
147
83
|
}
|
|
148
84
|
}
|
|
149
|
-
|
|
150
85
|
onLoad() {
|
|
151
86
|
if (!this.map.getSource(this.key)) {
|
|
152
87
|
this.map.addSource(this.key, this.source);
|
|
@@ -155,66 +90,36 @@ class TralisLayer extends mixin(Layer) {
|
|
|
155
90
|
this.map.addLayer(this.layer, this.beforeId);
|
|
156
91
|
}
|
|
157
92
|
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Function triggered when the user click the map.
|
|
161
|
-
* @override
|
|
162
|
-
*/
|
|
163
93
|
onUserClickCallback(evt) {
|
|
164
94
|
super.onUserClickCallback({
|
|
165
95
|
coordinate: fromLonLat(evt.lngLat.toArray()),
|
|
166
|
-
...evt
|
|
96
|
+
...evt
|
|
167
97
|
});
|
|
168
98
|
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Function triggered when the user moves the cursor over the map.
|
|
172
|
-
* @override
|
|
173
|
-
*/
|
|
174
99
|
onUserMoveCallback(evt) {
|
|
175
100
|
super.onUserMoveCallback({
|
|
176
101
|
coordinate: fromLonLat(evt.lngLat.toArray()),
|
|
177
|
-
...evt
|
|
102
|
+
...evt
|
|
178
103
|
});
|
|
179
104
|
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Render the trajectories using current map's size, resolution and rotation.
|
|
183
|
-
* @param {boolean} noInterpolate if true, renders the vehicles without interpolating theirs positions.
|
|
184
|
-
* @overrides
|
|
185
|
-
*/
|
|
186
105
|
renderTrajectories(noInterpolate) {
|
|
187
106
|
const { width, height } = this.map.getCanvas();
|
|
188
107
|
const center = this.map.getCenter();
|
|
189
|
-
|
|
190
|
-
// We use turf here to have good transform.
|
|
191
108
|
const leftBottom = this.map.unproject({
|
|
192
109
|
x: 0,
|
|
193
|
-
y: height / this.pixelRatio
|
|
194
|
-
});
|
|
195
|
-
const rightTop = this.map.unproject({ x: width / this.pixelRatio, y: 0 });
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
},
|
|
203
|
-
).geometry.coordinates;
|
|
204
|
-
const coord1 = transformRotate(
|
|
205
|
-
point([rightTop.lng, rightTop.lat]),
|
|
206
|
-
-this.map.getBearing(),
|
|
207
|
-
{
|
|
208
|
-
pivot: [center.lng, center.lat],
|
|
209
|
-
},
|
|
210
|
-
).geometry.coordinates;
|
|
211
|
-
|
|
110
|
+
y: height / this.pixelRatio
|
|
111
|
+
});
|
|
112
|
+
const rightTop = this.map.unproject({ x: width / this.pixelRatio, y: 0 });
|
|
113
|
+
const coord0 = transformRotate(point([leftBottom.lng, leftBottom.lat]), -this.map.getBearing(), {
|
|
114
|
+
pivot: [center.lng, center.lat]
|
|
115
|
+
}).geometry.coordinates;
|
|
116
|
+
const coord1 = transformRotate(point([rightTop.lng, rightTop.lat]), -this.map.getBearing(), {
|
|
117
|
+
pivot: [center.lng, center.lat]
|
|
118
|
+
}).geometry.coordinates;
|
|
212
119
|
const bounds = [...fromLonLat(coord0), ...fromLonLat(coord1)];
|
|
213
120
|
const xResolution = getWidth(bounds) / (width / this.pixelRatio);
|
|
214
121
|
const yResolution = getHeight(bounds) / (height / this.pixelRatio);
|
|
215
122
|
const res = Math.max(xResolution, yResolution);
|
|
216
|
-
|
|
217
|
-
// Coordinate of trajectories are in mercator so we have to pass the proper resolution and center in mercator.
|
|
218
123
|
const viewState = {
|
|
219
124
|
size: [width / this.pixelRatio, height / this.pixelRatio],
|
|
220
125
|
center: fromLonLat([center.lng, center.lat]),
|
|
@@ -222,57 +127,30 @@ class TralisLayer extends mixin(Layer) {
|
|
|
222
127
|
resolution: res,
|
|
223
128
|
zoom: this.map.getZoom(),
|
|
224
129
|
rotation: -(this.map.getBearing() * Math.PI) / 180,
|
|
225
|
-
pixelRatio: this.pixelRatio
|
|
130
|
+
pixelRatio: this.pixelRatio
|
|
226
131
|
};
|
|
227
|
-
|
|
228
132
|
super.renderTrajectories(viewState, noInterpolate);
|
|
229
133
|
}
|
|
230
|
-
|
|
231
|
-
/**
|
|
232
|
-
* Return the delay in ms before the next rendering.
|
|
233
|
-
*/
|
|
234
134
|
getRefreshTimeInMs() {
|
|
235
135
|
return super.getRefreshTimeInMs(this.map.getZoom());
|
|
236
136
|
}
|
|
237
|
-
|
|
238
137
|
getFeatureInfoAtCoordinate(coordinate, options = {}) {
|
|
239
138
|
const resolution = getMercatorResolution(this.map);
|
|
240
139
|
return super.getFeatureInfoAtCoordinate(coordinate, {
|
|
241
140
|
resolution,
|
|
242
|
-
...options
|
|
141
|
+
...options
|
|
243
142
|
});
|
|
244
143
|
}
|
|
245
|
-
|
|
246
144
|
onVisibilityChange() {
|
|
247
145
|
if (this.visible && !this.map.getLayer(this.key)) {
|
|
248
146
|
this.map.addLayer(this.layer, this.beforeId);
|
|
249
147
|
} else if (this.map.getLayer(this.key)) {
|
|
250
148
|
this.map.removeLayer(this.key);
|
|
251
149
|
}
|
|
252
|
-
// We can't use setLayoutProperty it triggers an error probably a bug in mapbox
|
|
253
|
-
// this.map.setLayoutProperty(
|
|
254
|
-
// this.key,
|
|
255
|
-
// 'visibilty',
|
|
256
|
-
// this.visible ? 'visible' : 'none',
|
|
257
|
-
// );
|
|
258
150
|
}
|
|
259
|
-
|
|
260
|
-
/**
|
|
261
|
-
* Remove the trajectory form the list if necessary.
|
|
262
|
-
*
|
|
263
|
-
* @private
|
|
264
|
-
*/
|
|
265
151
|
purgeTrajectory(trajectory, extent, zoom) {
|
|
266
|
-
return super.purgeTrajectory(
|
|
267
|
-
trajectory,
|
|
268
|
-
extent || this.getMercatorExtent(),
|
|
269
|
-
zoom || Math.floor(this.map.getZoom() + 1),
|
|
270
|
-
);
|
|
152
|
+
return super.purgeTrajectory(trajectory, extent || this.getMercatorExtent(), zoom || Math.floor(this.map.getZoom() + 1));
|
|
271
153
|
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Send the current bbox to the websocket
|
|
275
|
-
*/
|
|
276
154
|
setBbox(extent, zoom) {
|
|
277
155
|
let newExtent = extent;
|
|
278
156
|
let newZoom = zoom;
|
|
@@ -282,12 +160,6 @@ class TralisLayer extends mixin(Layer) {
|
|
|
282
160
|
}
|
|
283
161
|
super.setBbox(newExtent, newZoom);
|
|
284
162
|
}
|
|
285
|
-
|
|
286
|
-
/**
|
|
287
|
-
* Callback on 'move' event.
|
|
288
|
-
*
|
|
289
|
-
* @private
|
|
290
|
-
*/
|
|
291
163
|
onMove() {
|
|
292
164
|
const extent = getSourceCoordinates(this.map, this.pixelRatio);
|
|
293
165
|
const source = this.map.getSource(this.key);
|
|
@@ -296,34 +168,15 @@ class TralisLayer extends mixin(Layer) {
|
|
|
296
168
|
}
|
|
297
169
|
this.renderTrajectories();
|
|
298
170
|
}
|
|
299
|
-
|
|
300
|
-
/**
|
|
301
|
-
* Send the new BBOX to the websocket.
|
|
302
|
-
*
|
|
303
|
-
* @param {ol/MapEvent~MapEvent} evt Moveend event
|
|
304
|
-
* @private
|
|
305
|
-
* @override
|
|
306
|
-
*/
|
|
307
171
|
onMoveEnd() {
|
|
308
172
|
this.renderTrajectories();
|
|
309
|
-
|
|
310
173
|
if (this.visible && this.isUpdateBboxOnMoveEnd) {
|
|
311
174
|
this.setBbox();
|
|
312
175
|
}
|
|
313
176
|
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Update the cursor style when hovering a vehicle.
|
|
317
|
-
*
|
|
318
|
-
* @private
|
|
319
|
-
* @override
|
|
320
|
-
*/
|
|
321
177
|
onFeatureHover(features, layer, coordinate) {
|
|
322
178
|
super.onFeatureHover(features, layer, coordinate);
|
|
323
|
-
this.map.getCanvasContainer().style.cursor = features.length
|
|
324
|
-
? 'pointer'
|
|
325
|
-
: 'auto';
|
|
179
|
+
this.map.getCanvasContainer().style.cursor = features.length ? "pointer" : "auto";
|
|
326
180
|
}
|
|
327
181
|
}
|
|
328
|
-
|
|
329
182
|
export default TralisLayer;
|