@wemap/positioning 2.7.13 → 14.0.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 (104) hide show
  1. package/README.md +51 -0
  2. package/dist/index.d.ts +19 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +16582 -0
  5. package/dist/qr-scanner-worker.min-CdBZO1_x.js +2 -0
  6. package/dist/src/ILocationSource.d.ts +104 -0
  7. package/dist/src/ILocationSource.d.ts.map +1 -0
  8. package/dist/src/MapMatching.d.ts +83 -0
  9. package/dist/src/MapMatching.d.ts.map +1 -0
  10. package/dist/src/location-sources/GnssWifiLocationSource.d.ts +79 -0
  11. package/dist/src/location-sources/GnssWifiLocationSource.d.ts.map +1 -0
  12. package/dist/src/location-sources/LocationSource.d.ts +102 -0
  13. package/dist/src/location-sources/LocationSource.d.ts.map +1 -0
  14. package/dist/src/location-sources/VPSLocationSource.d.ts +107 -0
  15. package/dist/src/location-sources/VPSLocationSource.d.ts.map +1 -0
  16. package/dist/src/types.d.ts +65 -0
  17. package/dist/src/types.d.ts.map +1 -0
  18. package/dist/src/utils/permissions.d.ts +29 -0
  19. package/dist/src/utils/permissions.d.ts.map +1 -0
  20. package/dist/vitest.config.d.ts +3 -0
  21. package/dist/vitest.config.d.ts.map +1 -0
  22. package/package.json +23 -59
  23. package/babel.config.js +0 -11
  24. package/config.json +0 -4
  25. package/debug/absolute-attitude.html +0 -16
  26. package/debug/arcore-absolute.html +0 -16
  27. package/debug/arcore.html +0 -16
  28. package/debug/components/AbsoluteAttitudeComponent.jsx +0 -100
  29. package/debug/components/ArCoreAbsoluteComponent.jsx +0 -104
  30. package/debug/components/ArCoreComponent.jsx +0 -69
  31. package/debug/components/GnssWifiComponent.jsx +0 -56
  32. package/debug/components/GnssWifiPdrComponent.jsx +0 -76
  33. package/debug/components/ImuComponent.jsx +0 -95
  34. package/debug/components/InclinationComponent.jsx +0 -52
  35. package/debug/components/MapComponent.jsx +0 -228
  36. package/debug/components/NavigationConfig.js +0 -92
  37. package/debug/components/PdrComponent.jsx +0 -75
  38. package/debug/components/PoseComponent.jsx +0 -77
  39. package/debug/components/PositioningComponent.jsx +0 -29
  40. package/debug/components/PositioningInclinationComponent.jsx +0 -82
  41. package/debug/components/PositioningPoseComponent.jsx +0 -117
  42. package/debug/components/RelativeAttitudeComponent.jsx +0 -82
  43. package/debug/components/StartStopComponent.jsx +0 -50
  44. package/debug/components/Utils.js +0 -128
  45. package/debug/components/index.js +0 -34
  46. package/debug/gnss-wifi-pdr.html +0 -16
  47. package/debug/gnss-wifi.html +0 -16
  48. package/debug/imu.html +0 -16
  49. package/debug/inclination.html +0 -16
  50. package/debug/pdr.html +0 -16
  51. package/debug/pose.html +0 -16
  52. package/debug/positioning.html +0 -16
  53. package/debug/relative-attitude.html +0 -16
  54. package/dist/wemap-positioning.min.js +0 -1
  55. package/index.js +0 -8
  56. package/src/PositioningHandler.js +0 -237
  57. package/src/PositioningHandler.spec.js +0 -294
  58. package/src/PositioningOptions.js +0 -34
  59. package/src/errors/AskImuOnDesktopError.js +0 -9
  60. package/src/errors/ContainsIgnoredProviderError.js +0 -9
  61. package/src/errors/GeolocationApiMissingError.js +0 -9
  62. package/src/errors/GeolocationPermissionDeniedError.js +0 -9
  63. package/src/errors/GeolocationPositionUnavailableError.js +0 -9
  64. package/src/errors/IpResolveServerError.js +0 -9
  65. package/src/errors/MissingAccelerometerError.js +0 -11
  66. package/src/errors/MissingArCoreError.js +0 -9
  67. package/src/errors/MissingGyroscopeError.js +0 -11
  68. package/src/errors/MissingMagnetometerError.js +0 -9
  69. package/src/errors/MissingNativeInterfaceError.js +0 -9
  70. package/src/errors/MissingSensorError.js +0 -14
  71. package/src/errors/NoProviderFoundError.js +0 -9
  72. package/src/events/Availability.js +0 -30
  73. package/src/events/EventType.js +0 -22
  74. package/src/events/ProviderEvent.js +0 -35
  75. package/src/providers/Constants.js +0 -5
  76. package/src/providers/Provider.js +0 -247
  77. package/src/providers/ProvidersList.js +0 -44
  78. package/src/providers/ProvidersLogger.js +0 -75
  79. package/src/providers/attitude/AbsoluteAttitudeProvider.js +0 -199
  80. package/src/providers/attitude/EkfAttitude.js +0 -238
  81. package/src/providers/attitude/EkfAttitude.spec.js +0 -116
  82. package/src/providers/attitude/RelativeAttitudeProvider.js +0 -121
  83. package/src/providers/others/ImuProvider.js +0 -179
  84. package/src/providers/others/InclinationProvider.js +0 -99
  85. package/src/providers/others/MapMatchingProvider.js +0 -65
  86. package/src/providers/pose/ArCoreAbsoluteProvider.js +0 -235
  87. package/src/providers/pose/ArCoreProvider.js +0 -191
  88. package/src/providers/pose/GnssWifiPdrProvider.js +0 -219
  89. package/src/providers/pose/PoseProvider.js +0 -71
  90. package/src/providers/pose/pdr/PdrProvider.js +0 -364
  91. package/src/providers/pose/pdr/helpers/HeadingUnlocker.js +0 -41
  92. package/src/providers/pose/pdr/helpers/HeadingUnlocker.spec.js +0 -26
  93. package/src/providers/pose/pdr/helpers/Smoother.js +0 -92
  94. package/src/providers/pose/pdr/helpers/Smoother.spec.js +0 -426
  95. package/src/providers/pose/pdr/helpers/ThugDetector.js +0 -37
  96. package/src/providers/pose/pdr/steps/StepDetection.js +0 -7
  97. package/src/providers/pose/pdr/steps/StepDetectionLadetto.js +0 -67
  98. package/src/providers/pose/pdr/steps/StepDetectionMinMaxPeaks.js +0 -80
  99. package/src/providers/pose/pdr/steps/StepDetectionMinMaxPeaks2.js +0 -108
  100. package/src/providers/position/GnssWifiProvider.js +0 -130
  101. package/src/providers/position/IpProvider.js +0 -74
  102. package/webpack/webpack.common.js +0 -20
  103. package/webpack/webpack.dev.js +0 -24
  104. package/webpack/webpack.prod.js +0 -15
