@wemap/positioning 2.2.0 → 2.3.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.
@@ -0,0 +1,16 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+
4
+ <head>
5
+ <meta charset="utf-8">
6
+ <meta name="viewport" content="width=device-width, user-scalable=no">
7
+ <title>Debug ARCore Absolute</title>
8
+ <script src="/js/positioning-components.js"></script>
9
+ </head>
10
+
11
+ <body>
12
+ <div id="app"></div>
13
+ <script>createReactElement(ArCoreAbsoluteComponent, document.getElementById('app'));</script>
14
+ </body>
15
+
16
+ </html>
package/package.json CHANGED
@@ -81,5 +81,5 @@
81
81
  "lint": "eslint --ext .js,.jsx --quiet src",
82
82
  "test": "mocha -r esm \"src/**/*.spec.js\""
83
83
  },
84
- "version": "2.2.0"
84
+ "version": "2.3.0"
85
85
  }
@@ -5,6 +5,7 @@ import PoseProvider from './providers/pose/PoseProvider';
5
5
  import ProviderOptions from './providers/ProviderOptions';
6
6
  import InclinationProvider from './providers/others/InclinationProvider';
7
7
  import Logger from '@wemap/logger';
8
+ import ArCoreAbsoluteProvider from './providers/pose/ArCoreAbsoluteProvider';
8
9
 
