mobility-toolbox-js 2.0.0-beta.1 → 2.0.0
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/README.md +7 -4
- package/api/index.js +0 -1
- package/api/tralis/TralisAPI.js +1 -1
- package/common/controls/Control.js +4 -1
- package/common/layers/Layer.js +18 -49
- package/common/layers/Layer.test.js +2 -106
- package/common/mixins/SearchMixin.js +1 -1
- package/common/mixins/TralisLayerMixin.js +549 -21
- package/common/styles/index.js +4 -0
- package/common/{utils/delayTrackerStyle.js → styles/trackerDefaultStyle.js} +8 -8
- package/common/styles/trackerDelayStyle.js +17 -0
- package/common/styles/trackerSimpleStyle.js +22 -0
- package/common/trackerConfig.test.js +0 -13
- package/common/utils/getMapboxMapCopyrights.js +1 -0
- package/common/utils/index.js +2 -3
- package/common/utils/sortByDelay.js +23 -0
- package/index.js +1 -1
- package/index.js.map +1 -1
- package/mapbox/controls/CopyrightControl.js +5 -1
- package/mapbox/index.js +0 -2
- package/mapbox/layers/Layer.test.js +2 -2
- package/mapbox/layers/TralisLayer.js +270 -5
- package/mapbox/layers/TralisLayer.test.js +40 -0
- package/module.js +1 -9
- package/ol/controls/CopyrightControl.js +4 -4
- package/ol/controls/CopyrightControl.test.js +16 -16
- package/ol/controls/RoutingControl.js +9 -7
- package/ol/controls/RoutingControl.test.js +1 -1
- package/ol/controls/StopFinderControl.js +8 -6
- package/ol/controls/StopFinderControl.test.js +1 -1
- package/ol/index.js +3 -3
- package/ol/layers/Layer.js +9 -0
- package/ol/layers/Layer.test.js +22 -7
- package/ol/layers/MapboxLayer.js +39 -44
- package/ol/layers/MapboxLayer.test.js +5 -5
- package/ol/layers/MapboxStyleLayer.js +0 -6
- package/ol/layers/MapboxStyleLayer.test.js +22 -6
- package/ol/layers/MaplibreLayer.js +280 -0
- package/ol/layers/RoutingLayer.test.js +1 -1
- package/ol/layers/TralisLayer.js +258 -76
- package/ol/layers/TralisLayer.test.js +1 -49
- package/ol/layers/VectorLayer.test.js +1 -1
- package/ol/layers/WMSLayer.test.js +6 -2
- package/ol/styles/fullTrajectoryDelayStyle.js +35 -0
- package/ol/styles/fullTrajectoryStyle.js +51 -0
- package/ol/styles/index.js +2 -0
- package/package.json +16 -8
- package/api/trajserv/TrajservAPI.js +0 -71
- package/api/trajserv/TrajservAPI.test.js +0 -171
- package/api/trajserv/TrajservAPIUtils.js +0 -191
- package/api/trajserv/TrajservAPIUtils.test.js +0 -40
- package/api/trajserv/typedefs.js +0 -44
- package/common/mixins/MapMixin.js +0 -103
- package/common/mixins/TrackerLayerMixin.js +0 -745
- package/common/mixins/TrajservLayerMixin.js +0 -544
- package/common/utils/simpleTrackerStyle.js +0 -18
- package/mapbox/Map.js +0 -87
- package/mapbox/layers/TrackerLayer.js +0 -282
- package/mapbox/layers/TrackerLayer.test.js +0 -68
- package/mapbox/layers/TrajservLayer.js +0 -114
- package/mapbox/layers/TrajservLayer.test.js +0 -90
- package/ol/Map.js +0 -109
- package/ol/Map.test.js +0 -34
- package/ol/layers/TrackerLayer.js +0 -296
- package/ol/layers/TrackerLayer.test.js +0 -70
- package/ol/layers/TrajservLayer.js +0 -190
- package/ol/layers/TrajservLayer.test.js +0 -113
package/ol/layers/TralisLayer.js
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import GeoJSON from 'ol/format/GeoJSON';
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
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';
|
|
4
7
|
import mixin from '../../common/mixins/TralisLayerMixin';
|
|
5
|
-
import {
|
|
8
|
+
import { fullTrajectoryStyle } from '../styles';
|
|
6
9
|
|
|
7
10
|
const format = new GeoJSON();
|
|
8
11
|
|
|
@@ -20,36 +23,213 @@ const format = new GeoJSON();
|
|
|
20
23
|
*
|
|
21
24
|
* @see <a href="/api/class/src/api/tralis/TralisAPI%20js~TralisAPI%20html">TralisAPI</a>
|
|
22
25
|
*
|
|
23
|
-
* @extends {
|
|
26
|
+
* @extends {Layer}
|
|
24
27
|
* @implements {TralisLayerInterface}
|
|
25
28
|
*/
|
|
26
|
-
class TralisLayer extends mixin(
|
|
29
|
+
class TralisLayer extends mixin(Layer) {
|
|
27
30
|
/**
|
|
28
|
-
*
|
|
31
|
+
* Constructor.
|
|
29
32
|
*
|
|
33
|
+
* @param {Object} options
|
|
30
34
|
* @private
|
|
31
35
|
*/
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
constructor(options = {}) {
|
|
37
|
+
// We use a group to be able to add custom vector layer in extended class.
|
|
38
|
+
// For example TrajservLayer use a vectorLayer to display the complete trajectory.
|
|
39
|
+
super({
|
|
40
|
+
...options,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/** @ignore */
|
|
44
|
+
this.olLayer =
|
|
45
|
+
options.olLayer ||
|
|
46
|
+
new Group({
|
|
47
|
+
layers: [
|
|
48
|
+
new VectorLayer({
|
|
49
|
+
source: new VectorSource({ features: [] }),
|
|
50
|
+
style: options.fullTrajectoryStyle || fullTrajectoryStyle,
|
|
51
|
+
}),
|
|
52
|
+
new OLLayer({
|
|
53
|
+
source: new Source({}),
|
|
54
|
+
render: (frameState) => {
|
|
55
|
+
if (!this.tracker || !this.tracker.canvas) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (!this.container) {
|
|
60
|
+
this.container = document.createElement('div');
|
|
61
|
+
this.container.style.position = 'absolute';
|
|
62
|
+
this.container.style.width = '100%';
|
|
63
|
+
this.container.style.height = '100%';
|
|
64
|
+
this.transformContainer = document.createElement('div');
|
|
65
|
+
this.transformContainer.style.position = 'absolute';
|
|
66
|
+
this.transformContainer.style.width = '100%';
|
|
67
|
+
this.transformContainer.style.height = '100%';
|
|
68
|
+
this.container.appendChild(this.transformContainer);
|
|
69
|
+
this.tracker.canvas.style.position = 'absolute';
|
|
70
|
+
this.tracker.canvas.style.top = '0';
|
|
71
|
+
this.tracker.canvas.style.left = '0';
|
|
72
|
+
this.tracker.canvas.style.transformOrigin = 'top left';
|
|
73
|
+
this.transformContainer.appendChild(this.tracker.canvas);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (this.renderedViewState) {
|
|
77
|
+
const { center, resolution, rotation } = frameState.viewState;
|
|
78
|
+
const {
|
|
79
|
+
center: renderedCenter,
|
|
80
|
+
resolution: renderedResolution,
|
|
81
|
+
rotation: renderedRotation,
|
|
82
|
+
} = this.renderedViewState;
|
|
83
|
+
|
|
84
|
+
if (renderedResolution / resolution >= 3) {
|
|
85
|
+
// Avoid having really big points when zooming fast.
|
|
86
|
+
const { canvas } = this.tracker;
|
|
87
|
+
const context = canvas.getContext('2d');
|
|
88
|
+
context.clearRect(0, 0, canvas.width, canvas.height);
|
|
89
|
+
} else {
|
|
90
|
+
const pixelCenterRendered =
|
|
91
|
+
this.map.getPixelFromCoordinate(renderedCenter);
|
|
92
|
+
const pixelCenter = this.map.getPixelFromCoordinate(center);
|
|
93
|
+
this.transformContainer.style.transform = composeCssTransform(
|
|
94
|
+
pixelCenterRendered[0] - pixelCenter[0],
|
|
95
|
+
pixelCenterRendered[1] - pixelCenter[1],
|
|
96
|
+
renderedResolution / resolution,
|
|
97
|
+
renderedResolution / resolution,
|
|
98
|
+
rotation - renderedRotation,
|
|
99
|
+
0,
|
|
100
|
+
0,
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return this.container;
|
|
105
|
+
},
|
|
106
|
+
}),
|
|
107
|
+
],
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
// We store the layer used to highlight the full Trajectory
|
|
111
|
+
this.vectorLayer = this.olLayer.getLayers().item(0);
|
|
112
|
+
|
|
113
|
+
// Options the last render run did happen. If something changes
|
|
114
|
+
// we have to render again
|
|
115
|
+
/** @ignore */
|
|
116
|
+
this.renderState = {
|
|
117
|
+
center: [0, 0],
|
|
118
|
+
zoom: null,
|
|
119
|
+
rotation: 0,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
init(map) {
|
|
124
|
+
super.init(map);
|
|
125
|
+
if (this.map) {
|
|
126
|
+
this.olListenersKeys.push(
|
|
127
|
+
this.map.on(['moveend', 'change:target'], (evt) => {
|
|
128
|
+
const view = this.map.getView();
|
|
129
|
+
if (view.getAnimating() || view.getInteracting()) {
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
const zoom = view.getZoom();
|
|
133
|
+
|
|
134
|
+
// Update the interval between render updates
|
|
135
|
+
if (this.currentZoom !== zoom) {
|
|
136
|
+
this.onZoomEnd(evt);
|
|
137
|
+
}
|
|
138
|
+
this.currentZoom = zoom;
|
|
139
|
+
|
|
140
|
+
this.onMoveEnd(evt);
|
|
141
|
+
}),
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Destroy the container of the tracker.
|
|
148
|
+
*/
|
|
149
|
+
terminate() {
|
|
150
|
+
super.terminate();
|
|
151
|
+
this.container = null;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Detect in the canvas if there is data to query at a specific coordinate.
|
|
156
|
+
* @param {ol/coordinate~Coordinate} coordinate The coordinate to test
|
|
157
|
+
* @returns
|
|
158
|
+
*/
|
|
159
|
+
hasFeatureInfoAtCoordinate(coordinate) {
|
|
160
|
+
if (this.map && this.tracker && this.tracker.canvas) {
|
|
161
|
+
const context = this.tracker.canvas.getContext('2d');
|
|
162
|
+
const pixel = this.map.getPixelFromCoordinate(coordinate);
|
|
163
|
+
return !!context.getImageData(
|
|
164
|
+
pixel[0] * this.pixelRatio,
|
|
165
|
+
pixel[1] * this.pixelRatio,
|
|
166
|
+
1,
|
|
167
|
+
1,
|
|
168
|
+
).data[3];
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Render the trajectories using current map's size, resolution and rotation.
|
|
175
|
+
* @param {boolean} noInterpolate if true, renders the vehicles without interpolating theirs positions.
|
|
176
|
+
* @overrides
|
|
177
|
+
*/
|
|
178
|
+
renderTrajectories(noInterpolate) {
|
|
179
|
+
const view = this.map.getView();
|
|
180
|
+
super.renderTrajectories(
|
|
181
|
+
{
|
|
182
|
+
size: this.map.getSize(),
|
|
183
|
+
center: this.map.getView().getCenter(),
|
|
184
|
+
extent: view.calculateExtent(),
|
|
185
|
+
resolution: view.getResolution(),
|
|
186
|
+
rotation: view.getRotation(),
|
|
187
|
+
zoom: view.getZoom(),
|
|
188
|
+
pixelRatio: this.pixelRatio,
|
|
189
|
+
},
|
|
190
|
+
noInterpolate,
|
|
37
191
|
);
|
|
38
192
|
}
|
|
39
193
|
|
|
40
194
|
/**
|
|
41
|
-
*
|
|
42
|
-
*
|
|
195
|
+
* Launch renderTrajectories. it avoids duplicating code in renderTrajectories methhod.
|
|
43
196
|
* @private
|
|
197
|
+
* @override
|
|
44
198
|
*/
|
|
45
|
-
|
|
46
|
-
let
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
199
|
+
renderTrajectoriesInternal(viewState, noInterpolate) {
|
|
200
|
+
let isRendered = false;
|
|
201
|
+
|
|
202
|
+
const blockRendering =
|
|
203
|
+
this.map.getView().getAnimating() || this.map.getView().getInteracting();
|
|
204
|
+
|
|
205
|
+
// Don't render the map when the map is animating or interacting.
|
|
206
|
+
isRendered = blockRendering
|
|
207
|
+
? false
|
|
208
|
+
: super.renderTrajectoriesInternal(viewState, noInterpolate);
|
|
209
|
+
|
|
210
|
+
// We update the current render state.
|
|
211
|
+
if (isRendered) {
|
|
212
|
+
this.renderedViewState = { ...viewState };
|
|
213
|
+
|
|
214
|
+
if (this.transformContainer) {
|
|
215
|
+
this.transformContainer.style.transform = '';
|
|
216
|
+
}
|
|
51
217
|
}
|
|
52
|
-
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Return the delay in ms before the next rendering.
|
|
222
|
+
*/
|
|
223
|
+
getRefreshTimeInMs() {
|
|
224
|
+
return super.getRefreshTimeInMs(this.map.getView().getZoom());
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
getFeatureInfoAtCoordinate(coordinate, options = {}) {
|
|
228
|
+
const resolution = this.map.getView().getResolution();
|
|
229
|
+
return super.getFeatureInfoAtCoordinate(coordinate, {
|
|
230
|
+
resolution,
|
|
231
|
+
...options,
|
|
232
|
+
});
|
|
53
233
|
}
|
|
54
234
|
|
|
55
235
|
/**
|
|
@@ -59,9 +239,7 @@ class TralisLayer extends mixin(TrackerLayer) {
|
|
|
59
239
|
* @private
|
|
60
240
|
* @override
|
|
61
241
|
*/
|
|
62
|
-
onMoveEnd(
|
|
63
|
-
super.onMoveEnd(evt);
|
|
64
|
-
|
|
242
|
+
onMoveEnd() {
|
|
65
243
|
if (this.visible && this.isUpdateBboxOnMoveEnd) {
|
|
66
244
|
this.setBbox();
|
|
67
245
|
}
|
|
@@ -77,19 +255,74 @@ class TralisLayer extends mixin(TrackerLayer) {
|
|
|
77
255
|
}
|
|
78
256
|
|
|
79
257
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
258
|
+
* Function called on moveend event only when the zoom has changed.
|
|
259
|
+
*
|
|
260
|
+
* @param {ol/MapEvent~MapEvent} evt Moveend event.
|
|
261
|
+
* @private
|
|
262
|
+
* @override
|
|
263
|
+
*/
|
|
264
|
+
// eslint-disable-next-line no-unused-vars
|
|
265
|
+
onZoomEnd(evt) {
|
|
266
|
+
super.onZoomEnd(evt);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* Update the cursor style when hovering a vehicle.
|
|
271
|
+
*
|
|
272
|
+
* @private
|
|
273
|
+
* @override
|
|
274
|
+
*/
|
|
275
|
+
onFeatureHover(features, layer, coordinate) {
|
|
276
|
+
super.onFeatureHover(features, layer, coordinate);
|
|
277
|
+
this.map.getTargetElement().style.cursor = features.length
|
|
278
|
+
? 'pointer'
|
|
279
|
+
: 'auto';
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Display the complete trajectory of the vehicle.
|
|
82
284
|
*
|
|
83
285
|
* @private
|
|
84
286
|
* @override
|
|
85
287
|
*/
|
|
86
288
|
onFeatureClick(features, layer, coordinate) {
|
|
87
289
|
super.onFeatureClick(features, layer, coordinate);
|
|
290
|
+
if (!features.length && this.vectorLayer) {
|
|
291
|
+
this.vectorLayer.getSource().clear();
|
|
292
|
+
}
|
|
88
293
|
if (this.selectedVehicleId) {
|
|
89
294
|
this.highlightTrajectory(this.selectedVehicleId);
|
|
90
295
|
}
|
|
91
296
|
}
|
|
92
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Remove the trajectory form the list if necessary.
|
|
300
|
+
*
|
|
301
|
+
* @private
|
|
302
|
+
*/
|
|
303
|
+
purgeTrajectory(trajectory, extent, zoom) {
|
|
304
|
+
return super.purgeTrajectory(
|
|
305
|
+
trajectory,
|
|
306
|
+
extent || this.map.getView().calculateExtent(),
|
|
307
|
+
zoom || this.map.getView().getZoom(),
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Send the current bbox to the websocket
|
|
313
|
+
*
|
|
314
|
+
* @private
|
|
315
|
+
*/
|
|
316
|
+
setBbox(extent, zoom) {
|
|
317
|
+
let newExtent = extent;
|
|
318
|
+
let newZoom = zoom;
|
|
319
|
+
if (!newExtent && this.isUpdateBboxOnMoveEnd) {
|
|
320
|
+
newExtent = extent || this.map.getView().calculateExtent();
|
|
321
|
+
newZoom = Math.floor(this.map.getView().getZoom());
|
|
322
|
+
}
|
|
323
|
+
super.setBbox(newExtent, newZoom);
|
|
324
|
+
}
|
|
325
|
+
|
|
93
326
|
/**
|
|
94
327
|
* Highlight the trajectory of journey.
|
|
95
328
|
* @private
|
|
@@ -108,58 +341,7 @@ class TralisLayer extends mixin(TrackerLayer) {
|
|
|
108
341
|
) {
|
|
109
342
|
return;
|
|
110
343
|
}
|
|
111
|
-
|
|
112
|
-
let lineColor = '#ffffff'; // white
|
|
113
|
-
|
|
114
|
-
if (this.useDelayStyle) {
|
|
115
|
-
lineColor = '#a0a0a0'; // grey
|
|
116
|
-
} else {
|
|
117
|
-
const props = fullTrajectory.features[0].properties;
|
|
118
|
-
const { type } = props;
|
|
119
|
-
let { stroke } = props;
|
|
120
|
-
|
|
121
|
-
if (stroke && stroke[0] !== '#') {
|
|
122
|
-
stroke = `#${stroke}`;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
lineColor = stroke || getBgColor(type);
|
|
126
|
-
|
|
127
|
-
// Don't allow white lines, use red instead.
|
|
128
|
-
lineColor = /#ffffff/i.test(lineColor) ? '#ff0000' : lineColor;
|
|
129
|
-
}
|
|
130
|
-
const style = [
|
|
131
|
-
new Style({
|
|
132
|
-
zIndex: 2,
|
|
133
|
-
image: new Circle({
|
|
134
|
-
radius: 5,
|
|
135
|
-
fill: new Fill({
|
|
136
|
-
color: '#000000',
|
|
137
|
-
}),
|
|
138
|
-
}),
|
|
139
|
-
stroke: new Stroke({
|
|
140
|
-
color: '#000000',
|
|
141
|
-
width: 6,
|
|
142
|
-
}),
|
|
143
|
-
}),
|
|
144
|
-
new Style({
|
|
145
|
-
zIndex: 3,
|
|
146
|
-
image: new Circle({
|
|
147
|
-
radius: 4,
|
|
148
|
-
fill: new Fill({
|
|
149
|
-
color: lineColor,
|
|
150
|
-
}),
|
|
151
|
-
}),
|
|
152
|
-
stroke: new Stroke({
|
|
153
|
-
color: lineColor,
|
|
154
|
-
width: 4,
|
|
155
|
-
}),
|
|
156
|
-
}),
|
|
157
|
-
];
|
|
158
|
-
this.vectorLayer.setStyle(style);
|
|
159
344
|
const features = format.readFeatures(fullTrajectory);
|
|
160
|
-
features.forEach((feature) => {
|
|
161
|
-
feature.setStyle(style);
|
|
162
|
-
});
|
|
163
345
|
this.vectorLayer.getSource().addFeatures(features);
|
|
164
346
|
});
|
|
165
347
|
}
|
|
@@ -10,7 +10,7 @@ let onClick;
|
|
|
10
10
|
let olMap;
|
|
11
11
|
let server;
|
|
12
12
|
|
|
13
|
-
describe('
|
|
13
|
+
describe('TralisLayer', () => {
|
|
14
14
|
beforeEach(() => {
|
|
15
15
|
server = new WS('ws://localhost:1234');
|
|
16
16
|
global.fetch = fetch;
|
|
@@ -69,63 +69,17 @@ describe('TrajservLayer', () => {
|
|
|
69
69
|
sort: fn,
|
|
70
70
|
});
|
|
71
71
|
expect(laye).toBeInstanceOf(TralisLayer);
|
|
72
|
-
expect(laye.useDelayStyle).toBe(false);
|
|
73
72
|
expect(laye.sort).toBe(fn);
|
|
74
73
|
});
|
|
75
74
|
|
|
76
|
-
test.only('should set a default sort function if useDelayStyle is used.', () => {
|
|
77
|
-
const laye = new TralisLayer({
|
|
78
|
-
url: 'ws://localhost:1234',
|
|
79
|
-
apiKey: 'apiKey',
|
|
80
|
-
useDelayStyle: true,
|
|
81
|
-
});
|
|
82
|
-
expect(laye).toBeInstanceOf(TralisLayer);
|
|
83
|
-
expect(laye.useDelayStyle).toBe(true);
|
|
84
|
-
expect(laye.sort).toBeDefined();
|
|
85
|
-
const red = { properties: { delay: 1000000 } };
|
|
86
|
-
const yellow = { properties: { delay: 180000 } };
|
|
87
|
-
const green2 = { properties: { delay: 178990 } };
|
|
88
|
-
const green = { properties: { delay: 0 } };
|
|
89
|
-
const gray = { properties: { delay: null } };
|
|
90
|
-
const cancelled = { properties: { cancelled: true, delay: 3000000 } };
|
|
91
|
-
|
|
92
|
-
const trajectories = [gray, green, yellow, red, green2, cancelled];
|
|
93
|
-
trajectories.sort(laye.sort);
|
|
94
|
-
expect(trajectories).toEqual([red, yellow, cancelled, green2, green, gray]);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
test('should override the default sort function when useDelayStyle is used.', () => {
|
|
98
|
-
const laye = new TralisLayer({
|
|
99
|
-
url: 'ws://localhost:1234',
|
|
100
|
-
apiKey: 'apiKey',
|
|
101
|
-
useDelayStyle: true,
|
|
102
|
-
sort: () => -1, // reverse the array
|
|
103
|
-
});
|
|
104
|
-
expect(laye).toBeInstanceOf(TralisLayer);
|
|
105
|
-
expect(laye.useDelayStyle).toBe(true);
|
|
106
|
-
expect(laye.sort).toBeDefined();
|
|
107
|
-
const red = { delay: 1000000 };
|
|
108
|
-
const yellow = { delay: 180000 };
|
|
109
|
-
const green2 = { delay: 178990 };
|
|
110
|
-
const green = { delay: 0 };
|
|
111
|
-
const gray = { delay: null };
|
|
112
|
-
const cancelled = { cancelled: true, delay: 3000000 };
|
|
113
|
-
|
|
114
|
-
const trajectories = [gray, green, yellow, red, green2, cancelled];
|
|
115
|
-
trajectories.sort(laye.sort);
|
|
116
|
-
expect(trajectories).toEqual([cancelled, green2, red, yellow, green, gray]);
|
|
117
|
-
});
|
|
118
|
-
|
|
119
75
|
test('should use filter function.', () => {
|
|
120
76
|
const fn = () => true;
|
|
121
77
|
const laye = new TralisLayer({
|
|
122
78
|
url: 'ws://localhost:1234',
|
|
123
79
|
apiKey: 'apiKey',
|
|
124
|
-
useDelayStyle: true,
|
|
125
80
|
filter: fn, // reverse the array
|
|
126
81
|
});
|
|
127
82
|
expect(laye).toBeInstanceOf(TralisLayer);
|
|
128
|
-
expect(laye.useDelayStyle).toBe(true);
|
|
129
83
|
expect(laye.filter).toBe(fn);
|
|
130
84
|
});
|
|
131
85
|
|
|
@@ -134,12 +88,10 @@ describe('TrajservLayer', () => {
|
|
|
134
88
|
const laye = new TralisLayer({
|
|
135
89
|
url: 'ws://localhost:1234',
|
|
136
90
|
apiKey: 'apiKey',
|
|
137
|
-
useDelayStyle: true,
|
|
138
91
|
filter: fn, // reverse the array
|
|
139
92
|
publishedLineName: '.*',
|
|
140
93
|
});
|
|
141
94
|
expect(laye).toBeInstanceOf(TralisLayer);
|
|
142
|
-
expect(laye.useDelayStyle).toBe(true);
|
|
143
95
|
expect(laye.filter).not.toBe(fn);
|
|
144
96
|
});
|
|
145
97
|
});
|
|
@@ -3,7 +3,7 @@ import VectorSource from 'ol/source/Vector';
|
|
|
3
3
|
import View from 'ol/View';
|
|
4
4
|
import Feature from 'ol/Feature';
|
|
5
5
|
import Point from 'ol/geom/Point';
|
|
6
|
-
import Map from '
|
|
6
|
+
import Map from 'ol/Map';
|
|
7
7
|
import VectorLayer from './VectorLayer';
|
|
8
8
|
|
|
9
9
|
const feature1 = new Feature({
|
|
@@ -3,7 +3,7 @@ import ImageLayer from 'ol/layer/Image';
|
|
|
3
3
|
import ImageWMS from 'ol/source/ImageWMS';
|
|
4
4
|
import fetch from 'jest-fetch-mock';
|
|
5
5
|
import qs from 'query-string';
|
|
6
|
-
import Map from '
|
|
6
|
+
import Map from 'ol/Map';
|
|
7
7
|
import WMSLayer from './WMSLayer';
|
|
8
8
|
|
|
9
9
|
describe('WMSLayer', () => {
|
|
@@ -23,11 +23,15 @@ describe('WMSLayer', () => {
|
|
|
23
23
|
}),
|
|
24
24
|
}),
|
|
25
25
|
});
|
|
26
|
-
|
|
26
|
+
layer.init(map);
|
|
27
27
|
fetch.mockResponseOnce(JSON.stringify({ features: [] }));
|
|
28
28
|
global.fetch = fetch;
|
|
29
29
|
});
|
|
30
30
|
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
layer.terminate();
|
|
33
|
+
});
|
|
34
|
+
|
|
31
35
|
test('should initialize.', () => {
|
|
32
36
|
expect(layer).toBeInstanceOf(WMSLayer);
|
|
33
37
|
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Style, Fill, Stroke, Circle } from 'ol/style';
|
|
2
|
+
|
|
3
|
+
const stroke = 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
|
+
|
|
17
|
+
const fill = new Style({
|
|
18
|
+
zIndex: 3,
|
|
19
|
+
image: new Circle({
|
|
20
|
+
radius: 4,
|
|
21
|
+
fill: new Fill({
|
|
22
|
+
color: '#a0a0a0',
|
|
23
|
+
}),
|
|
24
|
+
}),
|
|
25
|
+
stroke: new Stroke({
|
|
26
|
+
color: '#a0a0a0',
|
|
27
|
+
width: 4,
|
|
28
|
+
}),
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
const fullTrajectoryDelaystyle = () => {
|
|
32
|
+
return [stroke, fill];
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default fullTrajectoryDelaystyle;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Style, Fill, Stroke, Circle } from 'ol/style';
|
|
2
|
+
import { getBgColor } from '../../common/trackerConfig';
|
|
3
|
+
|
|
4
|
+
const borderStyle = new Style({
|
|
5
|
+
zIndex: 2,
|
|
6
|
+
image: new Circle({
|
|
7
|
+
radius: 5,
|
|
8
|
+
fill: new Fill({
|
|
9
|
+
color: '#000000',
|
|
10
|
+
}),
|
|
11
|
+
}),
|
|
12
|
+
stroke: new Stroke({
|
|
13
|
+
color: '#000000',
|
|
14
|
+
width: 6,
|
|
15
|
+
}),
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
const fullTrajectorystyle = (feature) => {
|
|
19
|
+
let lineColor = '#ffffff'; // white
|
|
20
|
+
|
|
21
|
+
const type = feature.get('type');
|
|
22
|
+
let stroke = feature.get('stroke');
|
|
23
|
+
|
|
24
|
+
if (stroke && stroke[0] !== '#') {
|
|
25
|
+
stroke = `#${stroke}`;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
lineColor = stroke || getBgColor(type);
|
|
29
|
+
|
|
30
|
+
// Don't allow white lines, use red instead.
|
|
31
|
+
lineColor = /#ffffff/i.test(lineColor) ? '#ff0000' : lineColor;
|
|
32
|
+
|
|
33
|
+
const style = [
|
|
34
|
+
borderStyle,
|
|
35
|
+
new Style({
|
|
36
|
+
zIndex: 3,
|
|
37
|
+
image: new Circle({
|
|
38
|
+
radius: 4,
|
|
39
|
+
fill: new Fill({
|
|
40
|
+
color: lineColor,
|
|
41
|
+
}),
|
|
42
|
+
}),
|
|
43
|
+
stroke: new Stroke({
|
|
44
|
+
color: lineColor,
|
|
45
|
+
width: 4,
|
|
46
|
+
}),
|
|
47
|
+
}),
|
|
48
|
+
];
|
|
49
|
+
return style;
|
|
50
|
+
};
|
|
51
|
+
export default fullTrajectorystyle;
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "mobility-toolbox-js",
|
|
3
3
|
"license": "MIT",
|
|
4
4
|
"description": "Toolbox for JavaScript applications in the domains of mobility and logistics.",
|
|
5
|
-
"version": "2.0.0
|
|
5
|
+
"version": "2.0.0",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"module": "module.js",
|
|
8
8
|
"dependencies": {
|
|
@@ -18,9 +18,9 @@
|
|
|
18
18
|
"path": "^0.12.7",
|
|
19
19
|
"prop-types": "15.8.1",
|
|
20
20
|
"query-string": "7.1.0",
|
|
21
|
-
"react": "
|
|
21
|
+
"react": "18",
|
|
22
22
|
"react-app-polyfill": "^1.0.6",
|
|
23
|
-
"react-dom": "
|
|
23
|
+
"react-dom": "18",
|
|
24
24
|
"react-icons": "4.3.1",
|
|
25
25
|
"react-markdown": "8.0.0",
|
|
26
26
|
"react-router-dom": "6",
|
|
@@ -32,7 +32,8 @@
|
|
|
32
32
|
"uuid": "8.3.2"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"
|
|
35
|
+
"mapbox-gl": "^1",
|
|
36
|
+
"maplibre-gl": "^1",
|
|
36
37
|
"ol": "^6"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
@@ -41,6 +42,8 @@
|
|
|
41
42
|
"@babel/plugin-transform-runtime": "7.16.10",
|
|
42
43
|
"@babel/preset-env": "^7.16.11",
|
|
43
44
|
"@babel/preset-react": "7.16.7",
|
|
45
|
+
"@commitlint/cli": "17.0.2",
|
|
46
|
+
"@commitlint/config-conventional": "17.0.2",
|
|
44
47
|
"@neutrinojs/copy": "9.5.0",
|
|
45
48
|
"@neutrinojs/jest": "^9.5.0",
|
|
46
49
|
"@neutrinojs/library": "9.5.0",
|
|
@@ -63,13 +66,14 @@
|
|
|
63
66
|
"eslint-plugin-react": "7.28.0",
|
|
64
67
|
"eslint-plugin-react-hooks": "4.3.0",
|
|
65
68
|
"fixpack": "3.0.6",
|
|
66
|
-
"husky": "
|
|
69
|
+
"husky": "8.0.1",
|
|
67
70
|
"jest": "26.6.3",
|
|
68
71
|
"jest-canvas-mock": "2.3.1",
|
|
69
72
|
"jest-fetch-mock": "3.0.3",
|
|
70
73
|
"jest-serializer-html": "7.1.0",
|
|
71
74
|
"jest-websocket-mock": "2.3.0",
|
|
72
75
|
"lint-staged": "12.3.3",
|
|
76
|
+
"mapbox-gl": "1.13.2",
|
|
73
77
|
"maplibre-gl": "2.1.9",
|
|
74
78
|
"mock-socket": "9.1.2",
|
|
75
79
|
"neutrino": "9.5.0",
|
|
@@ -80,6 +84,7 @@
|
|
|
80
84
|
"sass": "1.52.2",
|
|
81
85
|
"sass-loader": "8.0.2",
|
|
82
86
|
"sort-json": "2.0.0",
|
|
87
|
+
"standard-version": "9.5.0",
|
|
83
88
|
"start-server-and-test": "1.14.0",
|
|
84
89
|
"stylelint": "14.3.0",
|
|
85
90
|
"stylelint-config-recommended-scss": "5.0.2",
|
|
@@ -104,8 +109,11 @@
|
|
|
104
109
|
"lib:dev": "REACT_APP_LIB_MODE=1 webpack --mode development",
|
|
105
110
|
"link2": "cmdToAdd=$(node ./scripts/read-pkg-json.js add) && $cmdToAdd && yarn build && cmdToRemove=$(node ./scripts/read-pkg-json.js remove) && $cmdToRemove && cd build && yarn link",
|
|
106
111
|
"lint": "eslint 'src/**/*.js' && stylelint 'src/**/*.css' 'src/**/*.scss'",
|
|
107
|
-
"publish:beta": "HUSKY=0 yarn publish
|
|
108
|
-
"publish:
|
|
112
|
+
"publish:beta": "HUSKY=0 yarn release -- --prerelease beta --skip.changelog && git push origin HEAD && yarn run build && cd build && git push --tags && HUSKY=0 yarn publish --tag beta",
|
|
113
|
+
"publish:beta:dryrun": "yarn release -- --prerelease beta --dry-run --skip.changelog",
|
|
114
|
+
"publish:public": "yarn release && git push origin HEAD && yarn run build && cd build && git push --tags && yarn publish",
|
|
115
|
+
"publish:public:dryrun": "yarn release --dry-run",
|
|
116
|
+
"release": "standard-version",
|
|
109
117
|
"start": "yarn doc && webpack-dev-server --mode development --open",
|
|
110
118
|
"start:examples": "webpack-dev-server --mode development --open",
|
|
111
119
|
"test": "REACT_APP_LIB_MODE=1 jest",
|
|
@@ -167,7 +175,7 @@
|
|
|
167
175
|
"./module": "./module.js",
|
|
168
176
|
"./api": "./api/index.js",
|
|
169
177
|
"./common/trackerConfig": "./common/trackerConfig.js",
|
|
170
|
-
"./
|
|
178
|
+
"./utils": "./common/utils/index.js",
|
|
171
179
|
"./mapbox": "./mapbox/index.js",
|
|
172
180
|
"./ol": "./ol/index.js"
|
|
173
181
|
},
|