1
1
import type { TrainScheduleResult } from 'common/api/osrdEditoastApi' ;
2
- import type { TrainScheduleWithDetails } from 'modules/trainschedule/components/Timetable/types' ;
2
+ import type {
3
+ TheoreticalMarginsRecord ,
4
+ TrainScheduleWithDetails ,
5
+ } from 'modules/trainschedule/components/Timetable/types' ;
3
6
import { ms2sec } from 'utils/timeManipulation' ;
4
7
5
8
import { formatDigitsAndUnit } from './utils' ;
9
+ import type { ScheduleEntry } from '../types' ;
6
10
7
- function getTheoreticalMargin ( selectedTrainSchedule : TrainScheduleResult , pathStepId : string ) {
8
- if ( selectedTrainSchedule . path . length === 0 ) {
11
+ export function getTheoreticalMargins ( selectedTrainSchedule : TrainScheduleResult ) {
12
+ const selectedTrainScheduleMargins = selectedTrainSchedule . margins ;
13
+ if ( ! selectedTrainScheduleMargins ) {
9
14
return undefined ;
10
15
}
11
- // pathStep is starting point => we take the first margin
12
- if ( selectedTrainSchedule . path [ 0 ] . id === pathStepId ) {
13
- return selectedTrainSchedule . margins ?. values [ 0 ] ;
14
- }
15
- const theoreticalMarginBoundaryIndex = selectedTrainSchedule . margins ?. boundaries ?. findIndex (
16
- ( id ) => id === pathStepId
17
- ) ;
18
- if (
19
- theoreticalMarginBoundaryIndex === undefined ||
20
- theoreticalMarginBoundaryIndex < 0 ||
21
- theoreticalMarginBoundaryIndex > selectedTrainSchedule . margins ! . values . length - 2
22
- ) {
23
- return undefined ;
24
- }
25
-
26
- return selectedTrainSchedule . margins ! . values [ theoreticalMarginBoundaryIndex + 1 ] ;
16
+ const theoreticalMargins : TheoreticalMarginsRecord = { } ;
17
+ let marginIndex = 0 ;
18
+ selectedTrainSchedule . path . forEach ( ( step , index ) => {
19
+ let isBoundary = index === 0 ;
20
+ if ( step . id === selectedTrainSchedule . margins ?. boundaries [ marginIndex ] ) {
21
+ marginIndex += 1 ;
22
+ isBoundary = true ;
23
+ }
24
+ theoreticalMargins [ step . id ] = {
25
+ theoreticalMargin : selectedTrainScheduleMargins . values [ marginIndex ] ,
26
+ isBoundary,
27
+ } ;
28
+ } ) ;
29
+ return theoreticalMargins ;
27
30
}
28
31
29
32
function computeMargins (
33
+ theoreticalMargins : TheoreticalMarginsRecord | undefined ,
30
34
selectedTrainSchedule : TrainScheduleResult ,
35
+ scheduleByAt : Record < string , ScheduleEntry > ,
31
36
pathStepIndex : number ,
32
37
pathItemTimes : NonNullable < TrainScheduleWithDetails [ 'pathItemTimes' ] > // in ms
33
38
) {
34
39
const { path, margins } = selectedTrainSchedule ;
40
+ const pathStepId = path [ pathStepIndex ] . id ;
35
41
if (
36
42
! margins ||
37
- ( margins . values . length === 1 && margins . values [ 0 ] === '0%' ) ||
38
- pathStepIndex === selectedTrainSchedule . path . length - 1
43
+ pathStepIndex === selectedTrainSchedule . path . length - 1 ||
44
+ ! theoreticalMargins ||
45
+ ! theoreticalMargins [ pathStepId ] ||
46
+ ! (
47
+ scheduleByAt [ pathStepId ] ?. arrival ||
48
+ scheduleByAt [ pathStepId ] ?. stop_for ||
49
+ theoreticalMargins [ pathStepId ] . isBoundary
50
+ )
39
51
) {
40
52
return {
41
53
theoreticalMargin : undefined ,
@@ -45,14 +57,21 @@ function computeMargins(
45
57
} ;
46
58
}
47
59
48
- const pathStepId = path [ pathStepIndex ] . id ;
49
- const theoreticalMargin = getTheoreticalMargin ( selectedTrainSchedule , pathStepId ) ;
60
+ const { theoreticalMargin, isBoundary } = theoreticalMargins [ pathStepId ] ;
61
+
62
+ // find the next pathStep where constraints are defined
63
+ let nextIndex = path . length - 1 ;
50
64
51
- // find the previous pathStep where margin was defined
52
- let prevIndex = 0 ;
53
- for ( let index = 1 ; index < pathStepIndex ; index += 1 ) {
54
- if ( margins . boundaries . includes ( path [ index ] . id ) ) {
55
- prevIndex = index ;
65
+ for ( let index = pathStepIndex + 1 ; index < path . length ; index += 1 ) {
66
+ const curStepId = path [ index ] . id ;
67
+ const curStepSchedule = scheduleByAt [ curStepId ] ;
68
+ if (
69
+ theoreticalMargins [ curStepId ] ?. isBoundary ||
70
+ curStepSchedule ?. arrival ||
71
+ curStepSchedule ?. stop_for
72
+ ) {
73
+ nextIndex = index ;
74
+ break ;
56
75
}
57
76
}
58
77
@@ -61,16 +80,17 @@ function computeMargins(
61
80
// provisional = margins
62
81
// final = margins + requested arrival times
63
82
const { base, provisional, final } = pathItemTimes ;
64
- const baseDuration = ms2sec ( base [ pathStepIndex + 1 ] - base [ prevIndex ] ) ;
65
- const provisionalDuration = ms2sec ( provisional [ pathStepIndex + 1 ] - provisional [ prevIndex ] ) ;
66
- const finalDuration = ms2sec ( final [ pathStepIndex + 1 ] - final [ prevIndex ] ) ;
83
+ const baseDuration = ms2sec ( base [ nextIndex ] - base [ pathStepIndex ] ) ;
84
+ const provisionalDuration = ms2sec ( provisional [ nextIndex ] - provisional [ pathStepIndex ] ) ;
85
+ const finalDuration = ms2sec ( final [ nextIndex ] - final [ pathStepIndex ] ) ;
67
86
68
87
// how much longer it took (s) with the margin than without
69
88
const provisionalLostTime = provisionalDuration - baseDuration ;
70
89
const finalLostTime = finalDuration - baseDuration ;
71
90
72
91
return {
73
92
theoreticalMargin : formatDigitsAndUnit ( theoreticalMargin ) ,
93
+ isTheoreticalMarginBoundary : isBoundary ,
74
94
theoreticalMarginSeconds : `${ Math . round ( provisionalLostTime ) } s` ,
75
95
calculatedMargin : `${ Math . round ( finalLostTime ) } s` ,
76
96
diffMargins : `${ Math . round ( finalLostTime - provisionalLostTime ) } s` ,
0 commit comments