@wemap/providers 3.1.16 → 3.1.18
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
|
@@ -65,6 +65,6 @@
|
|
|
65
65
|
"lint": "eslint --ext .js,.jsx --quiet src",
|
|
66
66
|
"test": "mocha -r esm \"src/**/*.spec.js\""
|
|
67
67
|
},
|
|
68
|
-
"version": "3.1.
|
|
69
|
-
"gitHead": "
|
|
68
|
+
"version": "3.1.18",
|
|
69
|
+
"gitHead": "faa44f5a027616ce6b61be6bb90be996543e133c"
|
|
70
70
|
}
|
|
@@ -129,27 +129,27 @@ class ProvidersInterface {
|
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
static get mapMatchingMaxDistance() {
|
|
132
|
-
return AbsolutePosition.
|
|
132
|
+
return AbsolutePosition.mapMatchingMaxDistance;
|
|
133
133
|
}
|
|
134
134
|
|
|
135
135
|
static set mapMatchingMaxDistance(maxDistance) {
|
|
136
|
-
AbsolutePosition.
|
|
136
|
+
AbsolutePosition.mapMatchingMaxDistance = maxDistance;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
139
|
static get mapMatchingMinDistance() {
|
|
140
|
-
return AbsolutePosition.
|
|
140
|
+
return AbsolutePosition.mapMatchingMinDistance;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
143
|
static set mapMatchingMinDistance(minDistance) {
|
|
144
|
-
AbsolutePosition.
|
|
144
|
+
AbsolutePosition.mapMatchingMinDistance = minDistance;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
147
|
static get mapMatchingMaxAngleBearing() {
|
|
148
|
-
return AbsolutePosition.
|
|
148
|
+
return AbsolutePosition.mapMatchingMaxAngleBearing;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
151
|
static set mapMatchingMaxAngleBearing(maxAngleBearing) {
|
|
152
|
-
AbsolutePosition.
|
|
152
|
+
AbsolutePosition.mapMatchingMaxAngleBearing = maxAngleBearing;
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
|
|
@@ -19,19 +19,21 @@ import ProvidersOptions from '../../../ProvidersOptions';
|
|
|
19
19
|
const ACCURACY_NEW_POS_EPS_RATIO = 1.5;
|
|
20
20
|
const ACCURACY_RELOC_RATIO = 2;
|
|
21
21
|
const MM_MAX_ANGLE = deg2rad(20);
|
|
22
|
-
const MM_MAX_DIST =
|
|
23
|
-
const MM_MIN_DIST =
|
|
22
|
+
const MM_MAX_DIST = 30;
|
|
23
|
+
const MM_MIN_DIST = 0;
|
|
24
24
|
const MM_MIN_TIME = 0.4;
|
|
25
25
|
|
|
26
26
|
class AbsolutePositionProvider extends MetaProvider {
|
|
27
27
|
|
|
28
28
|
lastMMAttempt = -Infinity;
|
|
29
|
+
lastEventBearing = null;
|
|
29
30
|
|
|
30
31
|
constructor() {
|
|
31
32
|
super();
|
|
32
33
|
this.mapMatching = new MapMatching();
|
|
33
34
|
this.mapMatching.maxDistance = MM_MAX_DIST;
|
|
34
35
|
this.mapMatching.maxAngleBearing = MM_MAX_ANGLE;
|
|
36
|
+
this._mapMatchingMinDistance = MM_MIN_DIST;
|
|
35
37
|
}
|
|
36
38
|
|
|
37
39
|
/**
|
|
@@ -93,22 +95,47 @@ class AbsolutePositionProvider extends MetaProvider {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
onAbsolutePosition(newPositionEvent, canContainLevel = true) {
|
|
96
|
-
|
|
98
|
+
let newPosition = newPositionEvent.data;
|
|
97
99
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
+
if (!this._useNewAbsolutePosition(newPosition)) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
100
103
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
if (this.lastEvent && !canContainLevel) {
|
|
105
|
+
newPosition.level = this.lastEvent.data.level;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (this.lastEventBearing !== null) {
|
|
109
|
+
newPosition.bearing = this.lastEventBearing;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (this._shouldHandleMapMatching()) {
|
|
113
|
+
|
|
114
|
+
let projectedPosition = null;
|
|
115
|
+
|
|
116
|
+
// Firstly, if lastEvent bearing is known, try to use map-matching with bearing
|
|
117
|
+
if (newPosition.bearing !== null) {
|
|
118
|
+
projectedPosition = this._calcMapMatchingPosition(newPosition, true);
|
|
104
119
|
}
|
|
105
120
|
|
|
106
|
-
if (
|
|
107
|
-
|
|
121
|
+
// Secondly, if map-matching with bearing did not work, try MM on nodes (without bearing).
|
|
122
|
+
if (!projectedPosition) {
|
|
123
|
+
projectedPosition = this._calcMapMatchingPosition(newPosition, false);
|
|
108
124
|
}
|
|
125
|
+
|
|
126
|
+
if (projectedPosition) {
|
|
127
|
+
newPosition = projectedPosition;
|
|
128
|
+
}
|
|
129
|
+
} else {
|
|
130
|
+
newPosition = newPosition.clone();
|
|
109
131
|
}
|
|
110
132
|
|
|
111
|
-
this.notify(
|
|
133
|
+
this.notify(this.createEvent(
|
|
134
|
+
EventType.AbsolutePosition,
|
|
135
|
+
newPosition,
|
|
136
|
+
newPositionEvent
|
|
137
|
+
));
|
|
138
|
+
|
|
112
139
|
}
|
|
113
140
|
|
|
114
141
|
/**
|
|
@@ -116,45 +143,78 @@ class AbsolutePositionProvider extends MetaProvider {
|
|
|
116
143
|
*/
|
|
117
144
|
onAbsolutePositionFromRel(newPositionEvent) {
|
|
118
145
|
|
|
119
|
-
|
|
120
|
-
* If map matching is not used or not set, raw position is returned
|
|
121
|
-
*/
|
|
122
|
-
if (!ProvidersOptions.useMapMatching
|
|
123
|
-
|| !this.mapMatching.network
|
|
124
|
-
|| newPositionEvent.data.time - this.lastMMAttempt < MM_MIN_TIME) {
|
|
125
|
-
this.notify(newPositionEvent.clone());
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
this.lastMMAttempt = newPositionEvent.data.time;
|
|
146
|
+
let newPosition = newPositionEvent.data;
|
|
129
147
|
|
|
130
|
-
|
|
131
|
-
const projection = this.mapMatching.getProjection(newPosition, true, true);
|
|
132
|
-
if (!projection || !projection.projection) {
|
|
133
|
-
// If no projection has been found, returns the position without map-matching
|
|
134
|
-
this.notify(newPositionEvent.clone());
|
|
135
|
-
return;
|
|
136
|
-
}
|
|
148
|
+
this.lastEventBearing = newPosition.bearing;
|
|
137
149
|
|
|
138
|
-
|
|
150
|
+
if (this._shouldHandleMapMatching()
|
|
151
|
+
&& newPositionEvent.data.time - this.lastMMAttempt > MM_MIN_TIME) {
|
|
139
152
|
|
|
140
|
-
|
|
141
|
-
|
|
153
|
+
// Firstly, try map matching with bearing
|
|
154
|
+
const projectedPosition = this._calcMapMatchingPosition(newPosition, true);
|
|
155
|
+
if (projectedPosition) {
|
|
156
|
+
newPosition = projectedPosition;
|
|
157
|
+
}
|
|
158
|
+
// map matching without bearing is not used to allow user to leave the network.
|
|
142
159
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
projectedPosition.lat = projection.projection.lat;
|
|
147
|
-
projectedPosition.lng = projection.projection.lng;
|
|
160
|
+
this.lastMMAttempt = newPositionEvent.data.time;
|
|
161
|
+
} else {
|
|
162
|
+
newPosition = newPosition.clone();
|
|
148
163
|
}
|
|
149
164
|
|
|
150
165
|
this.notify(this.createEvent(
|
|
151
166
|
EventType.AbsolutePosition,
|
|
152
|
-
|
|
167
|
+
newPosition,
|
|
153
168
|
newPositionEvent
|
|
154
169
|
));
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
_useNewAbsolutePosition(newPosition) {
|
|
173
|
+
|
|
174
|
+
if (!this.lastEvent) {
|
|
175
|
+
return true;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const lastPosition = this.lastEvent.data;
|
|
179
|
+
|
|
180
|
+
if (newPosition.accuracy <= newPosition.distanceTo(lastPosition) / ACCURACY_NEW_POS_EPS_RATIO) {
|
|
181
|
+
return true;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (newPosition.accuracy <= lastPosition.accuracy / ACCURACY_RELOC_RATIO) {
|
|
185
|
+
return true;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
return false;
|
|
155
189
|
|
|
156
190
|
}
|
|
157
191
|
|
|
192
|
+
_shouldHandleMapMatching() {
|
|
193
|
+
return ProvidersOptions.useMapMatching && this.mapMatching.network;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
_calcMapMatchingPosition(position, useBearing = true) {
|
|
197
|
+
|
|
198
|
+
const projection = this.mapMatching.getProjection(position, true, useBearing);
|
|
199
|
+
if (!projection || !projection.projection) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// Do not use projection if it too close from itinerary,
|
|
204
|
+
// this allows left/right movements (ie with ArCore)
|
|
205
|
+
if (projection.distanceFromNearestElement < this._mapMatchingMinDistance) {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Do not user projection.projection directly, because position has some specific properties like bearing
|
|
210
|
+
const projectedPosition = position.clone();
|
|
211
|
+
projectedPosition.lat = projection.projection.lat;
|
|
212
|
+
projectedPosition.lng = projection.projection.lng;
|
|
213
|
+
projectedPosition.level = projection.projection.level;
|
|
214
|
+
|
|
215
|
+
return projectedPosition;
|
|
216
|
+
}
|
|
217
|
+
|
|
158
218
|
/**
|
|
159
219
|
* @override
|
|
160
220
|
* @param {UserPosition | Network} data
|
|
@@ -174,12 +234,60 @@ class AbsolutePositionProvider extends MetaProvider {
|
|
|
174
234
|
));
|
|
175
235
|
} else if (data instanceof Network || eventType === EventType.Network) {
|
|
176
236
|
this.mapMatching.network = data;
|
|
237
|
+
|
|
238
|
+
if (this._shouldHandleMapMatching() && this.lastEvent) {
|
|
239
|
+
|
|
240
|
+
const position = this.lastEvent.data;
|
|
241
|
+
let projectedPosition = null;
|
|
242
|
+
|
|
243
|
+
// Firstly, if lastEvent bearing is known, try to use map-matching with bearing
|
|
244
|
+
if (position.bearing !== null) {
|
|
245
|
+
projectedPosition = this._calcMapMatchingPosition(position, true);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Secondly, if map-matching with bearing did not work, try MM on nodes (without bearing).
|
|
249
|
+
if (!projectedPosition) {
|
|
250
|
+
projectedPosition = this._calcMapMatchingPosition(position, false);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (projectedPosition) {
|
|
254
|
+
this.notify(this.createEvent(
|
|
255
|
+
EventType.AbsolutePosition,
|
|
256
|
+
projectedPosition,
|
|
257
|
+
this.lastEvent
|
|
258
|
+
));
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
|
|
177
262
|
} else {
|
|
178
263
|
throw new Error('Unknown feed object');
|
|
179
264
|
}
|
|
180
265
|
|
|
181
266
|
}
|
|
182
267
|
|
|
268
|
+
get mapMatchingMaxDistance() {
|
|
269
|
+
return this.mapMatching.maxDistance;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
set mapMatchingMaxDistance(maxDistance) {
|
|
273
|
+
this.mapMatching.maxDistance = maxDistance;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
get mapMatchingMinDistance() {
|
|
277
|
+
return this._mapMatchingMinDistance;
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
set mapMatchingMinDistance(minDistance) {
|
|
281
|
+
this._mapMatchingMinDistance = minDistance;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
get mapMatchingMaxAngleBearing() {
|
|
285
|
+
return this.mapMatching.maxAngleBearing;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
set mapMatchingMaxAngleBearing(maxAngleBearing) {
|
|
289
|
+
this.mapMatching.maxAngleBearing = maxAngleBearing;
|
|
290
|
+
}
|
|
183
291
|
}
|
|
184
292
|
|
|
185
293
|
export default AbsolutePositionProvider;
|