@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 CHANGED
@@ -8,10 +8,10 @@
8
8
  "Guillaume Pannetier <guillaume.pannetier@getwemap.com>"
9
9
  ],
10
10
  "dependencies": {
11
- "@wemap/geo": "^0.3.1",
12
- "@wemap/logger": "^0.1.5",
11
+ "@wemap/geo": "^0.3.6",
12
+ "@wemap/logger": "^0.1.6",
13
13
  "@wemap/maths": "^0.2.1",
14
- "@wemap/osm": "^0.2.1",
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.3"
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(Utils.INITIAL_POSITION);
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(Utils.INITIAL_POSITION);
25
- this.arCoreAbsoluteProvider.setHeading(deg2rad(Utils.INITIAL_HEADING));
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={Utils.ITINERARY}
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(Utils.ITINERARY);
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={Utils.ITINERARY} />
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(Utils.ITINERARY);
16
+ this.pdrProvider.enableMapMatching(NavigationConfig.ITINERARY);
16
17
  }
17
18
 
18
19
  componentDidMount() {
19
- this.pdrProvider.setPosition(Utils.INITIAL_POSITION);
20
- this.pdrProvider.setHeading(Utils.INITIAL_HEADING);
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={Utils.ITINERARY} />
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, Utils.ITINERARY);
42
- this.props.positioningHandler.setNetwork(this.id, Utils.ITINERARY);
43
- this.props.positioningHandler.setPosition(this.id, Utils.INITIAL_POSITION);
44
- this.props.positioningHandler.setHeading(this.id, Utils.INITIAL_HEADING);
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
- ? Utils.ITINERARY.getInfo(this.state.position)
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={Utils.ITINERARY} />
107
+ network={NavigationConfig.ITINERARY} />
107
108
  <h3>ItineraryInfo</h3>
108
109
  {itineraryRender}
109
110
  </div>
@@ -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
@@ -38,6 +38,14 @@ import Availability from '../../events/Availability';
38
38
  */
