@wemap/providers 4.0.4 → 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/package.json
CHANGED
|
@@ -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';
|
|
@@ -45,6 +45,12 @@ class MapMatchingHandler extends Provider {
|
|
|
45
45
|
/** @type {number} */
|
|
46
46
|
static MIN_STEPS_FOR_ORIENTATION_MATCHING = 5;
|
|
47
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
|
+
|
|
48
54
|
/** @type {MapMatching} */
|
|
49
55
|
_mapMatching;
|
|
50
56
|
|
|
@@ -69,6 +75,10 @@ class MapMatchingHandler extends Provider {
|
|
|
69
75
|
/** @type {number} */
|
|
70
76
|
_countStepsFromLastMatching = 0;
|
|
71
77
|
|
|
78
|
+
/** @type {Projection[]} */
|
|
79
|
+
_lastProjections = [];
|
|
80
|
+
|
|
81
|
+
|
|
72
82
|
constructor() {
|
|
73
83
|
super();
|
|
74
84
|
|
|
@@ -288,6 +298,7 @@ class MapMatchingHandler extends Provider {
|
|
|
288
298
|
|
|
289
299
|
if (TurnDectector.isTurning()) {
|
|
290
300
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
301
|
+
this._lastProjections = [];
|
|
291
302
|
AbsolutePosition.notify(positionEvent);
|
|
292
303
|
return;
|
|
293
304
|
}
|
|
@@ -297,6 +308,10 @@ class MapMatchingHandler extends Provider {
|
|
|
297
308
|
|
|
298
309
|
if (projection) {
|
|
299
310
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
311
|
+
this._lastProjections.push(projection);
|
|
312
|
+
if (this._lastProjections.length > MapMatchingHandler.LAST_PROJECTIONS_WINDOW_SIZE) {
|
|
313
|
+
this._lastProjections.shift();
|
|
314
|
+
}
|
|
300
315
|
|
|
301
316
|
const thisWillBeAHugeJump = projection.distanceFromNearestElement > MapMatchingHandler.MM_HUGE_JUMP_DISTANCE;
|
|
302
317
|
|
|
@@ -312,6 +327,12 @@ class MapMatchingHandler extends Provider {
|
|
|
312
327
|
return;
|
|
313
328
|
}
|
|
314
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
|
+
|
|
315
336
|
AbsolutePosition.notify(this.createEvent(
|
|
316
337
|
EventType.AbsolutePosition,
|
|
317
338
|
projection.projection,
|
|
@@ -335,6 +356,18 @@ class MapMatchingHandler extends Provider {
|
|
|
335
356
|
|
|
336
357
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow.push(projectionWithAbs);
|
|
337
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);
|
|
338
371
|
return;
|
|
339
372
|
}
|
|
340
373
|
|
|
@@ -350,6 +383,7 @@ class MapMatchingHandler extends Provider {
|
|
|
350
383
|
}
|
|
351
384
|
|
|
352
385
|
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
386
|
+
this._lastProjections = [];
|
|
353
387
|
|
|
354
388
|
// If no projection found with both projection methods, simply use the newPosition.
|
|
355
389
|
AbsolutePosition.notify(positionEvent);
|
|
@@ -380,6 +414,19 @@ class MapMatchingHandler extends Provider {
|
|
|
380
414
|
return false;
|
|
381
415
|
}
|
|
382
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
|
+
}
|
|
383
430
|
|
|
384
431
|
/**
|
|
385
432
|
* @param {Projection} projection
|
|
@@ -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);
|