@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.
- package/debug/Common.css +172 -0
- package/debug/MainComponent.jsx +64 -0
- package/debug/components/AbsolutePositionComponent.jsx +1 -1
- package/debug/components/GnssWifiComponent.jsx +1 -1
- package/debug/components/StartStopComponent.jsx +5 -3
- package/debug/components/Utils.js +4 -2
- package/debug/details/DetailsAttitudeComponent.jsx +121 -0
- package/debug/details/DetailsComponent.jsx +42 -0
- package/debug/details/DetailsPositionComponent.jsx +127 -0
- package/debug/details/ItineraryComponent.jsx +323 -0
- package/debug/index.js +28 -0
- package/debug/map/MapComponent.jsx +84 -0
- package/debug/map/MapHandler.js +53 -0
- package/debug/map/MapboxHelper.js +50 -0
- package/debug/map/helpers/ItineraryMapHandler.js +284 -0
- package/debug/map/helpers/MapClickHandler.js +119 -0
- package/debug/map/helpers/UserOnMapHandler.js +489 -0
- package/debug/stores/ItineraryStore.js +223 -0
- package/dist/assets/indoor-maps/bureaux-wemap-montpellier.geojson +7444 -0
- package/dist/{pose.html → index.html} +4 -1
- package/dist/js/providers-components.js +353 -209
- package/package.json +9 -7
- package/src/ProvidersInterface.js +5 -4
- package/src/providers/MetaProvider.js +3 -1
- package/src/providers/attitude/relative/RelativeAttitudeFromInertialProvider.js +1 -1
- package/src/providers/position/absolute/AbsolutePositionFromRelProvider.js +1 -1
- package/src/providers/position/absolute/AbsolutePositionProvider.js +27 -16
- package/src/providers/position/relative/GeoRelativePositionFromArCoreProvider.js +2 -1
- package/src/providers/position/relative/PdrProvider.js +2 -1
- package/src/smoothers/PositionSmoother.js +10 -2
- package/webpack/webpack.common.js +5 -5
- package/webpack/webpack.dev.js +7 -1
- package/debug/components/Common.css +0 -27
- package/debug/components/MapComponent.jsx +0 -366
- package/debug/components/PoseComponent.jsx +0 -169
- package/debug/components/index.js +0 -28
- package/src/providers/legacy/AbsolutePdrProvider.js +0 -258
- package/src/providers/legacy/ArCoreAbsoluteProvider.js +0 -230
- package/src/providers/legacy/GnssWifiPdrProvider.js +0 -217
- package/src/providers/legacy/MapMatchingProvider.js +0 -65
- package/src/providers/legacy/PdrProvider.old.js +0 -300
- package/src/providers/legacy/PoseProvider.js +0 -68
- package/src/providers/legacy/helpers/Smoother.js +0 -92
- 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;
|