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
|
@@ -1,544 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-unused-vars */
|
|
2
|
-
/* eslint-disable class-methods-use-this */
|
|
3
|
-
/* eslint-disable max-classes-per-file */
|
|
4
|
-
import qs from 'query-string';
|
|
5
|
-
import { unByKey } from 'ol/Observable';
|
|
6
|
-
import { getUTCDateString, getUTCTimeString } from '../utils';
|
|
7
|
-
import {
|
|
8
|
-
getRadius,
|
|
9
|
-
getBgColor,
|
|
10
|
-
getDelayColor,
|
|
11
|
-
getDelayText,
|
|
12
|
-
getTextColor,
|
|
13
|
-
getTextSize,
|
|
14
|
-
} from '../trackerConfig';
|
|
15
|
-
import { TrajservAPI } from '../../api';
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* TrajservLayerInterface.
|
|
19
|
-
*
|
|
20
|
-
* @classproperty {boolean} isTrackerLayer - Property for duck typing since `instanceof` is not working when the instance was created on different bundles.
|
|
21
|
-
* @classproperty {function} style - Style of the vehicle.
|
|
22
|
-
* @classproperty {FilterFunction} filter - Time speed.
|
|
23
|
-
* @classproperty {function} sort - Set the filter for tracker features.
|
|
24
|
-
*
|
|
25
|
-
* @extends {TrackerLayerInterface}
|
|
26
|
-
* @deprecated
|
|
27
|
-
*/
|
|
28
|
-
export class TrajservLayerInterface {
|
|
29
|
-
/**
|
|
30
|
-
* Initialize the layer and listen to feature clicks.
|
|
31
|
-
* @param {ol/Map~Map|mapboxgl.Map} map A map.
|
|
32
|
-
* @override
|
|
33
|
-
*/
|
|
34
|
-
init(map) {}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Start to update trajectories and initialize the filter.
|
|
38
|
-
* @override
|
|
39
|
-
*/
|
|
40
|
-
start() {}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Stop to update trajectories.
|
|
44
|
-
* @override
|
|
45
|
-
*/
|
|
46
|
-
stop() {}
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Set the tracker filter property using class properties.
|
|
50
|
-
* @private
|
|
51
|
-
*/
|
|
52
|
-
addTrackerFilters() {}
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Abort http requests.
|
|
56
|
-
*
|
|
57
|
-
* @private
|
|
58
|
-
*/
|
|
59
|
-
abortFetchTrajectories() {}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Fetch stations information with a trajectory id.
|
|
63
|
-
* @param {number} trajId The id of the trajectory.
|
|
64
|
-
* @private
|
|
65
|
-
*/
|
|
66
|
-
updateTrajectoryStations(trajId) {}
|
|
67
|
-
|
|
68
|
-
/**
|
|
69
|
-
* Returns the URL parameters.
|
|
70
|
-
* @param {Object} extraParams Extra parameters
|
|
71
|
-
* @return {Object}
|
|
72
|
-
* @private
|
|
73
|
-
*/
|
|
74
|
-
getParams(extraParams = {}) {}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Start the update of trajectories.
|
|
78
|
-
* @private
|
|
79
|
-
*/
|
|
80
|
-
startUpdateTrajectories() {}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Stop the update of trajectories.
|
|
84
|
-
* @private
|
|
85
|
-
*/
|
|
86
|
-
stopUpdateTrajectories() {}
|
|
87
|
-
|
|
88
|
-
/**
|
|
89
|
-
* Update the trajectories
|
|
90
|
-
* @private
|
|
91
|
-
*/
|
|
92
|
-
updateTrajectories() {}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Define the style of the vehicle.
|
|
96
|
-
* Draw a circle depending on trajectory data.
|
|
97
|
-
*
|
|
98
|
-
* @param {TrajservTrajectory} trajectory A trajectory
|
|
99
|
-
* @param {ViewState} viewState Map's view state (zoom, resolution, center, ...)
|
|
100
|
-
* @private
|
|
101
|
-
*/
|
|
102
|
-
defaultStyle(trajectory, viewState) {}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Mixin for TrajservLayerInterface.
|
|
107
|
-
*
|
|
108
|
-
* @param {TrackerLayer} TrackerLayer A {TrackerLayer} class to extend with {TrajservLayerInterface} functionnalities.
|
|
109
|
-
* @return {Class} A class that implements {TrajservLayerInterface} class and extends Base;
|
|
110
|
-
* @private
|
|
111
|
-
*/
|
|
112
|
-
const TrajservLayerMixin = (TrackerLayer) =>
|
|
113
|
-
class extends TrackerLayer {
|
|
114
|
-
/**
|
|
115
|
-
* Define layer's properties.
|
|
116
|
-
*
|
|
117
|
-
* @ignore
|
|
118
|
-
*/
|
|
119
|
-
defineProperties(options) {
|
|
120
|
-
super.defineProperties(options);
|
|
121
|
-
|
|
122
|
-
let requestIntervalSeconds = 3;
|
|
123
|
-
let defaultApi;
|
|
124
|
-
if (!options.api) {
|
|
125
|
-
const apiOptions = {};
|
|
126
|
-
if (options.url) {
|
|
127
|
-
apiOptions.url = options.url;
|
|
128
|
-
}
|
|
129
|
-
if (options.apiKey) {
|
|
130
|
-
apiOptions.apiKey = options.apiKey;
|
|
131
|
-
}
|
|
132
|
-
defaultApi = new TrajservAPI(apiOptions);
|
|
133
|
-
}
|
|
134
|
-
Object.defineProperties(this, {
|
|
135
|
-
requestIntervalSeconds: {
|
|
136
|
-
get: () => requestIntervalSeconds,
|
|
137
|
-
set: (newRequestIntervalSeconds) => {
|
|
138
|
-
if (newRequestIntervalSeconds !== requestIntervalSeconds) {
|
|
139
|
-
requestIntervalSeconds = newRequestIntervalSeconds;
|
|
140
|
-
if (this.visible) {
|
|
141
|
-
// stop() is call within the start.
|
|
142
|
-
this.start();
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
|
|
148
|
-
api: {
|
|
149
|
-
value: options.api || defaultApi,
|
|
150
|
-
},
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
init(map) {
|
|
155
|
-
super.init(map);
|
|
156
|
-
|
|
157
|
-
// Sort the trajectories.
|
|
158
|
-
if (this.sortFc) {
|
|
159
|
-
this.sort = this.sortFc;
|
|
160
|
-
} else if (this.useDelayStyle) {
|
|
161
|
-
// Automatic sorting depending on delay, higher delay on top.
|
|
162
|
-
this.sort = (a, b) => {
|
|
163
|
-
if (a.delay === null) return 1;
|
|
164
|
-
return a.delay < b.delay ? 1 : -1;
|
|
165
|
-
};
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
start() {
|
|
170
|
-
this.updateFilters();
|
|
171
|
-
super.start();
|
|
172
|
-
this.startUpdateTrajectories();
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
stop() {
|
|
176
|
-
this.stopUpdateTrajectories();
|
|
177
|
-
this.abortFetchTrajectories();
|
|
178
|
-
super.stop();
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Apply the highlight style on hover.
|
|
183
|
-
*
|
|
184
|
-
* @private
|
|
185
|
-
* @override
|
|
186
|
-
*/
|
|
187
|
-
onFeatureHover(features, layer, coordinate) {
|
|
188
|
-
const [feature] = features;
|
|
189
|
-
let id = null;
|
|
190
|
-
if (feature) {
|
|
191
|
-
id = feature.get('train_id');
|
|
192
|
-
}
|
|
193
|
-
if (this.hoverVehicleId !== id) {
|
|
194
|
-
/** @ignore */
|
|
195
|
-
this.hoverVehicleId = id;
|
|
196
|
-
this.renderTrajectories();
|
|
197
|
-
}
|
|
198
|
-
super.onFeatureHover(features, layer, coordinate);
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Display the complete trajectory of the vehicle.
|
|
203
|
-
*
|
|
204
|
-
* @private
|
|
205
|
-
* @override
|
|
206
|
-
*/
|
|
207
|
-
onFeatureClick(features, layer, coordinate) {
|
|
208
|
-
const [feature] = features;
|
|
209
|
-
if (feature) {
|
|
210
|
-
/** @ignore */
|
|
211
|
-
this.selectedVehicleId = feature.get('train_id');
|
|
212
|
-
/** @ignore */
|
|
213
|
-
this.journeyId = feature.get('journeyIdentifier');
|
|
214
|
-
this.highlightTrajectory();
|
|
215
|
-
} else {
|
|
216
|
-
this.selectedVehicleId = null;
|
|
217
|
-
this.journeyId = null;
|
|
218
|
-
}
|
|
219
|
-
super.onFeatureClick(features, layer, coordinate);
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
/**
|
|
223
|
-
* Highlight the trajectory of journey.
|
|
224
|
-
* @private
|
|
225
|
-
*/
|
|
226
|
-
highlightTrajectory() {
|
|
227
|
-
const { selectedVehicleId, journeyId } = this;
|
|
228
|
-
const promises = [
|
|
229
|
-
// Fetch stations information with a trajectory id.
|
|
230
|
-
this.api.fetchTrajectoryStations(
|
|
231
|
-
this.getParams({
|
|
232
|
-
id: selectedVehicleId,
|
|
233
|
-
time: getUTCTimeString(new Date()),
|
|
234
|
-
}),
|
|
235
|
-
),
|
|
236
|
-
// Full trajectory.
|
|
237
|
-
this.api.fetchTrajectoryById(
|
|
238
|
-
this.getParams({
|
|
239
|
-
id: journeyId,
|
|
240
|
-
time: getUTCTimeString(new Date()),
|
|
241
|
-
}),
|
|
242
|
-
),
|
|
243
|
-
];
|
|
244
|
-
|
|
245
|
-
Promise.all(promises)
|
|
246
|
-
.then(([trajStations, fullTraj]) => {
|
|
247
|
-
const stationsCoords = [];
|
|
248
|
-
if (trajStations) {
|
|
249
|
-
trajStations.stations.forEach((station) => {
|
|
250
|
-
stationsCoords.push(station.coordinates);
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
if (fullTraj) {
|
|
255
|
-
const { p: multiLine, t, c: color } = fullTraj;
|
|
256
|
-
const lineCoords = [];
|
|
257
|
-
multiLine.forEach((line) => {
|
|
258
|
-
line.forEach((point) => {
|
|
259
|
-
lineCoords.push([point.x, point.y]);
|
|
260
|
-
});
|
|
261
|
-
});
|
|
262
|
-
|
|
263
|
-
const lineColor = color ? `#${color}` : getBgColor(t);
|
|
264
|
-
// Don't allow white lines, use red instead.
|
|
265
|
-
const vehiculeColor = /#ffffff/i.test(lineColor)
|
|
266
|
-
? '#ff0000'
|
|
267
|
-
: lineColor;
|
|
268
|
-
|
|
269
|
-
this.drawFullTrajectory(
|
|
270
|
-
stationsCoords,
|
|
271
|
-
lineCoords,
|
|
272
|
-
this.useDelayStyle ? '#a0a0a0' : vehiculeColor,
|
|
273
|
-
);
|
|
274
|
-
}
|
|
275
|
-
})
|
|
276
|
-
.catch(() => {
|
|
277
|
-
this.drawFullTrajectory();
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
|
|
281
|
-
abortFetchTrajectories() {
|
|
282
|
-
if (this.abortController) {
|
|
283
|
-
this.abortController.abort();
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
getParams(extraParams = {}) {
|
|
288
|
-
// The 5 seconds more are used as a buffer if the request takes too long.
|
|
289
|
-
const requestIntervalInMs = (this.requestIntervalSeconds + 5) * 1000;
|
|
290
|
-
const intervalMs = this.speed * requestIntervalInMs;
|
|
291
|
-
const now = this.time;
|
|
292
|
-
|
|
293
|
-
let diff = true;
|
|
294
|
-
|
|
295
|
-
if (
|
|
296
|
-
this.later &&
|
|
297
|
-
now.getTime() >
|
|
298
|
-
this.later.getTime() - this.requestIntervalSeconds * 1000
|
|
299
|
-
) {
|
|
300
|
-
diff = false;
|
|
301
|
-
}
|
|
302
|
-
if (
|
|
303
|
-
!this.later ||
|
|
304
|
-
!diff ||
|
|
305
|
-
this.later.getTime() - now.getTime() > intervalMs
|
|
306
|
-
) {
|
|
307
|
-
const later = new Date(now.getTime() + intervalMs);
|
|
308
|
-
this.later = later;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
const params = {
|
|
312
|
-
...extraParams,
|
|
313
|
-
btime: getUTCTimeString(now),
|
|
314
|
-
etime: getUTCTimeString(this.later),
|
|
315
|
-
date: getUTCDateString(now),
|
|
316
|
-
rid: 1,
|
|
317
|
-
a: 1,
|
|
318
|
-
cd: 1,
|
|
319
|
-
nm: 1,
|
|
320
|
-
fl: 1,
|
|
321
|
-
// toff: this.time.getTime() / 1000,
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
// Allow to load only differences between the last request,
|
|
325
|
-
// but currently the Tracker render method doesn't manage to render only diff.
|
|
326
|
-
/* if (diff) {
|
|
327
|
-
// Not working
|
|
328
|
-
params.diff = this.lastRequestTime;
|
|
329
|
-
} */
|
|
330
|
-
return params;
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
startUpdateTrajectories() {
|
|
334
|
-
this.stopUpdateTrajectories();
|
|
335
|
-
|
|
336
|
-
this.updateTrajectories();
|
|
337
|
-
this.updateInterval = window.setInterval(() => {
|
|
338
|
-
this.updateTrajectories();
|
|
339
|
-
}, this.requestIntervalSeconds * 1000);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
stopUpdateTrajectories() {
|
|
343
|
-
clearInterval(this.updateInterval);
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
updateTrajectories() {
|
|
347
|
-
this.abortFetchTrajectories();
|
|
348
|
-
this.abortController = new AbortController();
|
|
349
|
-
|
|
350
|
-
this.api
|
|
351
|
-
.fetchTrajectories(
|
|
352
|
-
this.getParams({
|
|
353
|
-
attr_det: 1,
|
|
354
|
-
}),
|
|
355
|
-
this.abortController,
|
|
356
|
-
)
|
|
357
|
-
.catch((err) => {
|
|
358
|
-
if (err.name === 'AbortError') {
|
|
359
|
-
// Ignore abort error
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
throw err;
|
|
363
|
-
})
|
|
364
|
-
.then((trajectories) => {
|
|
365
|
-
// Don't set trajectories when the user has aborted the request.
|
|
366
|
-
if (trajectories) {
|
|
367
|
-
this.trajectories = trajectories;
|
|
368
|
-
this.renderTrajectories();
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Draw the trajectory as a line with points for each stop.
|
|
375
|
-
*
|
|
376
|
-
* @param {Array} stationsCoords Array of station coordinates in EPSG:4326.
|
|
377
|
-
* @param {Array<ol/coordinate~Coordinate>} lineCoords A list of coordinates in EPSG:3857.
|
|
378
|
-
* @param {string} color The color of the line.
|
|
379
|
-
* @private
|
|
380
|
-
*/
|
|
381
|
-
drawFullTrajectory(stationsCoords, lineCoords, color) {}
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* Define the style of the vehicle.
|
|
385
|
-
*
|
|
386
|
-
* @param {TrajservTrajectory} trajectory A trajectory
|
|
387
|
-
* @param {ViewState} viewState Map's view state (zoom, resolution, center, ...)
|
|
388
|
-
*/
|
|
389
|
-
defaultStyle(trajectory, viewState) {
|
|
390
|
-
const { zoom } = viewState;
|
|
391
|
-
const {
|
|
392
|
-
type,
|
|
393
|
-
name,
|
|
394
|
-
id,
|
|
395
|
-
color,
|
|
396
|
-
textColor,
|
|
397
|
-
delay,
|
|
398
|
-
cancelled,
|
|
399
|
-
operatorProvidesRealtime,
|
|
400
|
-
} = trajectory;
|
|
401
|
-
const z = Math.min(Math.floor(zoom || 1), 16);
|
|
402
|
-
const hover = this.hoverVehicleId === id;
|
|
403
|
-
const selected = this.selectedVehicleId === id;
|
|
404
|
-
let key = `${z}${type}${name}${operatorProvidesRealtime}${delay}${hover}${selected}${cancelled}`;
|
|
405
|
-
|
|
406
|
-
// Calcul the radius of the circle
|
|
407
|
-
let radius = getRadius(type, z) * this.pixelRatio;
|
|
408
|
-
const isDisplayStrokeAndDelay = radius >= 7 * this.pixelRatio;
|
|
409
|
-
if (hover || selected) {
|
|
410
|
-
radius = isDisplayStrokeAndDelay
|
|
411
|
-
? radius + 5 * this.pixelRatio
|
|
412
|
-
: 14 * this.pixelRatio;
|
|
413
|
-
}
|
|
414
|
-
const mustDrawText = radius > 10 * this.pixelRatio;
|
|
415
|
-
|
|
416
|
-
// Optimize the cache key, very important in high zoom level
|
|
417
|
-
if (!mustDrawText) {
|
|
418
|
-
key = `${z}${type}${color}${operatorProvidesRealtime}${delay}${hover}${selected}${cancelled}`;
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
if (!this.styleCache[key]) {
|
|
422
|
-
if (radius === 0) {
|
|
423
|
-
this.styleCache[key] = null;
|
|
424
|
-
return null;
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
const margin = 1 * this.pixelRatio;
|
|
428
|
-
const radiusDelay = radius + 2;
|
|
429
|
-
const markerSize = radius * 2;
|
|
430
|
-
|
|
431
|
-
const canvas = document.createElement('canvas');
|
|
432
|
-
// add space for delay information
|
|
433
|
-
canvas.width = radiusDelay * 2 + margin * 2 + 100 * this.pixelRatio;
|
|
434
|
-
canvas.height = radiusDelay * 2 + margin * 2 + 100 * this.pixelRatio;
|
|
435
|
-
const ctx = canvas.getContext('2d');
|
|
436
|
-
const origin = canvas.width / 2;
|
|
437
|
-
|
|
438
|
-
if (isDisplayStrokeAndDelay && delay !== null) {
|
|
439
|
-
// Draw circle delay background
|
|
440
|
-
ctx.save();
|
|
441
|
-
ctx.beginPath();
|
|
442
|
-
ctx.arc(origin, origin, radiusDelay, 0, 2 * Math.PI, false);
|
|
443
|
-
ctx.fillStyle = getDelayColor(delay, cancelled);
|
|
444
|
-
ctx.filter = 'blur(1px)';
|
|
445
|
-
ctx.fill();
|
|
446
|
-
ctx.restore();
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// Show delay if feature is hovered or if delay is above 5mins.
|
|
450
|
-
if (
|
|
451
|
-
isDisplayStrokeAndDelay &&
|
|
452
|
-
(hover || delay >= this.delayDisplay || cancelled)
|
|
453
|
-
) {
|
|
454
|
-
// Draw delay text
|
|
455
|
-
ctx.save();
|
|
456
|
-
ctx.textAlign = 'left';
|
|
457
|
-
ctx.textBaseline = 'middle';
|
|
458
|
-
ctx.font = `bold ${Math.max(
|
|
459
|
-
cancelled ? 19 : 14,
|
|
460
|
-
Math.min(cancelled ? 19 : 17, radius * 1.2),
|
|
461
|
-
)}px arial, sans-serif`;
|
|
462
|
-
ctx.fillStyle = getDelayColor(delay, cancelled, true);
|
|
463
|
-
|
|
464
|
-
ctx.strokeStyle = this.delayOutlineColor;
|
|
465
|
-
ctx.lineWidth = 1.5 * this.pixelRatio;
|
|
466
|
-
const delayText = getDelayText(delay, cancelled);
|
|
467
|
-
ctx.strokeText(delayText, origin + radiusDelay + margin, origin);
|
|
468
|
-
ctx.fillText(delayText, origin + radiusDelay + margin, origin);
|
|
469
|
-
ctx.restore();
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
// Draw colored circle with black border
|
|
473
|
-
let circleFillColor;
|
|
474
|
-
if (this.useDelayStyle) {
|
|
475
|
-
circleFillColor = getDelayColor(delay, cancelled);
|
|
476
|
-
} else {
|
|
477
|
-
circleFillColor = color || getBgColor(type);
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
ctx.save();
|
|
481
|
-
if (isDisplayStrokeAndDelay || hover || selected) {
|
|
482
|
-
ctx.lineWidth = 1 * this.pixelRatio;
|
|
483
|
-
ctx.strokeStyle = '#000000';
|
|
484
|
-
}
|
|
485
|
-
ctx.fillStyle = circleFillColor;
|
|
486
|
-
ctx.beginPath();
|
|
487
|
-
ctx.arc(origin, origin, radius, 0, 2 * Math.PI, false);
|
|
488
|
-
ctx.fill();
|
|
489
|
-
// Dashed outline if a provider provides realtime but we don't use it.
|
|
490
|
-
if (
|
|
491
|
-
isDisplayStrokeAndDelay &&
|
|
492
|
-
this.useDelayStyle &&
|
|
493
|
-
delay === null &&
|
|
494
|
-
operatorProvidesRealtime === 'yes'
|
|
495
|
-
) {
|
|
496
|
-
ctx.setLineDash([5, 3]);
|
|
497
|
-
}
|
|
498
|
-
if (isDisplayStrokeAndDelay || hover || selected) {
|
|
499
|
-
ctx.stroke();
|
|
500
|
-
}
|
|
501
|
-
ctx.restore();
|
|
502
|
-
|
|
503
|
-
// Draw text in the circle
|
|
504
|
-
if (mustDrawText) {
|
|
505
|
-
const fontSize = Math.max(radius, 10 * this.pixelRatio);
|
|
506
|
-
const textSize = getTextSize(ctx, markerSize, name, fontSize);
|
|
507
|
-
|
|
508
|
-
// Draw a stroke to the text only if a provider provides realtime but we don't use it.
|
|
509
|
-
if (
|
|
510
|
-
this.useDelayStyle &&
|
|
511
|
-
delay === null &&
|
|
512
|
-
operatorProvidesRealtime === 'yes'
|
|
513
|
-
) {
|
|
514
|
-
ctx.save();
|
|
515
|
-
ctx.textBaseline = 'middle';
|
|
516
|
-
ctx.textAlign = 'center';
|
|
517
|
-
ctx.font = `bold ${textSize + 2}px Arial`;
|
|
518
|
-
ctx.strokeStyle = circleFillColor;
|
|
519
|
-
ctx.strokeText(name, origin, origin);
|
|
520
|
-
ctx.restore();
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
// Draw a text
|
|
524
|
-
ctx.save();
|
|
525
|
-
ctx.textBaseline = 'middle';
|
|
526
|
-
ctx.textAlign = 'center';
|
|
527
|
-
ctx.fillStyle = !this.useDelayStyle
|
|
528
|
-
? textColor || getTextColor(type)
|
|
529
|
-
: '#000000';
|
|
530
|
-
ctx.font = `bold ${textSize}px Arial`;
|
|
531
|
-
ctx.strokeStyle = circleFillColor;
|
|
532
|
-
ctx.strokeText(name, origin, origin);
|
|
533
|
-
ctx.fillText(name, origin, origin);
|
|
534
|
-
ctx.restore();
|
|
535
|
-
}
|
|
536
|
-
|
|
537
|
-
this.styleCache[key] = canvas;
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return this.styleCache[key];
|
|
541
|
-
}
|
|
542
|
-
};
|
|
543
|
-
|
|
544
|
-
export default TrajservLayerMixin;
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A very simple tracker style.
|
|
3
|
-
* Display blue point for each train.
|
|
4
|
-
*/
|
|
5
|
-
const canvas = document.createElement('canvas');
|
|
6
|
-
canvas.width = 15;
|
|
7
|
-
canvas.height = 15;
|
|
8
|
-
const ctx = canvas.getContext('2d');
|
|
9
|
-
ctx.arc(8, 8, 5, 0, 2 * Math.PI, false);
|
|
10
|
-
ctx.fillStyle = '#8ED6FF';
|
|
11
|
-
ctx.fill();
|
|
12
|
-
ctx.lineWidth = 3;
|
|
13
|
-
ctx.strokeStyle = 'black';
|
|
14
|
-
ctx.stroke();
|
|
15
|
-
ctx.lineWidth = 3;
|
|
16
|
-
|
|
17
|
-
const style = () => canvas;
|
|
18
|
-
export default style;
|
package/mapbox/Map.js
DELETED
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { Map as MBMap } from 'maplibre-gl';
|
|
2
|
-
import Layer from '../common/layers/Layer';
|
|
3
|
-
import mixin from '../common/mixins/MapMixin';
|
|
4
|
-
import CopyrightControl from './controls/CopyrightControl';
|
|
5
|
-
import getMapboxStyleUrl from '../common/utils/getMapboxStyleUrl';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* An Mapbox Map](https://docs.mapbox.com/mapbox-gl-js/api/map) for handling mobility layers and controls.
|
|
9
|
-
*
|
|
10
|
-
* @extends {mapboxgl.Map}
|
|
11
|
-
* @implements {MapInterface}
|
|
12
|
-
*/
|
|
13
|
-
class Map extends mixin(MBMap) {
|
|
14
|
-
/**
|
|
15
|
-
* Constructor.
|
|
16
|
-
*/
|
|
17
|
-
constructor(options) {
|
|
18
|
-
const { style } = options;
|
|
19
|
-
const apiKey = options.apiKey || false;
|
|
20
|
-
const apiKeyName = options.apiKeyName || 'key';
|
|
21
|
-
let newStyle = options.style;
|
|
22
|
-
if (typeof style === 'string') {
|
|
23
|
-
newStyle = getMapboxStyleUrl(apiKey, apiKeyName, style);
|
|
24
|
-
}
|
|
25
|
-
super({
|
|
26
|
-
attributionControl: false,
|
|
27
|
-
controls: [new CopyrightControl()],
|
|
28
|
-
...options,
|
|
29
|
-
style: newStyle,
|
|
30
|
-
});
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Adds a layer to the map.
|
|
35
|
-
* @param {Layer|mapboxgl.Layer} layer The layer to add.
|
|
36
|
-
* @param {number} beforeId See [mapbox-gl-js doc](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#addlayer)
|
|
37
|
-
*/
|
|
38
|
-
addLayer(layer, beforeId) {
|
|
39
|
-
if (layer instanceof Layer) {
|
|
40
|
-
this.mobilityLayers.push(layer);
|
|
41
|
-
this.fire('change:mobilityLayers');
|
|
42
|
-
|
|
43
|
-
if (this.isStyleLoaded()) {
|
|
44
|
-
layer.init(this, beforeId);
|
|
45
|
-
} else {
|
|
46
|
-
this.on('load', () => {
|
|
47
|
-
layer.init(this, beforeId);
|
|
48
|
-
});
|
|
49
|
-
}
|
|
50
|
-
} else {
|
|
51
|
-
super.addLayer(layer, beforeId);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Removes a given layer from the map.
|
|
57
|
-
* @param {Layer|number} layer The layer to remove.
|
|
58
|
-
* If it's a mapbox-layer, pass the id instead..
|
|
59
|
-
*/
|
|
60
|
-
removeLayer(layer) {
|
|
61
|
-
if (layer instanceof Layer) {
|
|
62
|
-
layer.terminate();
|
|
63
|
-
this.mobilityLayers = this.mobilityLayers.filter((l) => l !== layer);
|
|
64
|
-
} else {
|
|
65
|
-
super.removeLayer(layer);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Adds a given control to the map.
|
|
71
|
-
* @param {Control|mapboxgl.IControl} control The control to add.
|
|
72
|
-
* @param {mapboxgl.position} position Position of the control. Only if control parameter is an <mapboxgl.IControl>.
|
|
73
|
-
*/
|
|
74
|
-
addControl(control, position) {
|
|
75
|
-
super.addControl(control, position);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Removes a given control to the map.
|
|
80
|
-
* @param {Control|mapboxgl.IControl} control The control to remove.
|
|
81
|
-
*/
|
|
82
|
-
removeControl(control) {
|
|
83
|
-
super.removeControl(control);
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export default Map;
|