Skip to content

Commit d62f480

Browse files
committed
front: stdcm: change map
1 parent 83f8fb5 commit d62f480

File tree

9 files changed

+82
-46
lines changed

9 files changed

+82
-46
lines changed

front/public/locales/en/stdcm.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"speedSpaceChart": "Speed Space Chart",
5959
"stdcmComputation": "Search for a train path",
6060
"stdcmErrors": {
61-
"bothOriginAndDestinationScheduled": "The calculation cannot take into account both an origin and a destination schedule. You have to choose one or the other:",
61+
"bothPointAreScheduled": "The calculation cannot take into account both an origin and a destination schedule. You have to choose one or the other:",
6262
"noPaths": "Incompatibility with other train paths.",
6363
"noResults": "No path found",
6464
"noScheduledPoint": "The calculation requires either the origin or destination schedule.",

front/src/applications/stdcm/hooks/useStdcm.ts

+1
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ const useStdcm = (showFailureNotification: boolean = true) => {
9595
rollingStock: stdcmRollingStock,
9696
creationDate: new Date(),
9797
speedLimitByTag,
98+
simulationPathSteps: osrdconf.pathSteps,
9899
} as StdcmV2SuccessResponse);
99100

100101
const stdcmTrain: TrainScheduleResult = {

front/src/applications/stdcm/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type {
1414
RollingStockWithLiveries,
1515
SimulationResponse,
1616
} from 'common/api/osrdEditoastApi';
17+
import type { PathStep } from 'reducers/osrdconf/types';
1718
import type { ValueOf } from 'utils/types';
1819

1920
export type StdcmRequestStatus = ValueOf<typeof STDCM_REQUEST_STATUS>;
@@ -26,6 +27,7 @@ export type StdcmV2SuccessResponse = Omit<
2627
rollingStock: LightRollingStock;
2728
creationDate: Date;
2829
speedLimitByTag?: string;
30+
simulationPathSteps: PathStep[];
2931
};
3032

3133
export type SimulationReportSheetProps = {

front/src/applications/stdcmV2/components/StdcmResults/StdcmResults.tsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,14 @@ const StcdmResults = ({
112112
<span className="change-criteria">{t('changeCriteria')}</span>
113113
</div>
114114
)}
115-
<div className="osrd-config-item-container osrd-config-item-container-map map-results">
115+
<div className="osrd-config-item-container osrd-config-item-container-map map-results no-pointer-events">
116116
<Map
117+
mapId="map-result"
118+
isReadOnly
117119
hideAttribution
118-
preventPointSelection
119120
setMapCanvas={setMapCanvas}
120121
pathProperties={selectedSimulation.outputs?.pathProperties}
122+
simulationPathSteps={selectedSimulation.outputs?.results.simulationPathSteps}
121123
/>
122124
</div>
123125
</div>

front/src/applications/stdcmV2/views/StdcmViewV2.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -136,7 +136,6 @@ const StdcmViewV2 = () => {
136136
<StdcmConfig
137137
selectedSimulation={selectedSimulation}
138138
currentSimulationInputs={currentSimulationInputs}
139-
pathProperties={pathProperties}
140139
isPending={isPending}
141140
showBtnToLaunchSimulation={showBtnToLaunchSimulation}
142141
retainedSimulationIndex={retainedSimulationIndex}

front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkersV2.tsx

+10-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ type MarkerInformation = {
3333
}
3434
);
3535

36+
type ItineraryMarkersProps = {
37+
map: Map;
38+
simulationPathSteps?: PathStep[];
39+
};
40+
3641
const formatPointWithNoName = (
3742
lineCode: number,
3843
lineName: string,
@@ -78,11 +83,14 @@ const extractMarkerInformation = (pathSteps: (PathStep | null)[]) =>
7883
return acc;
7984
}, [] as MarkerInformation[]);
8085

