diff --git a/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx b/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx index 3fb160ddebb..936d28ce066 100644 --- a/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx +++ b/front/src/applications/operationalStudies/views/ManageTrainSchedule.tsx @@ -102,7 +102,12 @@ const ManageTrainSchedule = ({ trainIdToEdit }: ManageTrainScheduleProps) => {
- + + diff --git a/front/src/applications/stdcm/utils/index.ts b/front/src/applications/stdcm/utils/index.ts index 357f65fc67e..69a31a2cb46 100644 --- a/front/src/applications/stdcm/utils/index.ts +++ b/front/src/applications/stdcm/utils/index.ts @@ -17,6 +17,7 @@ export const extractMarkersInfo = (pathSteps: StdcmPathStep[]) => pathSteps.reduce((acc, step) => { if (step.location) { acc.push({ + uic: step.location.uic, coordinates: step.location.coordinates, name: step.location.name, }); diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx index 057bd0e8445..4e74e862dea 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/ManageTrainScheduleMap/ItineraryMarkers.tsx @@ -1,28 +1,24 @@ -import { useCallback, useMemo } from 'react'; +import { useCallback, useEffect, useMemo, useState } from 'react'; import cx from 'classnames'; import type { Position } from 'geojson'; -import type { Map } from 'maplibre-gl'; import { Marker } from 'react-map-gl/maplibre'; +import useCachedTrackSections from 'applications/operationalStudies/hooks/useCachedTrackSections'; import destinationSVG from 'assets/pictures/destination.svg'; import stdcmDestination from 'assets/pictures/mapMarkers/destination.svg'; import stdcmVia from 'assets/pictures/mapMarkers/intermediate-point.svg'; import stdcmOrigin from 'assets/pictures/mapMarkers/start.svg'; import originSVG from 'assets/pictures/origin.svg'; import viaSVG from 'assets/pictures/via.svg'; -import { getNearestTrack } from 'utils/mapHelper'; - -export type MarkerInformation = { - name?: string; - coordinates?: number[] | Position; - metadata?: { - lineCode: number; - lineName: string; - trackName: string; - trackNumber: number; - }; -}; +import type { PathItemLocation, TrackSection } from 'common/api/osrdEditoastApi'; +import { matchPathStepAndOp } from 'modules/pathfinding/utils'; +import type { PathStep } from 'reducers/osrdconf/types'; + +import type { SuggestedOP } from '../types'; + +export type MarkerInformation = Pick & + PathItemLocation; enum MARKER_TYPE { ORIGIN = 'origin', @@ -31,7 +27,8 @@ enum MARKER_TYPE { } type MarkerProperties = { - marker: MarkerInformation; + op: SuggestedOP; + pathStep: MarkerInformation; coordinates: number[] | Position; imageSource: string; } & ( @@ -45,9 +42,10 @@ type MarkerProperties = { ); type ItineraryMarkersProps = { - map: Map; simulationPathSteps: MarkerInformation[]; + pathStepsAndSuggestedOPs?: SuggestedOP[]; showStdcmAssets: boolean; + infraId: number; }; const formatPointWithNoName = ( @@ -65,122 +63,156 @@ const formatPointWithNoName = ( ); -const extractMarkerInformation = (pathSteps: MarkerInformation[], showStdcmAssets: boolean) => - pathSteps.reduce((acc, cur, index) => { - if (cur && cur.coordinates) { - if (index === 0) { - acc.push({ - coordinates: cur.coordinates, - type: MARKER_TYPE.ORIGIN, - marker: cur, - imageSource: showStdcmAssets ? stdcmOrigin : originSVG, - }); - } else if (index > 0 && index < pathSteps.length - 1) { - acc.push({ - coordinates: cur.coordinates, +const extractMarkerInformation = ( + pathSteps: MarkerInformation[], + showStdcmAssets: boolean, + suggestedOP: SuggestedOP[] +): MarkerProperties[] => + pathSteps + .map((pathStep, index): MarkerProperties | null => { + const matchingOp = suggestedOP.find((op) => matchPathStepAndOp(pathStep, op)); + + if (!matchingOp) return null; + + if (pathStep.coordinates) { + if (index === 0) { + return { + coordinates: pathStep.coordinates, + type: MARKER_TYPE.ORIGIN, + imageSource: showStdcmAssets ? stdcmOrigin : originSVG, + op: matchingOp, + pathStep, + }; + } + + if (index === pathSteps.length - 1) { + return { + coordinates: pathStep.coordinates, + type: MARKER_TYPE.DESTINATION, + imageSource: showStdcmAssets ? stdcmDestination : destinationSVG, + op: matchingOp, + pathStep, + }; + } + + return { + coordinates: pathStep.coordinates, type: MARKER_TYPE.VIA, - marker: cur, imageSource: showStdcmAssets ? stdcmVia : viaSVG, index, - }); - } else if (index === pathSteps.length - 1) { - acc.push({ - coordinates: cur.coordinates, - type: MARKER_TYPE.DESTINATION, - marker: cur, - imageSource: showStdcmAssets ? stdcmDestination : destinationSVG, - }); + op: matchingOp, + pathStep, + }; } - } - return acc; - }, [] as MarkerProperties[]); + return null; + }) + .filter((marker): marker is MarkerProperties => marker !== null); + +const ItineraryMarkers = ({ + simulationPathSteps, + pathStepsAndSuggestedOPs, + showStdcmAssets, + infraId, +}: ItineraryMarkersProps) => { + const { getTrackSectionsByIds } = useCachedTrackSections(infraId); -const ItineraryMarkers = ({ map, simulationPathSteps, showStdcmAssets }: ItineraryMarkersProps) => { const markersInformation = useMemo( - () => extractMarkerInformation(simulationPathSteps, showStdcmAssets), + () => + pathStepsAndSuggestedOPs && + extractMarkerInformation(simulationPathSteps, showStdcmAssets, pathStepsAndSuggestedOPs), [simulationPathSteps, showStdcmAssets] ); - const getMarkerDisplayInformation = useCallback( - (markerInfo: MarkerProperties) => { - const { - marker: { coordinates: markerCoordinates, metadata: markerMetadata }, - type: markerType, - } = markerInfo; + if (!markersInformation) return null; - if (markerMetadata) { - const { - lineCode: markerLineCode, - lineName: markerLineName, - trackName: markerTrackName, - } = markerMetadata; - return formatPointWithNoName(markerLineCode, markerLineName, markerTrackName, markerType); - } + const [trackSections, setTrackSections] = useState>({}); - if (!markerCoordinates) return null; - - const trackResult = getNearestTrack(markerCoordinates, map); - if (trackResult) { - const { - track: { properties: trackProperties }, - } = trackResult; - if (trackProperties) { - const { - extensions_sncf_line_code: lineCode, - extensions_sncf_line_name: lineName, - extensions_sncf_track_name: trackName, - } = trackProperties; - if (lineCode && lineName && trackName) - return formatPointWithNoName(lineCode, lineName, trackName, markerType); - } - } + useEffect(() => { + const fetchTrackSections = async () => { + const trackId = markersInformation.map((markerInfo) => markerInfo.op.track); + setTrackSections(await getTrackSectionsByIds(trackId)); + }; + fetchTrackSections(); + }, [markersInformation]); - return null; - }, - [map] - ); + const getMarkerDisplayInformation = useCallback((markerInfo: MarkerProperties) => { + const { + pathStep: { metadata: markerMetadata, name: markerName }, + type: markerType, + } = markerInfo; - const Markers = useMemo( - () => - markersInformation.map((markerInfo) => { - const isDestination = markerInfo.type === MARKER_TYPE.DESTINATION; - const isVia = markerInfo.type === MARKER_TYPE.VIA; + if (markerName) return markerName; + if (!markerMetadata) return null; + + const { + lineCode: markerLineCode, + lineName: markerLineName, + trackName: markerTrackName, + } = markerMetadata; + + return formatPointWithNoName(markerLineCode, markerLineName, markerTrackName, markerType); + }, []); + + return markersInformation.map((markerInfo) => { + const isDestination = markerInfo.type === MARKER_TYPE.DESTINATION; + const isVia = markerInfo.type === MARKER_TYPE.VIA; + + if (!markerInfo.pathStep.metadata) { + const { op } = markerInfo; + const trackId = op.track; + const trackSection = trackSections[trackId]; + + const metadataFromSuggestedOp = trackSection?.extensions?.sncf; + + if (!metadataFromSuggestedOp) return null; - const markerName = ( + const { + line_code: markerLineCode, + line_name: markerLineName, + track_name: markerTrackName, + track_number: markerTrackNumber, + } = metadataFromSuggestedOp; + + markerInfo.pathStep = { + ...markerInfo.pathStep, + metadata: { + lineCode: markerLineCode, + lineName: markerLineName, + trackName: markerTrackName, + trackNumber: markerTrackNumber, + }, + }; + } + + return ( + + {markerInfo.type} + {isVia && ( + + {markerInfo.index} + + )} + {!showStdcmAssets && (
- {markerInfo.marker.name - ? markerInfo.marker.name - : getMarkerDisplayInformation(markerInfo)} + {getMarkerDisplayInformation(markerInfo)}
- ); - return ( - - {markerInfo.type} - {isVia && ( - - {markerInfo.index} - - )} - {!showStdcmAssets && markerName} - - ); - }), - [markersInformation, showStdcmAssets] - ); - return Markers; + )} +
+ ); + }); }; export default ItineraryMarkers; diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/Map.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/Map.tsx index adeef57281f..4022cfa0c0f 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/Map.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/Map.tsx @@ -46,7 +46,7 @@ import ItineraryLayer from './ManageTrainScheduleMap/ItineraryLayer'; import ItineraryMarkers, { type MarkerInformation, } from './ManageTrainScheduleMap/ItineraryMarkers'; -import type { FeatureInfoClick } from './types'; +import type { FeatureInfoClick, SuggestedOP } from './types'; type MapProps = { pathProperties?: ManageTrainSchedulePathProperties; @@ -57,6 +57,7 @@ type MapProps = { preventPointSelection?: boolean; mapId?: string; simulationPathSteps: MarkerInformation[]; + pathStepsAndSuggestedOPs?: SuggestedOP[]; showStdcmAssets?: boolean; isFeasible?: boolean; }; @@ -70,6 +71,7 @@ const Map = ({ preventPointSelection = false, mapId = 'map-container', simulationPathSteps, + pathStepsAndSuggestedOPs, showStdcmAssets = false, isFeasible = true, children, @@ -333,11 +335,12 @@ const Map = ({ showStdcmAssets={showStdcmAssets} isFeasible={isFeasible} /> - {mapRef.current && ( + {mapRef.current && infraID && ( )} {mapSearchMarker && } diff --git a/front/src/modules/trainschedule/components/ManageTrainSchedule/NewMap.tsx b/front/src/modules/trainschedule/components/ManageTrainSchedule/NewMap.tsx index e3e09fe9467..8fd451b56c1 100644 --- a/front/src/modules/trainschedule/components/ManageTrainSchedule/NewMap.tsx +++ b/front/src/modules/trainschedule/components/ManageTrainSchedule/NewMap.tsx @@ -346,11 +346,11 @@ const NewMap = ({ showStdcmAssets={showStdcmAssets} isFeasible={isFeasible} /> - {mapRef.current && ( + {mapRef.current && infraID && ( )} {mapSearchMarker && }