@wemap/positioning 2.4.3 → 2.4.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 +4 -4
- package/src/PositioningHandler.js +0 -16
- package/src/components/AbsoluteAttitudeComponent.jsx +2 -1
- package/src/components/ArCoreAbsoluteComponent.jsx +4 -3
- package/src/components/GnssWifiPdrComponent.jsx +3 -2
- package/src/components/NavigationConfig.js +94 -0
- package/src/components/PdrComponent.jsx +5 -4
- package/src/components/PositioningPoseComponent.jsx +7 -6
- package/src/components/Utils.js +1 -18
- package/src/providers/Provider.js +9 -0
- package/src/providers/attitude/AbsoluteAttitudeProvider.js +8 -0
- package/src/providers/attitude/RelativeAttitudeProvider.js +7 -0
- package/src/providers/others/ImuProvider.js +6 -0
- package/src/providers/others/InclinationProvider.js +7 -0
- package/src/providers/others/MapMatchingProvider.js +1 -21
- package/src/providers/pose/ArCoreAbsoluteProvider.js +46 -4
- package/src/providers/pose/ArCoreProvider.js +7 -0
- package/src/providers/pose/GnssWifiPdrProvider.js +9 -4
- package/src/providers/pose/PoseProvider.js +7 -0
- package/src/providers/pose/pdr/PdrProvider.js +26 -5
- package/src/providers/pose/pdr/helpers/Smoother.js +28 -28
- package/src/providers/position/GnssWifiProvider.js +7 -0
- package/src/providers/position/IpProvider.js +7 -0
package/package.json
CHANGED
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
"Guillaume Pannetier <guillaume.pannetier@getwemap.com>"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@wemap/geo": "^0.3.
|
|
12
|
-
"@wemap/logger": "^0.1.
|
|
11
|
+
"@wemap/geo": "^0.3.6",
|
|
12
|
+
"@wemap/logger": "^0.1.6",
|
|
13
13
|
"@wemap/maths": "^0.2.1",
|
|
14
|
-
"@wemap/osm": "^0.2.
|
|
14
|
+
"@wemap/osm": "^0.2.8",
|
|
15
15
|
"@wemap/utils": "^0.1.2",
|
|
16
16
|
"geomagnetism": "^0.1.0",
|
|
17
17
|
"lodash.isempty": "^4.4.0",
|
|
@@ -80,5 +80,5 @@
|
|
|
80
80
|
"lint": "eslint --ext .js,.jsx --quiet src",
|
|
81
81
|
"test": "mocha -r esm \"src/**/*.spec.js\""
|
|
82
82
|
},
|
|
83
|
-
"version": "2.4.
|
|
83
|
+
"version": "2.4.5"
|
|
84
84
|
}
|
|
@@ -184,22 +184,6 @@ class PositioningHandler {
|
|
|
184
184
|
provider.setNetwork(network);
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* @public
|
|
190
|
-
*/
|
|
191
|
-
getItineraryInfo(id) {
|
|
192
|
-
const provider = this.providerInstances[id];
|
|
193
|
-
if (!provider) {
|
|
194
|
-
throw new Error('Unknown provider');
|
|
195
|
-
}
|
|
196
|
-
if (!provider.getItineraryInfo) {
|
|
197
|
-
Logger.warn('Cannot getItineraryInfo from ' + provider.constructor.name);
|
|
198
|
-
return null;
|
|
199
|
-
}
|
|
200
|
-
return provider.getItineraryInfo();
|
|
201
|
-
}
|
|
202
|
-
|
|
203
187
|
}
|
|
204
188
|
|
|
205
189
|
export default PositioningHandler;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
|
|
3
3
|
import AbsoluteAttitudeProvider from '../providers/attitude/AbsoluteAttitudeProvider';
|
|
4
|
+
import NavigationConfig from './NavigationConfig';
|
|
4
5
|
import Utils from './Utils';
|
|
5
6
|
import EventType from '../events/EventType';
|
|
6
7
|
|
|
@@ -17,7 +18,7 @@ class AbsoluteAttitudeComponent extends React.Component {
|
|
|
17
18
|
};
|
|
18
19
|
|
|
19
20
|
this.absoluteAttitudeProvider = new AbsoluteAttitudeProvider(this.onEvent, this.onError);
|
|
20
|
-
this.absoluteAttitudeProvider.setPosition(
|
|
21
|
+
this.absoluteAttitudeProvider.setPosition(NavigationConfig.INITIAL_POSITION);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
componentDidMount() {
|
|
@@ -4,6 +4,7 @@ import isEmpty from 'lodash.isempty';
|
|
|
4
4
|
import { deg2rad } from '@wemap/maths';
|
|
5
5
|
|
|
6
6
|
import EventType from '../events/EventType';
|
|
7
|
+
import NavigationConfig from './NavigationConfig';
|
|
7
8
|
import Utils from './Utils';
|
|
8
9
|
import ArCoreAbsoluteProvider from '../providers/pose/ArCoreAbsoluteProvider';
|
|
9
10
|
import MapComponent from './MapComponent';
|
|
@@ -21,8 +22,8 @@ class ArCoreAbsoluteComponent extends React.Component {
|
|
|
21
22
|
this.onEvent,
|
|
22
23
|
this.onError
|
|
23
24
|
);
|
|
24
|
-
this.arCoreAbsoluteProvider.setPosition(
|
|
25
|
-
this.arCoreAbsoluteProvider.setHeading(deg2rad(
|
|
25
|
+
this.arCoreAbsoluteProvider.setPosition(NavigationConfig.INITIAL_POSITION);
|
|
26
|
+
this.arCoreAbsoluteProvider.setHeading(deg2rad(NavigationConfig.INITIAL_HEADING));
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
componentDidMount() {
|
|
@@ -72,7 +73,7 @@ class ArCoreAbsoluteComponent extends React.Component {
|
|
|
72
73
|
<MapComponent
|
|
73
74
|
ref={map => (this.map = map)}
|
|
74
75
|
defaultZoom={21}
|
|
75
|
-
network={
|
|
76
|
+
network={NavigationConfig.ITINERARY}
|
|
76
77
|
/>
|
|
77
78
|
</div>
|
|
78
79
|
);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import isEmpty from 'lodash.isempty';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
+
import NavigationConfig from './NavigationConfig';
|
|
4
5
|
import Utils from './Utils';
|
|
5
6
|
import EventType from '../events/EventType';
|
|
6
7
|
import GnssWifiPdrProvider from '../providers/pose/GnssWifiPdrProvider';
|
|
@@ -18,7 +19,7 @@ class GnssWifiPdrComponent extends React.Component {
|
|
|
18
19
|
}
|
|
19
20
|
|
|
20
21
|
componentDidMount() {
|
|
21
|
-
this.gnssWifiPdrProvider.enableMapMatching(
|
|
22
|
+
this.gnssWifiPdrProvider.enableMapMatching(NavigationConfig.ITINERARY);
|
|
22
23
|
this.gnssWifiPdrProvider.start();
|
|
23
24
|
}
|
|
24
25
|
|
|
@@ -63,7 +64,7 @@ class GnssWifiPdrComponent extends React.Component {
|
|
|
63
64
|
{attitudeRender}
|
|
64
65
|
<h3>Map</h3>
|
|
65
66
|
<MapComponent ref={map => (this.map = map)}
|
|
66
|
-
network={
|
|
67
|
+
network={NavigationConfig.ITINERARY} />
|
|
67
68
|
</div>
|
|
68
69
|
);
|
|
69
70
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
Itinerary, WGS84UserPosition, Level
|
|
5
|
+
} from '@wemap/geo';
|
|
6
|
+
import { deg2rad } from '@wemap/maths';
|
|
7
|
+
|
|
8
|
+
const datasets = {};
|
|
9
|
+
|
|
10
|
+
// Wemap Office
|
|
11
|
+
const wemapOffice = {
|
|
12
|
+
initialPosition: new WGS84UserPosition(43.6091955, 3.8841255),
|
|
13
|
+
initialHeading: deg2rad(191.9)
|
|
14
|
+
};
|
|
15
|
+
wemapOffice.itinerary = Itinerary.fromOrderedPointsArray(
|
|
16
|
+
[
|
|
17
|
+
[wemapOffice.initialPosition.lat, wemapOffice.initialPosition.lng],
|
|
18
|
+
[43.6091883, 3.8841242],
|
|
19
|
+
[43.6091709, 3.8842382],
|
|
20
|
+
[43.6091288, 3.884226],
|
|
21
|
+
[43.6091461, 3.884112]
|
|
22
|
+
],
|
|
23
|
+
[wemapOffice.initialPosition.lat, wemapOffice.initialPosition.lng],
|
|
24
|
+
[43.6091461, 3.884112],
|
|
25
|
+
false
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
// Wemap Office Multi-level
|
|
29
|
+
const wemapOfficeMulti = {
|
|
30
|
+
initialPosition: new WGS84UserPosition(43.6091965, 3.8841285, null, new Level(2)),
|
|
31
|
+
initialHeading: deg2rad(191.9)
|
|
32
|
+
};
|
|
33
|
+
wemapOfficeMulti.itinerary = Itinerary.fromOrderedPointsArray(
|
|
34
|
+
[
|
|
35
|
+
[43.6091888, 3.8841263, new Level(2)],
|
|
36
|
+
[43.6091749, 3.8842173, new Level(2)],
|
|
37
|
+
[43.6092935, 3.8842518, new Level(2)],
|
|
38
|
+
[43.6093022, 3.8842702, new Level(2)],
|
|
39
|
+
[43.6093123, 3.8842731, new Level(2)],
|
|
40
|
+
[43.6093234, 3.8842009, new Level(2)],
|
|
41
|
+
[43.6093629, 3.8842127, new Level(1, 2)],
|
|
42
|
+
[43.6093597, 3.8842336, new Level(1, 2)],
|
|
43
|
+
[43.6093202, 3.8842218, new Level(1)],
|
|
44
|
+
[43.6093123, 3.8842731, new Level(1)],
|
|
45
|
+
[43.6092681, 3.8842604, new Level(1)]
|
|
46
|
+
],
|
|
47
|
+
[wemapOfficeMulti.initialPosition.lat, wemapOffice.initialPosition.lng, wemapOfficeMulti.initialPosition.level],
|
|
48
|
+
[43.6092602, 3.8842669, new Level(1)],
|
|
49
|
+
false
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
// Gare de Lyon RER A
|
|
53
|
+
const gareDeLyonRerA = {
|
|
54
|
+
initialPosition: new WGS84UserPosition(48.8442365, 2.3728267, null, new Level(-2)),
|
|
55
|
+
initialHeading: deg2rad(41.6)
|
|
56
|
+
};
|
|
57
|
+
gareDeLyonRerA.itinerary = Itinerary.fromOrderedPointsArray(
|
|
58
|
+
[
|
|
59
|
+
[48.8442368, 2.3728274, new Level(-2)],
|
|
60
|
+
[48.8442378, 2.3728257, new Level(-2)],
|
|
61
|
+
[48.8443732, 2.3726023, new Level(-1)],
|
|
62
|
+
[48.8443864, 2.3726195, new Level(-1)],
|
|
63
|
+
[48.8444032, 2.3726407, new Level(-1)]
|
|
64
|
+
],
|
|
65
|
+
[gareDeLyonRerA.initialPosition.lat, gareDeLyonRerA.initialPosition.lng, gareDeLyonRerA.initialPosition.level],
|
|
66
|
+
[48.8444315, 2.3726809, new Level(-1)],
|
|
67
|
+
false
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
datasets['wemap-office'] = wemapOffice;
|
|
72
|
+
datasets['wemap-office-multi'] = wemapOfficeMulti;
|
|
73
|
+
datasets['gare-de-lyon-rer-a'] = gareDeLyonRerA;
|
|
74
|
+
|
|
75
|
+
class NavigationConfig {
|
|
76
|
+
|
|
77
|
+
static INITIAL_POSITION = wemapOffice.initialPosition;
|
|
78
|
+
static INITIAL_HEADING = wemapOffice.initialHeading;
|
|
79
|
+
static ITINERARY = wemapOffice.itinerary;
|
|
80
|
+
|
|
81
|
+
static load(datasetName) {
|
|
82
|
+
|
|
83
|
+
const dataset = datasets[datasetName];
|
|
84
|
+
if (!dataset) {
|
|
85
|
+
throw new Error('Unknown ' + datasetName);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
this.INITIAL_POSITION = dataset.initialPosition;
|
|
89
|
+
this.INITIAL_HEADING = dataset.initialHeading;
|
|
90
|
+
this.ITINERARY = dataset.itinerary;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export default NavigationConfig;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import isEmpty from 'lodash.isempty';
|
|
2
2
|
import React from 'react';
|
|
3
3
|
|
|
4
|
+
import NavigationConfig from './NavigationConfig';
|
|
4
5
|
import Utils from './Utils';
|
|
5
6
|
import PdrProvider from '../providers/pose/pdr/PdrProvider';
|
|
6
7
|
import EventType from '../events/EventType';
|
|
@@ -12,12 +13,12 @@ class PdrComponent extends React.Component {
|
|
|
12
13
|
this.state = { position: null };
|
|
13
14
|
|
|
14
15
|
this.pdrProvider = new PdrProvider(this.onEvent, this.onError);
|
|
15
|
-
this.pdrProvider.enableMapMatching(
|
|
16
|
+
this.pdrProvider.enableMapMatching(NavigationConfig.ITINERARY);
|
|
16
17
|
}
|
|
17
18
|
|
|
18
19
|
componentDidMount() {
|
|
19
|
-
this.pdrProvider.setPosition(
|
|
20
|
-
this.pdrProvider.setHeading(
|
|
20
|
+
this.pdrProvider.setPosition(NavigationConfig.INITIAL_POSITION);
|
|
21
|
+
this.pdrProvider.setHeading(NavigationConfig.INITIAL_HEADING);
|
|
21
22
|
this.pdrProvider.start();
|
|
22
23
|
}
|
|
23
24
|
|
|
@@ -62,7 +63,7 @@ class PdrComponent extends React.Component {
|
|
|
62
63
|
{attitudeRender}
|
|
63
64
|
<h3>Map</h3>
|
|
64
65
|
<MapComponent ref={map => (this.map = map)}
|
|
65
|
-
network={
|
|
66
|
+
network={NavigationConfig.ITINERARY} />
|
|
66
67
|
</div>
|
|
67
68
|
);
|
|
68
69
|
}
|
|
@@ -3,6 +3,7 @@ import isEmpty from 'lodash.isempty';
|
|
|
3
3
|
import PropTypes from 'prop-types';
|
|
4
4
|
|
|
5
5
|
import EventType from '../events/EventType';
|
|
6
|
+
import NavigationConfig from './NavigationConfig';
|
|
6
7
|
import Utils from './Utils';
|
|
7
8
|
import PositioningHandler from '../PositioningHandler';
|
|
8
9
|
import StartStopComponent from './StartStopComponent';
|
|
@@ -38,10 +39,10 @@ class PositioningPoseComponent extends React.Component {
|
|
|
38
39
|
|
|
39
40
|
this.id = output.id;
|
|
40
41
|
|
|
41
|
-
this.props.positioningHandler.setItinerary(this.id,
|
|
42
|
-
this.props.positioningHandler.setNetwork(this.id,
|
|
43
|
-
this.props.positioningHandler.setPosition(this.id,
|
|
44
|
-
this.props.positioningHandler.setHeading(this.id,
|
|
42
|
+
this.props.positioningHandler.setItinerary(this.id, NavigationConfig.ITINERARY);
|
|
43
|
+
this.props.positioningHandler.setNetwork(this.id, NavigationConfig.ITINERARY);
|
|
44
|
+
this.props.positioningHandler.setPosition(this.id, NavigationConfig.INITIAL_POSITION);
|
|
45
|
+
this.props.positioningHandler.setHeading(this.id, NavigationConfig.INITIAL_HEADING);
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
stop() {
|
|
@@ -85,7 +86,7 @@ class PositioningPoseComponent extends React.Component {
|
|
|
85
86
|
|
|
86
87
|
const itineraryRender = Utils.renderItineraryInfo(
|
|
87
88
|
this.state.position && !(this.state.position instanceof Error)
|
|
88
|
-
?
|
|
89
|
+
? NavigationConfig.ITINERARY.getInfo(this.state.position)
|
|
89
90
|
: null
|
|
90
91
|
);
|
|
91
92
|
|
|
@@ -103,7 +104,7 @@ class PositioningPoseComponent extends React.Component {
|
|
|
103
104
|
{attitudeRender}
|
|
104
105
|
<h3>Map</h3>
|
|
105
106
|
<MapComponent ref={map => (this.map = map)}
|
|
106
|
-
network={
|
|
107
|
+
network={NavigationConfig.ITINERARY} />
|
|
107
108
|
<h3>ItineraryInfo</h3>
|
|
108
109
|
{itineraryRender}
|
|
109
110
|
</div>
|
package/src/components/Utils.js
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import React from 'react'; // eslint-disable-line no-unused-vars
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
Itinerary, WGS84UserPosition
|
|
5
|
-
} from '@wemap/geo';
|
|
6
3
|
import { rad2deg } from '@wemap/maths';
|
|
7
4
|
import { OsrmUtils } from '@wemap/osm';
|
|
8
5
|
|
|
@@ -10,21 +7,6 @@ const NOT_AVAILABLE_STR = 'Not available';
|
|
|
10
7
|
|
|
11
8
|
class Utils {
|
|
12
9
|
|
|
13
|
-
static INITIAL_POSITION = new WGS84UserPosition(43.6091955, 3.8841255);
|
|
14
|
-
static INITIAL_HEADING = 191.9;
|
|
15
|
-
static ITINERARY = Itinerary.fromOrderedPointsArray(
|
|
16
|
-
[
|
|
17
|
-
[Utils.INITIAL_POSITION.lat, Utils.INITIAL_POSITION.lng],
|
|
18
|
-
[43.6091883, 3.8841242],
|
|
19
|
-
[43.6091709, 3.8842382],
|
|
20
|
-
[43.6091288, 3.884226],
|
|
21
|
-
[43.6091461, 3.884112]
|
|
22
|
-
],
|
|
23
|
-
[Utils.INITIAL_POSITION.lat, Utils.INITIAL_POSITION.lng],
|
|
24
|
-
[43.6091461, 3.884112],
|
|
25
|
-
false
|
|
26
|
-
);
|
|
27
|
-
|
|
28
10
|
static renderAttitude(attitude) {
|
|
29
11
|
|
|
30
12
|
if (!attitude) {
|
|
@@ -66,6 +48,7 @@ class Utils {
|
|
|
66
48
|
Latitude: {position.lat.toFixed(7)}<br />
|
|
67
49
|
Longitude: {position.lng.toFixed(7)}<br />
|
|
68
50
|
Altitude: {position.alt ? position.alt.toFixed(2) : NOT_AVAILABLE_STR}<br />
|
|
51
|
+
Level: {position.level ? position.level.toString() : NOT_AVAILABLE_STR}<br />
|
|
69
52
|
Bearing: {position.bearing ? position.bearing.toFixed(2) : NOT_AVAILABLE_STR}<br />
|
|
70
53
|
Accuracy: {position.accuracy ? position.accuracy.toFixed(2) : NOT_AVAILABLE_STR}<br />
|
|
71
54
|
Time: {position.time ? position.time.toFixed(2) : NOT_AVAILABLE_STR}<br />
|
|
@@ -53,6 +53,15 @@ class Provider {
|
|
|
53
53
|
ProvidersLogger.addEvent(this, 'constructor');
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Get the provider display name
|
|
58
|
+
* @public
|
|
59
|
+
* @abstract
|
|
60
|
+
*/
|
|
61
|
+
static get name() {
|
|
62
|
+
return this.DEFAULT_NAME;
|
|
63
|
+
}
|
|
64
|
+
|
|
56
65
|
/**
|
|
57
66
|
* Get the provider name
|
|
58
67
|
* @public
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import Provider from '../Provider';
|
|
2
2
|
import {
|
|
3
|
-
Itinerary, MapMatching, Network
|
|
3
|
+
Itinerary, MapMatching, Network
|
|
4
4
|
} from '@wemap/geo';
|
|
5
5
|
|
|
6
6
|
class MapMatchingProvider extends Provider {
|
|
@@ -63,26 +63,6 @@ class MapMatchingProvider extends Provider {
|
|
|
63
63
|
}
|
|
64
64
|
this.itinerary = itinerary;
|
|
65
65
|
}
|
|
66
|
-
|
|
67
|
-
/**
|
|
68
|
-
* Returns projection and itinerary info of a position on network
|
|
69
|
-
* @param {WGS84} position if position is null/undefined, projection of this.position is used
|
|
70
|
-
* @returns An object of the projected position and itinerary info or null.
|
|
71
|
-
* @public
|
|
72
|
-
*/
|
|
73
|
-
getItineraryInfo(position) {
|
|
74
|
-
|
|
75
|
-
if (!this.itinerary) {
|
|
76
|
-
throw new Error('No itinerary found');
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const _position = position || this.position;
|
|
80
|
-
if (!_position) {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return this.itinerary.getInfo(position || this.position);
|
|
85
|
-
}
|
|
86
66
|
}
|
|
87
67
|
|
|
88
68
|
export default MapMatchingProvider;
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
/* eslint-disable max-statements */
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
Attitude, WGS84UserPosition
|
|
4
|
+
} from '@wemap/geo';
|
|
3
5
|
|
|
4
|
-
import Provider from '../Provider';
|
|
5
6
|
import EventType from '../../events/EventType';
|
|
6
7
|
import ArCoreProvider from './ArCoreProvider';
|
|
7
8
|
import {
|
|
8
9
|
Quaternion, Vector3
|
|
9
10
|
} from '@wemap/maths';
|
|
10
11
|
import ImuProvider from '../others/ImuProvider';
|
|
12
|
+
import MapMatchingProvider from '../others/MapMatchingProvider';
|
|
13
|
+
import PdrProvider from './pdr/PdrProvider';
|
|
11
14
|
|
|
12
15
|
/**
|
|
13
16
|
* Pose provider is the provider used by the PositioningHandler. It uses the best fusion
|
|
14
17
|
* of what he can and provides an AbsoluteAttitude and an AbsolutePosition as an output.
|
|
15
18
|
*/
|
|
16
|
-
class ArCoreAbsoluteProvider extends
|
|
19
|
+
class ArCoreAbsoluteProvider extends MapMatchingProvider {
|
|
17
20
|
|
|
18
21
|
/**
|
|
19
22
|
* @override
|
|
@@ -31,6 +34,17 @@ class ArCoreAbsoluteProvider extends Provider {
|
|
|
31
34
|
onError,
|
|
32
35
|
Object.assign({}, options || {}, { require: [EventType.AngularRate] })
|
|
33
36
|
);
|
|
37
|
+
|
|
38
|
+
if (this.options.useMapMatching) {
|
|
39
|
+
this.enableMapMatching();
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* @override
|
|
45
|
+
*/
|
|
46
|
+
static get name() {
|
|
47
|
+
return 'ArCoreAbsolute';
|
|
34
48
|
}
|
|
35
49
|
|
|
36
50
|
/**
|
|
@@ -123,6 +137,12 @@ class ArCoreAbsoluteProvider extends Provider {
|
|
|
123
137
|
const dist = Math.sqrt(diffPos[0] ** 2 + diffPos[2] ** 2);
|
|
124
138
|
const bearing = Math.atan2(diffPos[0], -diffPos[2]) - this.offsetAngle;
|
|
125
139
|
this.position = this.position.destinationPoint(dist, bearing, diffPos[1]);
|
|
140
|
+
|
|
141
|
+
if (this.absoluteAttitude) {
|
|
142
|
+
this.position.bearing = this.absoluteAttitude.headingDegrees;
|
|
143
|
+
this.updateLevel(this.position);
|
|
144
|
+
}
|
|
145
|
+
|
|
126
146
|
this.notify(this.createEvent(EventType.AbsolutePosition, this.position, event.timestamp));
|
|
127
147
|
}
|
|
128
148
|
|
|
@@ -151,7 +171,7 @@ class ArCoreAbsoluteProvider extends Provider {
|
|
|
151
171
|
}
|
|
152
172
|
|
|
153
173
|
setPosition(position) {
|
|
154
|
-
this.position =
|
|
174
|
+
this.position = WGS84UserPosition.fromWGS84(position);
|
|
155
175
|
this.position.provider = this.constructor.name;
|
|
156
176
|
this.notify(this.createEvent(EventType.AbsolutePosition, this.position));
|
|
157
177
|
}
|
|
@@ -162,6 +182,28 @@ class ArCoreAbsoluteProvider extends Provider {
|
|
|
162
182
|
static get useCameraNatively() {
|
|
163
183
|
return true;
|
|
164
184
|
}
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* MapMatching
|
|
189
|
+
*/
|
|
190
|
+
|
|
191
|
+
enableMapMatching(network, maxDistance, maxAngleBearing) {
|
|
192
|
+
super.enableMapMatching(
|
|
193
|
+
network,
|
|
194
|
+
maxDistance || PdrProvider.MM_PDR_DIST,
|
|
195
|
+
maxAngleBearing || PdrProvider.MM_PDR_ANGLE
|
|
196
|
+
);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
updateLevel(position) {
|
|
200
|
+
if (this.mapMatching) {
|
|
201
|
+
const projection = this.mapMatching.getProjection(position, true);
|
|
202
|
+
if (projection) {
|
|
203
|
+
position.level = projection.projection.level;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
165
207
|
}
|
|
166
208
|
|
|
167
209
|
export default ArCoreAbsoluteProvider;
|
|
@@ -40,6 +40,12 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
+
/**
|
|
44
|
+
* @override
|
|
45
|
+
*/
|
|
46
|
+
static get name() {
|
|
47
|
+
return 'GnssWifi';
|
|
48
|
+
}
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* @override
|
|
@@ -126,8 +132,8 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
126
132
|
if (projection && projection.projection) {
|
|
127
133
|
|
|
128
134
|
// Create a new position from projection and new GNSS position.
|
|
129
|
-
|
|
130
|
-
this.
|
|
135
|
+
this.gnssPosition.lat = projection.projection.lat;
|
|
136
|
+
this.gnssPosition.lng = projection.projection.lng;
|
|
131
137
|
|
|
132
138
|
// // If nearest element is an edge, use its orientation to set heading
|
|
133
139
|
// if (projection.nearestElement instanceof Edge) {
|
|
@@ -141,9 +147,8 @@ class GnssWifiPdrProvider extends MapMatchingProvider {
|
|
|
141
147
|
this.pdrProvider.setHeading(this.lastAttitude.heading);
|
|
142
148
|
}
|
|
143
149
|
|
|
144
|
-
} else {
|
|
145
|
-
this.pdrProvider.setPosition(this.gnssPosition);
|
|
146
150
|
}
|
|
151
|
+
this.pdrProvider.setPosition(this.gnssPosition);
|
|
147
152
|
}
|
|
148
153
|
}
|
|
149
154
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-statements */
|
|
1
2
|
import noop from 'lodash.noop';
|
|
2
3
|
|
|
3
4
|
import {
|
|
@@ -36,6 +37,9 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
36
37
|
// this.position is smoothed position.
|
|
37
38
|
pdrPosition = null;
|
|
38
39
|
|
|
40
|
+
static MM_PDR_ANGLE = MM_PDR_ANGLE;
|
|
41
|
+
static MM_PDR_DIST = MM_PDR_DIST;
|
|
42
|
+
|
|
39
43
|
/**
|
|
40
44
|
* @override
|
|
41
45
|
*/
|
|
@@ -67,6 +71,12 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
73
|
|
|
74
|
+
/**
|
|
75
|
+
* @override
|
|
76
|
+
*/
|
|
77
|
+
static get name() {
|
|
78
|
+
return 'PDR';
|
|
79
|
+
}
|
|
70
80
|
|
|
71
81
|
/**
|
|
72
82
|
* @override
|
|
@@ -255,25 +265,36 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
255
265
|
return newPositionWithoutMM;
|
|
256
266
|
}
|
|
257
267
|
|
|
268
|
+
/**
|
|
269
|
+
* Try map-matching
|
|
270
|
+
*/
|
|
258
271
|
const projection = this.mapMatching.getProjection(newPositionWithoutMM, true, true);
|
|
259
|
-
|
|
260
272
|
if (!projection || !projection.projection) {
|
|
261
273
|
return newPositionWithoutMM;
|
|
262
274
|
}
|
|
263
275
|
|
|
276
|
+
const projectedPosition = newPositionWithoutMM;
|
|
277
|
+
projectedPosition.level = projection.projection.level;
|
|
278
|
+
|
|
264
279
|
if (projection.distanceFromNearestElement < stepSize) {
|
|
265
|
-
|
|
280
|
+
projectedPosition.lat = projection.projection.lat;
|
|
281
|
+
projectedPosition.lng = projection.projection.lng;
|
|
282
|
+
return projectedPosition;
|
|
266
283
|
}
|
|
267
284
|
|
|
268
285
|
/**
|
|
269
|
-
*
|
|
286
|
+
* Adapt map-matching to not stick corridor directly
|
|
287
|
+
* /!\ This smoothed position is different from the one of Smoother
|
|
270
288
|
*/
|
|
289
|
+
const smoothedPosition = projectedPosition;
|
|
290
|
+
smoothedPosition.lat = previousPosition.lat;
|
|
291
|
+
smoothedPosition.lng = previousPosition.lng;
|
|
292
|
+
|
|
271
293
|
const smoothedDistance = projection.distanceFromNearestElement * MM_CONV_SPEED;
|
|
272
294
|
const smoothedBearing = previousPosition.bearingTo(projection.projection);
|
|
273
|
-
const smoothedPosition = previousPosition.clone();
|
|
274
295
|
smoothedPosition.move(smoothedDistance, smoothedBearing);
|
|
275
296
|
|
|
276
|
-
return
|
|
297
|
+
return smoothedPosition;
|
|
277
298
|
}
|
|
278
299
|
|
|
279
300
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
/* eslint max-statements
|
|
1
|
+
/* eslint-disable max-statements */
|
|
2
2
|
import { WGS84UserPosition } from '@wemap/geo';
|
|
3
|
+
import { rad2deg } from '@wemap/maths';
|
|
3
4
|
|
|
4
5
|
// Generated positions by second
|
|
5
6
|
const GEN_FREQUENCY = 60;
|
|
@@ -17,50 +18,49 @@ class Smoother {
|
|
|
17
18
|
/**
|
|
18
19
|
* Calculate smoothed positions for the next milliseconds given a new position
|
|
19
20
|
*/
|
|
20
|
-
generateNextPositions(
|
|
21
|
+
generateNextPositions(newPosition, flyby = false) {
|
|
21
22
|
|
|
22
|
-
if (!(
|
|
23
|
+
if (!(newPosition instanceof WGS84UserPosition)) {
|
|
23
24
|
throw new TypeError('newPosition is not instance of WGS84UserPosition');
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
const newPosition = _newPosition.clone();
|
|
27
27
|
if (!newPosition.hasOwnProperty('time')) {
|
|
28
28
|
throw new Error('newPosition does not have time property');
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
if (
|
|
32
|
-
this.previousPosition = newPosition;
|
|
33
|
-
this.positionsQueue.push(this.previousPosition);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
31
|
+
if (this.previousPosition) {
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
33
|
+
const distance = this.previousPosition.distanceTo(newPosition);
|
|
34
|
+
const azimuth = this.previousPosition.bearingTo(newPosition);
|
|
39
35
|
|
|
40
|
-
|
|
36
|
+
let refTimestamp = newPosition.time;
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
38
|
+
const queueLength = this.positionsQueue.length;
|
|
39
|
+
if (queueLength) {
|
|
40
|
+
refTimestamp = Math.max(refTimestamp, this.positionsQueue[queueLength - 1].time);
|
|
41
|
+
}
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
let diffTime = newPosition.time - this.previousPosition.time;
|
|
48
44
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
45
|
+
if (flyby) {
|
|
46
|
+
diffTime = MAX_FLYBY_TIME;
|
|
47
|
+
}
|
|
52
48
|
|
|
53
|
-
|
|
49
|
+
const nSamples = GEN_FREQUENCY * Math.min(Math.max(MIN_FLYBY_TIME, diffTime), MAX_FLYBY_TIME);
|
|
54
50
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
51
|
+
let i = 1;
|
|
52
|
+
while (i < nSamples) {
|
|
53
|
+
i = Math.min(i, nSamples);
|
|
54
|
+
const smoothedPosition = this.previousPosition.destinationPoint(distance * i / nSamples, azimuth);
|
|
55
|
+
smoothedPosition.time = refTimestamp + (i - 1) / GEN_FREQUENCY;
|
|
56
|
+
smoothedPosition.bearing = rad2deg(azimuth);
|
|
57
|
+
this.positionsQueue.push(smoothedPosition);
|
|
58
|
+
i++;
|
|
59
|
+
}
|
|
60
|
+
newPosition.bearing = rad2deg(azimuth);
|
|
62
61
|
}
|
|
63
62
|
|
|
63
|
+
this.positionsQueue.push(newPosition);
|
|
64
64
|
this.previousPosition = newPosition;
|
|
65
65
|
}
|
|
66
66
|
|