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
package/ol/layers/MapboxLayer.js
CHANGED
|
@@ -1,105 +1,57 @@
|
|
|
1
|
-
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import { getMapboxMapCopyrights, getMapboxStyleUrl } from '../../common/utils';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A class representing Mapboxlayer to display on BasicMap
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* import { MapboxLayer } from 'mobility-toolbox-js/ol';
|
|
15
|
-
*
|
|
16
|
-
* const layer = new MapboxLayer({
|
|
17
|
-
* url: 'https://maps.geops.io/styles/travic_v2/style.json',
|
|
18
|
-
* apikey: 'yourApiKey',
|
|
19
|
-
* });
|
|
20
|
-
*
|
|
21
|
-
* @classproperty {ol/Map~Map} map - The map where the layer is displayed.
|
|
22
|
-
* @extends {Layer}
|
|
23
|
-
*/
|
|
1
|
+
import { toLonLat } from "ol/proj";
|
|
2
|
+
import { Map } from "mapbox-gl";
|
|
3
|
+
import Source from "ol/source/Source";
|
|
4
|
+
import OLLayer from "ol/layer/Layer";
|
|
5
|
+
import GeoJSON from "ol/format/GeoJSON";
|
|
6
|
+
import Layer from "./Layer";
|
|
7
|
+
import { getMapboxMapCopyrights, getMapboxStyleUrl } from "../../common/utils";
|
|
24
8
|
export default class MapboxLayer extends Layer {
|
|
25
|
-
/**
|
|
26
|
-
* Constructor.
|
|
27
|
-
*
|
|
28
|
-
* @param {Object} options
|
|
29
|
-
* @param {boolean} [options.preserveDrawingBuffer=false] If true able to export the canvas.
|
|
30
|
-
* @param {number} [options.fadeDuration=300] Duration of the fade effect in ms.
|
|
31
|
-
*/
|
|
32
9
|
constructor(options = {}) {
|
|
33
10
|
const mbLayer = new OLLayer({
|
|
34
11
|
source: new Source({}),
|
|
35
12
|
render: (frameState) => {
|
|
36
13
|
if (!this.mbMap) {
|
|
37
|
-
// eslint-disable-next-line no-console
|
|
38
14
|
console.warn("Mapbox map doesn't exist.");
|
|
39
15
|
return null;
|
|
40
16
|
}
|
|
41
17
|
let changed = false;
|
|
42
18
|
const canvas = this.mbMap.getCanvas();
|
|
43
19
|
const { viewState } = frameState;
|
|
44
|
-
|
|
45
20
|
const visible = this.olLayer.getVisible();
|
|
46
21
|
if (this.renderState.visible !== visible) {
|
|
47
|
-
canvas.style.display = visible ?
|
|
22
|
+
canvas.style.display = visible ? "block" : "none";
|
|
48
23
|
this.renderState.visible = visible;
|
|
49
|
-
|
|
50
|
-
// Without you don't see others ol layers on top.
|
|
51
|
-
canvas.style.position = 'absolute';
|
|
24
|
+
canvas.style.position = "absolute";
|
|
52
25
|
}
|
|
53
|
-
|
|
54
26
|
const opacity = this.olLayer.getOpacity();
|
|
55
27
|
if (this.renderState.opacity !== opacity) {
|
|
56
28
|
canvas.style.opacity = opacity;
|
|
57
29
|
this.renderState.opacity = opacity;
|
|
58
30
|
}
|
|
59
|
-
|
|
60
|
-
// adjust view parameters in mapbox
|
|
61
31
|
const { rotation } = viewState;
|
|
62
32
|
if (this.renderState.rotation !== rotation) {
|
|
63
|
-
this.mbMap.rotateTo(
|
|
64
|
-
animate: false
|
|
33
|
+
this.mbMap.rotateTo(-(rotation || 0) * 180 / Math.PI, {
|
|
34
|
+
animate: false
|
|
65
35
|
});
|
|
66
36
|
changed = true;
|
|
67
37
|
this.renderState.rotation = rotation;
|
|
68
38
|
}
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
this.renderState.zoom !== viewState.zoom ||
|
|
72
|
-
this.renderState.center[0] !== viewState.center[0] ||
|
|
73
|
-
this.renderState.center[1] !== viewState.center[1]
|
|
74
|
-
) {
|
|
39
|
+
if (this.renderState.zoom !== viewState.zoom || this.renderState.center[0] !== viewState.center[0] || this.renderState.center[1] !== viewState.center[1]) {
|
|
75
40
|
this.mbMap.jumpTo({
|
|
76
41
|
center: toLonLat(viewState.center),
|
|
77
42
|
zoom: viewState.zoom - 1,
|
|
78
|
-
animate: false
|
|
43
|
+
animate: false
|
|
79
44
|
});
|
|
80
45
|
changed = true;
|
|
81
46
|
this.renderState.zoom = viewState.zoom;
|
|
82
47
|
this.renderState.center = viewState.center;
|
|
83
48
|
}
|
|
84
|
-
|
|
85
49
|
const size = this.map.getSize();
|
|
86
|
-
if (
|
|
87
|
-
this.renderState.size[0] !== size[0] ||
|
|
88
|
-
this.renderState.size[1] !== size[1]
|
|
89
|
-
) {
|
|
50
|
+
if (this.renderState.size[0] !== size[0] || this.renderState.size[1] !== size[1]) {
|
|
90
51
|
changed = true;
|
|
91
52
|
this.renderState.size = size;
|
|
92
53
|
}
|
|
93
|
-
|
|
94
|
-
// cancel the scheduled update & trigger synchronous redraw
|
|
95
|
-
// see https://github.com/mapbox/mapbox-gl-js/issues/7893#issue-408992184
|
|
96
|
-
// NOTE: THIS MIGHT BREAK WHEN UPDATING MAPBOX
|
|
97
|
-
if (
|
|
98
|
-
this.mbMap &&
|
|
99
|
-
this.mbMap.style &&
|
|
100
|
-
this.mbMap.isStyleLoaded() &&
|
|
101
|
-
changed
|
|
102
|
-
) {
|
|
54
|
+
if (this.mbMap && this.mbMap.style && this.mbMap.isStyleLoaded() && changed) {
|
|
103
55
|
try {
|
|
104
56
|
if (this.mbMap._frame) {
|
|
105
57
|
this.mbMap._frame.cancel();
|
|
@@ -107,209 +59,112 @@ export default class MapboxLayer extends Layer {
|
|
|
107
59
|
}
|
|
108
60
|
this.mbMap._render();
|
|
109
61
|
} catch (err) {
|
|
110
|
-
// ignore render errors because it's probably related to
|
|
111
|
-
// a render during an update of the style.
|
|
112
|
-
// eslint-disable-next-line no-console
|
|
113
62
|
console.warn(err);
|
|
114
63
|
}
|
|
115
64
|
}
|
|
116
|
-
|
|
117
65
|
return this.mbMap.getContainer();
|
|
118
|
-
}
|
|
66
|
+
}
|
|
119
67
|
});
|
|
120
|
-
|
|
121
68
|
super({
|
|
122
69
|
...options,
|
|
123
|
-
olLayer: mbLayer
|
|
70
|
+
olLayer: mbLayer
|
|
124
71
|
});
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Url of the mapbox style.
|
|
128
|
-
* @type {string}
|
|
129
|
-
* @private
|
|
130
|
-
*/
|
|
131
72
|
this.styleUrl = options.url;
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Api key for the url of the mapbox style.
|
|
135
|
-
* If set to false, the apiKey is not required.
|
|
136
|
-
* @type {string}
|
|
137
|
-
* @private
|
|
138
|
-
*/
|
|
139
73
|
this.apiKey = options.apiKey;
|
|
140
|
-
|
|
141
|
-
/**
|
|
142
|
-
* Name of the apiKey to set in the url request.
|
|
143
|
-
* Default is 'key'.
|
|
144
|
-
* @type {string}
|
|
145
|
-
* @private
|
|
146
|
-
*/
|
|
147
|
-
this.apiKeyName = options.apiKeyName || 'key';
|
|
148
|
-
|
|
149
|
-
/** @ignore */
|
|
74
|
+
this.apiKeyName = options.apiKeyName || "key";
|
|
150
75
|
this.updateAttribution = this.updateAttribution.bind(this);
|
|
151
76
|
}
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
* Initialize the layer and listen to feature clicks.
|
|
155
|
-
* @param {ol/Map~Map} map
|
|
156
|
-
*/
|
|
157
|
-
init(map) {
|
|
158
|
-
super.init(map);
|
|
159
|
-
|
|
77
|
+
attachToMap(map) {
|
|
78
|
+
super.attachToMap(map);
|
|
160
79
|
if (!this.map || this.mbMap) {
|
|
161
80
|
return;
|
|
162
81
|
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* The feature format.
|
|
166
|
-
* @type {ol/format/GeoJSON}
|
|
167
|
-
*/
|
|
168
82
|
this.format = new GeoJSON({
|
|
169
|
-
featureProjection: this.map.getView().getProjection()
|
|
83
|
+
featureProjection: this.map.getView().getProjection()
|
|
170
84
|
});
|
|
171
|
-
|
|
172
85
|
this.loadMbMap();
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (this.mbMap) {
|
|
178
|
-
this.mbMap.resize();
|
|
179
|
-
}
|
|
180
|
-
} catch (err) {
|
|
181
|
-
// ignore render errors
|
|
182
|
-
// eslint-disable-next-line no-console
|
|
183
|
-
console.warn(err);
|
|
86
|
+
this.olListenersKeys.push(this.map.on("change:size", () => {
|
|
87
|
+
try {
|
|
88
|
+
if (this.mbMap) {
|
|
89
|
+
this.mbMap.resize();
|
|
184
90
|
}
|
|
185
|
-
})
|
|
186
|
-
|
|
91
|
+
} catch (err) {
|
|
92
|
+
console.warn(err);
|
|
93
|
+
}
|
|
94
|
+
}));
|
|
187
95
|
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Terminate what was initialized in init function. Remove layer, events...
|
|
191
|
-
*/
|
|
192
|
-
terminate() {
|
|
96
|
+
detachFromMap() {
|
|
193
97
|
if (this.mbMap) {
|
|
194
|
-
this.mbMap.off(
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
this.mbMap.triggerRepaint = () => {};
|
|
98
|
+
this.mbMap.off("idle", this.updateAttribution);
|
|
99
|
+
this.mbMap.triggerRepaint = () => {
|
|
100
|
+
};
|
|
198
101
|
this.mbMap.remove();
|
|
199
102
|
this.mbMap = null;
|
|
200
103
|
}
|
|
201
104
|
this.loaded = false;
|
|
202
|
-
super.
|
|
105
|
+
super.detachFromMap();
|
|
203
106
|
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Returns a style URL with apiKey & apiKeyName infos.
|
|
207
|
-
* @private
|
|
208
|
-
*/
|
|
209
107
|
createStyleUrl() {
|
|
210
108
|
return getMapboxStyleUrl(this.apiKey, this.apiKeyName, this.styleUrl);
|
|
211
109
|
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Create the mapbox map.
|
|
215
|
-
* @private
|
|
216
|
-
*/
|
|
217
110
|
loadMbMap() {
|
|
218
|
-
this.olListenersKeys.push(
|
|
219
|
-
this.
|
|
220
|
-
|
|
221
|
-
}),
|
|
222
|
-
);
|
|
223
|
-
|
|
111
|
+
this.olListenersKeys.push(this.map.on("change:target", () => {
|
|
112
|
+
this.loadMbMap();
|
|
113
|
+
}));
|
|
224
114
|
if (!this.map.getTargetElement()) {
|
|
225
115
|
return;
|
|
226
116
|
}
|
|
227
|
-
|
|
228
117
|
if (!this.visible) {
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
this.loadMbMap();
|
|
233
|
-
}),
|
|
234
|
-
);
|
|
118
|
+
this.olListenersKeys.push(this.once("change:visible", () => {
|
|
119
|
+
this.loadMbMap();
|
|
120
|
+
}));
|
|
235
121
|
return;
|
|
236
122
|
}
|
|
237
|
-
|
|
238
|
-
// If the map hasn't been resized, the center could be [NaN,NaN].
|
|
239
|
-
// We set default good value for the mapbox map, to avoid the app crashes.
|
|
240
123
|
let [x, y] = this.map.getView().getCenter();
|
|
241
124
|
if (!x || !y) {
|
|
242
125
|
x = 0;
|
|
243
126
|
y = 0;
|
|
244
127
|
}
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
container.style.
|
|
248
|
-
container.style.
|
|
249
|
-
container.style.height = '100%';
|
|
250
|
-
|
|
251
|
-
/**
|
|
252
|
-
* A mapbox map
|
|
253
|
-
* @type {mapboxgl.Map}
|
|
254
|
-
*/
|
|
128
|
+
const container = document.createElement("div");
|
|
129
|
+
container.style.position = "absolute";
|
|
130
|
+
container.style.width = "100%";
|
|
131
|
+
container.style.height = "100%";
|
|
255
132
|
this.mbMap = new Map({
|
|
256
133
|
style: this.createStyleUrl(),
|
|
257
134
|
container,
|
|
258
135
|
interactive: false,
|
|
259
136
|
trackResize: false,
|
|
260
137
|
attributionControl: false,
|
|
261
|
-
...
|
|
138
|
+
...this.options.mapOptions || {}
|
|
262
139
|
});
|
|
263
|
-
|
|
264
|
-
// Options the last render run did happen. If something changes
|
|
265
|
-
// we have to render again
|
|
266
|
-
/** @ignore */
|
|
267
140
|
this.renderState = {
|
|
268
141
|
center: [x, y],
|
|
269
142
|
zoom: null,
|
|
270
143
|
rotation: null,
|
|
271
144
|
visible: null,
|
|
272
145
|
opacity: null,
|
|
273
|
-
size: [0, 0]
|
|
146
|
+
size: [0, 0]
|
|
274
147
|
};
|
|
275
|
-
|
|
276
|
-
this.mbMap.once('load', () => {
|
|
148
|
+
this.mbMap.once("load", () => {
|
|
277
149
|
this.mbMap.resize();
|
|
278
|
-
/**
|
|
279
|
-
* Is the map loaded.
|
|
280
|
-
* @type {boolean}
|
|
281
|
-
*/
|
|
282
150
|
this.loaded = true;
|
|
283
|
-
|
|
284
|
-
/** @ignore */
|
|
285
151
|
this.copyrights = getMapboxMapCopyrights(this.mbMap) || [];
|
|
286
|
-
|
|
287
152
|
this.olLayer.getSource().setAttributions(this.copyrights);
|
|
288
|
-
|
|
289
153
|
this.dispatchEvent({
|
|
290
|
-
type:
|
|
291
|
-
target: this
|
|
154
|
+
type: "load",
|
|
155
|
+
target: this
|
|
292
156
|
});
|
|
293
157
|
});
|
|
294
|
-
|
|
295
158
|
const mapboxCanvas = this.mbMap.getCanvas();
|
|
296
159
|
if (mapboxCanvas) {
|
|
297
160
|
if (this.options.tabIndex) {
|
|
298
|
-
mapboxCanvas.setAttribute(
|
|
161
|
+
mapboxCanvas.setAttribute("tabindex", this.options.tabIndex);
|
|
299
162
|
} else {
|
|
300
|
-
|
|
301
|
-
// so we remove completely the tabIndex attribute.
|
|
302
|
-
mapboxCanvas.removeAttribute('tabindex');
|
|
163
|
+
mapboxCanvas.removeAttribute("tabindex");
|
|
303
164
|
}
|
|
304
165
|
}
|
|
305
|
-
|
|
306
|
-
this.mbMap.on('idle', this.updateAttribution);
|
|
166
|
+
this.mbMap.on("idle", this.updateAttribution);
|
|
307
167
|
}
|
|
308
|
-
|
|
309
|
-
/**
|
|
310
|
-
* Update attributions of the source.
|
|
311
|
-
* @private
|
|
312
|
-
*/
|
|
313
168
|
updateAttribution(evt) {
|
|
314
169
|
const newAttributions = getMapboxMapCopyrights(evt.target) || [];
|
|
315
170
|
if (this.copyrights.toString() !== newAttributions.toString()) {
|
|
@@ -317,61 +172,31 @@ export default class MapboxLayer extends Layer {
|
|
|
317
172
|
this.olLayer.getSource().setAttributions(newAttributions);
|
|
318
173
|
}
|
|
319
174
|
}
|
|
320
|
-
|
|
321
|
-
/**
|
|
322
|
-
* Request feature information for a given coordinate.
|
|
323
|
-
* @param {ol/coordinate~Coordinate} coordinate Coordinate to request the information at.
|
|
324
|
-
* @param {Object} options A [mapboxgl.Map#queryrenderedfeatures](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#queryrenderedfeatures) options parameter.
|
|
325
|
-
* @return {Promise<FeatureInfo>} Promise with features, layer and coordinate. The original Mapbox feature is available as a property named 'mapboxFeature'.
|
|
326
|
-
*/
|
|
327
175
|
getFeatureInfoAtCoordinate(coordinate, options) {
|
|
328
|
-
|
|
329
|
-
if (
|
|
330
|
-
!options ||
|
|
331
|
-
!this.format ||
|
|
332
|
-
!this.mbMap ||
|
|
333
|
-
!this.mbMap.isStyleLoaded()
|
|
334
|
-
) {
|
|
176
|
+
if (!options || !this.format || !this.mbMap || !this.mbMap.isStyleLoaded()) {
|
|
335
177
|
return Promise.resolve({ coordinate, features: [], layer: this });
|
|
336
178
|
}
|
|
337
|
-
|
|
338
179
|
let pixel = coordinate && this.mbMap.project(toLonLat(coordinate));
|
|
339
|
-
|
|
340
180
|
if (this.hitTolerance) {
|
|
341
181
|
const { x, y } = pixel;
|
|
342
182
|
pixel = [
|
|
343
183
|
{ x: x - this.hitTolerance, y: y - this.hitTolerance },
|
|
344
|
-
{ x: x + this.hitTolerance, y: y + this.hitTolerance }
|
|
184
|
+
{ x: x + this.hitTolerance, y: y + this.hitTolerance }
|
|
345
185
|
];
|
|
346
186
|
}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
if (olFeature) {
|
|
355
|
-
// We save the original mapbox feature to avoid losing informations
|
|
356
|
-
// potentially needed for other functionnality like highlighting
|
|
357
|
-
// (id, layer id, source, sourceLayer ...)
|
|
358
|
-
olFeature.set('mapboxFeature', feature);
|
|
359
|
-
}
|
|
360
|
-
return olFeature;
|
|
361
|
-
});
|
|
362
|
-
|
|
187
|
+
const features = this.mbMap.queryRenderedFeatures(pixel, options).map((feature) => {
|
|
188
|
+
const olFeature = this.format.readFeature(feature);
|
|
189
|
+
if (olFeature) {
|
|
190
|
+
olFeature.set("mapboxFeature", feature);
|
|
191
|
+
}
|
|
192
|
+
return olFeature;
|
|
193
|
+
});
|
|
363
194
|
return Promise.resolve({
|
|
364
195
|
layer: this,
|
|
365
196
|
features,
|
|
366
|
-
coordinate
|
|
197
|
+
coordinate
|
|
367
198
|
});
|
|
368
199
|
}
|
|
369
|
-
|
|
370
|
-
/**
|
|
371
|
-
* Create a copy of the MapboxLayer.
|
|
372
|
-
* @param {Object} newOptions Options to override
|
|
373
|
-
* @return {MapboxLayer} A MapboxLayer
|
|
374
|
-
*/
|
|
375
200
|
clone(newOptions) {
|
|
376
201
|
return new MapboxLayer({ ...this.options, ...newOptions });
|
|
377
202
|
}
|
|
@@ -1,180 +1,154 @@
|
|
|
1
|
-
import OlMap from
|
|
2
|
-
import View from
|
|
3
|
-
import gllib from
|
|
4
|
-
import MapboxLayer from
|
|
5
|
-
|
|
1
|
+
import OlMap from "ol/Map";
|
|
2
|
+
import View from "ol/View";
|
|
3
|
+
import gllib from "mapbox-gl";
|
|
4
|
+
import MapboxLayer from "./MapboxLayer";
|
|
6
5
|
let layer;
|
|
7
6
|
let map;
|
|
8
7
|
let consoleOutput;
|
|
9
|
-
const styleUrl =
|
|
10
|
-
|
|
11
|
-
describe(
|
|
12
|
-
describe('without apiKey', () => {
|
|
8
|
+
const styleUrl = "foo.com/styles";
|
|
9
|
+
describe("MapboxLayer", () => {
|
|
10
|
+
describe("without apiKey", () => {
|
|
13
11
|
beforeEach(() => {
|
|
14
|
-
// Mock console statement
|
|
15
12
|
consoleOutput = [];
|
|
16
|
-
// eslint-disable-next-line no-console
|
|
17
13
|
console.warn = (message) => consoleOutput.push(message);
|
|
18
14
|
layer = new MapboxLayer({
|
|
19
|
-
name:
|
|
20
|
-
url: styleUrl
|
|
15
|
+
name: "Layer",
|
|
16
|
+
url: styleUrl
|
|
21
17
|
});
|
|
22
18
|
map = new OlMap({
|
|
23
|
-
target: document.createElement(
|
|
24
|
-
view: new View({ center: [0, 0] })
|
|
19
|
+
target: document.createElement("div"),
|
|
20
|
+
view: new View({ center: [0, 0] })
|
|
25
21
|
});
|
|
26
22
|
});
|
|
27
|
-
|
|
28
|
-
test('should be instanced.', () => {
|
|
23
|
+
test("should be instanced.", () => {
|
|
29
24
|
expect(layer).toBeInstanceOf(MapboxLayer);
|
|
30
25
|
expect(layer.styleUrl).toBe(styleUrl);
|
|
31
26
|
});
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
layer.init();
|
|
27
|
+
test("should not initalized mapbox map.", () => {
|
|
28
|
+
layer.attachToMap();
|
|
35
29
|
expect(layer.mbMap).toBe();
|
|
36
30
|
});
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
layer.init(map);
|
|
31
|
+
test("should initalized mapbox map and warn the user if there is no api key defined.", () => {
|
|
32
|
+
layer.attachToMap(map);
|
|
40
33
|
expect(layer.mbMap).toBeInstanceOf(gllib.Map);
|
|
41
|
-
expect(consoleOutput[0]).toBe(
|
|
42
|
-
'No apiKey is defined for request to foo.com/styles',
|
|
43
|
-
);
|
|
34
|
+
expect(consoleOutput[0]).toBe("No apiKey is defined for request to foo.com/styles");
|
|
44
35
|
});
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
layer.init();
|
|
36
|
+
test("should called terminate on initalization.", () => {
|
|
37
|
+
const spy = jest.spyOn(layer, "detachFromMap");
|
|
38
|
+
layer.attachToMap();
|
|
49
39
|
expect(spy).toHaveBeenCalledTimes(1);
|
|
50
40
|
});
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const clone = layer.clone({ name: 'clone' });
|
|
41
|
+
test("should clone", () => {
|
|
42
|
+
const clone = layer.clone({ name: "clone" });
|
|
54
43
|
expect(clone).not.toBe(layer);
|
|
55
|
-
expect(clone.name).toBe(
|
|
44
|
+
expect(clone.name).toBe("clone");
|
|
56
45
|
expect(clone).toBeInstanceOf(MapboxLayer);
|
|
57
46
|
});
|
|
58
47
|
});
|
|
59
|
-
|
|
60
|
-
describe('with apiKey', () => {
|
|
48
|
+
describe("with apiKey", () => {
|
|
61
49
|
beforeEach(() => {
|
|
62
50
|
layer = new MapboxLayer({
|
|
63
|
-
name:
|
|
51
|
+
name: "Layer",
|
|
64
52
|
url: styleUrl,
|
|
65
|
-
apiKey:
|
|
53
|
+
apiKey: "apiKey"
|
|
66
54
|
});
|
|
67
55
|
map = new OlMap({
|
|
68
|
-
target: document.createElement(
|
|
69
|
-
view: new View({ center: [0, 0] })
|
|
56
|
+
target: document.createElement("div"),
|
|
57
|
+
view: new View({ center: [0, 0] })
|
|
70
58
|
});
|
|
71
59
|
});
|
|
72
|
-
|
|
73
|
-
test('should be instanced with apiKey.', () => {
|
|
60
|
+
test("should be instanced with apiKey.", () => {
|
|
74
61
|
expect(layer).toBeInstanceOf(MapboxLayer);
|
|
75
62
|
expect(layer.styleUrl).toBe(styleUrl);
|
|
76
63
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
layer.init();
|
|
64
|
+
test("should not initalized mapbox map.", () => {
|
|
65
|
+
layer.attachToMap();
|
|
80
66
|
expect(layer.mbMap).toBe();
|
|
81
67
|
});
|
|
82
|
-
|
|
83
68
|
test("should initalized mapbox map, with 'apiKey' prop", () => {
|
|
84
69
|
const layer1 = new MapboxLayer({
|
|
85
|
-
name:
|
|
70
|
+
name: "Layer",
|
|
86
71
|
url: styleUrl,
|
|
87
|
-
apiKey:
|
|
72
|
+
apiKey: "apiKeyVal"
|
|
88
73
|
});
|
|
89
|
-
layer1.
|
|
90
|
-
expect(layer1.mbMap.options.style).toBe(
|
|
74
|
+
layer1.attachToMap(map);
|
|
75
|
+
expect(layer1.mbMap.options.style).toBe("foo.com/styles?key=apiKeyVal");
|
|
91
76
|
});
|
|
92
|
-
|
|
93
77
|
test("should initalized mapbox map, with 'apiKeyName' prop", () => {
|
|
94
78
|
const layer1 = new MapboxLayer({
|
|
95
|
-
name:
|
|
79
|
+
name: "Layer",
|
|
96
80
|
url: styleUrl,
|
|
97
|
-
apiKey:
|
|
98
|
-
apiKeyName:
|
|
81
|
+
apiKey: "test",
|
|
82
|
+
apiKeyName: "apiKey"
|
|
99
83
|
});
|
|
100
|
-
layer1.
|
|
101
|
-
expect(layer1.mbMap.options.style).toBe(
|
|
84
|
+
layer1.attachToMap(map);
|
|
85
|
+
expect(layer1.mbMap.options.style).toBe("foo.com/styles?apiKey=test");
|
|
102
86
|
});
|
|
103
87
|
});
|
|
104
|
-
|
|
105
|
-
describe('#getFeatureInfoAtCoordinate()', () => {
|
|
88
|
+
describe("#getFeatureInfoAtCoordinate()", () => {
|
|
106
89
|
let layer1;
|
|
107
90
|
beforeEach(() => {
|
|
108
91
|
layer1 = new MapboxLayer({
|
|
109
|
-
name:
|
|
92
|
+
name: "Layer",
|
|
110
93
|
url: styleUrl,
|
|
111
|
-
apiKey:
|
|
112
|
-
apiKeyName:
|
|
94
|
+
apiKey: "test",
|
|
95
|
+
apiKeyName: "apiKey"
|
|
113
96
|
});
|
|
114
|
-
layer1.
|
|
97
|
+
layer1.attachToMap(map);
|
|
115
98
|
layer1.mbMap.isStyleLoaded = jest.fn(() => true);
|
|
116
99
|
layer1.mbMap.getSource = jest.fn(() => true);
|
|
117
100
|
});
|
|
118
|
-
|
|
119
101
|
afterEach(() => {
|
|
120
102
|
layer1.mbMap.getSource.mockRestore();
|
|
121
103
|
layer1.mbMap.isStyleLoaded.mockRestore();
|
|
122
104
|
});
|
|
123
|
-
|
|
124
|
-
test('should set the mapboxFeature as a property', (done) => {
|
|
105
|
+
test("should set the mapboxFeature as a property", (done) => {
|
|
125
106
|
const mapboxFeature = {
|
|
126
|
-
id:
|
|
127
|
-
type:
|
|
107
|
+
id: "2",
|
|
108
|
+
type: "Feature",
|
|
128
109
|
properties: {
|
|
129
|
-
foo:
|
|
110
|
+
foo: "bar"
|
|
130
111
|
},
|
|
131
|
-
source:
|
|
132
|
-
sourceLayer:
|
|
112
|
+
source: "barr",
|
|
113
|
+
sourceLayer: "fooo"
|
|
133
114
|
};
|
|
134
115
|
layer1.mbMap.project = jest.fn((coord) => ({ x: coord[0], y: coord[1] }));
|
|
135
116
|
layer1.mbMap.queryRenderedFeatures = jest.fn(() => [mapboxFeature]);
|
|
136
117
|
layer1.getFeatureInfoAtCoordinate([0, 0], {}).then((featureInfo) => {
|
|
137
|
-
expect(featureInfo.features[0].get(
|
|
138
|
-
mapboxFeature,
|
|
139
|
-
);
|
|
118
|
+
expect(featureInfo.features[0].get("mapboxFeature")).toBe(mapboxFeature);
|
|
140
119
|
done();
|
|
141
120
|
});
|
|
142
121
|
layer1.mbMap.project.mockRestore();
|
|
143
122
|
layer1.mbMap.queryRenderedFeatures.mockRestore();
|
|
144
123
|
});
|
|
145
|
-
describe(
|
|
124
|
+
describe("should use hitTolerance property", () => {
|
|
146
125
|
beforeEach(() => {
|
|
147
126
|
layer1.mbMap.project = jest.fn((coord) => ({
|
|
148
127
|
x: coord[0],
|
|
149
|
-
y: coord[1]
|
|
128
|
+
y: coord[1]
|
|
150
129
|
}));
|
|
151
130
|
});
|
|
152
|
-
|
|
153
131
|
afterEach(() => {
|
|
154
132
|
layer1.mbMap.project.mockRestore();
|
|
155
133
|
layer1.mbMap.queryRenderedFeatures.mockRestore();
|
|
156
134
|
});
|
|
157
|
-
|
|
158
|
-
test('when hitTolerance is not set', (done) => {
|
|
135
|
+
test("when hitTolerance is not set", (done) => {
|
|
159
136
|
layer1.mbMap.queryRenderedFeatures = jest.fn((pixelBounds) => {
|
|
160
|
-
// Use default hoitTolerance
|
|
161
137
|
expect(pixelBounds).toEqual([
|
|
162
138
|
{ x: -5, y: -5 },
|
|
163
|
-
{ x: 5, y: 5 }
|
|
139
|
+
{ x: 5, y: 5 }
|
|
164
140
|
]);
|
|
165
141
|
done();
|
|
166
142
|
return [];
|
|
167
143
|
});
|
|
168
144
|
layer1.getFeatureInfoAtCoordinate([0, 0], {});
|
|
169
145
|
});
|
|
170
|
-
|
|
171
|
-
test('when hitTolerance is set to 10', (done) => {
|
|
146
|
+
test("when hitTolerance is set to 10", (done) => {
|
|
172
147
|
layer1.hitTolerance = 10;
|
|
173
148
|
layer1.mbMap.queryRenderedFeatures = jest.fn((pixelBounds) => {
|
|
174
|
-
// Use default hoitTolerance
|
|
175
149
|
expect(pixelBounds).toEqual([
|
|
176
150
|
{ x: -10, y: -10 },
|
|
177
|
-
{ x: 10, y: 10 }
|
|
151
|
+
{ x: 10, y: 10 }
|
|
178
152
|
]);
|
|
179
153
|
done();
|
|
180
154
|
return [];
|