@wemap/providers 3.1.2 → 3.1.4

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 (44) hide show
  1. package/debug/Common.css +172 -0
  2. package/debug/MainComponent.jsx +64 -0
  3. package/debug/components/AbsolutePositionComponent.jsx +1 -1
  4. package/debug/components/GnssWifiComponent.jsx +1 -1
  5. package/debug/components/StartStopComponent.jsx +5 -3
  6. package/debug/components/Utils.js +4 -2
  7. package/debug/details/DetailsAttitudeComponent.jsx +121 -0
  8. package/debug/details/DetailsComponent.jsx +42 -0
  9. package/debug/details/DetailsPositionComponent.jsx +127 -0
  10. package/debug/details/ItineraryComponent.jsx +323 -0
  11. package/debug/index.js +28 -0
  12. package/debug/map/MapComponent.jsx +84 -0
  13. package/debug/map/MapHandler.js +53 -0
  14. package/debug/map/MapboxHelper.js +50 -0
  15. package/debug/map/helpers/ItineraryMapHandler.js +284 -0
  16. package/debug/map/helpers/MapClickHandler.js +119 -0
  17. package/debug/map/helpers/UserOnMapHandler.js +489 -0
  18. package/debug/stores/ItineraryStore.js +223 -0
  19. package/dist/assets/indoor-maps/bureaux-wemap-montpellier.geojson +7444 -0
  20. package/dist/{pose.html → index.html} +4 -1
  21. package/dist/js/providers-components.js +353 -209
  22. package/package.json +9 -7
  23. package/src/ProvidersInterface.js +5 -4
  24. package/src/providers/MetaProvider.js +3 -1
  25. package/src/providers/attitude/relative/RelativeAttitudeFromInertialProvider.js +1 -1
  26. package/src/providers/position/absolute/AbsolutePositionFromRelProvider.js +1 -1
  27. package/src/providers/position/absolute/AbsolutePositionProvider.js +27 -16
  28. package/src/providers/position/relative/GeoRelativePositionFromArCoreProvider.js +2 -1
  29. package/src/providers/position/relative/PdrProvider.js +2 -1
  30. package/src/smoothers/PositionSmoother.js +10 -2
  31. package/webpack/webpack.common.js +5 -5
  32. package/webpack/webpack.dev.js +7 -1
  33. package/debug/components/Common.css +0 -27
  34. package/debug/components/MapComponent.jsx +0 -366
  35. package/debug/components/PoseComponent.jsx +0 -169
  36. package/debug/components/index.js +0 -28
  37. package/src/providers/legacy/AbsolutePdrProvider.js +0 -258
  38. package/src/providers/legacy/ArCoreAbsoluteProvider.js +0 -230
  39. package/src/providers/legacy/GnssWifiPdrProvider.js +0 -217
  40. package/src/providers/legacy/MapMatchingProvider.js +0 -65
  41. package/src/providers/legacy/PdrProvider.old.js +0 -300
  42. package/src/providers/legacy/PoseProvider.js +0 -68
  43. package/src/providers/legacy/helpers/Smoother.js +0 -92
  44. package/src/providers/legacy/helpers/Smoother.spec.js +0 -426