81-
const ItineraryMarkers = ({ map }: { map: Map }) => {
86+
const ItineraryMarkers = ({ map, simulationPathSteps }: ItineraryMarkersProps) => {
8287
const { getPathSteps } = useOsrdConfSelectors();
8388
const pathSteps = useSelector(getPathSteps);
8489

85-
const markersInformation = useMemo(() => extractMarkerInformation(pathSteps), [pathSteps]);
90+
const markersInformation = useMemo(
91+
() => extractMarkerInformation(simulationPathSteps || pathSteps),
92+
[simulationPathSteps, pathSteps]
93+
);
8694

8795
const getMarkerDisplayInformation = useCallback(
8896
(markerInfo: MarkerInformation) => {

front/src/modules/trainschedule/components/ManageTrainSchedule/Map.tsx

+59-38
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ import RenderPopup from 'modules/trainschedule/components/ManageTrainSchedule/Ma
5555
import { updateViewport } from 'reducers/map';
5656
import type { Viewport } from 'reducers/map';
5757
import { getMap, getTerrain3DExaggeration } from 'reducers/map/selectors';
58+
import type { PathStep } from 'reducers/osrdconf/types';
5859
import { useAppDispatch } from 'store';
5960
import { getMapMouseEventNearestFeature } from 'utils/mapHelper';
6061

@@ -64,27 +65,39 @@ import ItineraryMarkersV2 from './ManageTrainScheduleMap/ItineraryMarkersV2';
6465
type MapProps = {
6566
pathProperties?: ManageTrainSchedulePathProperties;
6667
setMapCanvas?: (mapCanvas: string) => void;
68+
isReadOnly?: boolean;
6769
hideAttribution?: boolean;
6870
hideItinerary?: boolean;
6971
preventPointSelection?: boolean;
72+
mapId?: string;
73+
simulationPathSteps?: PathStep[];
7074
};
7175

7276
const Map: FC<PropsWithChildren<MapProps>> = ({
7377
pathProperties,
7478
setMapCanvas,
79+
isReadOnly = false,
7580
hideAttribution = false,
7681
hideItinerary = false,
7782
preventPointSelection = false,
83+
mapId = 'map-container',
84+
simulationPathSteps,
7885
children,
7986
}) => {
8087
const mapBlankStyle = useMapBlankStyle();
8188

8289
const infraID = useInfraID();
8390
const terrain3DExaggeration = useSelector(getTerrain3DExaggeration);
8491
const { viewport, mapSearchMarker, mapStyle, showOSM, layersSettings } = useSelector(getMap);
92+
const mapViewport = useMemo(
93+
() =>
94+
isReadOnly && pathProperties
95+
? computeBBoxViewport(bbox(pathProperties?.geometry), viewport)
96+
: viewport,
97+
[isReadOnly, pathProperties, viewport]
98+
);
8599

86100
const [mapIsLoaded, setMapIsLoaded] = useState(false);
87-
const [showLayers, setShowLayers] = useState(true);
88101

89102
const [snappedPoint, setSnappedPoint] = useState<Feature<Point> | undefined>();
90103
const { urlLat = '', urlLon = '', urlZoom = '', urlBearing = '', urlPitch = '' } = useParams();
@@ -119,15 +132,14 @@ const Map: FC<PropsWithChildren<MapProps>> = ({
119132

120133
const resetPitchBearing = () => {
121134
updateViewportChange({
122-
...viewport,
135+
...mapViewport,
123136
bearing: 0,
124137
pitch: 0,
125138
});
126139
};
127140

128141
const onFeatureClick = (e: MapLayerMouseEvent) => {
129142
if (preventPointSelection) return;
130-
131143
const result = getMapMouseEventNearestFeature(e, { layersId: ['chartis/tracks-geo/main'] });
132144
if (
133145
result &&
@@ -155,7 +167,6 @@ const Map: FC<PropsWithChildren<MapProps>> = ({
155167

156168
const onMoveGetFeature = (e: MapLayerMouseEvent) => {
157169
if (preventPointSelection) return;
158-
159170
const result = getMapMouseEventNearestFeature(e, { layersId: ['chartis/tracks-geo/main'] });
160171
if (
161172
result &&
@@ -193,7 +204,7 @@ const Map: FC<PropsWithChildren<MapProps>> = ({
193204
useEffect(() => {
194205
if (urlLat) {
195206
updateViewportChange({
196-
...viewport,
207+
...mapViewport,
197208
latitude: parseFloat(urlLat),
198209
longitude: parseFloat(urlLon),
199210
zoom: parseFloat(urlZoom),
@@ -206,60 +217,63 @@ const Map: FC<PropsWithChildren<MapProps>> = ({
206217

207218
useEffect(() => {
208219
if (pathProperties) {
209-
if (setMapCanvas) {
210-
setShowLayers(false);
211-
}
212-
const newViewport = computeBBoxViewport(bbox(pathProperties.geometry), viewport);
220+
const newViewport = computeBBoxViewport(bbox(pathProperties.geometry), mapViewport);
213221
dispatch(updateViewport(newViewport));
214222
}
215223
}, [pathProperties]);
216224

217225
const captureMap = async () => {
218226
if (!pathProperties) return;
219227

220-
const itineraryViewport = computeBBoxViewport(bbox(pathProperties.geometry), viewport);
228+
const itineraryViewport = computeBBoxViewport(bbox(pathProperties.geometry), mapViewport);
221229

222-
if (setMapCanvas && !showLayers && isEqual(viewport, itineraryViewport)) {
230+
if (setMapCanvas && isEqual(mapViewport, itineraryViewport)) {
223231
try {
224-
const mapElement = document.getElementById('map-container');
232+
const mapElement = document.getElementById(mapId);
225233
if (mapElement) {
226234
const canvas = await html2canvas(mapElement);
227235
setMapCanvas(canvas.toDataURL());
228236
}
229237
} catch (error) {
230238
console.error('Error capturing map:', error);
231-
} finally {
232-
setShowLayers(true);
233239
}
234240
}
235241
};
236242

237243
return (
238244
<>
239-
<MapButtons
240-
map={mapRef.current ?? undefined}
241-
resetPitchBearing={resetPitchBearing}
242-
closeFeatureInfoClickPopup={closeFeatureInfoClickPopup}
243-
bearing={viewport.bearing}
244-
withMapKeyButton
245-
viewPort={viewport}
246-
/>
245+
{!isReadOnly && (
246+
<MapButtons
247+
map={mapRef.current ?? undefined}
248+
resetPitchBearing={resetPitchBearing}
249+
closeFeatureInfoClickPopup={closeFeatureInfoClickPopup}
250+
bearing={mapViewport.bearing}
251+
withMapKeyButton
252+
viewPort={mapViewport}
253+
/>
254+
)}
247255
<ReactMapGL
256+
dragPan={false}
257+
scrollZoom={false}
248258
ref={mapRef}
249-
{...viewport}
259+
{...mapViewport}
250260
style={{ width: '100%', height: '100%' }}
251-
cursor={preventPointSelection ? 'default' : 'pointer'}
261+
cursor={isReadOnly || preventPointSelection ? 'default' : 'pointer'}
252262
mapStyle={mapBlankStyle}
253-
onMove={(e) => updateViewportChange(e.viewState)}
254-
onMouseMove={onMoveGetFeature}
255263
attributionControl={false} // Defined below
256-
onClick={onFeatureClick}
257-
onResize={(e) => {
258-
updateViewportChange({
259-
width: e.target.getContainer().offsetWidth,
260-
height: e.target.getContainer().offsetHeight,
261-
});
262-
}}
264+
{...(!isReadOnly && {
265+
dragPan: true,
266+
scrollZoom: true,
267+
onMove: (e) => updateViewportChange(e.viewState),
268+
onMouseMove: onMoveGetFeature,
269+
onClick: onFeatureClick,
270+
onResize: (e) => {
271+
updateViewportChange({
272+
width: e.target.getContainer().offsetWidth,
273+
height: e.target.getContainer().offsetHeight,
274+
});
275+
},
276+
})}
263277
interactiveLayerIds={interactiveLayerIds}
264278
touchZoomRotate
265279
maxPitch={85}
@@ -271,9 +285,11 @@ const Map: FC<PropsWithChildren<MapProps>> = ({
271285
onLoad={() => {
272286
setMapIsLoaded(true);
273287
}}
274-
onIdle={() => captureMap()}
288+
onIdle={() => {
289+
captureMap();
290+
}}
275291
preserveDrawingBuffer
276-
id="map-container"
292+
id={mapId}
277293
>
278294
<VirtualLayers />
279295
{!hideAttribution && (
@@ -325,7 +341,7 @@ const Map: FC<PropsWithChildren<MapProps>> = ({
325341
layerOrder={LAYER_GROUPS_ORDER[LAYERS.ROUTES.GROUP]}
326342
infraID={infraID}
327343
/>
328-
{showLayers && (
344+
{!isReadOnly && (
329345
<>
330346
{layersSettings.operationalpoints && (
331347
<OperationalPoints
@@ -384,17 +400,22 @@ const Map: FC<PropsWithChildren<MapProps>> = ({
384400
layerOrder={LAYER_GROUPS_ORDER[LAYERS.LINE_SEARCH.GROUP]}
385401
infraID={infraID}
386402
/>
403+
<RenderPopup pathProperties={pathProperties} />
387404
</>
388405
)}
389-
<RenderPopup pathProperties={pathProperties} />
390406
{mapIsLoaded && (
391407
<>
392408
<ItineraryLayer
393409
layerOrder={LAYER_GROUPS_ORDER[LAYERS.ITINERARY.GROUP]}
394410
geometry={pathProperties?.geometry}
395411
hideItineraryLine={hideItinerary}
396412
/>
397-
{mapRef.current && <ItineraryMarkersV2 map={mapRef.current.getMap()} />}
413+
{mapRef.current && (
414+
<ItineraryMarkersV2
415+
simulationPathSteps={simulationPathSteps}
416+
map={mapRef.current.getMap()}
417+
/>
418+
)}
398419
</>
399420
)}
400421
{mapSearchMarker && <SearchMarker data={mapSearchMarker} colors={colors[mapStyle]} />}

front/src/styles/scss/applications/stdcmV2/_home.scss

+2-2
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@
190190
}
191191

192192
.stdcm-v2-map {
193-
border-radius: 8px;
194-
border: 1px solid rgba(255, 255, 255, 1);
193+
border-radius: 0.5rem;
194+
border: 0.063rem solid rgba(255, 255, 255, 1);
195195
box-shadow:
196196
0px 0px 0px 2px rgba(255, 255, 255, 0.75) inset,
197197
0px 0px 0px 1px rgba(0, 0, 0, 0.25) inset;

front/src/styles/scss/applications/stdcmV2/_results.scss

+3
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,9 @@
342342
box-shadow:
343343
0rem 0rem 0rem 0.125rem rgba(255, 255, 255, 0.75) inset,
344344
0rem 0rem 0rem 0.063rem rgba(0, 0, 0, 0.25) inset;
345+
&.no-pointer-events {
346+
pointer-events: none;
347+
}
345348
}
346349
}
347350
}

0 commit comments

Comments
 (0)