@@ -1,14 +0,0 @@
1
- const DEFAULT_MESSAGE = 'Impossible to retrieve events, a sensor is missing';
2
-
3
- class MissingSensorError extends Error {
4
- constructor(message) {
5
- super(message || DEFAULT_MESSAGE);
6
- }
7
-
8
- from(fromMessage) {
9
- this.message += ' from ' + fromMessage;
10
- return this;
11
- }
12
- }
13
-
14
- export default MissingSensorError;
@@ -1,9 +0,0 @@
1
- const DEFAULT_MESSAGE = 'Unable to find a provider with your given parameters';
2
-
3
- class NoProviderFoundError extends Error {
4
- constructor(message) {
5
- super(message || DEFAULT_MESSAGE);
6
- }
7
- }
8
-
9
- export default NoProviderFoundError;
@@ -1,30 +0,0 @@
1
- class Availability {
2
-
3
- isSupported = false;
4
- reason = null;
5
-
6
- static no(reason) {
7
- const availability = new Availability();
8
- availability.reason = reason;
9
- availability.isSupported = false;
10
- return availability;
11
- }
12
-
13
- static yes() {
14
- const availability = new Availability();
15
- availability.isSupported = true;
16
- return availability;
17
- }
18
-
19
- static merge(...availabilities) {
20
- for (let i = 0; i < availabilities.length; i++) {
21
- const availability = availabilities[i];
22
- if (!availability.isSupported) {
23
- return availability;
24
- }
25
- }
26
- return Availability.yes();
27
- }
28
- }
29
-
30
- export default Availability;
@@ -1,22 +0,0 @@
1
- /**
2
- * Event data types handled by {@link ProviderEvent}
3
- */
4
- export default {
5
- Unknown: 'UNKNOWN',
6
- MagneticField: 'MAGNETIC_FIELD',
7
- AngularRate: 'ANGULAR_RATE',
8
- Acceleration: 'ACCELERATION',
9
- Inclination: 'INCLINATION',
10
- RelativeAttitude: 'RELATIVE_ATTITUDE',
11
- AbsoluteAttitude: 'ABSOLUTE_ATTITUDE',
12
- RelativePosition: 'RELATIVE_POSITION',
13
- AbsolutePosition: 'ABSOLUTE_POSITION',
14
- Pressure: 'PRESSURE',
15
- BluetoothSignals: 'BLUETOOTH_SIGNALS',
16
- WifiSignals: 'WIFI_SIGNALS',
17
- ScanId: 'SCAN_ID',
18
- Barcode: 'BARCODE',
19
- ProjectionMatrix: 'PROJECTION_MATRIX',
20
- Itinerary: 'ITINERARY',
21
- Network: 'NETWORK'
22
- };
@@ -1,35 +0,0 @@
1
- import EventType from './EventType';
2
-
3
- /**
4
- * A provider event is an event which can be triggered by device sensors
5
- * or can be computed from raw providers.
6
- */
7
- class ProviderEvent {
8
-
9
- timestamp = -1;
10
- dataType = EventType.Unknown;
11
- providerName = '';
12
- isFromNative = false;
13
- data = null;
14
-
15
- /**
16
- * Create a Provider Event with the minimum information
17
- * @param {String} providerName the provider name
18
- * @param {EventType} dataType the type of event
19
- * @param {Object} data the event data
20
- */
21
- constructor(providerName, dataType, data) {
22
- this.providerName = providerName;
23
- this.dataType = dataType;
24
- this.data = data;
25
- }
26
-
27
- clone() {
28
- const evt = new ProviderEvent(this.providerName, this.dataType, this.data);
29
- evt.timestamp = this.timestamp;
30
- evt.isFromNative = this.isFromNative;
31
- return evt;
32
- }
33
- }
34
-
35
- export default ProviderEvent;
@@ -1,5 +0,0 @@
1
- const Constants = {
2
- DEFAULT_ALTITUDE: 1.6
3
- };
4
-
5
- export default Constants;
@@ -1,247 +0,0 @@
1
- import noop from 'lodash.noop';
2
-
3
- import EventType from '../events/EventType';
4
- import ProviderEvent from '../events/ProviderEvent';
5
- import Logger from '@wemap/logger';
6
- import ProvidersLogger from './ProvidersLogger';
7
- import Availability from '../events/Availability';
8
- import PositioningOptions from '../PositioningOptions';
9
- import ContainsIgnoredProviderError from '../errors/ContainsIgnoredProviderError';
10
-
11
- let uniqueId = 1;
12
-
13
- /**
14
- * A provider is a meta class to define an entity which can be
15
- * started / stopped and provides a data of {@link ProviderEvent#DataType}
16
- */
17
- class Provider {
18
-
19
- static DEFAULT_NAME = 'Unknown';
20
- static DEFAULT_OPTIONS = Object.assign(
21
- {},
22
- PositioningOptions,
23
- {
24
- stopOnError: true,
25
- checkAvailabilityOnStart: true
26
- }
27
- );
28
-
29
- static State = {
30
- STARTING: 0,
31
- STARTED: 1,
32
- STOPPPED: 2
33
- };
34
-
35
- static Warnings = {
36
- ALREADY_STARTED: 'Provider already started',
37
- ALREADY_STOPPED: 'Provider already stopped'
38
- }
39
-
40
- state = Provider.State.STOPPPED;
41
-
42
- /**
43
- * Provider constructor
44
- * @param {Function} onEvent a callback which will receive events
45
- * @param {Function} onError a callback when an error happen
46
- * @param {Object} options provider options
47
- */
48
- constructor(onEvent, onError, options) {
49
- this.onEvent = onEvent || noop;
50
- this.onError = onError || noop;
51
- this.options = Object.assign({}, Provider.DEFAULT_OPTIONS, PositioningOptions, options);
52
- this.id = uniqueId++;
53
- ProvidersLogger.addEvent(this, 'constructor');
54
- }
55
-
56
- /**
57
- * Get the provider display name
58
- * @public
59
- * @abstract
60
- */
61
- static get name() {
62
- return this.DEFAULT_NAME;
63
- }
64
-
65
- /**
66
- * Get the provider name
67
- * @public
68
- * @abstract
69
- */
70
- static get displayName() {
71
- return this.constructor.DEFAULT_NAME;
72
- }
73
-
74
- /**
75
- * Get the list of events type which can be returned by the provider
76
- * @returns {EventType[]} the list of events type
77
- * @public
78
- * @abstract
79
- */
80
- static get eventsType() {
81
- return [];
82
- }
83
-
84
- /**
85
- * //TODO
86
- */
87
- static checkAvailability(options) {
88
-
89
- if (this.containsIgnoredProviders(options)) {
90
- return Availability.no(new ContainsIgnoredProviderError());
91
- }
92
-
93
- return this
94
- .getRequiredProviders(options)
95
- .reduce((acc, val) =>
96
- Availability.merge(acc, val.checkAvailability(options)), Availability.yes()
97
- );
98
- }
99
-
100
- /**
101
- * Return the list of required providers
102
- */
103
- static getRequiredProviders() {
104
- return [];
105
- }
106
-
107
- static containsIgnoredProviders(options) {
108
- return this
109
- .getRequiredProvidersRecursively(options)
110
- .some(elem => options.ignoreProviders.includes(elem.name));
111
- }
112
-
113
-
114
- /**
115
- * Return the list of required providers
116
- */
117
- static getRequiredProvidersRecursively(options) {
118
- if (this.getRequiredProviders(options).length === 0) {
119
- return [this];
120
- }
121
- return this.getRequiredProviders().reduce(
122
- (acc, val) => acc.concat(val.getRequiredProvidersRecursively(options)), [this]
123
- );
124
- }
125
-
126
- /**
127
- * Start the Provider
128
- * @public
129
- */
130
- start() {
131
- if (this.state === Provider.State.STARTING
132
- || this.state === Provider.State.STARTED) {
133
- Logger.warn(Provider.Warnings.ALREADY_STARTED);
134
- return;
135
- }
136
- this.state = Provider.State.STARTING;
137
-
138
- if (this.options.checkAvailabilityOnStart) {
139
- const availibility = this.constructor.checkAvailability(this.options);
140
- if (!availibility.isSupported) {
141
- this.notifyError(availibility.reason);
142
- return;
143
- }
144
- }
145
-
146
- ProvidersLogger.addEvent(this, 'start');
147
- this.state = Provider.State.STARTED;
148
- this.startInternal();
149
- }
150
-
151
- /**
152
- * @abstract
153
- */
154
- startInternal() {
155
- throw new Error('Provider "' + this.constructor.name
156
- + '" does not @override startInternal()');
157
- }
158
-
159
- /**
160
- * Stop the Provider
161
- * @public
162
- */
163
- stop() {
164
-
165
- if (this.state === Provider.State.STOPPPED) {
166
- Logger.warn(Provider.Warnings.ALREADY_STOPPED);
167
- return;
168
- }
169
-
170
- ProvidersLogger.addEvent(this, 'stop');
171
- this.state = Provider.State.STOPPPED;
172
- this.stopInternal();
173
- }
174
-
175
- /**
176
- * @abstract
177
- */
178
- stopInternal() {
179
- throw new Error('Provider "' + this.constructor.name
180
- + '" does not @override stopInternal()');
181
- }
182
-
183
-
184
- /**
185
- * Notify the subscriber defined in {@link constructor}
186
- * @param {ProviderEvent[]} events events to send to subscriber
187
- */
188
- notify(...events) {
189
- ProvidersLogger.incrementNotifications(this);
190
- this.onEvent(events);
191
- }
192
-
193
- /**
194
- * Notify the subscriber defined in {@link constructor}
195
- * @param {Error[]} errors The error raised
196
- */
197
- notifyError(error) {
198
- this.onError(error);
199
- if (this.options.stopOnError && this.state === Provider.State.STARTED) {
200
- this.stop();
201
- }
202
- }
203
-
204
- /**
205
- * Create an event from current provider
206
- * @param {ProviderEvent#DataType} dataType type of ProviderEvent
207
- * @param {Object} data data exported to ProviderEvent
208
- * @param {Number} timestamp event timestamp
209
- * @protected
210
- */
211
- static createEvent(dataType, data, timestamp) {
212
- const event = new ProviderEvent(this.constructor.name, dataType, data);
213
- if (timestamp) {
214
- event.timestamp = timestamp;
215
- }
216
- return event;
217
- }
218
-
219
- /**
220
- * Create an event from current provider
221
- * @param {EventType} dataType type of ProviderEvent
222
- * @param {Object} data data exported to ProviderEvent
223
- * @param {Number} timestamp event timestamp
224
- * @protected
225
- */
226
- createEvent(dataType, data, timestamp) {
227
- return this.constructor.createEvent(dataType, data, timestamp);
228
- }
229
-
230
- static hasNativeInterface() {
231
- return Boolean(Provider.nativeInterface);
232
- }
233
-
234
- static get nativeInterface() {
235
- return global.WemapProvidersAndroid;
236
- }
237
-
238
- static get useCameraNatively() {
239
- return false;
240
- }
241
-
242
- get useCameraNatively() {
243
- return this.constructor.useCameraNatively;
244
- }
245
- }
246
-
247
- export default Provider;
@@ -1,44 +0,0 @@
1
- import GnssWifi from './position/GnssWifiProvider';
2
- import Ip from './position/IpProvider';
3
- import Pdr from './pose/pdr/PdrProvider';
4
- import ArCore from './pose/ArCoreProvider';
5
- import ArCoreAbsolute from './pose/ArCoreAbsoluteProvider';
6
- import Inclination from './others/InclinationProvider';
7
- import GnssWifiPdr from './pose/GnssWifiPdrProvider';
8
- import Imu from './others/ImuProvider';
9
- import AbsoluteAttitude from './attitude/AbsoluteAttitudeProvider';
10
- import RelativeAttitude from './attitude/RelativeAttitudeProvider';
11
-
12
- const ProvidersName = {
13
- AbsoluteAttitude: AbsoluteAttitude.name,
14
- ArCore: ArCore.name,
15
- ArCoreAbsolute: ArCoreAbsolute.name,
16
- GnssWifi: GnssWifi.name,
17
- GnssWifiPdr: GnssWifiPdr.name,
18
- Imu: Imu.name,
19
- Inclination: Inclination.name,
20
- Ip: Ip.name,
21
- Pdr: Pdr.name,
22
- RelativeAttitude: RelativeAttitude.name
23
- };
24
-
25
- const ProvidersModules = {
26
- AbsoluteAttitude,
27
- ArCore,
28
- ArCoreAbsolute,
29
- GnssWifi,
30
- GnssWifiPdr,
31
- Imu,
32
- Inclination,
33
- Ip,
34
- Pdr,
35
- RelativeAttitude
36
- };
37
-
38
- function getModuleFromName(name) {
39
- return ProvidersModules[name];
40
- }
41
-
42
- export {
43
- ProvidersName, getModuleFromName
44
- };
@@ -1,75 +0,0 @@
1
- import Logger from '@wemap/logger';
2
-
3
- let currentId = 0;
4
- const objectsIdMap = new WeakMap();
5
-
6
- let pushEvents = {};
7
- let pushEventsRef = {};
8
-
9
- let interval;
10
- let initDate;
11
-
12
- class ProvidersLogger {
13
-
14
- static enabled = false;
15
-
16
- static initializeInterval() {
17
-
18
- if (interval) {
19
- return;
20
- }
21
-
22
- interval = setInterval(() => {
23
-
24
- for (const [key, value] of Object.entries(pushEvents)) {
25
- Logger.debug('Received ' + value + ' notifications from ' + pushEventsRef[key].constructor.name + ' last second');
26
- }
27
-
28
- pushEvents = {};
29
- pushEventsRef = {};
30
- }, 1000);
31
- }
32
-
33
- static getObjectId(object) {
34
- if (!objectsIdMap.has(object)) {
35
- objectsIdMap.set(object, ++currentId);
36
- }
37
- return objectsIdMap.get(object);
38
- }
39
-
40
- static addEvent(object, method) {
41
-
42
- if (!ProvidersLogger.enabled) {
43
- return;
44
- }
45
-
46
- if (!initDate) {
47
- initDate = Date.now();
48
- }
49
-
50
- ProvidersLogger.initializeInterval();
51
-
52
- const objectId = ProvidersLogger.getObjectId(object);
53
- const objectClassName = object.constructor.name;
54
-
55
- Logger.debug(objectClassName + '[' + objectId + '].' + method);
56
- }
57
-
58
- static incrementNotifications(object) {
59
-
60
- if (!ProvidersLogger.enabled) {
61
- return;
62
- }
63
-
64
- const objectId = ProvidersLogger.getObjectId(object);
65
-
66
- let counter = pushEvents[objectId];
67
- if (!counter) {
68
- counter = 0;
69
- pushEventsRef[objectId] = object;
70
- }
71
- pushEvents[objectId] = counter + 1;
72
- }
73
-
74
- }
75
- export default ProvidersLogger;
@@ -1,199 +0,0 @@
1
- import geomagnetism from 'geomagnetism';
2
-
3
- import {
4
- Attitude, WGS84
5
- } from '@wemap/geo';
6
- import {
7
- deg2rad, rad2deg, Quaternion, Rotations
8
- } from '@wemap/maths';
9
- import {
10
- Browser, BrowserUtils
11
- } from '@wemap/utils';
12
-
13
- import Provider from '../Provider';
14
- import EventType from '../../events/EventType';
15
- import AskImuOnDesktopError from '../../errors/AskImuOnDesktopError';
16
- import MissingMagnetometerError from '../../errors/MissingMagnetometerError';
17
- import MissingSensorError from '../../errors/MissingSensorError';
18
- import Logger from '@wemap/logger';
19
- import Availability from '../../events/Availability';
20
-
21
-
22
- /**
23
- * Absolute attitude provider gives the device attitude in East-North-Up (ENU) frame using
24
- * browser deviceorientation or deviceorientationabsolute
25
- * The provider does not work until an AbsolutePosition is given. This is necessary to
26
- * calculate declination.
27
- *
28
- * -----------------------------------
29
- * Overview of compatibilities:
30
- * -----------------------------------
31
- *
32
- * Chrome Android (v72.0.3626): YES (via deviceorientationabsolute)
33
- * Safari iOS (v12.0): YES (via deviceorientation and event.webkitCompassHeading)
34
- * Opera Android (v50.2.2426): NO {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/ondeviceorientation}
35
- * Firefox Android (v65.0.1): NO {@link https://www.fxsitecompat.com/en-CA/docs/2018/various-device-sensor-apis-are-now-deprecated/}
36
- *
37
- * -----------------------------------
38
- */
39
- class AbsoluteAttitudeProvider extends Provider {
40
-
41
-
42
- /**
43
- * @override
44
- */
45
- static get name() {
46
- return 'AbsoluteAttitude';
47
- }
48
-
49
- /**
50
- * @override
51
- */
52
- static get displayName() {
53
- return 'Absolute Attitude from Browser';
54
- }
55
-
56
- /**
57
- * @override
58
- */
59
- static get eventsType() {
60
- return [EventType.AbsoluteAttitude];
61
- }
62
-
63
- /**
64
- * @override
65
- */
66
- static checkAvailability(options) {
67
- return Availability.merge(
68
- super.checkAvailability(options),
69
- BrowserUtils.isMobile
70
- ? Availability.yes()
71
- : Availability.no(new AskImuOnDesktopError())
72
- );
73
- }
74
-
75
- /**
76
- * @override
77
- */
78
- startInternal() {
79
- switch (BrowserUtils.name) {
80
- case Browser.CHROME:
81
- window.addEventListener('deviceorientationabsolute',
82
- this.onDeviceOrientationChromeEvent, true);
83
- break;
84
-
85
- case Browser.SAFARI:
86
- window.addEventListener('deviceorientation',
87
- this.onDeviceOrientationSafariEvent, true);
88
- break;
89
- }
90
- }
91
-
92
- /**
93
- * @override
94
- */
95
- stopInternal() {
96
- switch (BrowserUtils.name) {
97
- case Browser.CHROME:
98
- window.removeEventListener('deviceorientationabsolute',
99
- this.onDeviceOrientationChromeEvent, true);
100
- break;
101
-
102
- case Browser.SAFARI:
103
- window.removeEventListener('deviceorientation',
104
- this.onDeviceOrientationSafariEvent, true);
105
- break;
106
- }
107
- }
108
-
109
-
110
- onDeviceOrientationChromeEvent = e => {
111
-
112
- const timestamp = e.timeStamp / 1e3;
113
-
114
- if (!e.alpha || !e.beta || !e.gamma) {
115
- this.notifyError(new MissingSensorError().from('deviceorientationabsolute'));
116
- return;
117
- }
118
- this.onDeviceOrientationCommonEvent(timestamp,
119
- Rotations.eulerToQuaternionZXYDegrees([e.alpha, e.beta, e.gamma]));
120
- };
121
-
122
-
123
- onDeviceOrientationSafariEvent = e => {
124
-
125
- const timestamp = e.timeStamp / 1e3;
126
-
127
- if (!e.beta || !e.gamma) {
128
- this.notifyError(new MissingSensorError().from('deviceorientation'));
129
- return;
130
- }
131
-
132
- if (!e.webkitCompassHeading) {
133
- super.notifyError(new MissingMagnetometerError().from('deviceorientation'));
134
- return;
135
- }
136
-
137
- let webkitCompassHeading = -e.webkitCompassHeading;
138
- // Be Careful: webkitCompassHeading is not continuous.
139
- // Reference frame changes in function of beta with thresholds: beta > 30deg and beta < 62deg
140
- // Below 30deg, East-North-Up (ENU) frame is used
141
- // Above 62def, East-Up-South (EUS) frame is used
142
- // Between 30deg and 62deg either ENU or EUS can be used
143
- if (e.beta > 62) {
144
- webkitCompassHeading = AbsoluteAttitudeProvider.headingEusToEnu(
145
- 180 - webkitCompassHeading, e.beta, e.gamma);
146
- }
147
- const quaternion = Rotations.eulerToQuaternionZXYDegrees(
148
- [webkitCompassHeading, e.beta, e.gamma]);
149
-
150
- this.onDeviceOrientationCommonEvent(timestamp, quaternion);
151
- };
152
-
153
-
154
- onDeviceOrientationCommonEvent = (timestamp, quaternion) => {
155
-
156
- if (!this.declinationQuaternion) {
157
- Logger.warn('Position of AbsoluteAttitude provider is not set yet. '
158
- + 'Please call setPosition() before.');
159
- return;
160
- }
161
- const trueQuaternion = Quaternion.multiply(this.declinationQuaternion, quaternion);
162
-
163
- super.notify(
164
- this.createEvent(
165
- EventType.AbsoluteAttitude,
166
- new Attitude(trueQuaternion),
167
- timestamp
168
- )
169
- );
170
- }
171
-
172
- /**
173
- * Initialized declination quaternion using current position.
174
- * This method should be theoretically called every time the user moves.
175
- * But in reality declination does not change as much.
176
- * @param {WGS84} position user position
177
- */
178
- setPosition(position) {
179
- const wmmResult = geomagnetism.model().point([position.lat, position.lng]);
180
- // Declination is given in NED frame and our code use ENU, that is why we have: "-decl"
181
- this.declinationQuaternion = Quaternion.fromAxisAngle([0, 0, 1], - deg2rad(wmmResult.decl));
182
- }
183
-
184
- /**
185
- * {@link https://math.stackexchange.com/questions/3181981/solve-a-system-of-rotation-matrices-z-x-z-z-x-y}
186
- */
187
- static headingEusToEnu(_alpha, _beta, _gamma) {
188
- const alpha = deg2rad(_alpha);
189
- const beta = deg2rad(_beta);
190
- const gamma = deg2rad(_gamma);
191
-
192
- return rad2deg(Math.atan2(
193
- Math.cos(alpha) * Math.sin(gamma) + Math.cos(gamma) * Math.sin(alpha) * Math.sin(beta),
194
- Math.sin(alpha) * Math.sin(gamma) - Math.cos(alpha) * Math.cos(gamma) * Math.sin(beta)
195
- ));
196
- }
197
- }
198
-
199
- export default AbsoluteAttitudeProvider;