-
Notifications
You must be signed in to change notification settings - Fork 46
/
Copy pathMap.js
122 lines (111 loc) · 3.97 KB
/
Map.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
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
import React, { useEffect, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import maplibregl from 'maplibre-gl';
import ReactMapGL, { AttributionControl, ScaleControl } from 'react-map-gl';
import { point as turfPoint } from '@turf/helpers';
import { useSelector } from 'react-redux';
import turfNearestPointOnLine from '@turf/nearest-point-on-line';
/* Main data & layers */
import Background from 'common/Map/Layers/Background';
import VirtualLayers from 'applications/osrd/views/OSRDSimulation/VirtualLayers';
import SnappedMarker from 'common/Map/Layers/SnappedMarker';
/* Objects & various */
import TracksGeographic from 'common/Map/Layers/TracksGeographic';
import colors from 'common/Map/Consts/colors';
import osmBlankStyle from 'common/Map/Layers/osmBlankStyle';
import { LAYER_GROUPS_ORDER, LAYERS } from 'config/layerOrder';
import 'common/Map/Map.scss';
import OperationalPoints from 'common/Map/Layers/OperationalPoints';
import Platforms from 'common/Map/Layers/Platforms';
import { getMapMouseEventNearestFeature } from 'utils/mapboxHelper';
export default function Map(props) {
const { viewport, setViewport, setClickedFeature } = props;
const mapStyle = useSelector((state) => state.map.mapStyle);
const [lngLatHover, setLngLatHover] = useState();
const [trackSectionGeoJSON, setTrackSectionGeoJSON] = useState();
const [snappedPoint, setSnappedPoint] = useState();
const mapRef = useRef(null);
const scaleControlStyle = {
left: 20,
bottom: 20,
};
const onFeatureClick = (e) => {
const result = getMapMouseEventNearestFeature(e);
if (
result &&
result.feature.properties &&
result.feature.properties.id &&
result.feature.geometry.type === 'LineString'
) {
setClickedFeature(result.feature);
}
};
const onMoveGetFeature = (e) => {
const result = getMapMouseEventNearestFeature(e);
if (
result &&
result.feature.properties &&
result.feature.properties.id &&
result.feature.geometry.type === 'LineString'
) {
setTrackSectionGeoJSON(result.feature.geometry);
setLngLatHover(result.nearest);
} else {
setSnappedPoint(undefined);
}
};
useEffect(() => {
if (trackSectionGeoJSON !== undefined && lngLatHover !== undefined) {
const point = turfPoint(lngLatHover);
try {
setSnappedPoint(turfNearestPointOnLine(trackSectionGeoJSON, point));
} catch (error) {
console.warn(`Ìmpossible to snapPoint - error ${error}`);
}
}
}, [trackSectionGeoJSON, lngLatHover]);
return (
<ReactMapGL
ref={mapRef}
{...viewport}
style={{ cursor: 'pointer' }}
width="100%"
height="100%"
mapLib={maplibregl}
mapStyle={osmBlankStyle}
onMove={(e) => setViewport(e.viewState)}
onMouseMove={(e) => onMoveGetFeature(e)}
attributionControl={false} // Defined below
onClick={onFeatureClick}
interactiveLayerIds={['chartis/tracks-geo/main']}
touchZoomRotate
>
<VirtualLayers />
<AttributionControl className="attribution-control" customAttribution="©SNCF Réseau" />
<ScaleControl maxWidth={100} unit="metric" style={scaleControlStyle} />
<Background
colors={colors[mapStyle]}
layerOrder={LAYER_GROUPS_ORDER[LAYERS.BACKGROUND.GROUP]}
/>
<Platforms
colors={colors[mapStyle]}
layerOrder={LAYER_GROUPS_ORDER[LAYERS.PLATFORMS.GROUP]}
/>
<TracksGeographic
colors={colors[mapStyle]}
layerOrder={LAYER_GROUPS_ORDER[LAYERS.TRACKS_GEOGRAPHIC.GROUP]}
/>
<OperationalPoints
geomType="geo"
colors={colors[mapStyle]}
layerOrder={LAYER_GROUPS_ORDER[LAYERS.OPERATIONAL_POINTS.GROUP]}
/>
{snappedPoint !== undefined ? <SnappedMarker geojson={snappedPoint} /> : null}
</ReactMapGL>
);
}
Map.propTypes = {
viewport: PropTypes.object.isRequired,
setViewport: PropTypes.func.isRequired,
setClickedFeature: PropTypes.func.isRequired,
};