Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { sortBy } from 'lodash';

import type { MacroNodeResponse, OperationalPoint } from 'common/api/osrdEditoastApi';
import type { TimetableItemId, TimetableItem } from 'reducers/osrdconf/types';
import type {
MacroNodeResponse,
OperationalPoint,
PathItemLocation,
} from 'common/api/osrdEditoastApi';
import type { TimetableItemId } from 'reducers/osrdconf/types';

import type { TrainrunCategory, TrainrunFrequency } from '../NGE/types';

Expand Down Expand Up @@ -254,7 +258,7 @@ export default class MacroEditorState {
/**
* Given an path step, returns its pathKey
*/
static getPathKey(item: TimetableItem['path'][0]): string {
static getPathKey(item: PathItemLocation): string {
if ('trigram' in item)
return `trigram:${item.trigram}${item.secondary_code ? `/${item.secondary_code}` : ''}`;
if ('operational_point' in item) return `op_id:${item.operational_point}`;
Expand All @@ -273,11 +277,35 @@ export default class MacroEditorState {

const result = [];
result.push(`op_id:${op.id}`);
result.push(`trigram:${trigram}${ch ? `/${ch}` : ''}`);
result.push(`uic:${uic}${ch ? `/${ch}` : ''}`);
if (trigram) result.push(`trigram:${trigram}${ch ? `/${ch}` : ''}`);
if (uic) result.push(`uic:${uic}${ch ? `/${ch}` : ''}`);
for (const opPart of op.parts) {
result.push(`track_offset:${opPart.track}+${opPart.position}`);
}
return result;
}

static parsePathKey(key: string): PathItemLocation {
const [type, value] = key.split(':');
if (!value) throw new Error('Invalid path key');
switch (type) {
case 'op_id': {
return { operational_point: value };
}
case 'trigram': {
const [trigram, secondary_code] = value.split('/');
return { trigram, secondary_code };
}
case 'uic': {
const [uic, secondary_code] = value.split('/');
return { uic: Number(uic), secondary_code };
}
case 'track_offset': {
const [track, offset] = value.split('+');
return { track, offset: Number(offset) };
}
default:
throw new Error(`Invalid path key type "${type}"`);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
type PacedTrain,
type SearchResultItemOperationalPoint,
type TrainSchedule,
type PathItemLocation,
} from 'common/api/osrdEditoastApi';
import {
createPacedTrain,
Expand Down Expand Up @@ -44,7 +45,7 @@ import {
DEFAULT_TIME_WINDOW,
TRAINRUN_DIRECTIONS,
} from './consts';
import type MacroEditorState from './MacroEditorState';
import MacroEditorState from './MacroEditorState';
import type { NodeIndexed } from './MacroEditorState';
import {
createMacroNode,
Expand Down Expand Up @@ -165,11 +166,21 @@ const getTrainrunSectionsByTrainrunId = (
return orderedSectionPaths;
};

const createPathItemFromNode = (node: NodeDto, index: number) => {
const [trigram, secondaryCode] = node.betriebspunktName.split('/');
const createPathItemFromNode = (
node: NodeDto,
index: number,
state?: MacroEditorState
): TrainSchedule['path'][number] => {
let pathItemLocation: PathItemLocation;
if (state) {
const indexedNode = state.getNodeByNgeId(node.id)!;
pathItemLocation = MacroEditorState.parsePathKey(indexedNode.path_item_key);
} else {
const [trigram, secondary_code] = node.betriebspunktName.split('/');
pathItemLocation = { trigram, secondary_code };
}
return {
trigram,
secondary_code: secondaryCode,
...pathItemLocation,
id: `${node.id}-${index}`,
deleted: false,
// TODO : handle this case in xml import refacto
Expand All @@ -196,16 +207,17 @@ const formatDateDifferenceFrom = (start: Date, stop: Date) =>
export const generatePath = (
trainrunSections: TrainrunSectionDto[],
nodes: NodeDto[],
trainrunDirection: TRAINRUN_DIRECTIONS
trainrunDirection: TRAINRUN_DIRECTIONS,
state?: MacroEditorState
): TrainSchedule['path'] => {
const isForward = trainrunDirection === TRAINRUN_DIRECTIONS.FORWARD;
const path = trainrunSections.map((section, index) => {
const fromNode = getNodeById(nodes, isForward ? section.sourceNodeId : section.targetNodeId);
const toNode = getNodeById(nodes, isForward ? section.targetNodeId : section.sourceNodeId);
if (!fromNode || !toNode) return [];
const originPathItem = createPathItemFromNode(fromNode, index);
const originPathItem = createPathItemFromNode(fromNode, index, state);
if (index === trainrunSections.length - 1) {
const destinationPathItem = createPathItemFromNode(toNode, index + 1);
const destinationPathItem = createPathItemFromNode(toNode, index + 1, state);
return [originPathItem, destinationPathItem];
}
return [originPathItem];
Expand Down Expand Up @@ -341,15 +353,16 @@ const generatePathAndSchedule = (
trainrunSections: TrainrunSectionDto[],
nodes: NodeDto[],
baseDate?: Date,
trainrunDirection: TRAINRUN_DIRECTIONS = TRAINRUN_DIRECTIONS.FORWARD
trainrunDirection: TRAINRUN_DIRECTIONS = TRAINRUN_DIRECTIONS.FORWARD,
state?: MacroEditorState
) => {
let sections = trainrunSections;
if (trainrunDirection === TRAINRUN_DIRECTIONS.BACKWARD) {
sections = [...trainrunSections].reverse();
}

const startDate = calculateStartDate(sections, baseDate ?? new Date(), trainrunDirection);
const path = generatePath(sections, nodes, trainrunDirection);
const path = generatePath(sections, nodes, trainrunDirection, state);
const schedule = generateSchedule(sections, nodes, startDate, trainrunDirection);
return { start_time: startDate.toISOString(), path, schedule };
};
Expand Down Expand Up @@ -418,13 +431,20 @@ const handleCreateTimetableItem = async (
'ngeToOsrd handleCreateTimetableItem received a one_way train dto instead of a round trip'
);
}
const pathAndSchedule = generatePathAndSchedule(trainrunSections, netzgrafikDto.nodes);
const pathAndSchedule = generatePathAndSchedule(
trainrunSections,
netzgrafikDto.nodes,
undefined,
TRAINRUN_DIRECTIONS.FORWARD,
state
);

const returnPathAndSchedule = generatePathAndSchedule(
trainrunSections,
netzgrafikDto.nodes,
undefined,
TRAINRUN_DIRECTIONS.BACKWARD
TRAINRUN_DIRECTIONS.BACKWARD,
state
);

await populateSecondaryCodesInPath(
Expand Down Expand Up @@ -590,7 +610,9 @@ const handleUpdateTimetableItem = async ({
const forwardPathAndSchedule = generatePathAndSchedule(
trainrunSections,
netzgrafikDto.nodes,
new Date(oldForwardTimetableItem.start_time)
new Date(oldForwardTimetableItem.start_time),
TRAINRUN_DIRECTIONS.FORWARD,
state
);
await populateSecondaryCodesInPath(forwardPathAndSchedule.path, infraId, dispatch);

Expand Down Expand Up @@ -672,7 +694,8 @@ const handleUpdateTimetableItem = async ({
trainrunSections,
netzgrafikDto.nodes,
new Date(oldForwardTimetableItem.start_time),
TRAINRUN_DIRECTIONS.BACKWARD
TRAINRUN_DIRECTIONS.BACKWARD,
state
);

await populateSecondaryCodesInPath(returnPathAndSchedule.path, infraId, dispatch);
Expand Down
Loading