@wemap/positioning 2.4.6 → 2.5.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/package.json
CHANGED
|
@@ -8,10 +8,11 @@
|
|
|
8
8
|
"Guillaume Pannetier <guillaume.pannetier@getwemap.com>"
|
|
9
9
|
],
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@wemap/geo": "^0.3.
|
|
11
|
+
"@wemap/geo": "^0.3.9",
|
|
12
|
+
"@wemap/graph": "^1.0.1",
|
|
12
13
|
"@wemap/logger": "^0.1.6",
|
|
13
14
|
"@wemap/maths": "^0.2.1",
|
|
14
|
-
"@wemap/osm": "^0.2.
|
|
15
|
+
"@wemap/osm": "^0.2.11",
|
|
15
16
|
"@wemap/utils": "^0.1.2",
|
|
16
17
|
"geomagnetism": "^0.1.0",
|
|
17
18
|
"lodash.isempty": "^4.4.0",
|
|
@@ -35,7 +36,7 @@
|
|
|
35
36
|
"dotenv": "^8.1.0",
|
|
36
37
|
"eslint": "^6.2.2",
|
|
37
38
|
"eslint-plugin-babel": "^5.3.0",
|
|
38
|
-
"eslint-plugin-jsdoc": "^15.
|
|
39
|
+
"eslint-plugin-jsdoc": "^15.12.1",
|
|
39
40
|
"eslint-plugin-react": "^7.14.3",
|
|
40
41
|
"esm": "^3.2.25",
|
|
41
42
|
"jsdom": "^15.1.1",
|
|
@@ -44,8 +45,8 @@
|
|
|
44
45
|
"mocha": "^6.2.0",
|
|
45
46
|
"npm": "^6.11.2",
|
|
46
47
|
"prop-types": "^15.7.2",
|
|
47
|
-
"react": "^16.
|
|
48
|
-
"react-dom": "^16.
|
|
48
|
+
"react": "^16.11.0",
|
|
49
|
+
"react-dom": "^16.11.0",
|
|
49
50
|
"react-router-dom": "^5.0.1",
|
|
50
51
|
"request": "^2.88.0",
|
|
51
52
|
"request-promise": "^4.2.4",
|
|
@@ -54,7 +55,7 @@
|
|
|
54
55
|
"url-parse": "^1.4.7",
|
|
55
56
|
"webpack": "^4.39.3",
|
|
56
57
|
"webpack-cli": "^3.3.7",
|
|
57
|
-
"webpack-dev-server": "^3.
|
|
58
|
+
"webpack-dev-server": "^3.9.0",
|
|
58
59
|
"webpack-merge": "^4.2.1"
|
|
59
60
|
},
|
|
60
61
|
"homepage": "https://github.com/wemap/wemap-positioning-js#readme",
|
|
@@ -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.5.0"
|
|
84
85
|
}
|
|
@@ -4,235 +4,225 @@ import 'mapbox-gl/dist/mapbox-gl.css';
|
|
|
4
4
|
import PropTypes from 'prop-types';
|
|
5
5
|
|
|
6
6
|
import {
|
|
7
|
-
Attitude,
|
|
7
|
+
Attitude, WGS84
|
|
8
8
|
} from '@wemap/geo';
|
|
9
|
+
import { Network } from '@wemap/graph';
|
|
9
10
|
|
|
10
11
|
import EventType from '../events/EventType';
|
|
11
12
|
|
|
12
|
-
mapboxgl.accessToken
|
|
13
|
-
|
|
13
|
+
mapboxgl.accessToken
|
|
14
|
+
= 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA';
|
|
14
15
|
|
|
15
16
|
const COMPASS_STYLE = {
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
width: '15px',
|
|
18
|
+
height: '15px',
|
|
18
19
|
'border-radius': '50%',
|
|
19
20
|
'z-index': '10000001',
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
position: 'absolute',
|
|
22
|
+
top: '-14px',
|
|
23
|
+
left: '-14px',
|
|
24
|
+
border: '7px solid',
|
|
24
25
|
'border-color': 'transparent',
|
|
25
26
|
'border-top-color': '#008DF1',
|
|
26
|
-
|
|
27
|
+
opacity: 0.5
|
|
27
28
|
};
|
|
28
29
|
|
|
29
30
|
const POSITION_STYLE = {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
width: '15px',
|
|
32
|
+
height: '15px',
|
|
33
|
+
top: '-7px',
|
|
34
|
+
left: '-7px',
|
|
35
|
+
position: 'absolute',
|
|
35
36
|
'border-radius': '50%',
|
|
36
|
-
|
|
37
|
+
background: '#008DF1'
|
|
37
38
|
};
|
|
38
39
|
|
|
39
|
-
|
|
40
40
|
class MapComponent extends React.Component {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
render() {
|
|
228
|
-
this.renderNetwork();
|
|
229
|
-
return (
|
|
230
|
-
<div
|
|
231
|
-
ref={map => (this.mapContainer = map)}
|
|
232
|
-
style={{ height: '300px' }} />
|
|
233
|
-
);
|
|
234
|
-
}
|
|
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
|
+
} else if (event.dataType === EventType.AbsoluteAttitude) {
|
|
115
|
+
this.updateAttitude(event.data);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
updatePosition(position) {
|
|
121
|
+
if (!this.map) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (!(position instanceof WGS84)) {
|
|
126
|
+
if (this.mapMarker) {
|
|
127
|
+
this.mapMarker.remove();
|
|
128
|
+
this.mapMarker = null;
|
|
129
|
+
this.positionIcon = null;
|
|
130
|
+
}
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const lngLat = [position.lng, position.lat];
|
|
135
|
+
|
|
136
|
+
if (!this.mapMarker) {
|
|
137
|
+
this.mapMarker = this.createPositionMarker(lngLat).addTo(this.map);
|
|
138
|
+
this.map.jumpTo({
|
|
139
|
+
center: lngLat,
|
|
140
|
+
zoom: this.props.defaultZoom
|
|
141
|
+
});
|
|
142
|
+
} else {
|
|
143
|
+
this.mapMarker.setLngLat(lngLat);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
updateAttitude(attitude) {
|
|
148
|
+
if (!this.positionIcon) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
if (!(attitude instanceof Attitude)) {
|
|
153
|
+
if (this.compassIcon) {
|
|
154
|
+
this.positionIcon.removeChild(this.compassIcon);
|
|
155
|
+
}
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (!this.compassIcon) {
|
|
160
|
+
this.createCompassElement();
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
this.positionIcon.style.transform
|
|
164
|
+
= 'rotate(' + attitude.headingDegrees + 'deg)';
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
renderNetwork() {
|
|
168
|
+
if (!this.map) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const network = this.props.network;
|
|
173
|
+
|
|
174
|
+
if (network === this.previousNetwork) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.previousNetwork = network;
|
|
178
|
+
|
|
179
|
+
if (!network) {
|
|
180
|
+
if (this.networkLayer) {
|
|
181
|
+
this.map.removeLayer(this.networkLayer);
|
|
182
|
+
this.networkLayer = null;
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const layer = {
|
|
188
|
+
id: 'network',
|
|
189
|
+
type: 'line',
|
|
190
|
+
source: {
|
|
191
|
+
type: 'geojson',
|
|
192
|
+
data: {
|
|
193
|
+
type: 'Feature',
|
|
194
|
+
properties: {},
|
|
195
|
+
geometry: {
|
|
196
|
+
type: 'MultiLineString',
|
|
197
|
+
coordinates: []
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
paint: {
|
|
202
|
+
'line-color': '#0000FF',
|
|
203
|
+
'line-width': 3
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
for (let i = 0; i < network.edges.length; i++) {
|
|
208
|
+
layer.source.data.geometry.coordinates.push([
|
|
209
|
+
[network.edges[i].node1.coords.lng, network.edges[i].node1.coords.lat],
|
|
210
|
+
[network.edges[i].node2.coords.lng, network.edges[i].node2.coords.lat]
|
|
211
|
+
]);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
this.map.on('load', () => {
|
|
215
|
+
this.networkLayer = this.map.addLayer(layer);
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
render() {
|
|
220
|
+
this.renderNetwork();
|
|
221
|
+
return (
|
|
222
|
+
<div ref={map => (this.mapContainer = map)}
|
|
223
|
+
style={{ height: '300px' }} />
|
|
224
|
+
);
|
|
225
|
+
}
|
|
235
226
|
}
|
|
236
227
|
|
|
237
|
-
|
|
238
228
|
export default MapComponent;
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import React from 'react'; // eslint-disable-line no-unused-vars
|
|
2
2
|
|
|
3
3
|
import {
|
|
4
|
-
|
|
4
|
+
WGS84UserPosition, Level
|
|
5
5
|
} from '@wemap/geo';
|
|
6
|
+
import { Itinerary } from '@wemap/graph';
|
|
6
7
|
import { deg2rad } from '@wemap/maths';
|
|
7
8
|
|
|
8
9
|
const datasets = {};
|
|
9
10
|
|
|
10
11
|
// Wemap Office
|
|
11
12
|
const wemapOffice = {
|
|
12
|
-
initialPosition: new WGS84UserPosition(43.6091955, 3.8841255),
|
|
13
|
+
initialPosition: new WGS84UserPosition(43.6091955, 3.8841255, 1.5),
|
|
13
14
|
initialHeading: deg2rad(191.9)
|
|
14
15
|
};
|
|
15
16
|
wemapOffice.itinerary = Itinerary.fromOrderedPointsArray(
|
|
@@ -27,7 +28,7 @@ wemapOffice.itinerary = Itinerary.fromOrderedPointsArray(
|
|
|
27
28
|
|
|
28
29
|
// Wemap Office Multi-level
|
|
29
30
|
const wemapOfficeMulti = {
|
|
30
|
-
initialPosition: new WGS84UserPosition(43.6091965, 3.8841285,
|
|
31
|
+
initialPosition: new WGS84UserPosition(43.6091965, 3.8841285, 1.5, new Level(2)),
|
|
31
32
|
initialHeading: deg2rad(191.9)
|
|
32
33
|
};
|
|
33
34
|
wemapOfficeMulti.itinerary = Itinerary.fromOrderedPointsArray(
|
|
@@ -51,7 +52,7 @@ wemapOfficeMulti.itinerary = Itinerary.fromOrderedPointsArray(
|
|
|
51
52
|
|
|
52
53
|
// Gare de Lyon RER A
|
|
53
54
|
const gareDeLyonRerA = {
|
|
54
|
-
initialPosition: new WGS84UserPosition(48.8442365, 2.3728267,
|
|
55
|
+
initialPosition: new WGS84UserPosition(48.8442365, 2.3728267, 1.5, new Level(-2)),
|
|
55
56
|
initialHeading: deg2rad(41.6)
|
|
56
57
|
};
|
|
57
58
|
gareDeLyonRerA.itinerary = Itinerary.fromOrderedPointsArray(
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
import noop from 'lodash.noop';
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
-
Constants as GeoConstants,
|
|
5
|
+
Constants as GeoConstants, WGS84, WGS84UserPosition
|
|
6
6
|
} from '@wemap/geo';
|
|
7
|
+
|
|
8
|
+
import { Itinerary } from '@wemap/graph';
|
|
7
9
|
import {
|
|
8
10
|
rad2deg, Quaternion
|
|
9
11
|
} from '@wemap/maths';
|
|
@@ -142,7 +144,7 @@ class PdrProvider extends MapMatchingProvider {
|
|
|
142
144
|
if (position instanceof WGS84) {
|
|
143
145
|
this.pdrPosition = WGS84UserPosition.fromWGS84(position);
|
|
144
146
|
if (window && window.performance) {
|
|
145
|
-
this.pdrPosition.time = window.performance / 1e3;
|
|
147
|
+
this.pdrPosition.time = window.performance.now() / 1e3;
|
|
146
148
|
}
|
|
147
149
|
} else {
|
|
148
150
|
this.pdrPosition = position;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* eslint max-statements
|
|
1
|
+
/* eslint-disable max-statements */
|
|
2
2
|
import { WGS84UserPosition } from '@wemap/geo';
|
|
3
3
|
|
|
4
4
|
// Generated positions by second
|
|
@@ -17,13 +17,12 @@ class Smoother {
|
|
|
17
17
|
/**
|
|
18
18
|
* Calculate smoothed positions for the next milliseconds given a new position
|
|
19
19
|
*/
|
|
20
|
-
generateNextPositions(
|
|
20
|
+
generateNextPositions(newPosition, flyby = false) {
|
|
21
21
|
|
|
22
|
-
if (!(
|
|
22
|
+
if (!(newPosition instanceof WGS84UserPosition)) {
|
|
23
23
|
throw new TypeError('newPosition is not instance of WGS84UserPosition');
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
const newPosition = _newPosition.clone();
|
|
27
26
|
if (!newPosition.hasOwnProperty('time')) {
|
|
28
27
|
throw new Error('newPosition does not have time property');
|
|
29
28
|
}
|
|
@@ -57,10 +56,13 @@ class Smoother {
|
|
|
57
56
|
i = Math.min(i, nSamples);
|
|
58
57
|
const smoothedPosition = this.previousPosition.destinationPoint(distance * i / nSamples, azimuth);
|
|
59
58
|
smoothedPosition.time = refTimestamp + (i - 1) / GEN_FREQUENCY;
|
|
59
|
+
smoothedPosition.bearing = newPosition.bearing;
|
|
60
60
|
this.positionsQueue.push(smoothedPosition);
|
|
61
61
|
i++;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
this.positionsQueue[this.positionsQueue.length - 1].level = newPosition.level;
|
|
65
|
+
|
|
64
66
|
this.previousPosition = newPosition;
|
|
65
67
|
}
|
|
66
68
|
|