@wemap/positioning 2.1.0 → 2.3.0
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/arcore-absolute.html +16 -0
- package/debug/arcore.html +16 -0
- package/package.json +2 -1
- package/src/PositioningHandler.js +19 -5
- package/src/components/AbsoluteAttitudeComponent.jsx +2 -2
- package/src/components/ArCoreAbsoluteComponent.jsx +100 -0
- package/src/components/ArCoreComponent.jsx +74 -0
- package/src/components/GnssWifiComponent.jsx +14 -2
- package/src/components/GnssWifiPdrComponent.jsx +11 -2
- package/src/components/MapComponent.jsx +237 -0
- package/src/components/PdrComponent.jsx +12 -3
- package/src/components/PoseComponent.jsx +7 -0
- package/src/components/PositioningPoseComponent.jsx +12 -3
- package/src/components/Utils.js +18 -0
- package/src/components/index.js +4 -0
- package/src/errors/MissingArCoreError.js +9 -0
- package/src/errors/MissingNativeInterfaceError.js +9 -0
- package/src/providers/Provider.js +15 -3
- package/src/providers/ProviderOptions.js +1 -1
- package/src/providers/attitude/AbsoluteAttitudeProvider.js +6 -6
- package/src/providers/others/MapMatchingProvider.js +19 -19
- package/src/providers/pose/ArCoreAbsoluteProvider.js +186 -0
- package/src/providers/pose/ArCoreProvider.js +115 -0
- package/src/providers/pose/GnssWifiPdrProvider.js +20 -20
- package/src/providers/pose/PoseProvider.js +1 -1
- package/src/providers/pose/pdr/PdrProvider.js +39 -39
- package/src/providers/pose/pdr/helpers/Smoother.js +33 -33
- package/src/providers/pose/pdr/helpers/Smoother.spec.js +7 -7
- package/src/providers/position/GnssWifiProvider.js +5 -5
- package/src/providers/position/IpProvider.js +2 -2
- package/webpack/webpack.common.js +1 -1
- package/src.old/Constants.js +0 -11
- package/src.old/NavigationHandler.js +0 -244
- package/src.old/Pose.js +0 -8
- package/src.old/attitude/AttitudeHandler.js +0 -342
- package/src.old/attitude/EkfAttitude.js +0 -238
- package/src.old/attitude/EkfAttitude.spec.js +0 -116
- package/src.old/components/AbsoluteAttitude.jsx +0 -136
- package/src.old/components/Imu.jsx +0 -89
- package/src.old/components/LocationSource.jsx +0 -434
- package/src.old/components/Logger.jsx +0 -113
- package/src.old/components/NavigationDebugApp.jsx +0 -106
- package/src.old/components/Others.jsx +0 -121
- package/src.old/components/RelativeAttitude.jsx +0 -104
- package/src.old/components/Utils.js +0 -35
- package/src.old/components/index.js +0 -13
- package/src.old/index.js +0 -7
- package/src.old/providers/FixedLocationImuLocationSource.js +0 -66
- package/src.old/providers/GnssLocationSource.js +0 -118
- package/src.old/providers/GnssPdrLocationSource.js +0 -182
- package/src.old/providers/IPLocationSource.js +0 -96
- package/src.old/providers/LocationSource.js +0 -290
- package/src.old/providers/PdrLocationSource.js +0 -320
- package/src.old/providers/ProvidersLogger.js +0 -77
- package/src.old/providers/pdr/HeadingUnlocker.js +0 -41
- package/src.old/providers/pdr/HeadingUnlocker.spec.js +0 -26
- package/src.old/providers/pdr/Smoother.js +0 -90
- package/src.old/providers/pdr/Smoother.spec.js +0 -424
- package/src.old/providers/pdr/ThugDetector.js +0 -37
- package/src.old/providers/steps/StepDetection.js +0 -7
- package/src.old/providers/steps/StepDetectionLadetto.js +0 -67
- package/src.old/providers/steps/StepDetectionMinMaxPeaks.js +0 -80
- package/src.old/providers/steps/StepDetectionMinMaxPeaks2.js +0 -108
- package/src.old/sensors/SensorsCompatibility.js +0 -486
- package/src.old/sensors/SensorsCompatibility.spec.js +0 -270
- package/src.old/sensors/SensorsLogger.js +0 -94
- package/src.old/sensors/SensorsLoggerUtils.js +0 -35
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
/* eslint max-statements: ["error", 40]*/
|
|
2
|
-
|
|
3
|
-
import { WGS84UserPosition } from '@wemap/geo';
|
|
4
|
-
|
|
5
|
-
import LocationSource from './LocationSource';
|
|
6
|
-
import AttitudeHandler from '../attitude/AttitudeHandler';
|
|
7
|
-
import Constants from '../Constants';
|
|
8
|
-
import GnssLocationSource from './GnssLocationSource';
|
|
9
|
-
import PdrLocationSource from './PdrLocationSource';
|
|
10
|
-
import NavigationHandler from '../NavigationHandler';
|
|
11
|
-
|
|
12
|
-
const GPF_ACCURACY = 25;
|
|
13
|
-
const GPF_DISTANCE = 25;
|
|
14
|
-
|
|
15
|
-
const MM_GNSS_DIST = 20;
|
|
16
|
-
const MM_GNSS_ANGLE = 20;
|
|
17
|
-
|
|
18
|
-
class GnssPdrLocationSource extends LocationSource {
|
|
19
|
-
|
|
20
|
-
constructor(callback, options) {
|
|
21
|
-
super(callback);
|
|
22
|
-
|
|
23
|
-
// Create a PdrLocationSource. Updates from Pdr will automatically set pose of GnssPdrLocationSource
|
|
24
|
-
this.pdrLocationSource = new PdrLocationSource(pose => {
|
|
25
|
-
this.pose = pose;
|
|
26
|
-
this.notify();
|
|
27
|
-
}, options);
|
|
28
|
-
|
|
29
|
-
// Create a GNSSLocationSource without IMU for attitude
|
|
30
|
-
this.gnssLocationSource = new GnssLocationSource(e => this.callbackGnss(e), false);
|
|
31
|
-
|
|
32
|
-
this.attitudeHandler = new AttitudeHandler();
|
|
33
|
-
|
|
34
|
-
this.gpsLastUpdate = 0;
|
|
35
|
-
this.isFirstGnssUpdate = true;
|
|
36
|
-
this.isFirstAttitudeUpdate = true;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Get provider name
|
|
41
|
-
* @override
|
|
42
|
-
*/
|
|
43
|
-
static get providerName() {
|
|
44
|
-
return Constants.LOCATION_SOURCE_PROVIDERS.GNSS_PDR;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
start() {
|
|
48
|
-
super.start();
|
|
49
|
-
|
|
50
|
-
return Promise.all([
|
|
51
|
-
this.pdrLocationSource.start(),
|
|
52
|
-
this.gnssLocationSource.start(),
|
|
53
|
-
this.attitudeHandler.startAbsolute(attitude => this.callbackAttitude(attitude))]);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
stop() {
|
|
57
|
-
super.stop();
|
|
58
|
-
|
|
59
|
-
this.pdrLocationSource.stop();
|
|
60
|
-
this.gnssLocationSource.stop();
|
|
61
|
-
this.attitudeHandler.stopAbsolute();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
setLogger(logger) {
|
|
65
|
-
super.setLogger(logger);
|
|
66
|
-
this.pdrLocationSource.setLogger(logger);
|
|
67
|
-
this.gnssLocationSource.setLogger(logger);
|
|
68
|
-
this.attitudeHandler.setLogger(logger);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
callbackGnss(pose) {
|
|
73
|
-
|
|
74
|
-
// This should be called to update True North / Magnetic North declination
|
|
75
|
-
this.attitudeHandler.setUserLocationForAbsolute(pose.location);
|
|
76
|
-
|
|
77
|
-
if (pose.location.accuracy > GPF_ACCURACY) {
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
this.gnssLocation = pose.location.clone();
|
|
82
|
-
this.gnssLocation.alt = NavigationHandler.DEFAULT_ALTITUDE;
|
|
83
|
-
|
|
84
|
-
if (!this.pose.location || this.pose.location
|
|
85
|
-
&& this.pose.location.distanceTo(this.gnssLocation) > GPF_DISTANCE) {
|
|
86
|
-
|
|
87
|
-
if (!this.mapMatching || !this.pose.attitude) {
|
|
88
|
-
this.pdrLocationSource.setLocation(this.gnssLocation);
|
|
89
|
-
} else {
|
|
90
|
-
|
|
91
|
-
this.gnssLocation.bearing = this.pose.attitude.headingDegrees;
|
|
92
|
-
const projection = this.mapMatching.getProjection(this.gnssLocation);
|
|
93
|
-
|
|
94
|
-
if (projection && projection.projection) {
|
|
95
|
-
|
|
96
|
-
// Create a new location from projection and new GNSS location.
|
|
97
|
-
const projectedLocation = WGS84UserPosition.fromWGS84(projection.projection, this.gnssLocation);
|
|
98
|
-
this.pdrLocationSource.setLocation(projectedLocation);
|
|
99
|
-
|
|
100
|
-
// // If nearest element is an edge, use its orientation to set heading
|
|
101
|
-
// if (projection.nearestElement instanceof Edge) {
|
|
102
|
-
// const edgeBearing = projection.nearestElement.bearing;
|
|
103
|
-
// const diff1 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssLocation.bearing), edgeBearing);
|
|
104
|
-
// const diff2 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssLocation.bearing), edgeBearing + Math.PI);
|
|
105
|
-
// this.pdrLocationSource.setHeading(diff1 < diff2 ? edgeBearing : edgeBearing + Math.PI);
|
|
106
|
-
// }
|
|
107
|
-
|
|
108
|
-
if (this.lastAttitude) {
|
|
109
|
-
this.pdrLocationSource.setHeading(this.lastAttitude.heading);
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
} else {
|
|
113
|
-
this.pdrLocationSource.setLocation(this.gnssLocation);
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
callbackAttitude(attitude) {
|
|
121
|
-
|
|
122
|
-
if (this.isFirstAttitudeUpdate) {
|
|
123
|
-
this.pdrLocationSource.setHeading(attitude.heading);
|
|
124
|
-
this.isFirstAttitudeUpdate = false;
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
this.lastAttitude = attitude;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* MapMatching
|
|
133
|
-
*/
|
|
134
|
-
|
|
135
|
-
enableMapMatching(network, maxDistance = MM_GNSS_DIST, maxAngleBearing = MM_GNSS_ANGLE) {
|
|
136
|
-
this.pdrLocationSource.enableMapMatching(network, maxDistance, maxAngleBearing);
|
|
137
|
-
super.enableMapMatching(network, maxDistance, maxAngleBearing);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
setNetwork(network) {
|
|
142
|
-
this.pdrLocationSource.setNetwork(network);
|
|
143
|
-
super.setNetwork(network);
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Itinerary
|
|
148
|
-
*/
|
|
149
|
-
|
|
150
|
-
setItinerary(itinerary) {
|
|
151
|
-
|
|
152
|
-
const isFirstItinerary = !this.itinerary;
|
|
153
|
-
|
|
154
|
-
super.setItinerary(itinerary);
|
|
155
|
-
|
|
156
|
-
if (isFirstItinerary && itinerary.length > 0) {
|
|
157
|
-
|
|
158
|
-
// When the first itinerary is received, first or second node (depending on MM_GNSS_DIST) is used as a starting point. No map-matching is needed here as router already provide the projection in the itinerary (node2 is node1 projection on OSRM network).
|
|
159
|
-
|
|
160
|
-
if (!this.gnssLocation
|
|
161
|
-
|| itinerary.length < 2
|
|
162
|
-
|| !itinerary.points[0].equalsTo(this.gnssLocation)) {
|
|
163
|
-
console.warn('Itinerary has not been calculated from GnssPdrLocationSource and these is not recommanded');
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
let startEdge;
|
|
167
|
-
if (itinerary.firstEdge.getLength() <= MM_GNSS_DIST) {
|
|
168
|
-
startEdge = itinerary.firstEdge;
|
|
169
|
-
} else {
|
|
170
|
-
startEdge = itinerary.secondEdge;
|
|
171
|
-
}
|
|
172
|
-
const startPoint = WGS84UserPosition.fromWGS84(startEdge.node1);
|
|
173
|
-
startPoint.alt = NavigationHandler.DEFAULT_ALTITUDE;
|
|
174
|
-
this.pdrLocationSource.setLocation(startPoint);
|
|
175
|
-
this.pdrLocationSource.setStepDetectionLockerOrientation(startEdge.getBearing());
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
export default GnssPdrLocationSource;
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { WGS84UserPosition } from '@wemap/geo';
|
|
2
|
-
|
|
3
|
-
import LocationSource from './LocationSource';
|
|
4
|
-
import AttitudeHandler from '../attitude/AttitudeHandler';
|
|
5
|
-
import Constants from '../Constants';
|
|
6
|
-
import SensorsLogger from '../sensors/SensorsLogger';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
class IPLocationSource extends LocationSource {
|
|
10
|
-
|
|
11
|
-
constructor(callback, imuEnabled = true) {
|
|
12
|
-
super(callback);
|
|
13
|
-
|
|
14
|
-
if (imuEnabled) {
|
|
15
|
-
this.attitudeHandler = new AttitudeHandler();
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Start the location source algorithm
|
|
21
|
-
* @override
|
|
22
|
-
*/
|
|
23
|
-
start() {
|
|
24
|
-
super.start();
|
|
25
|
-
|
|
26
|
-
if (this.attitudeHandler) {
|
|
27
|
-
this.attitudeHandler.startAbsolute(
|
|
28
|
-
attitude => {
|
|
29
|
-
this.pose.attitude = attitude;
|
|
30
|
-
this.notify();
|
|
31
|
-
})
|
|
32
|
-
// Attitude is optionnal here, do not throw an error if it not works.
|
|
33
|
-
.catch(() => { });
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
return new Promise((resolve, reject) => {
|
|
37
|
-
this.geolocate()
|
|
38
|
-
.then(location => {
|
|
39
|
-
this.pose.location = location;
|
|
40
|
-
if (this.attitudeHandler) {
|
|
41
|
-
this.attitudeHandler.setUserLocationForAbsolute(location);
|
|
42
|
-
}
|
|
43
|
-
resolve();
|
|
44
|
-
this.notify();
|
|
45
|
-
})
|
|
46
|
-
.catch(reject);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Stop the location source algorithm
|
|
52
|
-
* @override
|
|
53
|
-
*/
|
|
54
|
-
stop() {
|
|
55
|
-
super.stop();
|
|
56
|
-
|
|
57
|
-
if (this.attitudeHandler) {
|
|
58
|
-
this.attitudeHandler.stopAbsolute();
|
|
59
|
-
this.attitudeHandler = null;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
geolocate() {
|
|
64
|
-
return new Promise((resolve, reject) => {
|
|
65
|
-
fetch('https://ipinfo.io/geo?token=24a7ca2f3b489d')
|
|
66
|
-
.then((response) => {
|
|
67
|
-
if (!response) {
|
|
68
|
-
reject();
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const position = new WGS84UserPosition(
|
|
72
|
-
parseFloat(response.loc.split(',')[0]),
|
|
73
|
-
parseFloat(response.loc.split(',')[1]),
|
|
74
|
-
null,
|
|
75
|
-
performance.now() / 1e3
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
resolve(position);
|
|
79
|
-
|
|
80
|
-
if (this.logger) {
|
|
81
|
-
this.logger.feedWithCurrentTime(SensorsLogger.DataType.IP_POSITION, [position.lat, position.lng]);
|
|
82
|
-
}
|
|
83
|
-
});
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* Get provider name
|
|
89
|
-
* @override
|
|
90
|
-
*/
|
|
91
|
-
static get providerName() {
|
|
92
|
-
return Constants.LOCATION_SOURCE_PROVIDERS.IP;
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
export default IPLocationSource;
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
MapMatching, Network, Itinerary, Edge, WGS84
|
|
3
|
-
} from '@wemap/geo';
|
|
4
|
-
|
|
5
|
-
import Pose from '../Pose';
|
|
6
|
-
import Constants from '../Constants';
|
|
7
|
-
import SensorsLogger from '../sensors/SensorsLogger';
|
|
8
|
-
import ProvidersLogger from './ProvidersLogger';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* A LocationSource is an independant component which can be instantiate to provide a pose (localisation and orientation)
|
|
12
|
-
* @see PdrLocationSource
|
|
13
|
-
* @see GnssPdrLocationSource
|
|
14
|
-
* @see GnssLocationSource
|
|
15
|
-
* @see IPLocationSource
|
|
16
|
-
*/
|
|
17
|
-
class LocationSource {
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Constructor of a LocationSource
|
|
21
|
-
* This constructor must be called by any implementation of a LocationSource
|
|
22
|
-
* @param {Function} callback function called when a new location or new orientation is calculated
|
|
23
|
-
* @protected
|
|
24
|
-
*/
|
|
25
|
-
constructor(callback) {
|
|
26
|
-
if (new.target === LocationSource) {
|
|
27
|
-
throw new TypeError('Cannot instantiate LocationSource directly');
|
|
28
|
-
}
|
|
29
|
-
ProvidersLogger.addEvent(this, 'constructor');
|
|
30
|
-
this.callback = callback;
|
|
31
|
-
this.pose = new Pose();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Start the LocationSource
|
|
36
|
-
* @public
|
|
37
|
-
*/
|
|
38
|
-
start() {
|
|
39
|
-
ProvidersLogger.addEvent(this, 'start');
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Stop the LocationSource
|
|
44
|
-
* @public
|
|
45
|
-
*/
|
|
46
|
-
stop() {
|
|
47
|
-
ProvidersLogger.addEvent(this, 'stop');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Same than providerName but with options
|
|
52
|
-
* @public
|
|
53
|
-
*/
|
|
54
|
-
get providerNameWithOptions() {
|
|
55
|
-
return this.providerName;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Set a logger to record raw data
|
|
60
|
-
* @param {SensorsLogger} logger the sensors logger
|
|
61
|
-
*/
|
|
62
|
-
setLogger(logger) {
|
|
63
|
-
|
|
64
|
-
if (logger && !(logger instanceof SensorsLogger)) {
|
|
65
|
-
throw new Error('logger is not an instance of SensorsLogger');
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
this.logger = logger;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* @see providerName
|
|
73
|
-
* @public
|
|
74
|
-
*/
|
|
75
|
-
static get providerName() {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* Explicit name of Location Source
|
|
81
|
-
* This name is used in "provider" of pose.location
|
|
82
|
-
* @returns provider name
|
|
83
|
-
* @public
|
|
84
|
-
*/
|
|
85
|
-
get providerName() {
|
|
86
|
-
return this.constructor.providerName;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Get current pose
|
|
91
|
-
* @returns current pose
|
|
92
|
-
* @public
|
|
93
|
-
*/
|
|
94
|
-
getPose() {
|
|
95
|
-
return this.pose;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* This method must be called to notify callback when pose changed
|
|
100
|
-
* @protected
|
|
101
|
-
*/
|
|
102
|
-
notify() {
|
|
103
|
-
ProvidersLogger.addPushEvent(this);
|
|
104
|
-
|
|
105
|
-
if (!this.callback) {
|
|
106
|
-
return;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (!this.pose.location) {
|
|
110
|
-
return;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
this.pose.location.provider = this.providerName;
|
|
114
|
-
this.callback(this.pose);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
/**
|
|
118
|
-
* Get most accurate LocationSource from two LocationSource
|
|
119
|
-
* @param {LocationSource} ls1 LocationSource 1
|
|
120
|
-
* @param {LocationSource} ls2 LocationSource 2
|
|
121
|
-
* @returns The most accuracte LocationSource
|
|
122
|
-
* @public
|
|
123
|
-
*/
|
|
124
|
-
static getMostAccurateLocationSource(ls1, ls2) {
|
|
125
|
-
|
|
126
|
-
if (!(ls1 instanceof LocationSource)) {
|
|
127
|
-
throw new TypeError(ls1 + ' is not an instance of LocationSource');
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (!(ls2 instanceof LocationSource)) {
|
|
131
|
-
throw new TypeError(ls2 + ' is not an instance of LocationSource');
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const accuracyOrder = [];
|
|
135
|
-
accuracyOrder[Constants.LOCATION_SOURCE_PROVIDERS.IP] = 0;
|
|
136
|
-
accuracyOrder[Constants.LOCATION_SOURCE_PROVIDERS.GNSS] = 1;
|
|
137
|
-
accuracyOrder[Constants.LOCATION_SOURCE_PROVIDERS.GNSS_PDR] = 2;
|
|
138
|
-
accuracyOrder[Constants.LOCATION_SOURCE_PROVIDERS.PDR] = 3;
|
|
139
|
-
accuracyOrder[Constants.LOCATION_SOURCE_PROVIDERS.FIXED_LOCATION] = 4;
|
|
140
|
-
|
|
141
|
-
return accuracyOrder[ls1.providerName] > accuracyOrder[ls2.providerName] ? ls1 : ls2;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* MapMatching
|
|
147
|
-
*/
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Enable LocationSource mapmatching
|
|
151
|
-
* @param {*} network a network which will be used for map matching
|
|
152
|
-
* @param {*} maxDistance max distance between location and network to match. null disables maxDistance (default: null)
|
|
153
|
-
* @param {*} maxAngleBearing threshold to match a parallel segment for angle between location bearing and segment. null disables this threshold (default: null)
|
|
154
|
-
* @public
|
|
155
|
-
*/
|
|
156
|
-
enableMapMatching(network = null, maxDistance = null, maxAngleBearing = null) {
|
|
157
|
-
this.mapMatching = new MapMatching();
|
|
158
|
-
this.mapMatching.maxDistance = maxDistance;
|
|
159
|
-
this.mapMatching.maxAngleBearing = maxAngleBearing;
|
|
160
|
-
|
|
161
|
-
if (network) {
|
|
162
|
-
this.setNetwork(network);
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* Update the LocationSource network for mapmatching
|
|
168
|
-
* @param {Network} network a network instance
|
|
169
|
-
* @public
|
|
170
|
-
*/
|
|
171
|
-
setNetwork(network) {
|
|
172
|
-
if (!(network instanceof Network)) {
|
|
173
|
-
throw new TypeError(network + ' is not an instance of Network');
|
|
174
|
-
}
|
|
175
|
-
if (!this.mapMatching) {
|
|
176
|
-
throw new Error('MapMatching is not enabled');
|
|
177
|
-
}
|
|
178
|
-
this.mapMatching.setNetwork(network);
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
/**
|
|
182
|
-
* Is mapmatching activated?
|
|
183
|
-
* @returns is mapmatching activated
|
|
184
|
-
* @public
|
|
185
|
-
*/
|
|
186
|
-
get hasMapMatching() {
|
|
187
|
-
return this.mapMatching !== null;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Returns projection of a location on network
|
|
192
|
-
* @param {WGS84} location if location is null, projection of this.pose.location is used
|
|
193
|
-
* @returns The projected location {WGS84} or null.
|
|
194
|
-
* @public
|
|
195
|
-
*/
|
|
196
|
-
getProjectionOnNetwork(location = null) {
|
|
197
|
-
|
|
198
|
-
if (!this.mapMatching) {
|
|
199
|
-
return null;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
let locationToProject = location;
|
|
203
|
-
if (!location) {
|
|
204
|
-
locationToProject = this.pose.location;
|
|
205
|
-
}
|
|
206
|
-
if (!locationToProject) {
|
|
207
|
-
return null;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
return this.mapMatching.getProjection(locationToProject, false, false);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
/**
|
|
215
|
-
* Itinerary
|
|
216
|
-
*/
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Update itinerary of Location Source.
|
|
220
|
-
* Itinerary is different from network, it is not used for mapmatching. It can be used for others tricks like HeadingUnlocker
|
|
221
|
-
* @param {Itinerary} itinerary a given itinerary
|
|
222
|
-
* @public
|
|
223
|
-
*/
|
|
224
|
-
setItinerary(itinerary) {
|
|
225
|
-
if (!(itinerary instanceof Itinerary)) {
|
|
226
|
-
throw new TypeError(itinerary + ' is not an instance of Itinerary');
|
|
227
|
-
}
|
|
228
|
-
this.itinerary = itinerary;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
/**
|
|
233
|
-
* Returns projection and itinerary info of a location on network
|
|
234
|
-
* @param {WGS84} location if location is null, projection of this.pose.location is used
|
|
235
|
-
* @returns An object of the projected location and itinerary info or null.
|
|
236
|
-
* @public
|
|
237
|
-
*/
|
|
238
|
-
getItineraryInfo(location = null) {
|
|
239
|
-
|
|
240
|
-
if (!this.itinerary) {
|
|
241
|
-
throw new Error('No itinerary found');
|
|
242
|
-
}
|
|
243
|
-
const projection = this.getProjectionOnNetwork(location);
|
|
244
|
-
if (!projection) {
|
|
245
|
-
return null;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
const totalDistance = this.itinerary.distance;
|
|
249
|
-
let traveledDistance = 0;
|
|
250
|
-
const edges = this.itinerary.edges;
|
|
251
|
-
|
|
252
|
-
if (projection.nearestElement instanceof WGS84) {
|
|
253
|
-
|
|
254
|
-
for (let i = 0; i < edges.length; i++) {
|
|
255
|
-
const edge = edges[i];
|
|
256
|
-
if (edge.node1.equalsTo(projection.nearestElement)) {
|
|
257
|
-
break;
|
|
258
|
-
}
|
|
259
|
-
traveledDistance += edge.getLength();
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
} else if (projection.nearestElement instanceof Edge) {
|
|
264
|
-
|
|
265
|
-
for (let i = 0; i < edges.length; i++) {
|
|
266
|
-
const edge = edges[i];
|
|
267
|
-
if (edge.equalsTo(projection.nearestElement)) {
|
|
268
|
-
traveledDistance += edge.node1.distanceTo(projection.projection);
|
|
269
|
-
break;
|
|
270
|
-
}
|
|
271
|
-
traveledDistance += edge.getLength();
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
} else {
|
|
275
|
-
throw new Error('No projection found');
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
return {
|
|
279
|
-
projection: projection,
|
|
280
|
-
traveledDistance,
|
|
281
|
-
traveledPercentage: traveledDistance / totalDistance,
|
|
282
|
-
remainingDistance: totalDistance - traveledDistance,
|
|
283
|
-
remainingPercentage: 1 - traveledDistance / totalDistance
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
export default LocationSource;
|