@wemap/providers 4.0.3 → 4.0.5
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/debug/src/Utils.js +4 -0
- package/package.json +5 -5
- package/src/mapmatching/MapMatchingHandler.js +88 -2
- package/src/providers/attitude/TurnDectector.js +1 -1
- package/src/providers/attitude/absolute/AbsoluteAttitude.js +52 -24
- package/src/providers/steps/StraightLineDetector.js +5 -1
- package/src/smoothers/AttitudeSmoother.js +1 -1
package/debug/src/Utils.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import React from 'react'; // eslint-disable-line no-unused-vars
|
|
2
2
|
|
|
3
|
+
import { ItineraryInfo } from '@wemap/geo';
|
|
3
4
|
import { rad2deg } from '@wemap/maths';
|
|
4
5
|
import { OsrmUtils } from '@wemap/osm';
|
|
5
6
|
|
|
@@ -121,6 +122,9 @@ class Utils {
|
|
|
121
122
|
|
|
122
123
|
}
|
|
123
124
|
|
|
125
|
+
/**
|
|
126
|
+
* @param {ItineraryInfo} info
|
|
127
|
+
*/
|
|
124
128
|
static renderItineraryInfo(info) {
|
|
125
129
|
|
|
126
130
|
if (!info) {
|
package/package.json
CHANGED
|
@@ -8,16 +8,16 @@
|
|
|
8
8
|
"Guillaume Pannetier <guillaume.pannetier@getwemap.com>"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@wemap/geo": "^4.0.
|
|
11
|
+
"@wemap/geo": "^4.0.4",
|
|
12
12
|
"@wemap/geomagnetism": "^0.1.1",
|
|
13
13
|
"@wemap/logger": "^4.0.0",
|
|
14
|
-
"@wemap/map": "^4.0.
|
|
14
|
+
"@wemap/map": "^4.0.4",
|
|
15
15
|
"@wemap/maths": "^4.0.3",
|
|
16
16
|
"@wemap/utils": "^4.0.0"
|
|
17
17
|
},
|
|
18
18
|
"description": "A package using different geoloc systems",
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@wemap/osm": "^4.0.
|
|
20
|
+
"@wemap/osm": "^4.0.4",
|
|
21
21
|
"mapbox-gl": "^1.11.1"
|
|
22
22
|
},
|
|
23
23
|
"homepage": "https://github.com/wemap/wemap-modules-js#readme",
|
|
@@ -39,6 +39,6 @@
|
|
|
39
39
|
"url": "git+https://github.com/wemap/wemap-modules-js.git"
|
|
40
40
|
},
|
|
41
41
|
"type": "module",
|
|
42
|
-
"version": "4.0.
|
|
43
|
-
"gitHead": "
|
|
42
|
+
"version": "4.0.5",
|
|
43
|
+
"gitHead": "83de234c6e6e93200995545e5d4d523f40850ecd"
|
|
44
44
|
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
AbsoluteHeading, Edge, Itinerary, MapMatching, Network, Projection, UserPosition
|
|
4
4
|
} from '@wemap/geo';
|
|
5
|
-
import { deg2rad, diffAngle } from '@wemap/maths';
|
|
5
|
+
import { deg2rad, diffAngle, diffAngleLines } from '@wemap/maths';
|
|
6
6
|
import { TimeUtils } from '@wemap/utils';
|
|
7
7
|
|
|
8
8
|
import EventType from '../events/EventType.js';
|
|
@@ -42,6 +42,15 @@ class MapMatchingHandler extends Provider {
|
|
|
42
42
|
/** @type {number} */
|
|
43
43
|
static MIN_STEPS_BETWEEN_ORIENTATION_MATCHING = 3;
|
|
44
44
|
|
|
45
|
+
/** @type {number} */
|
|
46
|
+
static MIN_STEPS_FOR_ORIENTATION_MATCHING = 5;
|
|
47
|
+
|
|
48
|
+
/** @type {number} */
|
|
49
|
+
static LAST_PROJECTIONS_WINDOW_SIZE = 3;
|
|
50
|
+
|
|
51
|
+
/** @type {number} */
|
|
52
|
+
static LAST_PROJECTIONS_EDGE_ANGLE_THRESHOLD = deg2rad(3);
|
|
53
|
+
|
|
45
54
|
/** @type {MapMatching} */
|
|
46
55
|
_mapMatching;
|
|
47
56
|
|
|
@@ -66,6 +75,10 @@ class MapMatchingHandler extends Provider {
|
|
|
66
75
|
/** @type {number} */
|
|
67
76
|
_countStepsFromLastMatching = 0;
|
|
68
77
|
|
|
78
|
+
/** @type {Projection[]} */
|
|
79
|
+
_lastProjections = [];
|
|
80
|
+
|
|
81
|
+
|
|
69
82
|
constructor() {
|
|
70
83
|
super();
|
|
71
84
|
|
|
@@ -262,6 +275,11 @@ class MapMatchingHandler extends Provider {
|
|
|
262
275
|
return;
|
|
263
276
|
}
|
|
264
277
|
|
|
278
|
+
// Detector to avoid big jumps in the wrong direction
|
|
279
|
+
if (thisWillBeAHugeJump && this._detectWrongBigJump(projectionWithBearing)) {
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
|
|
265
283
|
AbsolutePosition.notify(this.createEvent(
|
|
266
284
|
EventType.AbsolutePosition,
|
|
267
285
|
projectionWithBearing.projection,
|
|
@@ -280,6 +298,7 @@ class MapMatchingHandler extends Provider {
|
|
|
280
298
|
|
|
281
299
|
if (TurnDectector.isTurning()) {
|
|
282
300
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
301
|
+
this._lastProjections = [];
|
|
283
302
|
AbsolutePosition.notify(positionEvent);
|
|
284
303
|
return;
|
|
285
304
|
}
|
|
@@ -289,6 +308,10 @@ class MapMatchingHandler extends Provider {
|
|
|
289
308
|
|
|
290
309
|
if (projection) {
|
|
291
310
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
311
|
+
this._lastProjections.push(projection);
|
|
312
|
+
if (this._lastProjections.length > MapMatchingHandler.LAST_PROJECTIONS_WINDOW_SIZE) {
|
|
313
|
+
this._lastProjections.shift();
|
|
314
|
+
}
|
|
292
315
|
|
|
293
316
|
const thisWillBeAHugeJump = projection.distanceFromNearestElement > MapMatchingHandler.MM_HUGE_JUMP_DISTANCE;
|
|
294
317
|
|
|
@@ -298,6 +321,18 @@ class MapMatchingHandler extends Provider {
|
|
|
298
321
|
return;
|
|
299
322
|
}
|
|
300
323
|
|
|
324
|
+
// Detector to avoid big jumps in the wrong direction
|
|
325
|
+
if (thisWillBeAHugeJump && this._detectWrongBigJump(projection)) {
|
|
326
|
+
AbsolutePosition.notify(positionEvent);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
// Do not use projection if the neareast element is not the same direction than previous
|
|
331
|
+
if (!this._areLastProjectionsInTheSameDirection()) {
|
|
332
|
+
AbsolutePosition.notify(positionEvent);
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
|
|
301
336
|
AbsolutePosition.notify(this.createEvent(
|
|
302
337
|
EventType.AbsolutePosition,
|
|
303
338
|
projection.projection,
|
|
@@ -321,6 +356,18 @@ class MapMatchingHandler extends Provider {
|
|
|
321
356
|
|
|
322
357
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow.push(projectionWithAbs);
|
|
323
358
|
if (this._projectionsWithAbsAndWithoutRelAttitudeInARow.length < 3) {
|
|
359
|
+
AbsolutePosition.notify(positionEvent);
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
this._lastProjections.push(projectionWithAbs);
|
|
364
|
+
if (this._lastProjections.length > MapMatchingHandler.LAST_PROJECTIONS_WINDOW_SIZE) {
|
|
365
|
+
this._lastProjections.shift();
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
if (!this._areLastProjectionsInTheSameDirection()) {
|
|
370
|
+
AbsolutePosition.notify(positionEvent);
|
|
324
371
|
return;
|
|
325
372
|
}
|
|
326
373
|
|
|
@@ -336,6 +383,7 @@ class MapMatchingHandler extends Provider {
|
|
|
336
383
|
}
|
|
337
384
|
|
|
338
385
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
386
|
+
this._lastProjections = [];
|
|
339
387
|
|
|
340
388
|
// If no projection found with both projection methods, simply use the newPosition.
|
|
341
389
|
AbsolutePosition.notify(positionEvent);
|
|
@@ -343,6 +391,43 @@ class MapMatchingHandler extends Provider {
|
|
|
343
391
|
|
|
344
392
|
}
|
|
345
393
|
|
|
394
|
+
/**
|
|
395
|
+
* @param {Projection} projection
|
|
396
|
+
*/
|
|
397
|
+
_detectWrongBigJump(projection) {
|
|
398
|
+
|
|
399
|
+
if (this.network instanceof Itinerary && AbsolutePosition.lastEvent) {
|
|
400
|
+
const itinerary = this.network;
|
|
401
|
+
const infoPrevious = itinerary.getInfo(AbsolutePosition.lastEvent.data);
|
|
402
|
+
const infoProjection = itinerary.getInfo(projection.projection);
|
|
403
|
+
if (infoPrevious
|
|
404
|
+
&& infoProjection
|
|
405
|
+
&& infoPrevious.traveledDistance > infoProjection.traveledDistance
|
|
406
|
+
&& (infoPrevious.traveledDistance - infoProjection.traveledDistance) > projection.origin.accuracy
|
|
407
|
+
&& projection.distanceFromNearestElement > projection.origin.accuracy
|
|
408
|
+
&& projection.origin.distanceTo(AbsolutePosition.lastEvent.data) < projection.origin.accuracy + AbsolutePosition.lastEvent.data.accuracy) {
|
|
409
|
+
|
|
410
|
+
return true;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
return false;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
_areLastProjectionsInTheSameDirection() {
|
|
418
|
+
|
|
419
|
+
if (this._lastProjections.length === 0) {
|
|
420
|
+
return false;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
const firstProjection = this._lastProjections[0];
|
|
424
|
+
return !this._lastProjections.some(projection =>
|
|
425
|
+
!(projection.nearestElement instanceof Edge)
|
|
426
|
+
|| (diffAngleLines(projection.nearestElement.bearing, firstProjection.nearestElement.bearing)
|
|
427
|
+
> MapMatchingHandler.LAST_PROJECTIONS_EDGE_ANGLE_THRESHOLD)
|
|
428
|
+
);
|
|
429
|
+
}
|
|
430
|
+
|
|
346
431
|
/**
|
|
347
432
|
* @param {Projection} projection
|
|
348
433
|
*/
|
|
@@ -353,7 +438,8 @@ class MapMatchingHandler extends Provider {
|
|
|
353
438
|
}
|
|
354
439
|
|
|
355
440
|
if (this.state !== ProviderState.STARTED
|
|
356
|
-
|| this._countStepsFromLastMatching < MapMatchingHandler.MIN_STEPS_BETWEEN_ORIENTATION_MATCHING
|
|
441
|
+
|| this._countStepsFromLastMatching < MapMatchingHandler.MIN_STEPS_BETWEEN_ORIENTATION_MATCHING
|
|
442
|
+
|| StraightLineDetector.numStepsDetectedFromLastTurn < MapMatchingHandler.MIN_STEPS_FOR_ORIENTATION_MATCHING) {
|
|
357
443
|
return;
|
|
358
444
|
}
|
|
359
445
|
|
|
@@ -108,22 +108,43 @@ class AbsoluteAttitude extends Provider {
|
|
|
108
108
|
/**
|
|
109
109
|
* @param {ProviderEvent<Attitude|AbsoluteHeading>} absoluteHeadingEvent
|
|
110
110
|
*/
|
|
111
|
-
_forceHeadingForRelative = (absoluteHeadingEvent
|
|
111
|
+
_forceHeadingForRelative = (absoluteHeadingEvent) => {
|
|
112
112
|
|
|
113
|
-
if (
|
|
114
|
-
&& absoluteHeadingEvent.data.accuracy > this.lastEvent.data.accuracy) {
|
|
113
|
+
if (this.lastEvent && absoluteHeadingEvent.data.accuracy > this.lastEvent.data.accuracy) {
|
|
115
114
|
return;
|
|
116
115
|
}
|
|
117
116
|
|
|
118
|
-
const currentRelativeHeading = this._relativeAttitude ? this._relativeAttitude.heading : 0;
|
|
119
117
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
118
|
+
/**
|
|
119
|
+
* @param {Attitude} relativeAttitude
|
|
120
|
+
*/
|
|
121
|
+
const calcForceHeading = (relativeAttitude) => {
|
|
122
|
+
const currentRelativeHeading = relativeAttitude.heading;
|
|
123
|
+
|
|
124
|
+
this._relAbsQuat = Quaternion.fromAxisAngle(
|
|
125
|
+
[0, 0, 1],
|
|
126
|
+
currentRelativeHeading - absoluteHeadingEvent.data.heading
|
|
127
|
+
);
|
|
128
|
+
|
|
129
|
+
this._relativeAccuracy = 0;
|
|
130
|
+
this._lastForcedHeadingEvent = absoluteHeadingEvent;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// If relativeAttitude does not exist yet, wait the next
|
|
134
|
+
if (this._relativeAttitude) {
|
|
135
|
+
calcForceHeading(this._relativeAttitude);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// If this._relativeAttitude does not exist, wait the first value
|
|
140
|
+
// /!\ This works only if the relative attitude event is provided rapidly.
|
|
141
|
+
const providerId = RelativeAttitude.addEventListener(
|
|
142
|
+
events => {
|
|
143
|
+
calcForceHeading(events[0].data);
|
|
144
|
+
RelativeAttitude.removeEventListener(providerId);
|
|
145
|
+
}
|
|
123
146
|
);
|
|
124
147
|
|
|
125
|
-
this._relativeAccuracy = 0;
|
|
126
|
-
this._lastForcedHeadingEvent = absoluteHeadingEvent;
|
|
127
148
|
};
|
|
128
149
|
|
|
129
150
|
/**
|
|
@@ -131,34 +152,41 @@ class AbsoluteAttitude extends Provider {
|
|
|
131
152
|
*/
|
|
132
153
|
_onRelativeAttitudeEvent(event) {
|
|
133
154
|
|
|
134
|
-
if (!this._lastForcedHeadingEvent) {
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
155
|
const { quaternion, accuracy, time } = event.data;
|
|
139
156
|
|
|
140
157
|
// Calculate relative accuracy
|
|
141
158
|
if (this._relativeAttitude) {
|
|
142
159
|
this._relativeAccuracy += (time - this._relativeAttitude.time) * accuracy;
|
|
143
160
|
}
|
|
161
|
+
|
|
144
162
|
// Keep the relative attitude event for the calculation of relAbsQuat
|
|
163
|
+
// /!\ Keep this even if forced heading is not set /!\
|
|
145
164
|
this._relativeAttitude = event.data;
|
|
146
165
|
|
|
166
|
+
|
|
167
|
+
if (!this._lastForcedHeadingEvent) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
147
171
|
const accuracyWithRelative = Math.min(
|
|
148
172
|
this._lastForcedHeadingEvent.data.accuracy + this._relativeAccuracy,
|
|
149
173
|
Math.PI
|
|
150
174
|
);
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
let
|
|
154
|
-
|
|
155
|
-
if (
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
175
|
+
|
|
176
|
+
let newAccuracy = accuracyWithRelative;
|
|
177
|
+
let relAbsQuat = this._relAbsQuat;
|
|
178
|
+
|
|
179
|
+
if (this._eventFromBrowser) {
|
|
180
|
+
|
|
181
|
+
const {
|
|
182
|
+
accuracy: accuracyWithAbsolute,
|
|
183
|
+
heading: headingFromAbsolute
|
|
184
|
+
} = this._eventFromBrowser.data;
|
|
185
|
+
|
|
186
|
+
if (accuracyWithAbsolute < accuracyWithRelative) {
|
|
187
|
+
newAccuracy = accuracyWithAbsolute;
|
|
188
|
+
relAbsQuat = Quaternion.fromAxisAngle([0, 0, 1], event.data.heading - headingFromAbsolute);
|
|
189
|
+
}
|
|
162
190
|
}
|
|
163
191
|
|
|
164
192
|
const absoluteQuat = Quaternion.multiply(relAbsQuat, quaternion);
|
|
@@ -6,7 +6,7 @@ import EventType from '../../events/EventType.js';
|
|
|
6
6
|
class StraightLineDetector extends Provider {
|
|
7
7
|
|
|
8
8
|
/** @type {number} */
|
|
9
|
-
static STEPS_CONSIDERED_FOR_STRAIGHT_LINE =
|
|
9
|
+
static STEPS_CONSIDERED_FOR_STRAIGHT_LINE = 2;
|
|
10
10
|
|
|
11
11
|
/** @type {number?} */
|
|
12
12
|
_turnDetectorProviderId = null;
|
|
@@ -75,6 +75,10 @@ class StraightLineDetector extends Provider {
|
|
|
75
75
|
isStraight() {
|
|
76
76
|
return this._countSteps >= StraightLineDetector.STEPS_CONSIDERED_FOR_STRAIGHT_LINE;
|
|
77
77
|
}
|
|
78
|
+
|
|
79
|
+
get numStepsDetectedFromLastTurn() {
|
|
80
|
+
return this._countSteps;
|
|
81
|
+
}
|
|
78
82
|
}
|
|
79
83
|
|
|
80
84
|
export default new StraightLineDetector();
|
|
@@ -5,7 +5,7 @@ import { deg2rad, diffAngle, Quaternion } from '@wemap/maths';
|
|
|
5
5
|
class AttitudeSmoother {
|
|
6
6
|
|
|
7
7
|
/** @type {number} in radians/s */
|
|
8
|
-
static ROTATION_SPEED_JUMP_THRESHOLD = deg2rad(
|
|
8
|
+
static ROTATION_SPEED_JUMP_THRESHOLD = deg2rad(180);
|
|
9
9
|
|
|
10
10
|
/** @type {number} in radians/s */
|
|
11
11
|
static ROTATION_SPEED_CONVERGENCE = deg2rad(10);
|