@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
@@ -0,0 +1,323 @@
1
+ import PropTypes from 'prop-types';
2
+ import React from 'react';
3
+
4
+ import { Level } from '@wemap/geo';
5
+
6
+ import ItineraryStore from '../stores/ItineraryStore';
7
+ import MapHandler from '../map/MapHandler';
8
+
9
+ const ItineraryServers = ItineraryStore.Servers;
10
+
11
+ const Mode = {
12
+ Config: 'config',
13
+ WaitUserPositionForStart: 'wait-user-position-for-start',
14
+ SelectStartOnMap: 'select-start-on-map',
15
+ SelectEndOnMap: 'select-end-on-map',
16
+ ItineraryCompute: 'itinerary-compute',
17
+ Itinerary: 'itinerary'
18
+ };
19
+
20
+ const ItineraryEvents = ItineraryStore.Events;
21
+
22
+ class ItineraryComponent extends React.PureComponent {
23
+
24
+ static propTypes = { mapHandler: PropTypes.instanceOf(MapHandler) };
25
+
26
+
27
+ constructor(props, context) {
28
+ super(props, context);
29
+
30
+ this.itineraryStore = ItineraryStore.instance;
31
+
32
+ this.state = {
33
+ endLevel: '',
34
+ error: null,
35
+ mode: this.itineraryStore.itinerary ? Mode.Itinerary : Mode.Config
36
+ };
37
+
38
+ }
39
+
40
+ componentDidMount() {
41
+ this.itineraryStore.on(ItineraryEvents.StartChanged, () => this.forceUpdate());
42
+ this.itineraryStore.on(ItineraryEvents.EndChanged, () => this.forceUpdate());
43
+ this.itineraryStore.on(ItineraryEvents.ItineraryChanged, it => this.onItineraryChanged(it));
44
+ this.itineraryStore.on(ItineraryEvents.ItineraryServerChanged, () => this.forceUpdate());
45
+ this.itineraryStore.on(ItineraryEvents.UseStairsChanged, () => this.forceUpdate());
46
+ this.itineraryStore.on(ItineraryEvents.ItineraryNotFound, () => this.setState({ error: ItineraryEvents.ItineraryNotFound }));
47
+ this.itineraryStore.on(ItineraryEvents.ServerError, () => this.setState({ error: ItineraryEvents.ServerError }));
48
+
49
+ if (this.props.mapHandler) {
50
+ this.initMapHandler();
51
+ }
52
+ }
53
+
54
+ componentDidUpdate(prevProps, prevState) {
55
+ if (prevProps.mapHandler !== this.props.mapHandler && this.props.mapHandler !== null) {
56
+ this.initMapHandler();
57
+ }
58
+
59
+ if (prevState.mode !== this.state.mode) {
60
+ if (this.state.mode === Mode.SelectStartOnMap || this.state.mode === Mode.SelectEndOnMap) {
61
+ this.props.mapHandler.needClick();
62
+ }
63
+ }
64
+ }
65
+
66
+ initMapHandler() {
67
+ this.props.mapHandler.onMapClick(coords => this.onMapClick(coords));
68
+
69
+ const transformLevel = mapLevel => mapLevel === null ? '' : mapLevel.toString();
70
+ const map = this.props.mapHandler.mapboxInstance;
71
+ this.setState({ endLevel: transformLevel(map.getLevel()) });
72
+ map.on('level', () => this.setState({ endLevel: transformLevel(map.getLevel()) }));
73
+ }
74
+
75
+ onItineraryChanged(itinerary) {
76
+ if (itinerary) {
77
+ this.setState({ mode: Mode.Itinerary });
78
+ } else {
79
+ this.setState({ mode: Mode.Config });
80
+ }
81
+ }
82
+
83
+ onMapClick(position) {
84
+ if (this.state.mode === Mode.SelectStartOnMap) {
85
+ this.itineraryStore.start = position;
86
+ this.setState({ mode: Mode.Config });
87
+ } else if (this.state.mode === Mode.SelectEndOnMap) {
88
+ if (this.itineraryStore.itineraryServer === ItineraryServers.Indoor
89
+ && this.state.endLevel !== ''
90
+ ) {
91
+ position.level = Level.fromString(this.state.endLevel);
92
+ }
93
+ this.itineraryStore.end = position;
94
+ this.setState({ mode: Mode.Config });
95
+ }
96
+ }
97
+
98
+ onUseUserPositionClick() {
99
+ this.setState({ mode: Mode.WaitUserPositionForStart });
100
+ this.itineraryStore.retrieveStartFromUserLocation().then(() => {
101
+ this.setState({ mode: Mode.Config });
102
+ });
103
+ }
104
+
105
+ render() {
106
+
107
+ const configMode = this.state.mode !== Mode.Itinerary;
108
+
109
+ return (
110
+ <div>
111
+ <div className="title">Itinerary</div>
112
+ {configMode ? this.renderConfig() : this.renderItinerary()}
113
+ </div>
114
+ );
115
+ }
116
+
117
+ renderItinerary() {
118
+ return (
119
+ <button
120
+ value=''
121
+ onClick={() => this.itineraryStore.remove()}>
122
+ Remove itinerary
123
+ </button>
124
+ );
125
+ }
126
+
127
+ renderConfig() {
128
+
129
+ const handleComputeClick = () => {
130
+ this.itineraryStore.compute();
131
+ this.setState({ itineraryNotFound: false });
132
+ };
133
+
134
+ const lockedMode = this.state.mode === Mode.SelectEndOnMap
135
+ || this.state.mode === Mode.SelectStartOnMap
136
+ || this.state.mode === Mode.WaitUserPositionForStart
137
+ || this.state.mode === Mode.ItineraryCompute;
138
+
139
+ return (
140
+ <div>
141
+ {this.state.error
142
+ ? <div style={{
143
+ marginBottom: '5px',
144
+ color: 'red'
145
+ }}>
146
+ {this.state.error === ItineraryEvents.ItineraryNotFound
147
+ ? 'Itinerary not found'
148
+ : 'Server error'
149
+ }
150
+ </div>
151
+ : null}
152
+ <div>
153
+ {this.renderServer()}
154
+ </div>
155
+
156
+ <div style={{ marginTop: '5px' }}>
157
+ {this.renderStart(lockedMode)}
158
+ </div>
159
+
160
+ <div style={{ marginTop: '5px' }}>
161
+ {this.renderEnd(lockedMode)}
162
+ </div>
163
+
164
+ <div style={{
165
+ marginTop: '10px',
166
+ width: '100%',
167
+ textAlign: 'center'
168
+ }}>
169
+ <button
170
+ disabled={!this.itineraryStore.start || !this.itineraryStore.end || lockedMode}
171
+ onClick={handleComputeClick}
172
+ >
173
+ Compute
174
+ </button>
175
+ </div>
176
+
177
+ </div>
178
+ );
179
+ }
180
+
181
+ renderServer() {
182
+
183
+ const serversList = Object.values(ItineraryServers);
184
+ const serverValue = serversList.indexOf(this.itineraryStore.itineraryServer);
185
+
186
+ const handleServerSelectChange = (event) => {
187
+ const server = serversList[event.target.value];
188
+ this.itineraryStore.itineraryServer = server;
189
+ };
190
+
191
+ const isIndoor = this.itineraryStore.itineraryServer === ItineraryServers.Indoor;
192
+
193
+ return (
194
+ <>
195
+ Server:
196
+ <select
197
+ style={{ marginLeft: '5px' }}
198
+ value={serverValue}
199
+ onChange={handleServerSelectChange}>
200
+ {
201
+ serversList.map((server, index) =>
202
+ <option key={index}
203
+ value={index}>
204
+ {server.name}
205
+ </option>
206
+ )
207
+ }
208
+ </select>
209
+
210
+ {isIndoor ? (
211
+ <img id='wheelchair-icon'
212
+ className={!this.itineraryStore.useStairs ? 'selected' : null}
213
+ onClick={() => (this.itineraryStore.useStairs = !this.itineraryStore.useStairs)} />
214
+ ) : null}
215
+ </>
216
+ );
217
+ }
218
+
219
+ renderStart(lockedMode) {
220
+
221
+ let buttons;
222
+
223
+ if (this.itineraryStore.start) {
224
+ buttons = (
225
+ <button
226
+ disabled={lockedMode}
227
+ style={{ backgroundColor: '#e57373' }}
228
+ onClick={() => (this.itineraryStore.start = null)}
229
+ >
230
+ Remove
231
+ </button>
232
+ );
233
+ } else {
234
+ buttons = (
235
+ <>
236
+ <button
237
+ disabled={lockedMode}
238
+ onClick={() => this.onUseUserPositionClick()}
239
+ >
240
+ {
241
+ this.state.mode === Mode.WaitUserPositionForStart ? (
242
+ <div className="loader"
243
+ style={{ marginRight: '5px' }}></div>
244
+ ) : null
245
+ }
246
+ User position
247
+ </button>
248
+
249
+ <button
250
+ disabled={lockedMode}
251
+ style={{ marginLeft: '5px' }}
252
+ onClick={() => this.setState({ mode: Mode.SelectStartOnMap })}
253
+ >
254
+ Select on map
255
+ </button>
256
+ </>
257
+ );
258
+ }
259
+
260
+ return (
261
+ <>
262
+ Start:
263
+ <span style={{ marginLeft: '5px' }}>{buttons}</span>
264
+ </>
265
+ );
266
+ }
267
+
268
+ renderEnd(lockedMode) {
269
+
270
+ let buttons;
271
+
272
+ if (this.itineraryStore.end) {
273
+ buttons = (
274
+ <button
275
+ disabled={lockedMode}
276
+ style={{ backgroundColor: '#e57373' }}
277
+ onClick={() => (this.itineraryStore.end = null)}
278
+ >
279
+ Remove
280
+ </button>
281
+ );
282
+ } else {
283
+ buttons = (
284
+ <button
285
+ disabled={lockedMode}
286
+ onClick={() => this.setState({ mode: Mode.SelectEndOnMap })}
287
+ >
288
+ Select on map
289
+ </button>
290
+ );
291
+ }
292
+
293
+ const isIndoor = this.itineraryStore.itineraryServer === ItineraryServers.Indoor;
294
+ const showEndLevel = isIndoor && !this.itineraryStore.end;
295
+
296
+ return (
297
+ <>
298
+ <div>
299
+ End:
300
+ <span style={{ marginLeft: '5px' }}>{buttons}</span>
301
+ {
302
+ showEndLevel ? (
303
+ <span style={{ marginLeft: '5px' }}>
304
+ level:
305
+ <input
306
+ disabled={lockedMode && !this.state.mode === Mode.SelectEndOnMap}
307
+ value={this.state.endLevel}
308
+ onChange={event => this.setState({ endLevel: event.target.value })}
309
+ style={{
310
+ marginLeft: '5px',
311
+ width: '30px'
312
+ }}
313
+ type='number' />
314
+ </span>
315
+ ) : null
316
+ }
317
+ </div>
318
+ </>
319
+ );
320
+ }
321
+ }
322
+
323
+ export default ItineraryComponent;
package/debug/index.js ADDED
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import ReactDOM from 'react-dom';
3
+
4
+ import AbsoluteAttitudeComponent from './components/AbsoluteAttitudeComponent';
5
+ import AbsolutePositionComponent from './components/AbsolutePositionComponent';
6
+ import GnssWifiComponent from './components/GnssWifiComponent';
7
+ import ImuComponent from './components/ImuComponent';
8
+ import InclinationComponent from './components/InclinationComponent';
9
+ import MainComponent from './MainComponent';
10
+ import RelativeAttitudeComponent from './components/RelativeAttitudeComponent';
11
+ import StepDetectionComponent from './components/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
+ MainComponent,
25
+ RelativeAttitudeComponent,
26
+ StepDetectionComponent,
27
+ createReactElement
28
+ };
@@ -0,0 +1,84 @@
1
+ import React from 'react';
2
+ import mapboxgl from 'mapbox-gl';
3
+ import 'mapbox-gl-css';
4
+ import PropTypes from 'prop-types';
5
+ import noop from 'lodash.noop';
6
+
7
+ import MapHandler from './MapHandler';
8
+
9
+ mapboxgl.accessToken
10
+ = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA';
11
+
12
+ const BELOW_LAYER_ID = 'housenum-label';
13
+
14
+ class MapComponent extends React.Component {
15
+ static propTypes = {
16
+ locationEnabled: PropTypes.bool.isRequired,
17
+ maxZoom: PropTypes.number,
18
+ onMapLoaded: PropTypes.func,
19
+ indoorMaps: PropTypes.array
20
+ };
21
+
22
+ static defaultProps = {
23
+ maxZoom: 22,
24
+ onMapLoaded: noop
25
+ };
26
+
27
+ componentDidMount() {
28
+ this.map = new mapboxgl.Map({
29
+ container: this.mapContainer,
30
+ style: 'mapbox://styles/mapbox/streets-v10',
31
+ maxZoom: this.props.maxZoom
32
+ });
33
+
34
+ this.mapHandler = new MapHandler(this.map, this.mapContainer);
35
+ this.mapHandler.componentDidMount();
36
+
37
+
38
+ const mapLoadedFn = () => this.props.onMapLoaded(this.mapHandler);
39
+
40
+ this.map.on('load', () => {
41
+ if (this.props.indoorMaps && this.props.indoorMaps.length > 0) {
42
+ this.loadIndoorMaps(this.props.indoorMaps)
43
+ .then(mapLoadedFn);
44
+ } else {
45
+ mapLoadedFn();
46
+ }
47
+ });
48
+
49
+ this.map.addControl(new mapboxgl.IndoorControl());
50
+
51
+ }
52
+
53
+ componentWillUnmount() {
54
+ this.mapHandler.componentWillUnmount();
55
+ this.map.remove();
56
+ }
57
+
58
+ componentDidUpdate(prevProps) {
59
+ if (prevProps.locationEnabled !== this.props.locationEnabled) {
60
+ this.mapHandler.locationEnabled = this.props.locationEnabled;
61
+ }
62
+ }
63
+
64
+ loadIndoorMaps(mapsPaths) {
65
+ return Promise.all(
66
+ mapsPaths.map(mapPath =>
67
+ fetch(mapPath)
68
+ .then(res => res.json())
69
+ .then(geojson => this.map.indoor.addMap(geojson, null, BELOW_LAYER_ID)))
70
+ );
71
+ }
72
+
73
+ render() {
74
+ return (
75
+ <div ref={map => (this.mapContainer = map)}
76
+ style={{
77
+ width: '100%',
78
+ height: '100%'
79
+ }} />
80
+ );
81
+ }
82
+ }
83
+
84
+ export default MapComponent;
@@ -0,0 +1,53 @@
1
+ import mapboxgl from 'mapbox-gl';
2
+
3
+ import { Coordinates } from '@wemap/geo';
4
+
5
+ import ItineraryMapHandler from './helpers/ItineraryMapHandler';
6
+ import UserOnMapHandler from './helpers/UserOnMapHandler';
7
+ import MapClickHandler from './helpers/MapClickHandler';
8
+
9
+ class MapHandler {
10
+
11
+ itineraryMapHandler;
12
+ userOnMapHandler;
13
+
14
+ /**
15
+ *
16
+ * @param {mapboxgl.Map} map
17
+ * @param {HTMLDivElement} mapContainer
18
+ */
19
+ constructor(map, mapContainer) {
20
+ this.itineraryMapHandler = new ItineraryMapHandler(map);
21
+ this.userOnMapHandler = new UserOnMapHandler(map, mapContainer);
22
+ this.mapClickHandler = new MapClickHandler(map, this.userOnMapHandler);
23
+ this.map = map;
24
+ }
25
+
26
+ componentDidMount() {
27
+ this.userOnMapHandler.componentDidMount();
28
+ }
29
+
30
+ componentWillUnmount() {
31
+ this.userOnMapHandler.componentWillUnmount();
32
+ }
33
+
34
+ /**
35
+ * @param {Function} fn
36
+ */
37
+ onMapClick(fn) {
38
+ this.map.on('click', e => {
39
+ fn(new Coordinates(e.lngLat.lat, e.lngLat.lng));
40
+ this.map.getCanvas().style.cursor = '';
41
+ });
42
+ }
43
+
44
+ needClick() {
45
+ this.map.getCanvas().style.cursor = 'pointer';
46
+ }
47
+
48
+ get mapboxInstance() {
49
+ return this.map;
50
+ }
51
+ }
52
+
53
+ export default MapHandler;
@@ -0,0 +1,50 @@
1
+ import mapboxgl from 'mapbox-gl';
2
+
3
+ class MapboxHelper {
4
+
5
+ static coordsToLngLat = coords => [coords.lng, coords.lat];
6
+
7
+ // https://stackoverflow.com/a/39006388/2239938
8
+ static createGeoJSONCircle(center, radiusInKm, points) {
9
+ if (!points) {
10
+ points = 64;
11
+ }
12
+
13
+ var coords = {
14
+ latitude: center[1],
15
+ longitude: center[0]
16
+ };
17
+
18
+ var km = radiusInKm;
19
+
20
+ var ret = [];
21
+ var distanceX = km / (111.320 * Math.cos(coords.latitude * Math.PI / 180));
22
+ var distanceY = km / 110.574;
23
+
24
+ var theta, x, y;
25
+ for (let i = 0; i < points; i++) {
26
+ theta = (i / points) * (2 * Math.PI);
27
+ x = distanceX * Math.cos(theta);
28
+ y = distanceY * Math.sin(theta);
29
+
30
+ ret.push([coords.longitude + x, coords.latitude + y]);
31
+ }
32
+ ret.push(ret[0]);
33
+ return ret;
34
+ }
35
+
36
+ static createMarker(options) {
37
+ const elem = document.createElement('div');
38
+ elem.style.marginLeft = '-' + options.iconAnchor[0] + 'px';
39
+ elem.style.marginTop = '-' + options.iconAnchor[1] + 'px';
40
+ elem.style.width = 0;
41
+ elem.style.height = 0;
42
+ elem.appendChild(options.dom);
43
+
44
+ const marker = new mapboxgl.Marker(elem);
45
+ marker.setLngLat([options.longitude, options.latitude]);
46
+ return marker;
47
+ }
48
+ }
49
+
50
+ export default MapboxHelper;