9
10
  /**
10
11
  * @private
@@ -55,12 +56,25 @@ class PositioningHandler {
55
56
  .every(elem => eventsType.includes(elem));
56
57
 
57
58
  if (wantPoseProvider) {
58
- if (options.ignoreProviders.includes(PdrProvider)) {
59
+
60
+ const arCoreAvailable = ArCoreAbsoluteProvider.checkAvailabilityErrors().length === 0;
61
+
62
+ if ((options.ignoreProviders.includes(PdrProvider)
63
+ && options.ignoreProviders.includes(ArCoreAbsoluteProvider))
64
+ || (!options.ignoreProviders.includes(ArCoreAbsoluteProvider)
65
+ && !arCoreAvailable)) {
59
66
  return PoseProvider;
60
67
  }
68
+
61
69
  if (options.waitInputPosition) {
62
- return PdrProvider;
70
+ if (!options.ignoreProviders.includes(ArCoreAbsoluteProvider) && arCoreAvailable) {
71
+ return ArCoreAbsoluteProvider;
72
+ }
73
+ if (!options.ignoreProviders.includes(PdrProvider)) {
74
+ return PdrProvider;
75
+ }
63
76
  }
77
+
64
78
  return GnssWifiPdrProvider;
65
79
  }
66
80
  if (eventsType.includes(EventType.Inclination)) {
@@ -85,10 +99,10 @@ class PositioningHandler {
85
99
  if (!provider) {
86
100
  throw new Error('Unknown provider');
87
101
  }
88
- if (!provider.setLocation) {
89
- Logger.warn('Cannot set location to ' + provider.constructor.name);
102
+ if (!provider.setPosition) {
103
+ Logger.warn('Cannot set position to ' + provider.constructor.name);
90
104
  }
91
- provider.setLocation(position);
105
+ provider.setPosition(position);
92
106
  }
93
107
 
94
108
  /**
@@ -6,7 +6,7 @@ import AbsoluteAttitudeProvider from '../providers/attitude/AbsoluteAttitudeProv
6
6
  import Utils from './Utils';
7
7
  import EventType from '../events/EventType';
8
8
 
9
- const userLocation = new WGS84(43.609275, 3.884236);
9
+ const userPosition = new WGS84(43.609275, 3.884236);
10
10
 
11
11
  class AbsoluteAttitudeComponent extends React.Component {
12
12
 
@@ -20,7 +20,7 @@ class AbsoluteAttitudeComponent extends React.Component {
20
20
  };
21
21
 
22
22
  this.absoluteAttitudeProvider = new AbsoluteAttitudeProvider(this.onEvent, this.onError);
23
- this.absoluteAttitudeProvider.setLocation(userLocation);
23
+ this.absoluteAttitudeProvider.setPosition(userPosition);
24
24
  }
25
25
 
26
26
  componentDidMount() {
@@ -0,0 +1,100 @@
1
+ import React from 'react';
2
+ import isEmpty from 'lodash.isempty';
3
+
4
+ import EventType from '../events/EventType';
5
+ import Utils from './Utils';
6
+ import ArCoreAbsoluteProvider from '../providers/pose/ArCoreAbsoluteProvider';
7
+ import { deg2rad } from '@wemap/maths';
8
+ import {
9
+ WGS84UserPosition, Itinerary
10
+ } from '@wemap/geo';
11
+ import MapComponent from './MapComponent';
12
+
13
+ const INITIAL_POSITION = new WGS84UserPosition(43.6091955, 3.8841255);
14
+ const INITIAL_HEADING = 191.9;
15
+ const ITINERARY = Itinerary.fromPoints([
16
+ [INITIAL_POSITION.lat, INITIAL_POSITION.lng],
17
+ [43.6091883, 3.8841242],
18
+ [43.6091709, 3.8842382],
19
+ [43.6091288, 3.884226],
20
+ [43.6091461, 3.884112]
21
+ ], false);
22
+
23
+ class ArCoreAbsoluteComponent extends React.Component {
24
+
25
+ constructor(props, context) {
26
+ super(props, context);
27
+ this.state = {
28
+ position: null,
29
+ attitude: null
30
+ };
31
+
32
+ this.arCoreAbsoluteProvider = new ArCoreAbsoluteProvider(this.onEvent, this.onError);
33
+ this.arCoreAbsoluteProvider.setPosition(INITIAL_POSITION);
34
+ this.arCoreAbsoluteProvider.setHeading(deg2rad(INITIAL_HEADING));
35
+
36
+ }
37
+
38
+ componentDidMount() {
39
+ this.arCoreAbsoluteProvider.start();
40
+ }
41
+
42
+ componentWillUnmount() {
43
+ this.arCoreAbsoluteProvider.stop();
44
+ }
45
+
46
+ onEvent = events => {
47
+ const newState = {};
48
+ events.forEach(event => {
49
+ if (event.dataType === EventType.AbsolutePosition) {
50
+ newState.position = event.data;
51
+ } else if (event.dataType === EventType.AbsoluteAttitude) {
52
+ newState.attitude = event.data;
53
+ }
54
+ });
55
+ if (!isEmpty(newState)) {
56
+ this.setState(newState);
57
+ }
58
+
59
+ if (this.map) {
60
+ this.map.parseEvents(events);
61
+ }
62
+ };
63
+
64
+ onError = events => {
65
+ const newState = {};
66
+ events.forEach(event => {
67
+ if (event.dataType === EventType.AbsolutePosition) {
68
+ newState.position = event.error;
69
+ } else if (event.dataType === EventType.AbsoluteAttitude) {
70
+ newState.attitude = event.error;
71
+ }
72
+ });
73
+ if (!isEmpty(newState)) {
74
+ this.setState(newState);
75
+ }
76
+ }
77
+
78
+ render() {
79
+
80
+ const attitudeRender = Utils.renderAttitude(this.state.attitude);
81
+ const positionRender = Utils.renderPosition(this.state.position);
82
+
83
+ return (
84
+ <div>
85
+ <h3>Position</h3>
86
+ {positionRender}
87
+ <h3>Attitude</h3>
88
+ {attitudeRender}
89
+ <h3>Map</h3>
90
+ <MapComponent
91
+ ref={map => (this.map = map)}
92
+ defaultZoom={21}
93
+ network={ITINERARY} />
94
+ </div>
95
+
96
+ );
97
+ }
98
+ }
99
+
100
+ export default ArCoreAbsoluteComponent;
@@ -14,16 +14,16 @@ class ArCoreComponent extends React.Component {
14
14
  attitude: null
15
15
  };
16
16
 
17
- this.poseProvider = new ArCoreProvider(this.onEvent, this.onError);
17
+ this.arCoreProvider = new ArCoreProvider(this.onEvent, this.onError);
18
18
  }
19
19
 
20
20
 
21
21
  componentDidMount() {
22
- this.poseProvider.start();
22
+ this.arCoreProvider.start();
23
23
  }
24
24
 
25
25
  componentWillUnmount() {
26
- this.poseProvider.stop();
26
+ this.arCoreProvider.stop();
27
27
  }
28
28
 
29
29
  onEvent = events => {
@@ -10,9 +10,9 @@ import EventType from '../events/EventType';
10
10
  import GnssWifiPdrProvider from '../providers/pose/GnssWifiPdrProvider';
11
11
  import MapComponent from './MapComponent';
12
12
 
13
- const INITIAL_LOCATION = new WGS84UserPosition(43.6091955, 3.8841255);
13
+ const INITIAL_POSITION = new WGS84UserPosition(43.6091955, 3.8841255);
14
14
  const ITINERARY = Itinerary.fromPoints([
15
- [INITIAL_LOCATION.lat, INITIAL_LOCATION.lng],
15
+ [INITIAL_POSITION.lat, INITIAL_POSITION.lng],
16
16
  [43.6091883, 3.8841242],
17
17
  [43.6091709, 3.8842382],
18
18
  [43.6091288, 3.884226],
@@ -25,7 +25,7 @@ const COMPASS_STYLE = {
25
25
  'opacity': 0.5
26
26
  };
27
27
 
28
- const LOCATION_STYLE = {
28
+ const POSITION_STYLE = {
29
29
  'width': '15px',
30
30
  'height': '15px',
31
31
  'top': '-7px',
@@ -38,14 +38,19 @@ const LOCATION_STYLE = {
38
38
 
39
39
  class MapComponent extends React.Component {
40
40
 
41
- static propTypes = { network: PropTypes.instanceOf(Network) };
41
+ static propTypes = {
42
+ network: PropTypes.instanceOf(Network),
43
+ defaultZoom: PropTypes.number
44
+ };
42
45
 
46
+ static defaultProps = {defaultZoom: 19};
43
47
 
44
48
  componentDidMount() {
45
49
  this.map = new mapboxgl.Map({
46
50
  container: this.mapContainer,
47
51
  style: 'mapbox://styles/mapbox/streets-v9'
48
52
  });
53
+ this.renderNetwork();
49
54
  }
50
55
 
51
56
  componentWillUnmount() {
@@ -67,28 +72,28 @@ class MapComponent extends React.Component {
67
72
  return marker;
68
73
  }
69
74
 
70
- createLocationMarker(location) {
75
+ createPositionMarker(position) {
71
76
  const coreIcon = document.createElement('div');
72
- this.applyStyleToDomElement(coreIcon, LOCATION_STYLE);
77
+ this.applyStyleToDomElement(coreIcon, POSITION_STYLE);
73
78
 
74
- this.locationIcon = document.createElement('div');
75
- this.locationIcon.appendChild(coreIcon);
79
+ this.positionIcon = document.createElement('div');
80
+ this.positionIcon.appendChild(coreIcon);
76
81
 
77
82
  return this.createMarker({
78
- dom: this.locationIcon,
83
+ dom: this.positionIcon,
79
84
  iconAnchor: [0, 0],
80
- latitude: location[1],
81
- longitude: location[0]
85
+ latitude: position[1],
86
+ longitude: position[0]
82
87
  });
83
88
  }
84
89
 
85
90
  createCompassElement() {
86
- if (!this.locationIcon) {
87
- throw new Error('createLocationMarker() should be called before');
91
+ if (!this.positionIcon) {
92
+ throw new Error('createPositionMarker() should be called before');
88
93
  }
89
94
  this.compassIcon = document.createElement('div');
90
95
  this.applyStyleToDomElement(this.compassIcon, COMPASS_STYLE);
91
- this.locationIcon.appendChild(this.compassIcon);
96
+ this.positionIcon.appendChild(this.compassIcon);
92
97
  }
93
98
 
94
99
  applyStyleToDomElement(domElement, style) {
@@ -123,7 +128,7 @@ class MapComponent extends React.Component {
123
128
  if (this.mapMarker) {
124
129
  this.mapMarker.remove();
125
130
  this.mapMarker = null;
126
- this.locationIcon = null;
131
+ this.positionIcon = null;
127
132
  }
128
133
  return;
129
134
  }
@@ -131,11 +136,11 @@ class MapComponent extends React.Component {
131
136
  const lngLat = [position.lng, position.lat];
132
137
 
133
138
  if (!this.mapMarker) {
134
- this.mapMarker = this.createLocationMarker(lngLat)
139
+ this.mapMarker = this.createPositionMarker(lngLat)
135
140
  .addTo(this.map);
136
141
  this.map.jumpTo({
137
142
  center: lngLat,
138
- zoom: 19
143
+ zoom: this.props.defaultZoom
139
144
  });
140
145
  } else {
141
146
  this.mapMarker.setLngLat(lngLat);
@@ -145,13 +150,13 @@ class MapComponent extends React.Component {
145
150
 
146
151
  updateAttitude(attitude) {
147
152
 
148
- if (!this.locationIcon) {
153
+ if (!this.positionIcon) {
149
154
  return;
150
155
  }
151
156
 
152
157
  if (!(attitude instanceof Attitude)) {
153
158
  if (this.compassIcon) {
154
- this.locationIcon.removeChild(this.compassIcon);
159
+ this.positionIcon.removeChild(this.compassIcon);
155
160
  }
156
161
  return;
157
162
  }
@@ -160,7 +165,7 @@ class MapComponent extends React.Component {
160
165
  this.createCompassElement();
161
166
  }
162
167
 
163
- this.locationIcon.style.transform = 'rotate(' + attitude.headingDegrees + 'deg)';
168
+ this.positionIcon.style.transform = 'rotate(' + attitude.headingDegrees + 'deg)';
164
169
  }
165
170
 
166
171
  renderNetwork() {
@@ -171,6 +176,11 @@ class MapComponent extends React.Component {
171
176
 
172
177
  const network = this.props.network;
173
178
 
179
+ if (network === this.previousNetwork) {
180
+ return;
181
+ }
182
+ this.previousNetwork = network;
183
+
174
184
  if (!network) {
175
185
  if (this.networkLayer) {
176
186
  this.map.removeLayer(this.networkLayer);
@@ -207,6 +217,7 @@ class MapComponent extends React.Component {
207
217
  ]
208
218
  );
209
219
  }
220
+
210
221
  this.map.on('load', () => {
211
222
  this.networkLayer = this.map.addLayer(layer);
212
223
  });
@@ -10,10 +10,10 @@ import PdrProvider from '../providers/pose/pdr/PdrProvider';
10
10
  import EventType from '../events/EventType';
11
11
  import MapComponent from './MapComponent';
12
12
 
13
- const INITIAL_LOCATION = new WGS84UserPosition(43.6091955, 3.8841255);
13
+ const INITIAL_POSITION = new WGS84UserPosition(43.6091955, 3.8841255);
14
14
  const INITIAL_HEADING = 191.9;
15
15
  const ITINERARY = Itinerary.fromPoints([
16
- [INITIAL_LOCATION.lat, INITIAL_LOCATION.lng],
16
+ [INITIAL_POSITION.lat, INITIAL_POSITION.lng],
17
17
  [43.6091883, 3.8841242],
18
18
  [43.6091709, 3.8842382],
19
19
  [43.6091288, 3.884226],
@@ -31,7 +31,7 @@ class PdrComponent extends React.Component {
31
31
 
32
32
 
33
33
  componentDidMount() {
34
- this.pdrProvider.setLocation(INITIAL_LOCATION);
34
+ this.pdrProvider.setPosition(INITIAL_POSITION);
35
35
  this.pdrProvider.setHeading(INITIAL_HEADING);
36
36
  this.pdrProvider.enableMapMatching(ITINERARY);
37
37
  this.pdrProvider.start();
@@ -11,10 +11,10 @@ import {
11
11
  } from '@wemap/geo';
12
12
  import MapComponent from './MapComponent';
13
13
 
14
- const INITIAL_LOCATION = new WGS84UserPosition(43.6091955, 3.8841255);
14
+ const INITIAL_POSITION = new WGS84UserPosition(43.6091955, 3.8841255);
15
15
  const INITIAL_HEADING = 191.9;
16
16
  const ITINERARY = Itinerary.fromPoints([
17
- [INITIAL_LOCATION.lat, INITIAL_LOCATION.lng],
17
+ [INITIAL_POSITION.lat, INITIAL_POSITION.lng],
18
18
  [43.6091883, 3.8841242],
19
19
  [43.6091709, 3.8842382],
20
20
  [43.6091288, 3.884226],
@@ -47,7 +47,7 @@ class PositioningPoseComponent extends React.Component {
47
47
  );
48
48
 
49
49
  setTimeout(() => {
50
- this.props.positioningHandler.setPosition(this.id, INITIAL_LOCATION);
50
+ this.props.positioningHandler.setPosition(this.id, INITIAL_POSITION);
51
51
  this.props.positioningHandler.setHeading(this.id, INITIAL_HEADING);
52
52
  this.props.positioningHandler.setItinerary(this.id, ITINERARY);
53
53
  }, 3000);
@@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
3
3
 
4
4
  import AbsoluteAttitudeComponent from './AbsoluteAttitudeComponent';
5
5
  import ArCoreComponent from './ArCoreComponent';
6
+ import ArCoreAbsoluteComponent from './ArCoreAbsoluteComponent';
6
7
  import GnssWifiComponent from './GnssWifiComponent';
7
8
  import GnssWifiPdrComponent from './GnssWifiPdrComponent';
8
9
  import ImuComponent from './ImuComponent';
@@ -20,6 +21,7 @@ const createReactElement = (component, container) => ReactDOM.render(
20
21
  export {
21
22
  AbsoluteAttitudeComponent,
22
23
  ArCoreComponent,
24
+ ArCoreAbsoluteComponent,
23
25
  ImuComponent,
24
26
  InclinationComponent,
25
27
  GnssWifiComponent,
@@ -215,10 +215,10 @@ class Provider {
215
215
 
216
216
 
217
217
  static hasNativeInterface() {
218
- return Boolean(Provider.getNativeInterface());
218
+ return Boolean(Provider.nativeInterface);
219
219
  }
220
220
 
221
- static getNativeInterface() {
221
+ static get nativeInterface() {
222
222
  return global.WemapProvidersAndroid;
223
223
  }
224
224
 
@@ -2,7 +2,7 @@ const ProviderOptions = {
2
2
 
3
3
  /**
4
4
  * Does provider have to wait an input position to start
5
- * @see PositioningHandler#setLocation()
5
+ * @see PositioningHandler#setPosition()
6
6
  */
