@wemap/positioning 2.1.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.
- package/debug/arcore-absolute.html +16 -0
- package/debug/arcore.html +16 -0
- package/package.json +2 -1
- package/src/PositioningHandler.js +19 -5
- package/src/components/AbsoluteAttitudeComponent.jsx +2 -2
- package/src/components/ArCoreAbsoluteComponent.jsx +100 -0
- package/src/components/ArCoreComponent.jsx +74 -0
- package/src/components/GnssWifiComponent.jsx +14 -2
- package/src/components/GnssWifiPdrComponent.jsx +11 -2
- package/src/components/MapComponent.jsx +237 -0
- package/src/components/PdrComponent.jsx +12 -3
- package/src/components/PoseComponent.jsx +7 -0
- package/src/components/PositioningPoseComponent.jsx +12 -3
- package/src/components/Utils.js +18 -0
- package/src/components/index.js +4 -0
- package/src/errors/MissingArCoreError.js +9 -0
- package/src/errors/MissingNativeInterfaceError.js +9 -0
- package/src/providers/Provider.js +15 -3
- package/src/providers/ProviderOptions.js +1 -1
- package/src/providers/attitude/AbsoluteAttitudeProvider.js +6 -6
- package/src/providers/others/MapMatchingProvider.js +19 -19
- package/src/providers/pose/ArCoreAbsoluteProvider.js +186 -0
- package/src/providers/pose/ArCoreProvider.js +115 -0
- package/src/providers/pose/GnssWifiPdrProvider.js +20 -20
- package/src/providers/pose/PoseProvider.js +1 -1
- package/src/providers/pose/pdr/PdrProvider.js +39 -39
- package/src/providers/pose/pdr/helpers/Smoother.js +33 -33
- package/src/providers/pose/pdr/helpers/Smoother.spec.js +7 -7
- package/src/providers/position/GnssWifiProvider.js +5 -5
- package/src/providers/position/IpProvider.js +2 -2
- package/webpack/webpack.common.js +1 -1
- package/src.old/Constants.js +0 -11
- package/src.old/NavigationHandler.js +0 -244
- package/src.old/Pose.js +0 -8
- package/src.old/attitude/AttitudeHandler.js +0 -342
- package/src.old/attitude/EkfAttitude.js +0 -238
- package/src.old/attitude/EkfAttitude.spec.js +0 -116
- package/src.old/components/AbsoluteAttitude.jsx +0 -136
- package/src.old/components/Imu.jsx +0 -89
- package/src.old/components/LocationSource.jsx +0 -434
- package/src.old/components/Logger.jsx +0 -113
- package/src.old/components/NavigationDebugApp.jsx +0 -106
- package/src.old/components/Others.jsx +0 -121
- package/src.old/components/RelativeAttitude.jsx +0 -104
- package/src.old/components/Utils.js +0 -35
- package/src.old/components/index.js +0 -13
- package/src.old/index.js +0 -7
- package/src.old/providers/FixedLocationImuLocationSource.js +0 -66
- package/src.old/providers/GnssLocationSource.js +0 -118
- package/src.old/providers/GnssPdrLocationSource.js +0 -182
- package/src.old/providers/IPLocationSource.js +0 -96
- package/src.old/providers/LocationSource.js +0 -290
- package/src.old/providers/PdrLocationSource.js +0 -320
- package/src.old/providers/ProvidersLogger.js +0 -77
- package/src.old/providers/pdr/HeadingUnlocker.js +0 -41
- package/src.old/providers/pdr/HeadingUnlocker.spec.js +0 -26
- package/src.old/providers/pdr/Smoother.js +0 -90
- package/src.old/providers/pdr/Smoother.spec.js +0 -424
- package/src.old/providers/pdr/ThugDetector.js +0 -37
- package/src.old/providers/steps/StepDetection.js +0 -7
- package/src.old/providers/steps/StepDetectionLadetto.js +0 -67
- package/src.old/providers/steps/StepDetectionMinMaxPeaks.js +0 -80
- package/src.old/providers/steps/StepDetectionMinMaxPeaks2.js +0 -108
- package/src.old/sensors/SensorsCompatibility.js +0 -486
- package/src.old/sensors/SensorsCompatibility.spec.js +0 -270
- package/src.old/sensors/SensorsLogger.js +0 -94
- package/src.old/sensors/SensorsLoggerUtils.js +0 -35
|
@@ -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>
|
|
@@ -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</title>
|
|
8
|
+
<script src="/js/positioning-components.js"></script>
|
|
9
|
+
</head>
|
|
10
|
+
|
|
11
|
+
<body>
|
|
12
|
+
<div id="app"></div>
|
|
13
|
+
<script>createReactElement(ArCoreComponent, document.getElementById('app'));</script>
|
|
14
|
+
</body>
|
|
15
|
+
|
|
16
|
+
</html>
|
package/package.json
CHANGED
|
@@ -51,6 +51,7 @@
|
|
|
51
51
|
"request": "^2.88.0",
|
|
52
52
|
"request-promise": "^4.2.4",
|
|
53
53
|
"simple-git": "^1.124.0",
|
|
54
|
+
"style-loader": "^1.0.0",
|
|
54
55
|
"url-parse": "^1.4.7",
|
|
55
56
|
"webpack": "^4.39.3",
|
|
56
57
|
"webpack-cli": "^3.3.7",
|
|
@@ -80,5 +81,5 @@
|
|
|
80
81
|
"lint": "eslint --ext .js,.jsx --quiet src",
|
|
81
82
|
"test": "mocha -r esm \"src/**/*.spec.js\""
|
|
82
83
|
},
|
|
83
|
-
"version": "2.
|
|
84
|
+
"version": "2.3.0"
|
|
84
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
|
-
|
|
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
|
-
|
|
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.
|
|
89
|
-
Logger.warn('Cannot set
|
|
102
|
+
if (!provider.setPosition) {
|
|
103
|
+
Logger.warn('Cannot set position to ' + provider.constructor.name);
|
|
90
104
|
}
|
|
91
|
-
provider.
|
|
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
|
|
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.
|
|
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;
|
|
@@ -0,0 +1,74 @@
|
|
|
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 ArCoreProvider from '../providers/pose/ArCoreProvider';
|
|
7
|
+
|
|
8
|
+
class ArCoreComponent extends React.Component {
|
|
9
|
+
|
|
10
|
+
constructor(props, context) {
|
|
11
|
+
super(props, context);
|
|
12
|
+
this.state = {
|
|
13
|
+
position: null,
|
|
14
|
+
attitude: null
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
this.arCoreProvider = new ArCoreProvider(this.onEvent, this.onError);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
componentDidMount() {
|
|
22
|
+
this.arCoreProvider.start();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
componentWillUnmount() {
|
|
26
|
+
this.arCoreProvider.stop();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
onEvent = events => {
|
|
30
|
+
const newState = {};
|
|
31
|
+
events.forEach(event => {
|
|
32
|
+
if (event.dataType === EventType.RelativePosition) {
|
|
33
|
+
newState.position = event.data;
|
|
34
|
+
} else if (event.dataType === EventType.RelativeAttitude) {
|
|
35
|
+
newState.attitude = event.data;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
if (!isEmpty(newState)) {
|
|
39
|
+
this.setState(newState);
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
onError = events => {
|
|
44
|
+
const newState = {};
|
|
45
|
+
events.forEach(event => {
|
|
46
|
+
if (event.dataType === EventType.RelativePosition) {
|
|
47
|
+
newState.position = event.error;
|
|
48
|
+
} else if (event.dataType === EventType.RelativeAttitude) {
|
|
49
|
+
newState.attitude = event.error;
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
if (!isEmpty(newState)) {
|
|
53
|
+
this.setState(newState);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
render() {
|
|
58
|
+
|
|
59
|
+
const attitudeRender = Utils.renderAttitude(this.state.attitude);
|
|
60
|
+
const positionRender = Utils.renderRelativePosition(this.state.position);
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<div>
|
|
64
|
+
<h3>Position</h3>
|
|
65
|
+
{positionRender}
|
|
66
|
+
<h3>Attitude</h3>
|
|
67
|
+
{attitudeRender}
|
|
68
|
+
</div>
|
|
69
|
+
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export default ArCoreComponent;
|
|
@@ -3,12 +3,13 @@ import React from 'react';
|
|
|
3
3
|
import GnssWifiProvider from '../providers/position/GnssWifiProvider';
|
|
4
4
|
import Utils from './Utils';
|
|
5
5
|
import EventType from '../events/EventType';
|
|
6
|
+
import MapComponent from './MapComponent';
|
|
6
7
|
|
|
7
8
|
class GnssWifiComponent extends React.Component {
|
|
8
9
|
|
|
9
10
|
constructor(props, context) {
|
|
10
11
|
super(props, context);
|
|
11
|
-
this.state = {position: null};
|
|
12
|
+
this.state = { position: null };
|
|
12
13
|
|
|
13
14
|
this.gnssWifiProvider = new GnssWifiProvider(this.onEvent, this.onError);
|
|
14
15
|
}
|
|
@@ -28,6 +29,10 @@ class GnssWifiComponent extends React.Component {
|
|
|
28
29
|
this.setState({ position: event.data });
|
|
29
30
|
}
|
|
30
31
|
});
|
|
32
|
+
|
|
33
|
+
if (this.map) {
|
|
34
|
+
this.map.parseEvents(events);
|
|
35
|
+
}
|
|
31
36
|
};
|
|
32
37
|
|
|
33
38
|
onError = events => {
|
|
@@ -39,7 +44,14 @@ class GnssWifiComponent extends React.Component {
|
|
|
39
44
|
}
|
|
40
45
|
|
|
41
46
|
render() {
|
|
42
|
-
return
|
|
47
|
+
return (
|
|
48
|
+
<div>
|
|
49
|
+
<h3>Position</h3>
|
|
50
|
+
{Utils.renderPosition(this.state.position)}
|
|
51
|
+
<h3>Map</h3>
|
|
52
|
+
<MapComponent ref={map => (this.map = map)} />
|
|
53
|
+
</div>
|
|
54
|
+
);
|
|
43
55
|
}
|
|
44
56
|
}
|
|
45
57
|
|
|
@@ -8,10 +8,11 @@ import {
|
|
|
8
8
|
import Utils from './Utils';
|
|
9
9
|
import EventType from '../events/EventType';
|
|
10
10
|
import GnssWifiPdrProvider from '../providers/pose/GnssWifiPdrProvider';
|
|
11
|
+
import MapComponent from './MapComponent';
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
+
const INITIAL_POSITION = new WGS84UserPosition(43.6091955, 3.8841255);
|
|
13
14
|
const ITINERARY = Itinerary.fromPoints([
|
|
14
|
-
[
|
|
15
|
+
[INITIAL_POSITION.lat, INITIAL_POSITION.lng],
|
|
15
16
|
[43.6091883, 3.8841242],
|
|
16
17
|
[43.6091709, 3.8842382],
|
|
17
18
|
[43.6091288, 3.884226],
|
|
@@ -49,6 +50,10 @@ class GnssWifiPdrComponent extends React.Component {
|
|
|
49
50
|
if (!isEmpty(newState)) {
|
|
50
51
|
this.setState(newState);
|
|
51
52
|
}
|
|
53
|
+
|
|
54
|
+
if (this.map) {
|
|
55
|
+
this.map.parseEvents(events);
|
|
56
|
+
}
|
|
52
57
|
};
|
|
53
58
|
|
|
54
59
|
onError = events => {
|
|
@@ -76,6 +81,10 @@ class GnssWifiPdrComponent extends React.Component {
|
|
|
76
81
|
{positionRender}
|
|
77
82
|
<h3>Attitude</h3>
|
|
78
83
|
{attitudeRender}
|
|
84
|
+
<h3>Map</h3>
|
|
85
|
+
<MapComponent
|
|
86
|
+
ref={map => (this.map = map)}
|
|
87
|
+
network={ITINERARY} />
|
|
79
88
|
</div>
|
|
80
89
|
|
|
81
90
|
);
|
|
@@ -0,0 +1,237 @@
|
|
|
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
|
+
WGS84, Attitude, Network
|
|
8
|
+
} from '@wemap/geo';
|
|
9
|
+
import EventType from '../events/EventType';
|
|
10
|
+
|
|
11
|
+
mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA';
|
|
12
|
+
|
|
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
|
+
|
|
39
|
+
class MapComponent extends React.Component {
|
|
40
|
+
|
|
41
|
+
static propTypes = {
|
|
42
|
+
network: PropTypes.instanceOf(Network),
|
|
43
|
+
defaultZoom: PropTypes.number
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
static defaultProps = {defaultZoom: 19};
|
|
47
|
+
|
|
48
|
+
componentDidMount() {
|
|
49
|
+
this.map = new mapboxgl.Map({
|
|
50
|
+
container: this.mapContainer,
|
|
51
|
+
style: 'mapbox://styles/mapbox/streets-v9'
|
|
52
|
+
});
|
|
53
|
+
this.renderNetwork();
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
componentWillUnmount() {
|
|
57
|
+
this.map.remove();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
createMarker(options) {
|
|
61
|
+
var elem, marker;
|
|
62
|
+
|
|
63
|
+
elem = document.createElement('div');
|
|
64
|
+
elem.style.marginLeft = '-' + options.iconAnchor[0] + 'px';
|
|
65
|
+
elem.style.marginTop = '-' + options.iconAnchor[1] + 'px';
|
|
66
|
+
elem.style.width = 0;
|
|
67
|
+
elem.style.height = 0;
|
|
68
|
+
elem.appendChild(options.dom);
|
|
69
|
+
|
|
70
|
+
marker = new mapboxgl.Marker(elem);
|
|
71
|
+
marker.setLngLat([options.longitude, options.latitude]);
|
|
72
|
+
return marker;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
createPositionMarker(position) {
|
|
76
|
+
const coreIcon = document.createElement('div');
|
|
77
|
+
this.applyStyleToDomElement(coreIcon, POSITION_STYLE);
|
|
78
|
+
|
|
79
|
+
this.positionIcon = document.createElement('div');
|
|
80
|
+
this.positionIcon.appendChild(coreIcon);
|
|
81
|
+
|
|
82
|
+
return this.createMarker({
|
|
83
|
+
dom: this.positionIcon,
|
|
84
|
+
iconAnchor: [0, 0],
|
|
85
|
+
latitude: position[1],
|
|
86
|
+
longitude: position[0]
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
createCompassElement() {
|
|
91
|
+
if (!this.positionIcon) {
|
|
92
|
+
throw new Error('createPositionMarker() should be called before');
|
|
93
|
+
}
|
|
94
|
+
this.compassIcon = document.createElement('div');
|
|
95
|
+
this.applyStyleToDomElement(this.compassIcon, COMPASS_STYLE);
|
|
96
|
+
this.positionIcon.appendChild(this.compassIcon);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
applyStyleToDomElement(domElement, style) {
|
|
100
|
+
for (const key in style) {
|
|
101
|
+
if (style.hasOwnProperty(key)) {
|
|
102
|
+
domElement.style[key] = style[key];
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
parseEvents(events) {
|
|
108
|
+
if (!this.map) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
events.forEach(event => {
|
|
112
|
+
if (event.dataType === EventType.AbsolutePosition) {
|
|
113
|
+
this.updatePosition(event.data);
|
|
114
|
+
|
|
115
|
+
} else if (event.dataType === EventType.AbsoluteAttitude) {
|
|
116
|
+
this.updateAttitude(event.data);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
updatePosition(position) {
|
|
122
|
+
|
|
123
|
+
if (!this.map) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
if (!(position instanceof WGS84)) {
|
|
128
|
+
if (this.mapMarker) {
|
|
129
|
+
this.mapMarker.remove();
|
|
130
|
+
this.mapMarker = null;
|
|
131
|
+
this.positionIcon = null;
|
|
132
|
+
}
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const lngLat = [position.lng, position.lat];
|
|
137
|
+
|
|
138
|
+
if (!this.mapMarker) {
|
|
139
|
+
this.mapMarker = this.createPositionMarker(lngLat)
|
|
140
|
+
.addTo(this.map);
|
|
141
|
+
this.map.jumpTo({
|
|
142
|
+
center: lngLat,
|
|
143
|
+
zoom: this.props.defaultZoom
|
|
144
|
+
});
|
|
145
|
+
} else {
|
|
146
|
+
this.mapMarker.setLngLat(lngLat);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
updateAttitude(attitude) {
|
|
152
|
+
|
|
153
|
+
if (!this.positionIcon) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
if (!(attitude instanceof Attitude)) {
|
|
158
|
+
if (this.compassIcon) {
|
|
159
|
+
this.positionIcon.removeChild(this.compassIcon);
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (!this.compassIcon) {
|
|
165
|
+
this.createCompassElement();
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
this.positionIcon.style.transform = 'rotate(' + attitude.headingDegrees + 'deg)';
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
renderNetwork() {
|
|
172
|
+
|
|
173
|
+
if (!this.map) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const network = this.props.network;
|
|
178
|
+
|
|
179
|
+
if (network === this.previousNetwork) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
this.previousNetwork = network;
|
|
183
|
+
|
|
184
|
+
if (!network) {
|
|
185
|
+
if (this.networkLayer) {
|
|
186
|
+
this.map.removeLayer(this.networkLayer);
|
|
187
|
+
this.networkLayer = null;
|
|
188
|
+
}
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const layer = {
|
|
193
|
+
id: 'network',
|
|
194
|
+
type: 'line',
|
|
195
|
+
source: {
|
|
196
|
+
type: 'geojson',
|
|
197
|
+
data: {
|
|
198
|
+
type: 'Feature',
|
|
199
|
+
properties: {},
|
|
200
|
+
geometry: {
|
|
201
|
+
type: 'MultiLineString',
|
|
202
|
+
coordinates: []
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
},
|
|
206
|
+
paint: {
|
|
207
|
+
'line-color': '#0000FF',
|
|
208
|
+
'line-width': 3
|
|
209
|
+
}
|
|
210
|
+
};
|
|
211
|
+
|
|
212
|
+
for (let i = 0; i < network.length; i++) {
|
|
213
|
+
layer.source.data.geometry.coordinates.push(
|
|
214
|
+
[
|
|
215
|
+
[network.edges[i].node1.lng, network.edges[i].node1.lat],
|
|
216
|
+
[network.edges[i].node2.lng, network.edges[i].node2.lat]
|
|
217
|
+
]
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
this.map.on('load', () => {
|
|
222
|
+
this.networkLayer = this.map.addLayer(layer);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
render() {
|
|
227
|
+
this.renderNetwork();
|
|
228
|
+
return (
|
|
229
|
+
<div
|
|
230
|
+
ref={map => (this.mapContainer = map)}
|
|
231
|
+
style={{ height: '300px' }} />
|
|
232
|
+
);
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
export default MapComponent;
|
|
@@ -8,11 +8,12 @@ import {
|
|
|
8
8
|
import Utils from './Utils';
|
|
9
9
|
import PdrProvider from '../providers/pose/pdr/PdrProvider';
|
|
10
10
|
import EventType from '../events/EventType';
|
|
11
|
+
import MapComponent from './MapComponent';
|
|
11
12
|
|
|
12
|
-
const
|
|
13
|
+
const INITIAL_POSITION = new WGS84UserPosition(43.6091955, 3.8841255);
|
|
13
14
|
const INITIAL_HEADING = 191.9;
|
|
14
15
|
const ITINERARY = Itinerary.fromPoints([
|
|
15
|
-
[
|
|
16
|
+
[INITIAL_POSITION.lat, INITIAL_POSITION.lng],
|
|
16
17
|
[43.6091883, 3.8841242],
|
|
17
18
|
[43.6091709, 3.8842382],
|
|
18
19
|
[43.6091288, 3.884226],
|
|
@@ -30,7 +31,7 @@ class PdrComponent extends React.Component {
|
|
|
30
31
|
|
|
31
32
|
|
|
32
33
|
componentDidMount() {
|
|
33
|
-
this.pdrProvider.
|
|
34
|
+
this.pdrProvider.setPosition(INITIAL_POSITION);
|
|
34
35
|
this.pdrProvider.setHeading(INITIAL_HEADING);
|
|
35
36
|
this.pdrProvider.enableMapMatching(ITINERARY);
|
|
36
37
|
this.pdrProvider.start();
|
|
@@ -52,6 +53,10 @@ class PdrComponent extends React.Component {
|
|
|
52
53
|
if (!isEmpty(newState)) {
|
|
53
54
|
this.setState(newState);
|
|
54
55
|
}
|
|
56
|
+
|
|
57
|
+
if (this.map) {
|
|
58
|
+
this.map.parseEvents(events);
|
|
59
|
+
}
|
|
55
60
|
};
|
|
56
61
|
|
|
57
62
|
onError = events => {
|
|
@@ -79,6 +84,10 @@ class PdrComponent extends React.Component {
|
|
|
79
84
|
{positionRender}
|
|
80
85
|
<h3>Attitude</h3>
|
|
81
86
|
{attitudeRender}
|
|
87
|
+
<h3>Map</h3>
|
|
88
|
+
<MapComponent
|
|
89
|
+
ref={map => (this.map = map)}
|
|
90
|
+
network={ITINERARY} />
|
|
82
91
|
</div>
|
|
83
92
|
|
|
84
93
|
);
|
|
@@ -4,6 +4,7 @@ import isEmpty from 'lodash.isempty';
|
|
|
4
4
|
import EventType from '../events/EventType';
|
|
5
5
|
import Utils from './Utils';
|
|
6
6
|
import PoseProvider from '../providers/pose/PoseProvider';
|
|
7
|
+
import MapComponent from './MapComponent';
|
|
7
8
|
|
|
8
9
|
class PoseComponent extends React.Component {
|
|
9
10
|
|
|
@@ -38,6 +39,10 @@ class PoseComponent extends React.Component {
|
|
|
38
39
|
if (!isEmpty(newState)) {
|
|
39
40
|
this.setState(newState);
|
|
40
41
|
}
|
|
42
|
+
|
|
43
|
+
if (this.map) {
|
|
44
|
+
this.map.parseEvents(events);
|
|
45
|
+
}
|
|
41
46
|
};
|
|
42
47
|
|
|
43
48
|
onError = events => {
|
|
@@ -65,6 +70,8 @@ class PoseComponent extends React.Component {
|
|
|
65
70
|
{positionRender}
|
|
66
71
|
<h3>Attitude</h3>
|
|
67
72
|
{attitudeRender}
|
|
73
|
+
<h3>Map</h3>
|
|
74
|
+
<MapComponent ref={map => (this.map = map)} />
|
|
68
75
|
</div>
|
|
69
76
|
|
|
70
77
|
);
|