39
39
  class AbsoluteAttitudeProvider extends Provider {
40
40
 
41
+
42
+ /**
43
+ * @override
44
+ */
45
+ static get name() {
46
+ return 'AbsoluteAttitude';
47
+ }
48
+
41
49
  /**
42
50
  * @override
43
51
  */
@@ -29,6 +29,13 @@ class RelativeAttitudeProvider extends Provider {
29
29
 
30
30
  }
31
31
 
32
+ /**
33
+ * @override
34
+ */
35
+ static get name() {
36
+ return 'RelativeAttitude';
37
+ }
38
+
32
39
  /**
33
40
  * @override
34
41
  */
@@ -61,6 +61,12 @@ class ImuProvider extends Provider {
61
61
  this.requiredSensors = options.require;
62
62
  }
63
63
 
64
+ /**
65
+ * @override
66
+ */
67
+ static get name() {
68
+ return 'Imu';
69
+ }
64
70
 
65
71
  /**
66
72
  * @override
@@ -23,6 +23,13 @@ class InclinationProvider extends Provider {
23
23
  );
24
24
  }
25
25
 
26
+ /**
27
+ * @override
28
+ */
29
+ static get name() {
30
+ return 'Inclination';
31
+ }
32
+
26
33
  /**
27
34
  * @override
28
35
  */
@@ -1,6 +1,6 @@
1
1
  import Provider from '../Provider';
2
2
  import {
3
- Itinerary, MapMatching, Network, WGS84
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 { Attitude } from '@wemap/geo';
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 Provider {
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 = position.clone();
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;
@@ -12,6 +12,13 @@ import Availability from '../../events/Availability';
12
12
  */
13
13
  class ArCoreProvider extends Provider {
14
14
 
15
+ /**
16
+ * @override
17
+ */
18
+ static get name() {
19
+ return 'ArCore';
20
+ }
21
+
15
22
  /**
16
23
  * @override
17
24
  */
@@ -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
- const projectedPosition = WGS84UserPosition.fromWGS84(projection.projection, this.gnssPosition);
130
- this.pdrProvider.setPosition(projectedPosition);
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
 
@@ -23,6 +23,13 @@ class PoseProvider extends Provider {
23
23
  }, onError);
24
24
  }
25
25
 
26
+ /**
27
+ * @override
28
+ */
29
+ static get name() {
30
+ return 'Pose';
31
+ }
32
+
26
33
  /**
27
34
  * @override
28
35
  */
@@ -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
- return WGS84UserPosition.fromWGS84(projection.projection, newPositionWithoutMM);
280
+ projectedPosition.lat = projection.projection.lat;
281
+ projectedPosition.lng = projection.projection.lng;
282
+ return projectedPosition;
266
283
  }
267
284
 
268
285
  /**
269
- * Update new_position
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 WGS84UserPosition.fromWGS84(smoothedPosition, newPositionWithoutMM);
297
+ return smoothedPosition;
277
298
  }
278
299
 
279
300
 
@@ -1,5 +1,6 @@
1
- /* eslint max-statements: ["error", 27]*/
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(_newPosition, flyby = false) {
21
+ generateNextPositions(newPosition, flyby = false) {
21
22
 
22
- if (!(_newPosition instanceof WGS84UserPosition)) {
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 (!this.previousPosition) {
32
- this.previousPosition = newPosition;
33
- this.positionsQueue.push(this.previousPosition);
34
- return;
35
- }
31
+ if (this.previousPosition) {
36
32
 
37
- const distance = this.previousPosition.distanceTo(newPosition);
38
- const azimuth = this.previousPosition.bearingTo(newPosition);
33
+ const distance = this.previousPosition.distanceTo(newPosition);
34
+ const azimuth = this.previousPosition.bearingTo(newPosition);
39
35
 
40
- let refTimestamp = newPosition.time;
36
+ let refTimestamp = newPosition.time;
41
37
 
42
- const queueLength = this.positionsQueue.length;
43
- if (queueLength) {
44
- refTimestamp = Math.max(refTimestamp, this.positionsQueue[queueLength - 1].time);
45
- }
38
+ const queueLength = this.positionsQueue.length;
39
+ if (queueLength) {
40
+ refTimestamp = Math.max(refTimestamp, this.positionsQueue[queueLength - 1].time);
41
+ }
46
42
 
47
- let diffTime = newPosition.time - this.previousPosition.time;
43
+ let diffTime = newPosition.time - this.previousPosition.time;
48
44
 
49
- if (flyby) {
50
- diffTime = MAX_FLYBY_TIME;
51
- }
45
+ if (flyby) {
46
+ diffTime = MAX_FLYBY_TIME;
47
+ }
52
48
 
53
- const nSamples = GEN_FREQUENCY * Math.min(Math.max(MIN_FLYBY_TIME, diffTime), MAX_FLYBY_TIME);
49
+ const nSamples = GEN_FREQUENCY * Math.min(Math.max(MIN_FLYBY_TIME, diffTime), MAX_FLYBY_TIME);
54
50
 
55
- let i = 1;
56
- while (i < nSamples + 1) {
57
- i = Math.min(i, nSamples);
58
- const smoothedPosition = this.previousPosition.destinationPoint(distance * i / nSamples, azimuth);
59
- smoothedPosition.time = refTimestamp + (i - 1) / GEN_FREQUENCY;
60
- this.positionsQueue.push(smoothedPosition);
61
- i++;
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
 
@@ -23,6 +23,13 @@ const POSITION_OPTIONS = {
23
23
  */
24
24
  class GnssWifiProvider extends Provider {
25
25
 
26
+ /**
27
+ * @override
28
+ */
29
+ static get name() {
30
+ return 'GnssWifi';
31
+ }
32
+
26
33
  /**
27
34
  * @override
28
35
  */
@@ -12,6 +12,13 @@ import IpResolveServerError from '../../errors/IpResolveServerError';
12
12
  */
13
13
  class IpProvider extends Provider {
14
14
 
15
+ /**
16
+ * @override
17
+ */
18
+ static get name() {
19
+ return 'IP';
20
+ }
21
+
15
22
  /**
16
23
  * @override
17
24
  */