@wemap/providers 4.0.0 → 4.0.3
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/dist/index.html +1 -0
- package/debug/dist/turn-detection.html +19 -0
- package/debug/index.js +2 -0
- package/debug/src/AbsoluteAttitudeComponent.jsx +3 -10
- package/debug/src/StepDetectionComponent.jsx +3 -3
- package/debug/src/TurnDetectionComponent.jsx +47 -0
- package/debug/src/Utils.js +20 -0
- package/package.json +7 -9
- package/src/Providers.js +26 -81
- package/src/ProvidersInterface.js +5 -6
- package/src/errors/AskImuOnDesktopError.js +4 -3
- package/src/errors/ContainsIgnoredProviderError.js +4 -3
- package/src/errors/GeolocationApiMissingError.js +4 -3
- package/src/errors/GeolocationPermissionDeniedError.js +4 -3
- package/src/errors/GeolocationPositionUnavailableError.js +4 -3
- package/src/errors/IpResolveServerError.js +4 -3
- package/src/errors/MissingAccelerometerError.js +3 -3
- package/src/errors/MissingArCoreError.js +4 -3
- package/src/errors/MissingGyroscopeError.js +3 -3
- package/src/errors/MissingNativeInterfaceError.js +4 -3
- package/src/errors/MissingSensorError.js +4 -3
- package/src/errors/NoProviderFoundError.js +4 -3
- package/src/events/EventType.js +5 -1
- package/src/events/ProviderEvent.js +7 -0
- package/src/events/ProvidersLoggerOld.js +35 -34
- package/src/mapmatching/MapMatchingHandler.js +335 -69
- package/src/providers/FakeProvider.spec.js +15 -15
- package/src/providers/Provider.js +44 -27
- package/src/providers/Provider.spec.js +18 -29
- package/src/providers/attitude/TurnDectector.js +71 -0
- package/src/providers/attitude/absolute/AbsoluteAttitude.js +232 -0
- package/src/providers/attitude/absolute/{AbsoluteAttitudeFromBrowserProvider.js → AbsoluteAttitudeFromBrowser.js} +4 -4
- package/src/providers/attitude/relative/{RelativeAttitudeProvider.js → RelativeAttitude.js} +5 -8
- package/src/providers/attitude/relative/{RelativeAttitudeFromBrowserProvider.js → RelativeAttitudeFromBrowser.js} +4 -5
- package/src/providers/attitude/relative/{RelativeAttitudeFromEkfProvider.js → RelativeAttitudeFromEkf.js} +7 -8
- package/src/providers/attitude/relative/{RelativeAttitudeFromInertialProvider.js → RelativeAttitudeFromInertial.js} +24 -7
- package/src/providers/imu/{AccelerometerProvider.js → Accelerometer.js} +3 -3
- package/src/providers/imu/{GyroscopeProvider.js → Gyroscope.js} +3 -3
- package/src/providers/imu/HighRotationsDetector.js +62 -0
- package/src/providers/imu/{ImuProvider.js → Imu.js} +3 -3
- package/src/providers/inclination/{InclinationProvider.js → Inclination.js} +5 -6
- package/src/providers/inclination/{InclinationFromAccProvider.js → InclinationFromAcc.js} +4 -3
- package/src/providers/inclination/{InclinationFromRelativeAttitudeProvider.js → InclinationFromRelativeAttitude.js} +4 -3
- package/src/providers/legacy/helpers/ThugDetector.js +7 -7
- package/src/providers/others/{BarcodeProvider.js → Barcode.js} +3 -3
- package/src/providers/others/{CameraNativeProvider.js → CameraNative.js} +3 -3
- package/src/providers/others/{CameraProjectionMatrixProvider.js → CameraProjectionMatrix.js} +4 -4
- package/src/providers/position/absolute/AbsolutePosition.js +217 -0
- package/src/providers/position/absolute/{GnssWifiProvider.js → GnssWifi.js} +9 -8
- package/src/providers/position/absolute/{IpProvider.js → Ip.js} +2 -2
- package/src/providers/position/relative/{ArCoreProvider.js → ArCore.js} +28 -30
- package/src/providers/position/relative/{GeoRelativePositionProvider.js → GeoRelativePosition.js} +6 -6
- package/src/providers/position/relative/{GeoRelativePositionFromArCoreProvider.js → GeoRelativePositionFromArCore.js} +4 -5
- package/src/providers/position/relative/{PdrProvider.js → Pdr.js} +8 -8
- package/src/providers/steps/StepDetectionLadetto.js +12 -13
- package/src/providers/steps/StepDetectionMinMaxPeaks.js +19 -17
- package/src/providers/steps/StepDetectionMinMaxPeaks2.js +17 -18
- package/src/providers/steps/{StepDetectionProvider.js → StepDetector.js} +8 -7
- package/src/providers/steps/StraightLineDetector.js +80 -0
- package/src/smoothers/AttitudeSmoother.js +94 -59
- package/src/providers/MetaProvider.js +0 -44
- package/src/providers/attitude/absolute/AbsoluteAttitudeFromRelAttProvider.js +0 -132
- package/src/providers/attitude/absolute/AbsoluteAttitudeFusedProvider.js +0 -166
- package/src/providers/attitude/absolute/AbsoluteAttitudeProvider.js +0 -175
- package/src/providers/position/absolute/AbsolutePositionFromRelProvider.js +0 -107
- package/src/providers/position/absolute/AbsolutePositionProvider.js +0 -189
|
@@ -1,83 +1,84 @@
|
|
|
1
1
|
import Logger from '@wemap/logger';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
const objectsIdMap = new WeakMap();
|
|
3
|
+
class ProvidersLoggerOld {
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
let pushEventsRef = {};
|
|
5
|
+
_enabled = false;
|
|
8
6
|
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
currentId = 0;
|
|
8
|
+
objectsIdMap = new WeakMap();
|
|
11
9
|
|
|
12
|
-
|
|
10
|
+
pushEvents = {};
|
|
11
|
+
pushEventsRef = {};
|
|
12
|
+
|
|
13
|
+
interval;
|
|
14
|
+
initDate;
|
|
13
15
|
|
|
14
|
-
static _enabled = false;
|
|
15
16
|
|
|
16
|
-
|
|
17
|
+
get enabled() {
|
|
17
18
|
return this._enabled;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
|
|
21
|
+
set enabled(_newVal) {
|
|
21
22
|
this._enabled = _newVal;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
|
|
25
|
+
initializeInterval() {
|
|
25
26
|
|
|
26
|
-
if (interval) {
|
|
27
|
+
if (this.interval) {
|
|
27
28
|
return;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
|
-
interval = setInterval(() => {
|
|
31
|
+
this.interval = setInterval(() => {
|
|
31
32
|
|
|
32
|
-
for (const [key, value] of Object.entries(pushEvents)) {
|
|
33
|
-
Logger.debug('Received ' + value + ' notifications from ' + pushEventsRef[key].pname + ' last second');
|
|
33
|
+
for (const [key, value] of Object.entries(this.pushEvents)) {
|
|
34
|
+
Logger.debug('Received ' + value + ' notifications from ' + this.pushEventsRef[key].pname + ' last second');
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
pushEvents = {};
|
|
37
|
-
pushEventsRef = {};
|
|
37
|
+
this.pushEvents = {};
|
|
38
|
+
this.pushEventsRef = {};
|
|
38
39
|
}, 1000);
|
|
39
40
|
}
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
if (!objectsIdMap.has(object)) {
|
|
43
|
-
objectsIdMap.set(object, ++currentId);
|
|
42
|
+
getObjectId(object) {
|
|
43
|
+
if (!this.objectsIdMap.has(object)) {
|
|
44
|
+
this.objectsIdMap.set(object, ++this.currentId);
|
|
44
45
|
}
|
|
45
|
-
return objectsIdMap.get(object);
|
|
46
|
+
return this.objectsIdMap.get(object);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
+
addEvent(object, method) {
|
|
49
50
|
|
|
50
|
-
if (!
|
|
51
|
+
if (!this.enabled) {
|
|
51
52
|
return;
|
|
52
53
|
}
|
|
53
54
|
|
|
54
|
-
if (!initDate) {
|
|
55
|
-
initDate = Date.now();
|
|
55
|
+
if (!this.initDate) {
|
|
56
|
+
this.initDate = Date.now();
|
|
56
57
|
}
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
this.initializeInterval();
|
|
59
60
|
|
|
60
|
-
const objectId =
|
|
61
|
+
const objectId = this.getObjectId(object);
|
|
61
62
|
const objectClassName = object.pname;
|
|
62
63
|
|
|
63
64
|
Logger.debug(objectClassName + '[' + objectId + '].' + method);
|
|
64
65
|
}
|
|
65
66
|
|
|
66
|
-
|
|
67
|
+
incrementNotifications(object) {
|
|
67
68
|
|
|
68
|
-
if (!
|
|
69
|
+
if (!this.enabled) {
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
72
|
|
|
72
|
-
const objectId =
|
|
73
|
+
const objectId = this.getObjectId(object);
|
|
73
74
|
|
|
74
|
-
let counter = pushEvents[objectId];
|
|
75
|
+
let counter = this.pushEvents[objectId];
|
|
75
76
|
if (!counter) {
|
|
76
77
|
counter = 0;
|
|
77
|
-
pushEventsRef[objectId] = object;
|
|
78
|
+
this.pushEventsRef[objectId] = object;
|
|
78
79
|
}
|
|
79
|
-
pushEvents[objectId] = counter + 1;
|
|
80
|
+
this.pushEvents[objectId] = counter + 1;
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
}
|
|
83
|
-
export default ProvidersLoggerOld;
|
|
84
|
+
export default new ProvidersLoggerOld();
|
|
@@ -1,19 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
/* eslint-disable max-statements */
|
|
2
2
|
import {
|
|
3
|
-
MapMatching, Network
|
|
3
|
+
AbsoluteHeading, Edge, Itinerary, MapMatching, Network, Projection, UserPosition
|
|
4
4
|
} from '@wemap/geo';
|
|
5
|
-
import { deg2rad } from '@wemap/maths';
|
|
5
|
+
import { deg2rad, diffAngle } from '@wemap/maths';
|
|
6
|
+
import { TimeUtils } from '@wemap/utils';
|
|
6
7
|
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
import EventType from '../events/EventType.js';
|
|
9
|
+
import ProviderEvent from '../events/ProviderEvent.js';
|
|
10
|
+
|
|
11
|
+
import AbsoluteAttitude from '../providers/attitude/absolute/AbsoluteAttitude.js';
|
|
12
|
+
import AbsoluteAttitudeFromBrowser from '../providers/attitude/absolute/AbsoluteAttitudeFromBrowser.js';
|
|
13
|
+
import TurnDectector from '../providers/attitude/TurnDectector.js';
|
|
14
|
+
import Constants from '../providers/Constants.js';
|
|
15
|
+
import AbsolutePosition from '../providers/position/absolute/AbsolutePosition.js';
|
|
16
|
+
import Provider from '../providers/Provider.js';
|
|
17
|
+
import ProviderState from '../providers/ProviderState.js';
|
|
18
|
+
import StepDetector from '../providers/steps/StepDetector.js';
|
|
19
|
+
import StraightLineDetector from '../providers/steps/StraightLineDetector.js';
|
|
10
20
|
import ProvidersOptions from '../ProvidersOptions.js';
|
|
11
21
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
22
|
+
class MapMatchingHandler extends Provider {
|
|
23
|
+
|
|
24
|
+
/** @type {number} in radians */
|
|
25
|
+
static MM_MAX_ANGLE = deg2rad(30);
|
|
26
|
+
|
|
27
|
+
/** @type {number} in meters */
|
|
28
|
+
static MM_MAX_DIST = 30;
|
|
29
|
+
|
|
30
|
+
/** @type {number} in meters */
|
|
31
|
+
static MM_MIN_DIST = 0;
|
|
32
|
+
|
|
33
|
+
/** @type {boolean} */
|
|
34
|
+
static ORIENTATION_MATCHING = true;
|
|
35
|
+
|
|
36
|
+
/** @type {boolean} */
|
|
37
|
+
static USE_ITINERARY_START_AS_POSITION = true;
|
|
38
|
+
|
|
39
|
+
/** @type {number} in meters */
|
|
40
|
+
static MM_HUGE_JUMP_DISTANCE = 3;
|
|
15
41
|
|
|
16
|
-
|
|
42
|
+
/** @type {number} */
|
|
43
|
+
static MIN_STEPS_BETWEEN_ORIENTATION_MATCHING = 3;
|
|
17
44
|
|
|
18
45
|
/** @type {MapMatching} */
|
|
19
46
|
_mapMatching;
|
|
@@ -21,105 +48,344 @@ class MapMatchingHandler {
|
|
|
21
48
|
/** @type {number} */
|
|
22
49
|
_mapMatchingMinDistance;
|
|
23
50
|
|
|
51
|
+
/** @type {boolean} */
|
|
52
|
+
_internalProvidersStarted = false;
|
|
53
|
+
|
|
54
|
+
/** @type {number?} */
|
|
55
|
+
_straightLineDetectorProviderId;
|
|
56
|
+
|
|
57
|
+
/** @type {number?} */
|
|
58
|
+
_turnDetectorProviderId;
|
|
59
|
+
|
|
60
|
+
/** @type {number?} */
|
|
61
|
+
_stepDetectorProviderId;
|
|
62
|
+
|
|
63
|
+
/** @type {Projection[]} */
|
|
64
|
+
_projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
65
|
+
|
|
66
|
+
/** @type {number} */
|
|
67
|
+
_countStepsFromLastMatching = 0;
|
|
68
|
+
|
|
69
|
+
constructor() {
|
|
70
|
+
super();
|
|
71
|
+
|
|
72
|
+
this._mapMatching = new MapMatching();
|
|
73
|
+
this._mapMatching.maxDistance = MapMatchingHandler.MM_MAX_DIST;
|
|
74
|
+
this._mapMatching.maxAngleBearing = MapMatchingHandler.MM_MAX_ANGLE;
|
|
75
|
+
this._mapMatchingMinDistance = MapMatchingHandler.MM_MIN_DIST;
|
|
76
|
+
}
|
|
77
|
+
|
|
24
78
|
/**
|
|
25
|
-
*
|
|
26
|
-
* @returns {MapMatchingHandler}
|
|
79
|
+
* @override
|
|
27
80
|
*/
|
|
28
|
-
|
|
29
|
-
if (
|
|
30
|
-
this.
|
|
81
|
+
start() {
|
|
82
|
+
if (this.network) {
|
|
83
|
+
this._startInternalProviders();
|
|
31
84
|
}
|
|
32
|
-
return this._instance;
|
|
33
85
|
}
|
|
34
86
|
|
|
35
|
-
|
|
87
|
+
/**
|
|
88
|
+
* @override
|
|
89
|
+
*/
|
|
90
|
+
stop() {
|
|
91
|
+
this._stopInternalProviders();
|
|
92
|
+
}
|
|
36
93
|
|
|
37
|
-
|
|
38
|
-
|
|
94
|
+
_manageStartStop = () => {
|
|
95
|
+
if (this.network && !this._internalProvidersStarted) {
|
|
96
|
+
this._startInternalProviders();
|
|
97
|
+
} else if (!this.network && this._internalProvidersStarted) {
|
|
98
|
+
this._stopInternalProviders();
|
|
39
99
|
}
|
|
100
|
+
}
|
|
40
101
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.
|
|
44
|
-
|
|
102
|
+
_startInternalProviders() {
|
|
103
|
+
|
|
104
|
+
if (this.enabled && this._internalProvidersStarted) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
this._straightLineDetectorProviderId = StraightLineDetector.addEventListener();
|
|
109
|
+
this._turnDetectorProviderId = TurnDectector.addEventListener();
|
|
110
|
+
this._stepDetectorProviderId = StepDetector.addEventListener(() => (this._countStepsFromLastMatching++));
|
|
111
|
+
|
|
112
|
+
this._internalProvidersStarted = true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
_stopInternalProviders() {
|
|
116
|
+
|
|
117
|
+
if (this.enabled && !this._internalProvidersStarted) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
StraightLineDetector.removeEventListener(this._straightLineDetectorProviderId);
|
|
122
|
+
TurnDectector.removeEventListener(this._turnDetectorProviderId);
|
|
123
|
+
StepDetector.removeEventListener(this._stepDetectorProviderId);
|
|
124
|
+
|
|
125
|
+
this._internalProvidersStarted = false;
|
|
45
126
|
}
|
|
46
127
|
|
|
47
128
|
get enabled() {
|
|
48
129
|
return ProvidersOptions.useMapMatching;
|
|
49
130
|
}
|
|
50
131
|
|
|
51
|
-
/**
|
|
52
|
-
|
|
53
|
-
|
|
132
|
+
/** @type {Network} */
|
|
133
|
+
get network() {
|
|
134
|
+
return this._mapMatching.network;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/** @type {Network} */
|
|
54
138
|
set network(network) {
|
|
139
|
+
|
|
55
140
|
this._mapMatching.network = network;
|
|
141
|
+
this.notify(this.createEvent(EventType.Network, network));
|
|
56
142
|
|
|
57
|
-
|
|
58
|
-
|
|
143
|
+
this._manageStartStop();
|
|
144
|
+
|
|
145
|
+
if (this.canUseMapMatching()) {
|
|
146
|
+
this._notifyPositionFromNetworkInput(network);
|
|
59
147
|
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/**
|
|
151
|
+
* @returns {boolean}
|
|
152
|
+
*/
|
|
153
|
+
canUseMapMatching() {
|
|
154
|
+
return this.enabled && this.network;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* @param {Network} network
|
|
159
|
+
*/
|
|
160
|
+
_notifyPositionFromNetworkInput(network) {
|
|
60
161
|
|
|
61
162
|
const lastEvent = AbsolutePosition.lastEvent;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
AbsolutePosition
|
|
163
|
+
const lastPosition = lastEvent ? lastEvent.data : null;
|
|
164
|
+
|
|
165
|
+
const notify = (pos) => {
|
|
166
|
+
const newEvent = lastEvent
|
|
167
|
+
? lastEvent.clone()
|
|
168
|
+
: new ProviderEvent(EventType.AbsolutePosition);
|
|
169
|
+
newEvent.data = pos;
|
|
170
|
+
AbsolutePosition.notify(newEvent);
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
let newPosition;
|
|
174
|
+
if (MapMatchingHandler.USE_ITINERARY_START_AS_POSITION
|
|
175
|
+
&& network instanceof Itinerary && network.start) {
|
|
176
|
+
|
|
177
|
+
// In case of an itinerary, use itinerary start as new position,
|
|
178
|
+
// but add the distance between lastPosition and itinerary start for the accuracy
|
|
179
|
+
newPosition = UserPosition.fromCoordinates(network.start);
|
|
180
|
+
|
|
181
|
+
if (lastPosition) {
|
|
182
|
+
newPosition.alt = lastPosition.alt;
|
|
183
|
+
newPosition.time = lastPosition.time;
|
|
184
|
+
newPosition.accuracy = lastPosition.accuracy + newPosition.distanceTo(lastPosition);
|
|
185
|
+
newPosition.bearing = lastPosition.bearing;
|
|
186
|
+
} else {
|
|
187
|
+
newPosition.alt = Constants.DEFAULT_ALTITUDE;
|
|
188
|
+
newPosition.time = TimeUtils.preciseTime();
|
|
189
|
+
newPosition.accuracy = 0;
|
|
190
|
+
newPosition.bearing = network.edges[0].bearing;
|
|
68
191
|
}
|
|
192
|
+
|
|
193
|
+
// if the distance between itinerary.start and itinerary.nodes[0] is less than MM_MAX_DIST,
|
|
194
|
+
// projection.projection is itinerary.nodes[0]
|
|
195
|
+
const projection = this.getProjection(newPosition, true);
|
|
196
|
+
if (projection) {
|
|
197
|
+
notify(projection.projection);
|
|
198
|
+
// Do not notify for attitude projection because bearing has not been used.
|
|
199
|
+
} else {
|
|
200
|
+
// This means the first position is far from the network and the user has
|
|
201
|
+
// to reach itinerary.nodes[0] before to continue
|
|
202
|
+
notify(newPosition);
|
|
203
|
+
}
|
|
204
|
+
return;
|
|
69
205
|
}
|
|
206
|
+
|
|
207
|
+
if (!lastPosition) {
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
newPosition = lastPosition.clone();
|
|
212
|
+
// TODO in function of the lastEvent, if it is from relative or absolute
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* @param {ProviderEvent<UserPosition>} newPositionEvent
|
|
217
|
+
*/
|
|
218
|
+
notifyPositionFromFeed(newPositionEvent) {
|
|
219
|
+
|
|
220
|
+
const projection = this.getProjection(newPositionEvent.data, true, false);
|
|
221
|
+
if (!projection) {
|
|
222
|
+
AbsolutePosition.notify(newPositionEvent);
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
AbsolutePosition.notify(this.createEvent(
|
|
227
|
+
EventType.AbsolutePosition,
|
|
228
|
+
projection.projection,
|
|
229
|
+
[newPositionEvent]
|
|
230
|
+
));
|
|
70
231
|
}
|
|
71
232
|
|
|
233
|
+
|
|
72
234
|
/**
|
|
73
|
-
* @param {UserPosition}
|
|
74
|
-
* @param {boolean} shouldTryMmOnNodes
|
|
75
|
-
* @returns {UserPosition}
|
|
235
|
+
* @param {ProviderEvent<UserPosition>} positionEvent
|
|
76
236
|
*/
|
|
77
|
-
|
|
237
|
+
notifyPositionFromAbsolute(positionEvent) {
|
|
78
238
|
|
|
79
|
-
|
|
80
|
-
let bearingUsedForProjection = false;
|
|
239
|
+
const newPosition = positionEvent.data;
|
|
81
240
|
|
|
82
|
-
|
|
83
|
-
|
|
241
|
+
let projectionWithBearing = null;
|
|
242
|
+
if (newPosition.bearing !== null) {
|
|
243
|
+
projectionWithBearing = this.getProjection(newPosition, true, true);
|
|
84
244
|
}
|
|
85
245
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
246
|
+
if (!projectionWithBearing) {
|
|
247
|
+
// Verify if the newPosition is far enough from the network to be used by the system.
|
|
248
|
+
const projectionWithoutBearing = this.getProjection(newPosition, true, false);
|
|
249
|
+
if (!projectionWithoutBearing) {
|
|
250
|
+
// In this case, the newPosition is far enough and can be used safely.
|
|
251
|
+
AbsolutePosition.notify(positionEvent);
|
|
252
|
+
}
|
|
253
|
+
return;
|
|
91
254
|
}
|
|
92
255
|
|
|
93
|
-
//
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
256
|
+
// newPosition must not be used after this line
|
|
257
|
+
|
|
258
|
+
const thisWillBeAHugeJump = projectionWithBearing.distanceFromNearestElement > MapMatchingHandler.MM_HUGE_JUMP_DISTANCE;
|
|
259
|
+
|
|
260
|
+
// In case of a huge jump, be sure the user is in a straight line
|
|
261
|
+
if (thisWillBeAHugeJump && !StraightLineDetector.isStraight()) {
|
|
262
|
+
return;
|
|
99
263
|
}
|
|
100
264
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
265
|
+
AbsolutePosition.notify(this.createEvent(
|
|
266
|
+
EventType.AbsolutePosition,
|
|
267
|
+
projectionWithBearing.projection,
|
|
268
|
+
[positionEvent]
|
|
269
|
+
));
|
|
270
|
+
|
|
271
|
+
this.tryOrientationMatching(projectionWithBearing);
|
|
272
|
+
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* @param {ProviderEvent<UserPosition>} positionEvent
|
|
278
|
+
*/
|
|
279
|
+
notifyPositionFromRelative(positionEvent) {
|
|
280
|
+
|
|
281
|
+
if (TurnDectector.isTurning()) {
|
|
282
|
+
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
283
|
+
AbsolutePosition.notify(positionEvent);
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const newPosition = positionEvent.data;
|
|
288
|
+
const projection = this.getProjection(newPosition, true, true);
|
|
289
|
+
|
|
290
|
+
if (projection) {
|
|
291
|
+
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
292
|
+
|
|
293
|
+
const thisWillBeAHugeJump = projection.distanceFromNearestElement > MapMatchingHandler.MM_HUGE_JUMP_DISTANCE;
|
|
294
|
+
|
|
295
|
+
// In case of a huge jump, be sure the user is in a straight line
|
|
296
|
+
if (thisWillBeAHugeJump && !StraightLineDetector.isStraight()) {
|
|
297
|
+
AbsolutePosition.notify(positionEvent);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
AbsolutePosition.notify(this.createEvent(
|
|
302
|
+
EventType.AbsolutePosition,
|
|
303
|
+
projection.projection,
|
|
304
|
+
[positionEvent]
|
|
305
|
+
));
|
|
306
|
+
this.tryOrientationMatching(projection);
|
|
307
|
+
|
|
308
|
+
} else {
|
|
309
|
+
|
|
310
|
+
// Sometimes, the newPosition.bearing diverges due to the Absolute Attitude offset
|
|
311
|
+
// and the Orientation Matching. So, we created this detector to check if projection
|
|
312
|
+
// with bearing from "AbsoluteAttitudeFromBrowser" is better than the current bearing.
|
|
313
|
+
// /!\ This works only if the user is waking in the same direction than the smartphone orientation /!\
|
|
314
|
+
if (StraightLineDetector.isStraight()) {
|
|
315
|
+
|
|
316
|
+
const testedPosition = newPosition.clone();
|
|
317
|
+
testedPosition.bearing = AbsoluteAttitudeFromBrowser.lastEvent.data.heading;
|
|
318
|
+
const projectionWithAbs = this.getProjection(testedPosition, true, true);
|
|
319
|
+
|
|
320
|
+
if (projectionWithAbs) {
|
|
321
|
+
|
|
322
|
+
this._projectionsWithAbsAndWithoutRelAttitudeInARow.push(projectionWithAbs);
|
|
323
|
+
if (this._projectionsWithAbsAndWithoutRelAttitudeInARow.length < 3) {
|
|
324
|
+
return;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
AbsolutePosition.notify(this.createEvent(
|
|
328
|
+
EventType.AbsolutePosition,
|
|
329
|
+
projectionWithAbs.projection,
|
|
330
|
+
[positionEvent]
|
|
331
|
+
));
|
|
332
|
+
|
|
333
|
+
this.tryOrientationMatching(projectionWithAbs);
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
this._projectionsWithAbsAndWithoutRelAttitudeInARow = [];
|
|
339
|
+
|
|
340
|
+
// If no projection found with both projection methods, simply use the newPosition.
|
|
341
|
+
AbsolutePosition.notify(positionEvent);
|
|
104
342
|
}
|
|
105
343
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* @param {Projection} projection
|
|
348
|
+
*/
|
|
349
|
+
tryOrientationMatching(projection) {
|
|
350
|
+
|
|
351
|
+
if (!MapMatchingHandler.ORIENTATION_MATCHING) {
|
|
352
|
+
return;
|
|
110
353
|
}
|
|
111
354
|
|
|
112
|
-
if (
|
|
113
|
-
|
|
355
|
+
if (this.state !== ProviderState.STARTED
|
|
356
|
+
|| this._countStepsFromLastMatching < MapMatchingHandler.MIN_STEPS_BETWEEN_ORIENTATION_MATCHING) {
|
|
357
|
+
return;
|
|
114
358
|
}
|
|
115
359
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
360
|
+
const { nearestElement, origin } = projection;
|
|
361
|
+
if (!(nearestElement instanceof Edge)) {
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
let matchingDirection;
|
|
366
|
+
const matchingDirectionAngle1 = diffAngle(nearestElement.bearing, origin.bearing);
|
|
367
|
+
const matchingDirectionAngle2 = diffAngle(nearestElement.bearing + Math.PI, origin.bearing);
|
|
368
|
+
|
|
369
|
+
if (Math.abs(matchingDirectionAngle1) < Math.abs(matchingDirectionAngle2)) {
|
|
370
|
+
matchingDirection = nearestElement.bearing;
|
|
371
|
+
} else {
|
|
372
|
+
matchingDirection = (nearestElement.bearing + Math.PI) % (2 * Math.PI);
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const matchedHeading = new AbsoluteHeading(
|
|
376
|
+
matchingDirection,
|
|
377
|
+
origin.time,
|
|
378
|
+
0
|
|
379
|
+
// Math.min(Math.abs(matchingDirectionAngle1), Math.abs(matchingDirectionAngle2))
|
|
380
|
+
);
|
|
381
|
+
|
|
382
|
+
AbsoluteAttitude.feed(new ProviderEvent(EventType.AbsoluteHeading, matchedHeading));
|
|
383
|
+
|
|
384
|
+
this._countStepsFromLastMatching = 0;
|
|
385
|
+
}
|
|
121
386
|
|
|
122
|
-
|
|
387
|
+
getProjection(position, useDistance, useBearing) {
|
|
388
|
+
return this._mapMatching.getProjection(position, useDistance, useBearing);
|
|
123
389
|
}
|
|
124
390
|
|
|
125
391
|
get maxDistance() {
|
|
@@ -147,4 +413,4 @@ class MapMatchingHandler {
|
|
|
147
413
|
}
|
|
148
414
|
}
|
|
149
415
|
|
|
150
|
-
export default MapMatchingHandler
|
|
416
|
+
export default new MapMatchingHandler();
|
|
@@ -3,13 +3,15 @@ import { UserPosition } from '@wemap/geo';
|
|
|
3
3
|
import Provider from './Provider.js';
|
|
4
4
|
import EventType from '../events/EventType.js';
|
|
5
5
|
|
|
6
|
-
class
|
|
6
|
+
class FakeProvider1Clazz extends Provider {
|
|
7
7
|
static get pname() {
|
|
8
8
|
return 'FakeProvider1';
|
|
9
9
|
}
|
|
10
10
|
}
|
|
11
|
+
const FakeProvider1 = new FakeProvider1Clazz();
|
|
12
|
+
export { FakeProvider1 };
|
|
11
13
|
|
|
12
|
-
class
|
|
14
|
+
class FakeProvider2Clazz extends Provider {
|
|
13
15
|
static get pname() {
|
|
14
16
|
return 'FakeProvider2';
|
|
15
17
|
}
|
|
@@ -19,8 +21,10 @@ class FakeProvider2 extends Provider {
|
|
|
19
21
|
start() { }
|
|
20
22
|
stop() { }
|
|
21
23
|
}
|
|
24
|
+
const FakeProvider2 = new FakeProvider2Clazz();
|
|
25
|
+
export { FakeProvider2 };
|
|
22
26
|
|
|
23
|
-
class
|
|
27
|
+
class FakeProvider3Clazz extends Provider {
|
|
24
28
|
static get pname() {
|
|
25
29
|
return 'FakeProvider3';
|
|
26
30
|
}
|
|
@@ -34,31 +38,27 @@ class FakeProvider3 extends Provider {
|
|
|
34
38
|
clearInterval(this.intervalId);
|
|
35
39
|
}
|
|
36
40
|
}
|
|
41
|
+
const FakeProvider3 = new FakeProvider3Clazz();
|
|
42
|
+
export { FakeProvider3 };
|
|
37
43
|
|
|
38
|
-
class
|
|
44
|
+
class FakeProvider4Clazz extends Provider {
|
|
39
45
|
|
|
40
46
|
static get pname() {
|
|
41
47
|
return 'FakeProvider4';
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
constructor() {
|
|
45
|
-
super();
|
|
46
|
-
this.fp3 = FakeProvider3.instance;
|
|
47
|
-
}
|
|
48
50
|
get _availability() {
|
|
49
|
-
return
|
|
51
|
+
return FakeProvider3.availability;
|
|
50
52
|
}
|
|
51
53
|
start() {
|
|
52
|
-
this.fp3id =
|
|
54
|
+
this.fp3id = FakeProvider3.addEventListener(
|
|
53
55
|
events => this.notify(events[0].clone()),
|
|
54
56
|
this.notifyError.bind(this)
|
|
55
57
|
);
|
|
56
58
|
}
|
|
57
59
|
stop() {
|
|
58
|
-
|
|
60
|
+
FakeProvider3.removeEventListener(this.fp3id);
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
|
-
|
|
62
|
-
export {
|
|
63
|
-
FakeProvider1, FakeProvider2, FakeProvider3, FakeProvider4
|
|
64
|
-
};
|
|
63
|
+
const FakeProvider4 = new FakeProvider4Clazz();
|
|
64
|
+
export { FakeProvider4 };
|