@wemap/providers 3.2.16 → 3.2.18

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.
@@ -16,6 +16,8 @@ ProvidersLoggerOld.enabled = true;
16
16
 
17
17
  class AbsoluteAttitudeComponent extends React.Component {
18
18
 
19
+ isStarted = false;
20
+
19
21
  constructor(props, context) {
20
22
  super(props, context);
21
23
 
@@ -29,7 +31,12 @@ class AbsoluteAttitudeComponent extends React.Component {
29
31
 
30
32
  }
31
33
 
32
- componentDidMount() {
34
+ start() {
35
+
36
+ if (this.isStarted) {
37
+ this.stop();
38
+ }
39
+ this.isStarted = true;
33
40
 
34
41
  this.providerFromBrowserId = AbsoluteAttitudeFromBrowser.addEventListener(
35
42
  events => this.setState({ attitudeFromBrowser: events[0] }),
@@ -54,7 +61,8 @@ class AbsoluteAttitudeComponent extends React.Component {
54
61
  window.addEventListener('deviceorientationabsolute', this.onDeviceOrientationAbsoluteEventListener, true);
55
62
  }
56
63
 
57
- componentWillUnmount() {
64
+ stop() {
65
+ this.isStarted = false;
58
66
  AbsoluteAttitudeFromBrowser.removeEventListener(this.providerFromBrowserId);
59
67
  AbsoluteAttitudeFromRelAtt.removeEventListener(this.providerFromRelAttId);
60
68
  AbsoluteAttitude.removeEventListener(this.providerId);
@@ -62,6 +70,12 @@ class AbsoluteAttitudeComponent extends React.Component {
62
70
  window.removeEventListener('deviceorientationabsolute', this.onDeviceOrientationAbsoluteEventListener, true);
63
71
  }
64
72
 
73
+ componentWillUnmount() {
74
+ if (this.isStarted) {
75
+ this.stop();
76
+ }
77
+ }
78
+
65
79
  handleHeadingSubmit() {
66
80
  const heading = Number(this.inputHeading);
67
81
  if (!isNaN(heading)) {
@@ -77,7 +91,6 @@ class AbsoluteAttitudeComponent extends React.Component {
77
91
  );
78
92
  }
79
93
 
80
-
81
94
  render() {
82
95
 
83
96
  let rawRender = <span>Not available</span>;
@@ -109,22 +122,34 @@ class AbsoluteAttitudeComponent extends React.Component {
109
122
 
110
123
 
111
124
  return (
112
- <div>
113
- <input type="text"
114
- style={{ width: '50px' }}
115
- placeholder='Heading'
116
- pattern="[0-9]*"
117
- onChange={event => (this.inputHeading = event.target.value)}
118
- />
119
- <input type="button"
120
- style={{ marginRight: '20px' }}
121
- onClick={() => this.handleHeadingSubmit()}
122
- value="Send" />
123
- |
124
- <input type="button"
125
- style={{ marginLeft: '20px' }}
126
- onClick={() => this.handlePosSubmit()}
127
- value="Send Montpellier position" />
125
+ <div style={{ width: '100%' }}>
126
+ <div style={{ width: '100%' }}>
127
+ <input type="button"
128
+ style={{
129
+ marginLeft: 'auto',
130
+ marginRight: 'auto',
131
+ display: 'block'
132
+ }}
133
+ onClick={() => this.start()}
134
+ value="Start" />
135
+ </div>
136
+ <div style={{ marginTop: '20px' }}>
137
+ <input type="text"
138
+ style={{ width: '50px' }}
139
+ placeholder='Heading'
140
+ pattern="[0-9]*"
141
+ onChange={event => (this.inputHeading = event.target.value)}
142
+ />
143
+ <input type="button"
144
+ style={{ marginRight: '20px' }}
145
+ onClick={() => this.handleHeadingSubmit()}
146
+ value="Send" />
147
+ |
148
+ <input type="button"
149
+ style={{ marginLeft: '20px' }}
150
+ onClick={() => this.handlePosSubmit()}
151
+ value="Send Montpellier position" />
152
+ </div>
128
153
  <h3>Raw:</h3>
129
154
  {rawRender}
130
155
  <h3>Absolute attitude:</h3>
package/package.json CHANGED
@@ -8,19 +8,19 @@
8
8
  "Guillaume Pannetier <guillaume.pannetier@getwemap.com>"
9
9
  ],
10
10
  "dependencies": {
11
- "@wemap/geo": "^3.2.16",
11
+ "@wemap/geo": "^3.2.17",
12
12
  "@wemap/geomagnetism": "^0.1.1",
13
- "@wemap/graph": "^3.2.16",
14
- "@wemap/logger": "^3.2.3",
15
- "@wemap/map": "^3.2.16",
16
- "@wemap/maths": "^3.2.15",
13
+ "@wemap/graph": "^3.2.17",
14
+ "@wemap/logger": "^3.2.17",
15
+ "@wemap/map": "^3.2.17",
16
+ "@wemap/maths": "^3.2.17",
17
17
  "@wemap/utils": "^3.2.16",
18
18
  "lodash.isempty": "^4.4.0",
19
19
  "lodash.noop": "^3.0.1"
20
20
  },
21
21
  "description": "A package using different geoloc systems",
22
22
  "devDependencies": {
23
- "@wemap/osm": "^3.2.16",
23
+ "@wemap/osm": "^3.2.17",
24
24
  "mapbox-gl": "^1.11.1"
25
25
  },
26
26
  "homepage": "https://github.com/wemap/wemap-modules-js#readme",
@@ -42,6 +42,6 @@
42
42
  "url": "git+https://github.com/wemap/wemap-modules-js.git"
43
43
  },
44
44
  "type": "module",
45
- "version": "3.2.16",
46
- "gitHead": "01e6c2ed3b4f24b230cb6a774fe159e7b20b810a"
45
+ "version": "3.2.18",
46
+ "gitHead": "5b5342754059b05298d7961f78c13b8198685a85"
47
47
  }
@@ -127,7 +127,7 @@ class Provider {
127
127
  }
128
128
 
129
129
  get nativeInterface() {
130
- return global.WemapProvidersAndroid || null;
130
+ return typeof window !== 'undefined' ? (window.__nativeProviders || null) : null;
131
131
  }
132
132
 
133
133
  get useCameraNatively() {
@@ -152,6 +152,9 @@ class AbsoluteAttitudeFromBrowserProvider extends Provider {
152
152
  };
153
153
 
154
154
 
155
+ iosPreviousQuat = null;
156
+ iosIsSkyMode;
157
+
155
158
  onDeviceOrientationSafariEvent = e => {
156
159
 
157
160
  this.magQuaternionTimestamp = e.timeStamp / 1e3;
@@ -166,18 +169,49 @@ class AbsoluteAttitudeFromBrowserProvider extends Provider {
166
169
  return;
167
170
  }
168
171
 
169
- let webkitCompassHeading = -e.webkitCompassHeading;
170
- // Be Careful: webkitCompassHeading is not continuous.
171
- // Reference frame changes in function of beta with thresholds: beta > 30deg and beta < 62deg
172
- // Below 30deg, East-North-Up (ENU) frame is used
173
- // Above 62def, East-Up-South (EUS) frame is used
174
- // Between 30deg and 62deg either ENU or EUS can be used
175
- if (e.beta > 62) {
176
- webkitCompassHeading = this.constructor.headingEusToEnu(
177
- 180 - webkitCompassHeading, e.beta, e.gamma);
172
+ /**
173
+ * Trying the best to retrieve a good quaternion from devicemotion event.
174
+ */
175
+
176
+ let alpha;
177
+ const [qw, qx, qy, qz] = Rotations.eulerToQuaternionZXYDegrees([e.webkitCompassHeading, e.beta, e.gamma]);
178
+ const groundAngle = rad2deg(Math.acos(qw ** 2 - qx ** 2 - qy ** 2 + qz ** 2));
179
+
180
+ let isSkyMode;
181
+ if (groundAngle > 136) {
182
+ isSkyMode = true;
183
+ } else if (groundAngle < 134) {
184
+ isSkyMode = false;
185
+ } else if (this.iosPreviousQuat && this.iosIsSkyMode !== null) {
186
+ /**
187
+ * This condition is true only if :
188
+ * - we are in the [134°; 136°] ground angle range
189
+ * - we know the previous quaternion
190
+ * - one of the both previous condition has been reached during this session
191
+ *
192
+ * In this case, we define a threshold to detect if there is a "jump" in the quaternion calculation,
193
+ * then, the mode is switched.
194
+ */
195
+ isSkyMode = Quaternion.distance([qw, qx, qy, qz], this.iosPreviousQuat) < 0.5
196
+ ? this.iosIsSkyMode
197
+ : !this.iosIsSkyMode;
178
198
  }
179
- this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees(
180
- [webkitCompassHeading, e.beta, e.gamma]);
199
+ this.iosPreviousQuat = [qw, qx, qy, qz];
200
+ this.iosIsSkyMode = isSkyMode;
201
+
202
+ if (typeof (isSkyMode) === 'undefined') {
203
+ // Algorithm uncertainity
204
+ return;
205
+ }
206
+
207
+ if (isSkyMode) {
208
+ alpha = 180 - e.webkitCompassHeading;
209
+ } else {
210
+ alpha = AbsoluteAttitudeFromBrowserProvider.webkitCompassToHeading(
211
+ e.webkitCompassHeading, e.beta, e.gamma);
212
+ }
213
+
214
+ this.magQuaternion = Rotations.eulerToQuaternionZXYDegrees([alpha, e.beta, e.gamma]);
181
215
 
182
216
  this.compute();
183
217
  };
@@ -224,18 +258,22 @@ class AbsoluteAttitudeFromBrowserProvider extends Provider {
224
258
  this.compute();
225
259
  }
226
260
 
227
- /**
228
- * {@link https://math.stackexchange.com/questions/3181981/solve-a-system-of-rotation-matrices-z-x-z-z-x-y}
229
- */
230
- static headingEusToEnu(_alpha, _beta, _gamma) {
231
- const alpha = deg2rad(_alpha);
261
+ static webkitCompassToHeading(_webkitCompassHeading, _beta, _gamma) {
262
+ const webkitCompassHeading = deg2rad(_webkitCompassHeading);
232
263
  const beta = deg2rad(_beta);
233
264
  const gamma = deg2rad(_gamma);
234
265
 
235
- return rad2deg(Math.atan2(
236
- Math.cos(alpha) * Math.sin(gamma) + Math.cos(gamma) * Math.sin(alpha) * Math.sin(beta),
237
- Math.sin(alpha) * Math.sin(gamma) - Math.cos(alpha) * Math.cos(gamma) * Math.sin(beta)
238
- ));
266
+ const c1 = Math.cos(webkitCompassHeading / 2);
267
+ const c2 = Math.cos(beta / 2);
268
+ const c3 = Math.cos(gamma / 2);
269
+ const s1 = Math.sin(webkitCompassHeading / 2);
270
+ const s2 = Math.sin(beta / 2);
271
+ const s3 = Math.sin(gamma / 2);
272
+
273
+ const qw = c1 * c2 * c3 - s1 * s2 * s3;
274
+ const qz = s1 * c2 * c3 + c1 * s2 * s3;
275
+
276
+ return rad2deg(-2 * Math.atan(qz / qw));
239
277
  }
240
278
  }
241
279
 
@@ -74,7 +74,7 @@ class PositionSmoother {
74
74
  clearTimeout(this.timeoutNotify);
75
75
  }
76
76
  } else {
77
- this.positionsQueue.push(newPosition);
77
+ this.positionsQueue.push(newPosition.clone());
78
78
  }
79
79
 
80
80
  this.previousPosition = newPosition;