@wemap/providers 3.0.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.
Files changed (102) hide show
  1. package/babel.config.js +11 -0
  2. package/config.json +4 -0
  3. package/debug/absolute-attitude.html +16 -0
  4. package/debug/absolute-position.html +16 -0
  5. package/debug/attitude.html +16 -0
  6. package/debug/components/AbsoluteAttitudeComponent.jsx +142 -0
  7. package/debug/components/AbsolutePositionComponent.jsx +79 -0
  8. package/debug/components/AttitudeComponent.jsx +40 -0
  9. package/debug/components/Common.css +27 -0
  10. package/debug/components/GnssWifiComponent.jsx +53 -0
  11. package/debug/components/ImuComponent.jsx +53 -0
  12. package/debug/components/InclinationComponent.jsx +68 -0
  13. package/debug/components/MapComponent.jsx +366 -0
  14. package/debug/components/NavigationConfig.js +112 -0
  15. package/debug/components/PoseComponent.jsx +168 -0
  16. package/debug/components/RelativeAttitudeComponent.jsx +85 -0
  17. package/debug/components/StartStopComponent.jsx +45 -0
  18. package/debug/components/StepDetectionComponent.jsx +39 -0
  19. package/debug/components/Utils.js +216 -0
  20. package/debug/components/index.js +30 -0
  21. package/debug/components/old/PositioningComponent.jsx +29 -0
  22. package/debug/components/old/PositioningInclinationComponent.jsx +82 -0
  23. package/debug/components/old/PositioningPoseComponent.jsx +117 -0
  24. package/debug/gnss-wifi.html +16 -0
  25. package/debug/imu.html +16 -0
  26. package/debug/inclination.html +16 -0
  27. package/debug/pose.html +16 -0
  28. package/debug/positioning-legacy.html +16 -0
  29. package/debug/relative-attitude.html +16 -0
  30. package/debug/step-detection.html +16 -0
  31. package/index.js +7 -0
  32. package/package.json +67 -0
  33. package/src/Providers.js +80 -0
  34. package/src/ProvidersInterface.js +125 -0
  35. package/src/ProvidersOptions.js +29 -0
  36. package/src/errors/AskImuOnDesktopError.js +9 -0
  37. package/src/errors/ContainsIgnoredProviderError.js +9 -0
  38. package/src/errors/GeolocationApiMissingError.js +9 -0
  39. package/src/errors/GeolocationPermissionDeniedError.js +9 -0
  40. package/src/errors/GeolocationPositionUnavailableError.js +9 -0
  41. package/src/errors/IpResolveServerError.js +9 -0
  42. package/src/errors/MissingAccelerometerError.js +11 -0
  43. package/src/errors/MissingArCoreError.js +9 -0
  44. package/src/errors/MissingGyroscopeError.js +11 -0
  45. package/src/errors/MissingMagnetometerError.js +9 -0
  46. package/src/errors/MissingNativeInterfaceError.js +9 -0
  47. package/src/errors/MissingSensorError.js +14 -0
  48. package/src/errors/NoProviderFoundError.js +9 -0
  49. package/src/events/Availability.js +44 -0
  50. package/src/events/EventType.js +33 -0
  51. package/src/events/ProviderEvent.js +32 -0
  52. package/src/events/ProvidersLogger.js +83 -0
  53. package/src/providers/Constants.js +5 -0
  54. package/src/providers/FakeProvider.spec.js +57 -0
  55. package/src/providers/MetaProvider.js +42 -0
  56. package/src/providers/Provider.js +314 -0
  57. package/src/providers/Provider.spec.js +136 -0
  58. package/src/providers/ProviderState.js +5 -0
  59. package/src/providers/attitude/AttitudeProvider.js +63 -0
  60. package/src/providers/attitude/EkfAttitude.js +224 -0
  61. package/src/providers/attitude/EkfAttitude.spec.js +114 -0
  62. package/src/providers/attitude/absolute/AbsoluteAttitudeFromBrowserProvider.js +224 -0
  63. package/src/providers/attitude/absolute/AbsoluteAttitudeFromRelAttProvider.js +134 -0
  64. package/src/providers/attitude/absolute/AbsoluteAttitudeProvider.js +143 -0
  65. package/src/providers/attitude/relative/RelativeAttitudeFromBrowserProvider.js +89 -0
  66. package/src/providers/attitude/relative/RelativeAttitudeFromEkfProvider.js +114 -0
  67. package/src/providers/attitude/relative/RelativeAttitudeProvider.js +103 -0
  68. package/src/providers/imu/AccelerometerProvider.js +61 -0
  69. package/src/providers/imu/GyroscopeProvider.js +61 -0
  70. package/src/providers/imu/ImuProvider.js +122 -0
  71. package/src/providers/inclination/InclinationFromAccProvider.js +87 -0
  72. package/src/providers/inclination/InclinationFromAttitudeProvider.js +77 -0
  73. package/src/providers/inclination/InclinationProvider.js +69 -0
  74. package/src/providers/legacy/AbsolutePdrProvider.js +258 -0
  75. package/src/providers/legacy/ArCoreAbsoluteProvider.js +230 -0
  76. package/src/providers/legacy/GnssWifiPdrProvider.js +217 -0
  77. package/src/providers/legacy/MapMatchingProvider.js +65 -0
  78. package/src/providers/legacy/PdrProvider.old.js +300 -0
  79. package/src/providers/legacy/PoseProvider.js +68 -0
  80. package/src/providers/legacy/helpers/HeadingUnlocker.js +47 -0
  81. package/src/providers/legacy/helpers/HeadingUnlocker.spec.js +53 -0
  82. package/src/providers/legacy/helpers/Smoother.js +92 -0
  83. package/src/providers/legacy/helpers/Smoother.spec.js +426 -0
  84. package/src/providers/legacy/helpers/ThugDetector.js +37 -0
  85. package/src/providers/others/CameraNativeProvider.js +44 -0
  86. package/src/providers/position/absolute/AbsolutePositionFromRelProvider.js +109 -0
  87. package/src/providers/position/absolute/AbsolutePositionProvider.js +172 -0
  88. package/src/providers/position/absolute/GnssWifiProvider.js +122 -0
  89. package/src/providers/position/absolute/IpProvider.js +68 -0
  90. package/src/providers/position/relative/ArCoreProvider.js +197 -0
  91. package/src/providers/position/relative/GeoRelativePositionFromArCoreProvider.js +85 -0
  92. package/src/providers/position/relative/GeoRelativePositionProvider.js +66 -0
  93. package/src/providers/position/relative/PdrProvider.js +132 -0
  94. package/src/providers/steps/StepDetectionLadetto.js +67 -0
  95. package/src/providers/steps/StepDetectionMinMaxPeaks.js +80 -0
  96. package/src/providers/steps/StepDetectionMinMaxPeaks2.js +108 -0
  97. package/src/providers/steps/StepDetectionProvider.js +100 -0
  98. package/src/smoothers/PositionSmoother.js +86 -0
  99. package/src/smoothers/PositionSmoother.spec.js +55 -0
  100. package/webpack/webpack.common.js +20 -0
  101. package/webpack/webpack.dev.js +24 -0
  102. package/webpack/webpack.prod.js +15 -0
