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