@@ -1,366 +0,0 @@
1
- import React from 'react';
2
- import mapboxgl from 'mapbox-gl';
3
- import 'mapbox-gl/dist/mapbox-gl.css';
4
- import PropTypes from 'prop-types';
5
-
6
- import {
7
- Attitude, UserPosition, Constants
8
- } from '@wemap/geo';
9
- import { Network } from '@wemap/graph';
10
-
11
- mapboxgl.accessToken
12
- = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA';
13
-
14
- const COMPASS_STYLE = {
15
- width: '15px',
16
- height: '15px',
17
- 'border-radius': '50%',
18
- 'z-index': '10000001',
19
- position: 'absolute',
20
- top: '-14px',
21
- left: '-14px',
22
- border: '7px solid',
23
- 'border-color': 'transparent',
24
- 'border-top-color': '#008DF1',
25
- opacity: 0.5
26
- };
27
-
28
- const POSITION_STYLE = {
29
- width: '15px',
30
- height: '15px',
31
- top: '-7px',
32
- left: '-7px',
33
- position: 'absolute',
34
- 'border-radius': '50%',
35
- background: '#008DF1'
36
- };
37
-
38
- class MapComponent extends React.Component {
39
- static propTypes = {
40
- network: PropTypes.instanceOf(Network),
41
- positionRenderFrequency: PropTypes.number,
42
- centerCameraFrequency: PropTypes.number,
43
- maxZoom: PropTypes.number
44
- };
45
-
46
- static defaultProps = {
47
- maxZoom: 22,
48
- positionRenderFrequency: 60,
49
- centerCameraFrequency: 1
50
- };
51
-
52
- userAccuracySource = {
53
- 'type': 'geojson',
54
- 'data': {
55
- 'type': 'FeatureCollection',
56
- 'features': []
57
- }
58
- };
59
-
60
- followUser = true;
61
- positionDirty = false;
62
- positionForCameraDirty = false;
63
-
64
- componentDidMount() {
65
- this.map = new mapboxgl.Map({
66
- container: this.mapContainer,
67
- style: 'mapbox://styles/mapbox/streets-v9',
68
- maxZoom: this.props.maxZoom
69
- });
70
-
71
- this.createFollowingUser();
72
- this.map.on('load', () => {
73
- this.createUserAccuracyLayer();
74
- });
75
- this.renderNetwork();
76
-
77
- this.positionRenderLoopId = setInterval(this.positionRenderLoop, 1e3 / this.props.positionRenderFrequency);
78
- this.centerCameraRenderLoopId = setInterval(this.centerCameraRenderLoop, 1e3 / this.props.centerCameraFrequency);
79
- }
80
-
81
- componentWillUnmount() {
82
- clearInterval(this.positionRenderLoopId);
83
- clearInterval(this.centerCameraRenderLoopId);
84
- this.map.remove();
85
- }
86
-
87
- createMarker(options) {
88
- var elem, marker;
89
-
90
- elem = document.createElement('div');
91
- elem.style.marginLeft = '-' + options.iconAnchor[0] + 'px';
92
- elem.style.marginTop = '-' + options.iconAnchor[1] + 'px';
93
- elem.style.width = 0;
94
- elem.style.height = 0;
95
- elem.appendChild(options.dom);
96
-
97
- marker = new mapboxgl.Marker(elem);
98
- marker.setLngLat([options.longitude, options.latitude]);
99
- return marker;
100
- }
101
-
102
- createPositionMarker(position) {
103
- const coreIcon = document.createElement('div');
104
- this.applyStyleToDomElement(coreIcon, POSITION_STYLE);
105
-
106
- this.positionIcon = document.createElement('div');
107
- this.positionIcon.appendChild(coreIcon);
108
-
109
- return this.createMarker({
110
- dom: this.positionIcon,
111
- iconAnchor: [0, 0],
112
- latitude: position[1],
113
- longitude: position[0]
114
- });
115
- }
116
-
117
- createCompassElement() {
118
- if (!this.positionIcon) {
119
- throw new Error('createPositionMarker() should be called before');
120
- }
121
- this.compassIcon = document.createElement('div');
122
- this.applyStyleToDomElement(this.compassIcon, COMPASS_STYLE);
123
- this.positionIcon.appendChild(this.compassIcon);
124
- }
125
-
126
- applyStyleToDomElement(domElement, style) {
127
- for (const key in style) {
128
- if (style.hasOwnProperty(key)) {
129
- domElement.style[key] = style[key];
130
- }
131
- }
132
- }
133
-
134
- /**
135
- * @param {UserPosition} position
136
- */
137
- updatePosition(position) {
138
- if (this.position !== position) {
139
- this.positionDirty = true;
140
- this.positionForCameraDirty = true;
141
- }
142
- this.position = position;
143
- }
144
-
145
- positionRenderLoop = () => {
146
-
147
- if (!this.positionDirty) {
148
- return;
149
- }
150
-
151
- if (this.position === null) {
152
- if (this.mapMarker) {
153
- this.mapMarker.remove();
154
- this.mapMarker = null;
155
- }
156
- this.map.setLayoutProperty('user-accuracy', 'visibility', 'none');
157
- this.positionIcon = null;
158
- this.compassIcon = null;
159
- return;
160
- }
161
-
162
- const lngLat = [this.position.lng, this.position.lat];
163
-
164
- if (!this.mapMarker) {
165
- this.mapMarker = this.createPositionMarker(lngLat).addTo(this.map);
166
- } else {
167
- this.mapMarker.setLngLat(lngLat);
168
- }
169
-
170
- if (this.position.accuracy) {
171
- this.userAccuracySource.data.features = [{
172
- 'type': 'Feature',
173
- 'geometry': {
174
- 'type': 'Polygon',
175
- 'coordinates': [this.constructor.createGeoJSONCircle(lngLat, this.position.accuracy / 1e3)]
176
- }
177
- }];
178
- this.map.setLayoutProperty('user-accuracy', 'visibility', 'visible');
179
- } else {
180
- this.userAccuracySource.data.features = [];
181
- }
182
-
183
- const userAccuracySource = this.map.getSource('user-accuracy');
184
- if (userAccuracySource) {
185
- userAccuracySource.setData(this.userAccuracySource.data);
186
- }
187
- }
188
-
189
- centerCameraRenderLoop = () => {
190
-
191
- if (!this.positionForCameraDirty || !this.followUser || !this.position) {
192
- return;
193
- }
194
-
195
- this.positionForCameraDirty = false;
196
-
197
- const center = [this.position.lng, this.position.lat];
198
- let zoom = this.props.maxZoom;
199
- if (this.position.accuracy) {
200
- zoom = Math.min(Math.round(Math.log2(
201
- Constants.R_MAJOR * Math.cos(this.position.lat / 180 * Math.PI)
202
- / this.position.accuracy
203
- / 256
204
- * Math.min(this.mapContainer.offsetWidth, this.mapContainer.offsetHeight)
205
- )), this.props.maxZoom);
206
- }
207
-
208
- this.map.easeTo({
209
- center,
210
- zoom
211
- });
212
- }
213
-
214
- updateAttitude(attitude) {
215
- if (!this.positionIcon) {
216
- return;
217
- }
218
-
219
- if (!(attitude instanceof Attitude)) {
220
- if (this.compassIcon) {
221
- this.positionIcon.removeChild(this.compassIcon);
222
- }
223
- return;
224
- }
225
-
226
- if (!this.compassIcon) {
227
- this.createCompassElement();
228
- }
229
-
230
- this.positionIcon.style.transform
231
- = 'rotate(' + attitude.headingDegrees + 'deg)';
232
- }
233
-
234
- renderNetwork() {
235
- if (!this.map) {
236
- return;
237
- }
238
-
239
- const network = this.props.network;
240
-
241
- if (network === this.previousNetwork) {
242
- return;
243
- }
244
- this.previousNetwork = network;
245
-
246
- if (!network) {
247
- if (this.networkLayer) {
248
- this.map.removeLayer(this.networkLayer);
249
- this.networkLayer = null;
250
- }
251
- return;
252
- }
253
-
254
- const layer = {
255
- id: 'network',
256
- type: 'line',
257
- source: {
258
- type: 'geojson',
259
- data: {
260
- type: 'Feature',
261
- properties: {},
262
- geometry: {
263
- type: 'MultiLineString',
264
- coordinates: []
265
- }
266
- }
267
- },
268
- paint: {
269
- 'line-color': '#0000FF',
270
- 'line-width': 3
271
- }
272
- };
273
-
274
- for (let i = 0; i < network.edges.length; i++) {
275
- layer.source.data.geometry.coordinates.push([
276
- [network.edges[i].node1.coords.lng, network.edges[i].node1.coords.lat],
277
- [network.edges[i].node2.coords.lng, network.edges[i].node2.coords.lat]
278
- ]);
279
- }
280
-
281
- this.networkLayer = this.map.addLayer(layer);
282
- }
283
-
284
- createUserAccuracyLayer() {
285
- this.map.addSource('user-accuracy', this.userAccuracySource);
286
- this.map.addLayer({
287
- 'id': 'user-accuracy',
288
- 'type': 'fill',
289
- 'source': 'user-accuracy',
290
- 'layout': {},
291
- 'paint': {
292
- 'fill-color': 'blue',
293
- 'fill-opacity': 0.1
294
- }
295
- });
296
- }
297
-
298
- // https://stackoverflow.com/a/39006388/2239938
299
- static createGeoJSONCircle(center, radiusInKm, points) {
300
- if (!points) {
301
- points = 64;
302
- }
303
-
304
- var coords = {
305
- latitude: center[1],
306
- longitude: center[0]
307
- };
308
-
309
- var km = radiusInKm;
310
-
311
- var ret = [];
312
- var distanceX = km / (111.320 * Math.cos(coords.latitude * Math.PI / 180));
313
- var distanceY = km / 110.574;
314
-
315
- var theta, x, y;
316
- for (let i = 0; i < points; i++) {
317
- theta = (i / points) * (2 * Math.PI);
318
- x = distanceX * Math.cos(theta);
319
- y = distanceY * Math.sin(theta);
320
-
321
- ret.push([coords.longitude + x, coords.latitude + y]);
322
- }
323
- ret.push(ret[0]);
324
- return ret;
325
- }
326
-
327
- createFollowingUser() {
328
-
329
- const topRightContainer = document.getElementsByClassName('mapboxgl-ctrl-top-right')[0];
330
-
331
- const container = document.createElement('div');
332
- container.className = 'mapboxgl-ctrl mapboxgl-ctrl-group';
333
- topRightContainer.appendChild(container);
334
-
335
- const button = document.createElement('button');
336
- button.type = 'button';
337
- button.title = 'Find my location';
338
- button.className = 'mapboxgl-ctrl-geolocate';
339
- container.appendChild(button);
340
-
341
- const span = document.createElement('span');
342
- span.className = 'mapboxgl-ctrl-icon';
343
- button.appendChild(span);
344
-
345
- button.onclick = () => {
346
- this.followUser = true;
347
- this.positionForCameraDirty = true;
348
- this.centerCameraRenderLoop();
349
- };
350
-
351
- this.map.on('dragstart', () => (this.followUser = false));
352
- }
353
-
354
- render() {
355
- this.renderNetwork();
356
- return (
357
- <div ref={map => (this.mapContainer = map)}
358
- style={{
359
- width: '100%',
360
- height: '100%'
361
- }} />
362
- );
363
- }
364
- }
365
-
366
- export default MapComponent;
@@ -1,169 +0,0 @@
1
- import React from 'react';
2
-
3
- import {
4
- PositionSmoother, ProvidersInterface, EventType
5
- } from '../..';
6
-
7
- import Utils from './Utils';
8
- import MapComponent from './MapComponent';
9
- import NavigationConfig from './NavigationConfig';
10
-
11
- import './Common.css';
12
- import StartStopComponent from './StartStopComponent';
13
-
14
-
15
- class PoseComponent extends React.Component {
16
-
17
- started = false;
18
-
19
- constructor(props, context) {
20
- super(props, context);
21
- this.state = {
22
- position: null,
23
- attitude: null
24
- };
25
-
26
- this.smoother = new PositionSmoother(position => {
27
- if (this.map && this.started) {
28
- this.map.updatePosition(position);
29
- }
30
- });
31
-
32
- ProvidersInterface.logger = true;
33
- }
34
-
35
- componentWillUnmount() {
36
- this.onStop();
37
- }
38
-
39
- onStart = () => {
40
- this.started = true;
41
- this.onAttitudeEvent(ProvidersInterface.getLastKnown(EventType.AbsoluteAttitude));
42
- this.attitudeProviderId = ProvidersInterface.addEventListener(
43
- EventType.AbsoluteAttitude,
44
- this.onAttitudeEvent,
45
- this.onAttitudeError
46
- );
47
-
48
- this.onPositionEvent(ProvidersInterface.getLastKnown(EventType.AbsolutePosition));
49
- this.positionProviderId = ProvidersInterface.addEventListener(
50
- EventType.AbsolutePosition,
51
- this.onPositionEvent,
52
- this.onPositionError
53
- );
54
- }
55
-
56
- onStop = () => {
57
- this.started = false;
58
- ProvidersInterface.removeEventListener(this.attitudeProviderId);
59
- ProvidersInterface.removeEventListener(this.positionProviderId);
60
- this.map.updatePosition(null);
61
- this.map.updateAttitude(null);
62
- }
63
-
64
- onPositionEvent = position => {
65
- if (!position) {
66
- return;
67
- }
68
- this.setState({ position });
69
- this.smoother.feed(position);
70
- };
71
-
72
- onPositionError = error => {
73
- this.setState({ position: error });
74
- };
75
-
76
- onAttitudeEvent = attitude => {
77
- if (!attitude) {
78
- return;
79
- }
80
- this.setState({ attitude });
81
- if (this.map && this.started) {
82
- this.map.updateAttitude(attitude);
83
- }
84
- };
85
-
86
- onAttitudeError = error => {
87
- this.setState({ attitude: error });
88
- };
89
-
90
- handleHeadingButton() {
91
- ProvidersInterface.feed(EventType.AbsoluteHeading, NavigationConfig.INITIAL_HEADING);
92
- }
93
-
94
- handlePosButton() {
95
- ProvidersInterface.feed(EventType.AbsolutePosition, NavigationConfig.INITIAL_POSITION);
96
- }
97
-
98
- handleItinerary() {
99
- const itinerary = NavigationConfig.ITINERARY;
100
- ProvidersInterface.feed(EventType.Network, itinerary);
101
- this.setState({ itinerary });
102
- }
103
-
104
-
105
- render() {
106
-
107
- const errored = this.state.attitude instanceof Error
108
- && this.state.position instanceof Error;
109
-
110
- return (
111
- <div style={{
112
- display: 'flex',
113
- flexFlow: 'column',
114
- height: 'calc(100% - 16px)',
115
- padding: '8px'
116
- }}>
117
-
118
- <StartStopComponent
119
- onStart={this.onStart}
120
- onStop={this.onStop}
121
- errored={errored}
122
- />
123
-
124
- <div style={{ marginTop: '10px' }}>
125
- <input type="button"
126
- onClick={() => this.handlePosButton()}
127
- value="Send Wemap position" />
128
- <input type="button"
129
- style={{ marginLeft: '10px' }}
130
- onClick={() => this.handleHeadingButton()}
131
- value="Send heading" />
132
- <input type="button"
133
- value="Add itinerary"
134
- style={{ marginLeft: '10px' }}
135
- onClick={() => this.handleItinerary()} />
136
- </div>
137
-
138
- <div style={{
139
- display: 'flex',
140
- flexFlow: 'row'
141
- }}>
142
- <div style={{ width: '50%' }}>
143
- <div className="title">Position</div>
144
- {Utils.renderPositionEvent(this.state.position)}
145
- </div>
146
- <div style={{ width: '50%' }}>
147
- <div className="title">Attitude</div>
148
- {Utils.renderAttitudeEvent(this.state.attitude)}
149
- </div>
150
- </div>
151
-
152
- <div className="title">Map</div>
153
- <div style={{
154
- flexGrow: 1,
155
- height: '0px',
156
- minHeight: '300px'
157
- }}>
158
- <MapComponent
159
- ref={map => (this.map = map)}
160
- network={this.state.itinerary}
161
- />
162
- </div>
163
- </div >
164
-
165
- );
166
- }
167
- }
168
-
169
- export default PoseComponent;
@@ -1,28 +0,0 @@
1
- import React from 'react';
2
- import ReactDOM from 'react-dom';
3
-
4
- import AbsoluteAttitudeComponent from './AbsoluteAttitudeComponent';
5
- import AbsolutePositionComponent from './AbsolutePositionComponent';
6
- import GnssWifiComponent from './GnssWifiComponent';
7
- import ImuComponent from './ImuComponent';
8
- import InclinationComponent from './InclinationComponent';
9
- import PoseComponent from './PoseComponent';
10
- import RelativeAttitudeComponent from './RelativeAttitudeComponent';
11
- import StepDetectionComponent from './StepDetectionComponent';
12
-
13
- const createReactElement = (component, container) => ReactDOM.render(
14
- React.createElement(component, {}, null),
15
- container
16
- );
17
-
18
- export {
19
- AbsoluteAttitudeComponent,
20
- AbsolutePositionComponent,
21
- ImuComponent,
22
- InclinationComponent,
23
- GnssWifiComponent,
24
- PoseComponent,
25
- RelativeAttitudeComponent,
26
- StepDetectionComponent,
27
- createReactElement
28
- };