|
1 |
| -import { useCallback, useEffect, useRef, useState } from 'react'; |
| 1 | +import { useCallback, useMemo, useRef } from 'react'; |
2 | 2 |
|
3 |
| -import { isNil } from 'lodash'; |
4 |
| -import ReactMapGL, { AttributionControl, ScaleControl } from 'react-map-gl/maplibre'; |
5 | 3 | import type { MapRef } from 'react-map-gl/maplibre';
|
6 | 4 | import { useSelector } from 'react-redux';
|
7 |
| -import { useParams } from 'react-router-dom'; |
8 | 5 |
|
| 6 | +import BaseMap from 'common/Map/BaseMap'; |
9 | 7 | import MapButtons from 'common/Map/Buttons/MapButtons';
|
10 |
| -import { CUSTOM_ATTRIBUTION } from 'common/Map/const'; |
11 |
| -import colors from 'common/Map/Consts/colors'; |
12 |
| -import { useMapBlankStyle } from 'common/Map/Layers/blankStyle'; |
13 |
| -import IGNLayers from 'common/Map/Layers/IGNLayers'; |
14 |
| -import InfraObjectLayers from 'common/Map/Layers/InfraObjectLayers'; |
15 |
| -import LineSearchLayer from 'common/Map/Layers/LineSearchLayer'; |
16 |
| -import OSMLayers from 'common/Map/Layers/OSMLayers'; |
17 |
| -import SearchMarker from 'common/Map/Layers/SearchMarker'; |
18 | 8 | import { removeSearchItemMarkersOnMap } from 'common/Map/utils';
|
19 | 9 | import { useInfraID } from 'common/osrdContext';
|
20 |
| -import { LAYER_GROUPS_ORDER, LAYERS } from 'config/layerOrder'; |
21 |
| -import VirtualLayers from 'modules/simulationResult/components/SimulationResultsMap/VirtualLayers'; |
22 | 10 | import type { Viewport } from 'reducers/map';
|
23 | 11 | import { updateViewport } from 'reducers/map';
|
24 | 12 | import { getMap, getTerrain3DExaggeration } from 'reducers/map/selectors';
|
25 | 13 | import { useAppDispatch } from 'store';
|
26 | 14 |
|
27 |
| -function Map() { |
28 |
| - const mapBlankStyle = useMapBlankStyle(); |
| 15 | +const REFERENCE_MAP_ID = 'reference-map'; |
29 | 16 |
|
30 |
| - const [mapLoaded, setMapLoaded] = useState(false); |
| 17 | +const Map = () => { |
| 18 | + const dispatch = useAppDispatch(); |
31 | 19 | const { viewport, mapSearchMarker, mapStyle, showOSM, layersSettings } = useSelector(getMap);
|
32 | 20 | const infraID = useInfraID();
|
33 | 21 | const terrain3DExaggeration = useSelector(getTerrain3DExaggeration);
|
| 22 | + |
34 | 23 | const mapRef = useRef<MapRef | null>(null);
|
35 |
| - const { urlLat, urlLon, urlZoom, urlBearing, urlPitch } = useParams(); |
36 |
| - const dispatch = useAppDispatch(); |
| 24 | + |
37 | 25 | const updateViewportChange = useCallback(
|
38 |
| - (value: Partial<Viewport>, updateRouter = false) => { |
| 26 | + (value: Partial<Viewport>, { updateRouter } = { updateRouter: false }) => { |
39 | 27 | dispatch(updateViewport(value, `/map`, updateRouter));
|
40 | 28 | },
|
41 | 29 | [dispatch]
|
42 | 30 | );
|
43 | 31 |
|
44 |
| - const scaleControlStyle = { |
45 |
| - left: 20, |
46 |
| - bottom: 20, |
47 |
| - }; |
48 |
| - |
49 | 32 | const resetPitchBearing = () => {
|
50 | 33 | updateViewportChange({
|
51 |
| - ...viewport, |
52 | 34 | bearing: 0,
|
53 | 35 | pitch: 0,
|
54 | 36 | });
|
55 | 37 | };
|
56 | 38 |
|
57 |
| - const defineInteractiveLayers = () => { |
58 |
| - const interactiveLayersLocal = []; |
59 |
| - if (layersSettings.tvds) { |
60 |
| - interactiveLayersLocal.push('chartis/osrd_tvd_section/geo'); |
61 |
| - } |
62 |
| - return interactiveLayersLocal; |
63 |
| - }; |
64 |
| - |
65 |
| - /** |
66 |
| - * When the component mount |
67 |
| - * => we check if url has viewport and set it in store |
68 |
| - */ |
69 |
| - useEffect(() => { |
70 |
| - // viewport |
71 |
| - const newViewport: Partial<Viewport> = {}; |
72 |
| - if (!isNil(urlLat)) newViewport.latitude = parseFloat(urlLat); |
73 |
| - if (!isNil(urlLon)) newViewport.longitude = parseFloat(urlLon); |
74 |
| - if (!isNil(urlZoom)) newViewport.zoom = parseFloat(urlZoom); |
75 |
| - if (!isNil(urlBearing)) newViewport.bearing = parseFloat(urlBearing); |
76 |
| - if (!isNil(urlPitch)) newViewport.pitch = parseFloat(urlPitch); |
77 |
| - if (Object.keys(newViewport).length > 0) updateViewportChange(newViewport); |
78 |
| - // we only do it at mount time |
79 |
| - // eslint-disable-next-line react-hooks/exhaustive-deps |
80 |
| - }, []); |
| 39 | + const interactiveLayerIds = useMemo( |
| 40 | + () => (layersSettings.tvds ? ['chartis/osrd_tvd_section/geo'] : []), |
| 41 | + [layersSettings] |
| 42 | + ); |
81 | 43 |
|
82 | 44 | return (
|
83 | 45 | <main className="mastcontainer mastcontainer-map">
|
84 | 46 | <MapButtons
|
85 | 47 | map={mapRef.current ?? undefined}
|
86 | 48 | resetPitchBearing={resetPitchBearing}
|
87 |
| - withInfraButton |
88 |
| - withMapKeyButton |
89 | 49 | bearing={viewport.bearing}
|
90 | 50 | viewPort={viewport}
|
| 51 | + withInfraButton |
| 52 | + withMapKeyButton |
91 | 53 | />
|
92 |
| - <ReactMapGL |
93 |
| - {...viewport} |
94 |
| - ref={mapRef} |
| 54 | + <BaseMap |
| 55 | + mapId={REFERENCE_MAP_ID} |
| 56 | + mapRef={mapRef} |
95 | 57 | cursor="normal"
|
96 |
| - style={{ width: '100%', height: '100%' }} |
97 |
| - mapStyle={mapBlankStyle} |
98 |
| - onMove={(e) => updateViewportChange(e.viewState)} |
99 |
| - onMoveEnd={(e) => updateViewportChange(e.viewState, true)} |
100 |
| - attributionControl={false} // Defined below |
101 |
| - onResize={(e) => { |
102 |
| - updateViewportChange({ |
103 |
| - width: e.target.getContainer().offsetWidth, |
104 |
| - height: e.target.getContainer().offsetHeight, |
105 |
| - }); |
106 |
| - }} |
107 |
| - interactiveLayerIds={defineInteractiveLayers()} |
108 |
| - touchZoomRotate |
109 |
| - maxPitch={85} |
110 |
| - terrain={ |
111 |
| - terrain3DExaggeration |
112 |
| - ? { source: 'terrain', exaggeration: terrain3DExaggeration } |
113 |
| - : undefined |
114 |
| - } |
115 |
| - onLoad={() => { |
116 |
| - setMapLoaded(true); |
117 |
| - }} |
| 58 | + infraId={infraID} |
| 59 | + interactiveLayerIds={interactiveLayerIds} |
| 60 | + mapSearchMarker={mapSearchMarker} |
| 61 | + mapStyle={mapStyle} |
118 | 62 | onClick={() => {
|
119 | 63 | removeSearchItemMarkersOnMap(dispatch);
|
120 | 64 | }}
|
121 |
| - > |
122 |
| - <VirtualLayers /> |
123 |
| - <AttributionControl customAttribution={CUSTOM_ATTRIBUTION} /> |
124 |
| - <ScaleControl maxWidth={100} unit="metric" style={scaleControlStyle} /> |
125 |
| - |
126 |
| - <OSMLayers mapStyle={mapStyle} showOSM={showOSM && mapLoaded} /> |
127 |
| - <IGNLayers /> |
128 |
| - |
129 |
| - {infraID && <InfraObjectLayers infraId={infraID} mapStyle={mapStyle} />} |
130 |
| - |
131 |
| - <LineSearchLayer |
132 |
| - layerOrder={LAYER_GROUPS_ORDER[LAYERS.LINE_SEARCH.GROUP]} |
133 |
| - infraID={infraID} |
134 |
| - /> |
135 |
| - |
136 |
| - {mapSearchMarker && <SearchMarker data={mapSearchMarker} colors={colors[mapStyle]} />} |
137 |
| - </ReactMapGL> |
| 65 | + showOSM={showOSM} |
| 66 | + viewPort={viewport} |
| 67 | + updatePartialViewPort={updateViewportChange} |
| 68 | + terrain3DExaggeration={terrain3DExaggeration} |
| 69 | + /> |
138 | 70 | </main>
|
139 | 71 | );
|
140 |
| -} |
| 72 | +}; |
141 | 73 |
|
142 | 74 | export default Map;
|
0 commit comments