@wemap/providers 9.0.0-alpha.7 → 9.0.0-alpha.9
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/helpers/CustomMapProvider.js +11 -0
- package/package.json +4 -4
- package/src/mapmatching/MapMatchingHandler.js +51 -44
- package/src/providers/attitude/absolute/AbsoluteAttitude.js +1 -1
- package/src/providers/position/absolute/AbsolutePosition.js +60 -9
- package/src/providers/position/absolute/PoleStar.js +1 -2
|
@@ -9,8 +9,15 @@ export default class CustomMapProvider extends Evented {
|
|
|
9
9
|
positionProviderId = null;
|
|
10
10
|
smoother = null;
|
|
11
11
|
|
|
12
|
+
_started = false;
|
|
13
|
+
|
|
12
14
|
start() {
|
|
13
15
|
|
|
16
|
+
if (this._started) {
|
|
17
|
+
return;
|
|
18
|
+
}
|
|
19
|
+
this._started = true;
|
|
20
|
+
|
|
14
21
|
/**
|
|
15
22
|
* Attitude
|
|
16
23
|
*/
|
|
@@ -41,6 +48,10 @@ export default class CustomMapProvider extends Evented {
|
|
|
41
48
|
}
|
|
42
49
|
|
|
43
50
|
stop() {
|
|
51
|
+
if (!this._started) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
this._started = false;
|
|
44
55
|
|
|
45
56
|
/**
|
|
46
57
|
* Attitude
|
package/package.json
CHANGED
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
"@wemap/geo": "^9.0.0-alpha.5",
|
|
13
13
|
"@wemap/geomagnetism": "^0.1.1",
|
|
14
14
|
"@wemap/logger": "^9.0.0-alpha.1",
|
|
15
|
-
"@wemap/map": "^9.0.0-alpha.
|
|
15
|
+
"@wemap/map": "^9.0.0-alpha.9",
|
|
16
16
|
"@wemap/maths": "^9.0.0-alpha.5",
|
|
17
17
|
"@wemap/osm": "^9.0.0-alpha.5",
|
|
18
|
-
"@wemap/routers": "^9.0.0-alpha.
|
|
18
|
+
"@wemap/routers": "^9.0.0-alpha.9",
|
|
19
19
|
"@wemap/utils": "^8.1.0"
|
|
20
20
|
},
|
|
21
21
|
"description": "A package using different geoloc systems",
|
|
@@ -42,6 +42,6 @@
|
|
|
42
42
|
"url": "git+https://github.com/wemap/wemap-modules-js.git"
|
|
43
43
|
},
|
|
44
44
|
"type": "module",
|
|
45
|
-
"version": "9.0.0-alpha.
|
|
46
|
-
"gitHead": "
|
|
45
|
+
"version": "9.0.0-alpha.9",
|
|
46
|
+
"gitHead": "ccde674b419c921379f50a920bdf95eb493d2673"
|
|
47
47
|
}
|
|
@@ -256,6 +256,7 @@ class MapMatchingHandler extends Provider {
|
|
|
256
256
|
|
|
257
257
|
/**
|
|
258
258
|
* @param {ProviderEvent<UserPosition>} positionEvent
|
|
259
|
+
* @returns {boolean} if input position is used by the system (true = used, false = discarded)
|
|
259
260
|
*/
|
|
260
261
|
notifyPositionFromAbsolute(positionEvent) {
|
|
261
262
|
|
|
@@ -273,7 +274,7 @@ class MapMatchingHandler extends Provider {
|
|
|
273
274
|
// In this case, the newPosition is far enough and can be used safely.
|
|
274
275
|
AbsolutePosition.notify(positionEvent);
|
|
275
276
|
}
|
|
276
|
-
return;
|
|
277
|
+
return true;
|
|
277
278
|
}
|
|
278
279
|
|
|
279
280
|
// newPosition must not be used after this line
|
|
@@ -282,12 +283,12 @@ class MapMatchingHandler extends Provider {
|
|
|
282
283
|
|
|
283
284
|
// In case of a huge jump, be sure the user is in a straight line
|
|
284
285
|
if (thisWillBeAHugeJump && !StraightLineDetector.isStraight()) {
|
|
285
|
-
return;
|
|
286
|
+
return false;
|
|
286
287
|
}
|
|
287
288
|
|
|
288
289
|
// Detector to avoid big jumps in the wrong direction
|
|
289
290
|
if (thisWillBeAHugeJump && this._detectWrongBigJump(projectionWithBearing)) {
|
|
290
|
-
return;
|
|
291
|
+
return false;
|
|
291
292
|
}
|
|
292
293
|
|
|
293
294
|
AbsolutePosition.notify(this.createEvent(
|
|
@@ -297,12 +298,13 @@ class MapMatchingHandler extends Provider {
|
|
|
297
298
|
));
|
|
298
299
|
|
|
299
300
|
this.tryOrientationMatching(projectionWithBearing);
|
|
300
|
-
|
|
301
|
+
return true;
|
|
301
302
|
}
|
|
302
303
|
|
|
303
304
|
|
|
304
305
|
/**
|
|
305
306
|
* @param {ProviderEvent<UserPosition>} positionEvent
|
|
307
|
+
* @returns {boolean} if input position is used by the system (true = used, false = discarded)
|
|
306
308
|
*/
|
|
307
309
|
notifyPositionFromRelative(positionEvent) {
|
|
308
310
|
|
|
@@ -310,7 +312,7 @@ class MapMatchingHandler extends Provider {
|
|
|
310
312
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
311
313
|
this._lastProjections = [];
|
|
312
314
|
AbsolutePosition.notify(positionEvent);
|
|
313
|
-
return;
|
|
315
|
+
return true;
|
|
314
316
|
}
|
|
315
317
|
|
|
316
318
|
const newPosition = positionEvent.data;
|
|
@@ -328,19 +330,19 @@ class MapMatchingHandler extends Provider {
|
|
|
328
330
|
// In case of a huge jump, be sure the user is in a straight line
|
|
329
331
|
if (thisWillBeAHugeJump && !StraightLineDetector.isStraight()) {
|
|
330
332
|
AbsolutePosition.notify(positionEvent);
|
|
331
|
-
return;
|
|
333
|
+
return true;
|
|
332
334
|
}
|
|
333
335
|
|
|
334
336
|
// Detector to avoid big jumps in the wrong direction
|
|
335
337
|
if (thisWillBeAHugeJump && this._detectWrongBigJump(projection)) {
|
|
336
338
|
AbsolutePosition.notify(positionEvent);
|
|
337
|
-
return;
|
|
339
|
+
return true;
|
|
338
340
|
}
|
|
339
341
|
|
|
340
342
|
// Do not use projection if the neareast element is not the same direction than previous
|
|
341
343
|
if (!this._areLastProjectionsInTheSameDirection()) {
|
|
342
344
|
AbsolutePosition.notify(positionEvent);
|
|
343
|
-
return;
|
|
345
|
+
return true;
|
|
344
346
|
}
|
|
345
347
|
|
|
346
348
|
AbsolutePosition.notify(this.createEvent(
|
|
@@ -350,55 +352,60 @@ class MapMatchingHandler extends Provider {
|
|
|
350
352
|
));
|
|
351
353
|
this.tryOrientationMatching(projection);
|
|
352
354
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
// Sometimes, the newPosition.bearing diverges due to the Absolute Attitude offset
|
|
356
|
-
// and the Orientation Matching. So, we created this detector to check if projection
|
|
357
|
-
// with bearing from "AbsoluteAttitudeFromBrowser" is better than the current bearing.
|
|
358
|
-
// /!\ This works only if the user is waking in the same direction than the smartphone orientation /!\
|
|
359
|
-
if (StraightLineDetector.isStraight()) {
|
|
355
|
+
return true;
|
|
360
356
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
const projectionWithAbs = this.getProjection(testedPosition, true, true);
|
|
357
|
+
}
|
|
358
|
+
// else {
|
|
364
359
|
|
|
365
|
-
|
|
360
|
+
// Sometimes, the newPosition.bearing diverges due to the Absolute Attitude offset
|
|
361
|
+
// and the Orientation Matching. So, we created this detector to check if projection
|
|
362
|
+
// with bearing from "AbsoluteAttitudeFromBrowser" is better than the current bearing.
|
|
363
|
+
// /!\ This works only if the user is waking in the same direction than the smartphone orientation /!\
|
|
364
|
+
if (StraightLineDetector.isStraight()) {
|
|
366
365
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
return;
|
|
371
|
-
}
|
|
366
|
+
const testedPosition = newPosition.clone();
|
|
367
|
+
testedPosition.bearing = AbsoluteAttitudeFromBrowser.lastEvent.data.heading;
|
|
368
|
+
const projectionWithAbs = this.getProjection(testedPosition, true, true);
|
|
372
369
|
|
|
373
|
-
|
|
374
|
-
if (this._lastProjections.length > MapMatchingHandler.LAST_PROJECTIONS_WINDOW_SIZE) {
|
|
375
|
-
this._lastProjections.shift();
|
|
376
|
-
}
|
|
370
|
+
if (projectionWithAbs) {
|
|
377
371
|
|
|
372
|
+
this._projectionsWithAbsAndWithoutRelAttitudeInARow.push(projectionWithAbs);
|
|
373
|
+
if (this._projectionsWithAbsAndWithoutRelAttitudeInARow.length < 3) {
|
|
374
|
+
AbsolutePosition.notify(positionEvent);
|
|
375
|
+
return true;
|
|
376
|
+
}
|
|
378
377
|
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
378
|
+
this._lastProjections.push(projectionWithAbs);
|
|
379
|
+
if (this._lastProjections.length > MapMatchingHandler.LAST_PROJECTIONS_WINDOW_SIZE) {
|
|
380
|
+
this._lastProjections.shift();
|
|
381
|
+
}
|
|
383
382
|
|
|
384
|
-
AbsolutePosition.notify(this.createEvent(
|
|
385
|
-
EventType.AbsolutePosition,
|
|
386
|
-
projectionWithAbs.projection,
|
|
387
|
-
[positionEvent]
|
|
388
|
-
));
|
|
389
383
|
|
|
390
|
-
|
|
391
|
-
|
|
384
|
+
if (!this._areLastProjectionsInTheSameDirection()) {
|
|
385
|
+
AbsolutePosition.notify(positionEvent);
|
|
386
|
+
return true;
|
|
392
387
|
}
|
|
393
|
-
}
|
|
394
388
|
|
|
395
|
-
|
|
396
|
-
|
|
389
|
+
AbsolutePosition.notify(this.createEvent(
|
|
390
|
+
EventType.AbsolutePosition,
|
|
391
|
+
projectionWithAbs.projection,
|
|
392
|
+
[positionEvent]
|
|
393
|
+
));
|
|
397
394
|
|
|
398
|
-
|
|
399
|
-
|
|
395
|
+
this.tryOrientationMatching(projectionWithAbs);
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
400
398
|
}
|
|
401
399
|
|
|
400
|
+
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
401
|
+
this._lastProjections = [];
|
|
402
|
+
|
|
403
|
+
// If no projection found with both projection methods, simply use the newPosition.
|
|
404
|
+
AbsolutePosition.notify(positionEvent);
|
|
405
|
+
return true;
|
|
406
|
+
|
|
407
|
+
// }
|
|
408
|
+
|
|
402
409
|
}
|
|
403
410
|
|
|
404
411
|
/**
|
|
@@ -313,7 +313,7 @@ class AbsoluteAttitude extends Provider {
|
|
|
313
313
|
throw Error('the accuracy of the attitude is not defined');
|
|
314
314
|
}
|
|
315
315
|
|
|
316
|
-
this._forceHeadingForRelative(new ProviderEvent(EventType.
|
|
316
|
+
this._forceHeadingForRelative(new ProviderEvent(EventType.Attitude, data));
|
|
317
317
|
|
|
318
318
|
} else if (data instanceof ProviderEvent) {
|
|
319
319
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { UserPosition, GeoRelativePosition } from '@wemap/geo';
|
|
2
|
-
import { PromiseUtils } from '@wemap/utils';
|
|
2
|
+
import { PromiseUtils, TimeUtils } from '@wemap/utils';
|
|
3
3
|
|
|
4
4
|
import Provider from '../../Provider.js';
|
|
5
5
|
import EventType from '../../../events/EventType.js';
|
|
@@ -20,6 +20,12 @@ class AbsolutePosition extends Provider {
|
|
|
20
20
|
/** @type {boolean} */
|
|
21
21
|
static USE_MM_FOR_FEED = true;
|
|
22
22
|
|
|
23
|
+
// /** @type {number} */
|
|
24
|
+
// static POLESTAR_TIME_DISCARD_GNSSWIFI_FROM_LAST_FIX = 3000;
|
|
25
|
+
|
|
26
|
+
// /** @type {number} */
|
|
27
|
+
// static GNSSWIFI_DISCARD_POLESTAR_IF_ACCURACY_RATIO_BETTER_THAN = 2;
|
|
28
|
+
|
|
23
29
|
|
|
24
30
|
/** @type {number?} */
|
|
25
31
|
_gnssWifiProviderId;
|
|
@@ -28,11 +34,14 @@ class AbsolutePosition extends Provider {
|
|
|
28
34
|
_relativePositionProviderId;
|
|
29
35
|
|
|
30
36
|
/** @type {number?} */
|
|
31
|
-
_mapMatchingHandlerId
|
|
37
|
+
_mapMatchingHandlerId;
|
|
32
38
|
|
|
33
39
|
/** @type {boolean?} */
|
|
34
40
|
_waitUntilNextVpsPosition = false;
|
|
35
41
|
|
|
42
|
+
// /** @type {?number} */
|
|
43
|
+
// _lastPolestarFix;
|
|
44
|
+
|
|
36
45
|
/**
|
|
37
46
|
* @override
|
|
38
47
|
*/
|
|
@@ -84,6 +93,25 @@ class AbsolutePosition extends Provider {
|
|
|
84
93
|
|
|
85
94
|
this._gnssWifiProviderId = GnssWifi.addEventListener(
|
|
86
95
|
events => {
|
|
96
|
+
// const useLevel = false;
|
|
97
|
+
// if (typeof this._lastPolestarFix !== 'undefined'
|
|
98
|
+
// && TimeUtils.preciseTime() - this._lastPolestarFix < AbsolutePosition.POLESTAR_TIME_DISCARD_GNSSWIFI_FROM_LAST_FIX) {
|
|
99
|
+
// // Discard the GNSSWifi position if the last Polestar position is too recent
|
|
100
|
+
// console.log(`[Dev] Formula - PS: ${PoleStar.lastEvent.data.accuracy},
|
|
101
|
+
// GNSSWifi: ${events[0].data.accuracy},
|
|
102
|
+
// ratio: ${PoleStar.lastEvent.data.accuracy / events[0].data.accuracy}`);
|
|
103
|
+
// if (PoleStar.lastEvent.data.accuracy / events[0].data.accuracy > AbsolutePosition.GNSSWIFI_DISCARD_POLESTAR_IF_ACCURACY_RATIO_BETTER_THAN) {
|
|
104
|
+
// // Except if the accuracy of the Polestar position is really better than the GNSSWifi position
|
|
105
|
+
// // In this case we add the level provided by Pole Star to the position
|
|
106
|
+
// console.log(`[Dev] Apply PS level ${PoleStar.lastEvent.data.level} to GnssWifi`);
|
|
107
|
+
// events[0].data.level = PoleStar.lastEvent.data.level;
|
|
108
|
+
// useLevel = true;
|
|
109
|
+
// } else {
|
|
110
|
+
// console.log('[Dev] Discard GnssWifi fix with accuracy: ', events[0].data.accuracy);
|
|
111
|
+
// return;
|
|
112
|
+
// }
|
|
113
|
+
// }
|
|
114
|
+
// console.log('[Dev] Use GnssWifi fix with accuracy: ', events[0].data.accuracy);
|
|
87
115
|
// bearing from GnssWifi is not reliable for our usecase
|
|
88
116
|
events[0].data.bearing = null;
|
|
89
117
|
this._onAbsolutePosition(events[0], false);
|
|
@@ -94,7 +122,28 @@ class AbsolutePosition extends Provider {
|
|
|
94
122
|
|
|
95
123
|
if (ProvidersOptions.hasPoleStar) {
|
|
96
124
|
this._polestarProviderId = PoleStar.addEventListener(events => {
|
|
97
|
-
|
|
125
|
+
|
|
126
|
+
const polestarPositionEvent = events.find(event => event.dataType === EventType.AbsolutePosition);
|
|
127
|
+
|
|
128
|
+
this._lastPolestarFix = TimeUtils.preciseTime();
|
|
129
|
+
const psPositionUsed = this._onAbsolutePosition(polestarPositionEvent);
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* In the case of a degraded position from PoleStar and a good position from GnssWifi,
|
|
133
|
+
* we still need to retrieve the level from PoleStar.
|
|
134
|
+
* To do so, we duplicate lastEvent and add the level from PoleStar to the current
|
|
135
|
+
* position, then we notify with the new position.
|
|
136
|
+
*/
|
|
137
|
+
if (!psPositionUsed && this.lastEvent.data.level === null) {
|
|
138
|
+
const lastPositionWithLevel = this.lastEvent.data.clone();
|
|
139
|
+
lastPositionWithLevel.level = polestarPositionEvent.data.level;
|
|
140
|
+
const leveledEvent = this.createEvent(
|
|
141
|
+
EventType.AbsolutePosition,
|
|
142
|
+
lastPositionWithLevel,
|
|
143
|
+
[...this.lastEvent.providersStack, ...polestarPositionEvent.providersStack]
|
|
144
|
+
);
|
|
145
|
+
this.notify(leveledEvent);
|
|
146
|
+
}
|
|
98
147
|
});
|
|
99
148
|
}
|
|
100
149
|
|
|
@@ -129,6 +178,7 @@ class AbsolutePosition extends Provider {
|
|
|
129
178
|
/**
|
|
130
179
|
* @param {ProviderEvent<UserPosition>} positionEvent
|
|
131
180
|
* @param {boolean} canContainLevel
|
|
181
|
+
* @returns {boolean} if input position is used by the system (true = used, false = discarded)
|
|
132
182
|
*/
|
|
133
183
|
_onAbsolutePosition(positionEvent, canContainLevel = true) {
|
|
134
184
|
|
|
@@ -145,7 +195,7 @@ class AbsolutePosition extends Provider {
|
|
|
145
195
|
const isFarEnough = lastPosition.distanceTo(newPosition) > lastPosition.accuracy + newPosition.accuracy;
|
|
146
196
|
|
|
147
197
|
if (!isBetterEnough && !isFarEnough) {
|
|
148
|
-
return;
|
|
198
|
+
return false;
|
|
149
199
|
}
|
|
150
200
|
|
|
151
201
|
if (!canContainLevel) {
|
|
@@ -169,19 +219,20 @@ class AbsolutePosition extends Provider {
|
|
|
169
219
|
// If the position bearing is null, do not use MM, it is too dangerous.
|
|
170
220
|
if (!MapMatchingHandler.canUseMapMatching()) {
|
|
171
221
|
this.notify(newPositionEvent);
|
|
172
|
-
return;
|
|
222
|
+
return true;
|
|
173
223
|
}
|
|
174
224
|
|
|
175
|
-
MapMatchingHandler.notifyPositionFromAbsolute(newPositionEvent);
|
|
225
|
+
return MapMatchingHandler.notifyPositionFromAbsolute(newPositionEvent);
|
|
176
226
|
}
|
|
177
227
|
|
|
178
228
|
/**
|
|
179
229
|
* @param {ProviderEvent<GeoRelativePosition>} relativeEvent
|
|
230
|
+
* @returns {boolean} if input position is used by the system (true = used, false = discarded)
|
|
180
231
|
*/
|
|
181
232
|
_onRelativePosition(relativeEvent) {
|
|
182
233
|
|
|
183
234
|
if (!this.lastEvent || this._waitUntilNextVpsPosition) {
|
|
184
|
-
return;
|
|
235
|
+
return false;
|
|
185
236
|
}
|
|
186
237
|
|
|
187
238
|
const lastPosition = this.lastEvent.data;
|
|
@@ -207,10 +258,10 @@ class AbsolutePosition extends Provider {
|
|
|
207
258
|
|
|
208
259
|
if (!MapMatchingHandler.canUseMapMatching()) {
|
|
209
260
|
this.notify(newPositionEvent);
|
|
210
|
-
return;
|
|
261
|
+
return true;
|
|
211
262
|
}
|
|
212
263
|
|
|
213
|
-
MapMatchingHandler.notifyPositionFromRelative(newPositionEvent);
|
|
264
|
+
return MapMatchingHandler.notifyPositionFromRelative(newPositionEvent);
|
|
214
265
|
}
|
|
215
266
|
|
|
216
267
|
|