@@ -0,0 +1,230 @@
1
+ /* eslint-disable max-statements */
2
+ import {
3
+ Attitude, UserPosition
4
+ } from '@wemap/geo';
5
+
6
+ import {
7
+ Quaternion, Vector3
8
+ } from '@wemap/maths';
9
+
10
+
11
+ import Availability from '../../events/Availability';
12
+ import EventType from '../../events/EventType';
13
+ import ArCoreProvider from '../position/relative/ArCoreProvider';
14
+ import ImuProvider from '../others/ImuProvider';
15
+ import MapMatchingProvider from './MapMatchingProvider';
16
+ import PdrProvider from './pdr/PdrProvider';
17
+
18
+ const MM_ARCORE_DIST = 5;
19
+
20
+
21
+ class ArCoreAbsoluteProvider extends MapMatchingProvider {
22
+
23
+ /**
24
+ * @override
25
+ */
26
+ constructor(onEvent, onError, options) {
27
+ super(onEvent, onError, options);
28
+
29
+ this.arCoreProvider = new ArCoreProvider(
30
+ e => this.onArCoreEvent(e),
31
+ onError,
32
+ options);
33
+
34
+ this.imuProvider = new ImuProvider(
35
+ this.onImuEvent,
36
+ onError,
37
+ Object.assign({}, options || {}, { require: [EventType.AngularRate] })
38
+ );
39
+
40
+ if (this.options.useMapMatching) {
41
+ this.enableMapMatching();
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @override
47
+ */
48
+ static get displayName() {
49
+ return 'ArCore absolute provider';
50
+ }
51
+
52
+ /**
53
+ * @override
54
+ */
55
+ static get eventsType() {
56
+ return [EventType.AbsoluteAttitude, EventType.AbsolutePosition];
57
+ }
58
+
59
+ /**
60
+ * Return the list of required providers
61
+ */
62
+ static get _availability() {
63
+ return Availability.union(
64
+ ArCoreProvider.availability,
65
+ ImuProvider.availability
66
+ );
67
+ }
68
+
69
+ /**
70
+ * @override
71
+ */
72
+ _start() {
73
+ this.arCoreProvider.start();
74
+ this.imuProvider.start();
75
+ }
76
+
77
+ /**
78
+ * @override
79
+ */
80
+ _stop() {
81
+ this.arCoreProvider.stop();
82
+ this.imuProvider.stop();
83
+ }
84
+
85
+ onArCoreEvent = events => {
86
+
87
+ const eventsForNotification = [];
88
+
89
+ events.forEach(event => {
90
+ if (event.dataType === EventType.RelativeAttitude) {
91
+
92
+ // const previousAttitude = this.relativeAttitude;
93
+ this.relativeAttitude = event.data;
94
+
95
+ /**
96
+ * The two following blocks cannot be called in the same call because this.waitingForceHeading
97
+ * if exists, is called before the first this.relativeAttitude assigment. So, this.waitingForceHeading
98
+ * and previousAttitude should not be defined in the same time.
99
+ */
100
+
101
+ if (typeof this.waitingForceHeading !== 'undefined') {
102
+ /**
103
+ * waitingForceHeading is set by setHeading() if this.relativeAttitude does not exist
104
+ * At this moment, this.relativeAttitude is defined, so we can call setHeading again
105
+ */
106
+ this.setHeading(this.waitingForceHeading);
107
+ delete this.waitingForceHeading;
108
+
109
+ }
110
+
111
+ // if (previousAttitude && this.absoluteAttitude) {
112
+ // /**
113
+ // * Sometimes ArCore has "orientation jumps" around z-axis.
114
+ // * Here we try to detect and remove them.
115
+ // */
116
+ // const dist = Quaternion.distance(event.data.quaternion, previousAttitude.quaternion);
117
+ // if (typeof this.angularRate !== 'undefined') {
118
+ // const velocity = Vector3.norm(this.angularRate);
119
+ // if (dist > deg2rad(10) && velocity < deg2rad(4)) {
120
+ // this.setHeading(this.absoluteAttitude.heading);
121
+ // }
122
+ // }
123
+ // }
124
+
125
+ if (this.offsetQuat) {
126
+ const absoluteQuaternion = Quaternion.multiply(this.offsetQuat, this.relativeAttitude.quaternion);
127
+ this.absoluteAttitude = new Attitude(absoluteQuaternion);
128
+ eventsForNotification.push(this.createEvent(EventType.AbsoluteAttitude, this.absoluteAttitude, event.timestamp));
129
+ }
130
+ }
131
+
132
+ if (event.dataType === EventType.RelativePosition) {
133
+
134
+ if (this.oldRelativePos && this.offsetAngle
135
+ && !ArCoreAbsoluteProvider.positionEquals(this.oldRelativePos, event.data)) {
136
+
137
+ const diffPos = Vector3.subtract(event.data, this.oldRelativePos);
138
+ const dist = Math.sqrt(diffPos[0] ** 2 + diffPos[2] ** 2);
139
+ const bearing = Math.atan2(diffPos[0], -diffPos[2]) - this.offsetAngle;
140
+ this.position = this.position.destinationPoint(dist, bearing, diffPos[1]);
141
+
142
+ if (this.absoluteAttitude) {
143
+ this.position.bearing = this.absoluteAttitude.heading;
144
+ this.updatePositionWithMapMatching();
145
+ }
146
+
147
+ eventsForNotification.push(this.createEvent(EventType.AbsolutePosition, this.position, event.timestamp));
148
+ }
149
+
150
+ this.oldRelativePos = event.data;
151
+ }
152
+
153
+ if (event.dataType === EventType.Barcode) {
154
+ eventsForNotification.push(event);
155
+ }
156
+
157
+ if (eventsForNotification.length !== 0) {
158
+ this.notify(...eventsForNotification);
159
+ }
160
+ });
161
+ }
162
+
163
+ static positionEquals(pos1, pos2) {
164
+ return pos1[0] === pos2[0] && pos1[1] === pos2[1] && pos1[2] === pos2[2];
165
+ }
166
+
167
+ onImuEvent = events => {
168
+ this.angularRate = events[0].data;
169
+ }
170
+
171
+ setHeading(heading) {
172
+
173
+ if (!this.relativeAttitude) {
174
+ this.waitingForceHeading = heading;
175
+ return;
176
+ }
177
+
178
+ this.offsetAngle = this.relativeAttitude.heading - heading;
179
+ this.offsetQuat = Quaternion.fromAxisAngle([0, 0, 1], this.offsetAngle);
180
+ }
181
+
182
+ setPosition(position) {
183
+ this.position = UserPosition.fromCoordinates(position);
184
+ this.notify(this.createEvent(EventType.AbsolutePosition, this.position));
185
+ }
186
+
187
+ /**
188
+ * @override
189
+ */
190
+ static get useCameraNatively() {
191
+ return true;
192
+ }
193
+
194
+
195
+ /**
196
+ * MapMatching
197
+ */
198
+
199
+ enableMapMatching(network, maxDistance, maxAngleBearing) {
200
+ super.enableMapMatching(
201
+ network,
202
+ maxDistance || MM_ARCORE_DIST,
203
+ maxAngleBearing || PdrProvider.MM_PDR_ANGLE
204
+ );
205
+ }
206
+
207
+ updatePositionWithMapMatching() {
208
+ if (!this.mapMatching) {
209
+ return;
210
+ }
211
+ const projection = this.mapMatching.getProjection(this.position, true, true);
212
+ if (projection) {
213
+ if (projection.distanceFromNearestElement > 1) {
214
+ this.position.lat = projection.projection.lat;
215
+ this.position.lng = projection.projection.lng;
216
+ }
217
+ this.position.level = projection.projection.level;
218
+ }
219
+ }
220
+
221
+ enableBarcodeScanner() {
222
+ this.arCoreProvider.enableBarcodeScanner();
223
+ }
224
+
225
+ disableBarcodeScanner() {
226
+ this.arCoreProvider.disableBarcodeScanner();
227
+ }
228
+ }
229
+
230
+ export default ArCoreAbsoluteProvider;
@@ -0,0 +1,217 @@
1
+ /* eslint max-statements: ["error", 40]*/
2
+
3
+ import { UserPosition } from '@wemap/geo';
4
+ import { deg2rad } from '@wemap/maths';
5
+
6
+ import MapMatchingProvider from './MapMatchingProvider';
7
+ import PdrProvider from './pdr/PdrProvider';
8
+ import GnssWifiProvider from '../position/GnssWifiProvider';
9
+ import Availability from '../../events/Availability';
10
+ import EventType from '../../events/EventType';
11
+ import AbsoluteAttitudeProvider from '../attitude/absolute/AbsoluteAttitudeProvider';
12
+ import Constants from '../Constants';
13
+
14
+ const GPF_ACCURACY = 25;
15
+ const GPF_DISTANCE = 25;
16
+
17
+ const MM_GNSS_DIST = 20;
18
+ const MM_GNSS_ANGLE = deg2rad(20);
19
+
20
+ class GnssWifiPdrProvider extends MapMatchingProvider {
21
+
22
+ /**
23
+ * @override
24
+ */
25
+ constructor(onEvent, onError, options) {
26
+ super(onEvent, onError, options);
27
+
28
+ this.pdrProvider = new PdrProvider(e => this.onPdrEvent(e), onError, options);
29
+ this.gnssWifiProvider = new GnssWifiProvider(e => this.onGnssWifiEvent(e), onError, options);
30
+ this.absoluteAttitudeProvider = new AbsoluteAttitudeProvider(
31
+ e => this.onAbsoluteAttitudeEvent(e),
32
+ onError,
33
+ options
34
+ );
35
+
36
+ this.gpsLastUpdate = 0;
37
+ this.isFirstGnssUpdate = true;
38
+ this.isFirstAttitudeUpdate = true;
39
+
40
+ if (this.options.useMapMatching) {
41
+ this.enableMapMatching();
42
+ }
43
+ }
44
+
45
+ /**
46
+ * @override
47
+ */
48
+ static get displayName() {
49
+ return 'GnssWifiPdr';
50
+ }
51
+
52
+ /**
53
+ * @override
54
+ */
55
+ static get eventsType() {
56
+ return [EventType.AbsoluteAttitude, EventType.AbsolutePosition];
57
+ }
58
+
59
+ /**
60
+ * @override
61
+ */
62
+ static get _availability() {
63
+ return Availability.merge(
64
+ PdrProvider.availability,
65
+ GnssWifiProvider.availability,
66
+ AbsoluteAttitudeProvider.availability
67
+ );
68
+ }
69
+
70
+
71
+ /**
72
+ * @override
73
+ */
74
+ _start() {
75
+ this.pdrProvider.start();
76
+ this.gnssWifiProvider.start();
77
+ this.absoluteAttitudeProvider.start();
78
+ }
79
+
80
+ /**
81
+ * @override
82
+ */
83
+ stop() {
84
+ this.pdrProvider.stop();
85
+ this.gnssWifiProvider.stop();
86
+ this.absoluteAttitudeProvider.stop();
87
+ }
88
+
89
+ /**
90
+ * @private
91
+ */
92
+ onPdrEvent(pdrEvent) {
93
+ pdrEvent.forEach(event => {
94
+ if (event.dataType === EventType.AbsolutePosition) {
95
+ this.position = event.data;
96
+ } else if (event.dataType === EventType.AbsoluteAttitude) {
97
+ this.attitude = event.data;
98
+ }
99
+ });
100
+ this.notify(...pdrEvent);
101
+ }
102
+
103
+ /**
104
+ * @private
105
+ */
106
+ onGnssWifiEvent(events) {
107
+
108
+ const gnssWifiEvent = events[0];
109
+ const position = gnssWifiEvent.data;
110
+
111
+ // This should be called to update True North / Magnetic North declination
112
+ this.absoluteAttitudeProvider.setPosition(position);
113
+
114
+ if (position.accuracy > GPF_ACCURACY) {
115
+ return;
116
+ }
117
+
118
+ this.gnssPosition = position.clone();
119
+ this.gnssPosition.alt = Constants.DEFAULT_ALTITUDE;
120
+
121
+ if (!this.position || this.position
122
+ && this.position.distanceTo(this.gnssPosition) > GPF_DISTANCE) {
123
+
124
+ if (!this.mapMatching || !this.attitude) {
125
+ this.pdrProvider.setPosition(this.gnssPosition);
126
+ } else {
127
+
128
+ this.gnssPosition.bearing = this.attitude.heading;
129
+ const projection = this.mapMatching.getProjection(this.gnssPosition, true, true);
130
+
131
+ if (projection && projection.projection) {
132
+
133
+ // Create a new position from projection and new GNSS position.
134
+ this.gnssPosition.lat = projection.projection.lat;
135
+ this.gnssPosition.lng = projection.projection.lng;
136
+
137
+ // // If nearest element is an edge, use its orientation to set heading
138
+ // if (projection.nearestElement instanceof Edge) {
139
+ // const edgeBearing = projection.nearestElement.bearing;
140
+ // const diff1 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssPosition.bearing), edgeBearing);
141
+ // const diff2 = MathUtils.diffAngle(MathUtils.deg2rad(this.gnssPosition.bearing), edgeBearing + Math.PI);
142
+ // this.pdrProvider.setHeading(diff1 < diff2 ? edgeBearing : edgeBearing + Math.PI);
143
+ // }
144
+
145
+ if (this.lastAttitude) {
146
+ this.pdrProvider.setHeading(this.lastAttitude.heading);
147
+ }
148
+
149
+ }
150
+ this.pdrProvider.setPosition(this.gnssPosition);
151
+ }
152
+ }
153
+
154
+ }
155
+
156
+ onAbsoluteAttitudeEvent(events) {
157
+
158
+ const attitude = events[0].data;
159
+
160
+ if (this.isFirstAttitudeUpdate) {
161
+ this.pdrProvider.setHeading(attitude.heading);
162
+ this.isFirstAttitudeUpdate = false;
163
+ }
164
+
165
+ this.lastAttitude = attitude;
166
+ }
167
+
168
+ /**
169
+ * MapMatching
170
+ */
171
+
172
+ enableMapMatching(network = null, maxDistance = MM_GNSS_DIST, maxAngleBearing = MM_GNSS_ANGLE) {
173
+ this.pdrProvider.enableMapMatching(network, maxDistance, maxAngleBearing);
174
+ super.enableMapMatching(network, maxDistance, maxAngleBearing);
175
+ }
176
+
177
+
178
+ setNetwork(network) {
179
+ this.pdrProvider.setNetwork(network);
180
+ super.setNetwork(network);
181
+ }
182
+
183
+ /**
184
+ * Itinerary
185
+ */
186
+
187
+ setItinerary(itinerary) {
188
+
189
+ const isFirstItinerary = !this.itinerary;
190
+
191
+ super.setItinerary(itinerary);
192
+
193
+ if (isFirstItinerary && itinerary.length > 0) {
194
+
195
+ // 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).
196
+
197
+ if (!this.gnssPosition
198
+ || itinerary.length < 2
199
+ || !itinerary.points[0].equalsTo(this.gnssPosition)) {
200
+ console.warn('Itinerary has not been calculated from GnssWifiPdrProvider and these is not recommanded');
201
+ }
202
+
203
+ const startEdge = itinerary.getEdgeAt(MM_GNSS_DIST);
204
+ if (!startEdge) {
205
+ return;
206
+ }
207
+ const startPoint = UserPosition.fromCoordinates(startEdge.node1.coords);
208
+ startPoint.alt = Constants.DEFAULT_ALTITUDE;
209
+ this.pdrProvider.setPosition(startPoint);
210
+ this.pdrProvider.setStepDetectionLockerOrientation(startEdge.bearing);
211
+ }
212
+
213
+ }
214
+
215
+ }
216
+
217
+ export default GnssWifiPdrProvider;
@@ -0,0 +1,65 @@
1
+ import Provider from '../Provider';
2
+ import {
3
+ Itinerary, MapMatching, Network
4
+ } from '@wemap/graph';
5
+
6
+ class MapMatchingProvider extends Provider {
7
+
8
+ /**
9
+ * Enable mapmatching
10
+ * @param {*} network a network which will be used for map matching
11
+ * @param {*} maxDistance max distance between position and network to match. null disables maxDistance (default: null)
12
+ * @param {*} maxAngleBearing threshold to match a parallel segment for angle between position bearing and segment. null disables this threshold (default: null)
13
+ * @public
14
+ */
15
+ enableMapMatching(network, maxDistance, maxAngleBearing) {
16
+ this.mapMatching = new MapMatching();
17
+ this.mapMatching.maxDistance = maxDistance;
18
+ this.mapMatching.maxAngleBearing = maxAngleBearing;
19
+
20
+ if (network) {
21
+ this.setNetwork(network);
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Update the network for mapmatching
27
+ * @param {Network} network a network instance
28
+ * @public
29
+ */
30
+ setNetwork(network) {
31
+ if (!this.mapMatching) {
32
+ throw new Error('MapMatching is not enabled');
33
+ }
34
+ this.mapMatching.network = network;
35
+ }
36
+
37
+ /**
38
+ * Is mapmatching activated?
39
+ * @returns is mapmatching activated
40
+ * @public
41
+ */
42
+ get hasMapMatching() {
43
+ return this.mapMatching !== null;
44
+ }
45
+
46
+
47
+ /**
48
+ * Itinerary
49
+ */
50
+
51
+ /**
52
+ * Update itinerary.
53
+ * Itinerary is different from network, it is not used for mapmatching. It can be used for others tricks like HeadingUnlocker
54
+ * @param {Itinerary} itinerary a given itinerary
55
+ * @public
56
+ */
57
+ setItinerary(itinerary) {
58
+ if (!(itinerary instanceof Itinerary)) {
59
+ throw new TypeError(itinerary + ' is not an instance of Itinerary');
60
+ }
61
+ this.itinerary = itinerary;
62
+ }
63
+ }
64
+
65
+ export default MapMatchingProvider;