7
7
  waitInputPosition: false,
8
8
 
@@ -162,8 +162,8 @@ class AbsoluteAttitudeProvider extends Provider {
162
162
  onDeviceOrientationCommonEvent = (timestamp, quaternion) => {
163
163
 
164
164
  if (!this.declinationQuaternion) {
165
- Logger.warn('Location of AbsoluteAttitude provider is not set yet. '
166
- + 'Please call setLocation() before.');
165
+ Logger.warn('Position of AbsoluteAttitude provider is not set yet. '
166
+ + 'Please call setPosition() before.');
167
167
  return;
168
168
  }
169
169
  const trueQuaternion = Quaternion.multiply(this.declinationQuaternion, quaternion);
@@ -178,13 +178,13 @@ class AbsoluteAttitudeProvider extends Provider {
178
178
  }
179
179
 
180
180
  /**
181
- * Initialized declination quaternion using current location.
181
+ * Initialized declination quaternion using current position.
182
182
  * This method should be theoretically called every time the user moves.
183
183
  * But in reality declination does not change as much.
184
- * @param {WGS84} location user location
184
+ * @param {WGS84} position user position
185
185
  */
186
- setLocation(location) {
187
- const wmmResult = geomagnetism.model().point([location.lat, location.lng]);
186
+ setPosition(position) {
187
+ const wmmResult = geomagnetism.model().point([position.lat, position.lng]);
188
188
  // Declination is given in NED frame and our code use ENU, that is why we have: "-decl"
189
189
  this.declinationQuaternion = Quaternion.fromAxisAngle([0, 0, 1], - deg2rad(wmmResult.decl));
190
190
  }
@@ -6,10 +6,10 @@ import {
6
6
  class MapMatchingProvider extends Provider {
7
7
 
8
8
  /**
9
- * Enable LocationSource mapmatching
9
+ * Enable mapmatching
10
10
  * @param {*} network a network which will be used for map matching
11
- * @param {*} maxDistance max distance between location and network to match. null disables maxDistance (default: null)
12
- * @param {*} maxAngleBearing threshold to match a parallel segment for angle between location bearing and segment. null disables this threshold (default: null)
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
13
  * @public
14
14
  */
15
15
  enableMapMatching(network, maxDistance, maxAngleBearing) {
@@ -23,7 +23,7 @@ class MapMatchingProvider extends Provider {
23
23
  }
24
24
 
25
25
  /**
26
- * Update the LocationSource network for mapmatching
26
+ * Update the network for mapmatching
27
27
  * @param {Network} network a network instance
28
28
  * @public
29
29
  */
@@ -47,26 +47,26 @@ class MapMatchingProvider extends Provider {
47
47
  }
48
48
 
49
49
  /**
50
- * Returns projection of a location on network
51
- * @param {WGS84} location if location is null, projection of this.pose.location is used
52
- * @returns The projected location {WGS84} or null.
50
+ * Returns projection of a position on network
51
+ * @param {WGS84} position if position is null, projection of this.position is used
52
+ * @returns The projected position {WGS84} or null.
53
53
  * @public
54
54
  */
55
- getProjectionOnNetwork(location = null) {
55
+ getProjectionOnNetwork(position = null) {
56
56
 
57
57
  if (!this.mapMatching) {
58
58
  return null;
59
59
  }
60
60
 
61
- let locationToProject = location;
62
- if (!location) {
63
- locationToProject = this.pose.location;
61
+ let positionToProject = position;
62
+ if (!position) {
63
+ positionToProject = this.position;
64
64
  }
65
- if (!locationToProject) {
65
+ if (!positionToProject) {
66
66
  return null;
67
67
  }
68
68
 
69
- return this.mapMatching.getProjection(locationToProject, false, false);
69
+ return this.mapMatching.getProjection(positionToProject, false, false);
70
70
  }
71
71
 
72
72
 
@@ -75,7 +75,7 @@ class MapMatchingProvider extends Provider {
75
75
  */
76
76
 
77
77
  /**
78
- * Update itinerary of Location Source.
78
+ * Update itinerary.
79
79
  * Itinerary is different from network, it is not used for mapmatching. It can be used for others tricks like HeadingUnlocker
80
80
  * @param {Itinerary} itinerary a given itinerary
81
81
  * @public
@@ -89,17 +89,17 @@ class MapMatchingProvider extends Provider {
89
89
 
90
90
 
91
91
  /**
92
- * Returns projection and itinerary info of a location on network
93
- * @param {WGS84} location if location is null, projection of this.pose.location is used
94
- * @returns An object of the projected location and itinerary info or null.
92
+ * Returns projection and itinerary info of a position on network
93
+ * @param {WGS84} position if position is null, projection of this.position is used
94
+ * @returns An object of the projected position and itinerary info or null.
95
95
  * @public
96
96
  */
97
- getItineraryInfo(location = null) {
97
+ getItineraryInfo(position = null) {
98
98
 
99
99
  if (!this.itinerary) {
100
100
  throw new Error('No itinerary found');
101
101
  }
102
- const projection = this.getProjectionOnNetwork(location);
102
+ const projection = this.getProjectionOnNetwork(position);
103
103
  if (!projection) {
104
104
  return null;
105
105
  }