@@ -37,19 +37,92 @@ export function formatCreationDate(date: string) {
37
37
} ;
38
38
}
39
39
40
+ export function getStopDurationTime ( sec : number ) {
41
+ const timeInMilliseconds = sec * 1000 ;
42
+ const time = new Date ( timeInMilliseconds ) ;
43
+
44
+ if ( timeInMilliseconds < 60000 ) {
45
+ return `${ time . getUTCSeconds ( ) } sec` ;
46
+ }
47
+ return `${ time . getUTCMinutes ( ) } min` ;
48
+ }
49
+
40
50
export function extractSpeedLimit ( speedLimitByTag : string ) : string {
41
51
const parts = speedLimitByTag . split ( ' - ' ) ;
42
52
return parts [ parts . length - 1 ] ;
43
53
}
44
54
55
+ function secondsToTimeString ( duration : number ) : string {
56
+ const minutes = Math . floor ( duration / 60 ) ;
57
+ const seconds = duration % 60 ;
58
+ return `${ String ( minutes ) . padStart ( 2 , '0' ) } :${ String ( seconds ) . padStart ( 2 , '0' ) } ` ;
59
+ }
60
+
61
+ function timeStringToSeconds ( time : string ) : number {
62
+ const [ minutes , seconds ] = time . split ( ':' ) . map ( Number ) ;
63
+ return minutes * 60 + seconds ;
64
+ }
65
+
66
+ /**
67
+ * Based on a stop arrival time and a stop duration, calculate the departure time on this stop
68
+ */
69
+ function computeStopDepartureTime ( hhmm : string , mmss : string ) : string {
70
+ const [ hh , mm ] = hhmm . split ( ':' ) . map ( Number ) ;
71
+ const totalSeconds1 = hh * 3600 + mm * 60 ;
72
+ const totalSeconds2 = timeStringToSeconds ( mmss ) ;
73
+
74
+ const totalSeconds = totalSeconds1 + totalSeconds2 ;
75
+ const hours = Math . floor ( totalSeconds / 3600 ) ;
76
+ const minutes = Math . floor ( ( totalSeconds % 3600 ) / 60 ) ;
77
+
78
+ return `${ String ( hours ) . padStart ( 2 , '0' ) } :${ String ( minutes ) . padStart ( 2 , '0' ) } ` ;
79
+ }
80
+
81
+ // Function to add minutes to the departure time
82
+ const addMinutesToTime = ( baseHour : number , baseMinute : number , minutesToAdd : number ) : string => {
83
+ const totalMinutes = baseHour * 60 + baseMinute + minutesToAdd ;
84
+ const finalHour = Math . floor ( totalMinutes / 60 ) % 24 ;
85
+ const finalMinutes = totalMinutes % 60 ;
86
+ return `${ String ( finalHour ) . padStart ( 2 , '0' ) } :${ String ( finalMinutes ) . padStart ( 2 , '0' ) } ` ;
87
+ } ;
88
+
89
+ const getTimeAtPosition = (
90
+ trainPosition : number ,
91
+ trainPositions : number [ ] ,
92
+ trainTimes : number [ ] ,
93
+ trainDepartureHour : number ,
94
+ trainDepartureMinute : number
95
+ ) : string => {
96
+ const index = trainPositions . findIndex ( ( pos ) => pos >= trainPosition ) ;
97
+ const timeInMillis = trainTimes [ index ] ;
98
+ const timeInMinutes = Math . floor ( timeInMillis / 60000 ) ;
99
+ return addMinutesToTime ( trainDepartureHour , trainDepartureMinute , timeInMinutes ) ;
100
+ } ;
101
+
102
+ const getStopDurationBetweenToPositions = (
103
+ position : number ,
104
+ trainPositions : number [ ] ,
105
+ trainTimes : number [ ]
106
+ ) : number | null => {
107
+ const firstIndex = trainPositions . indexOf ( position ) ;
108
+ const lastIndex = trainPositions . lastIndexOf ( position ) ;
109
+ if ( firstIndex !== - 1 && lastIndex !== - 1 && firstIndex !== lastIndex ) {
110
+ return trainTimes [ lastIndex ] - trainTimes [ firstIndex ] ;
111
+ }
112
+ return null ;
113
+ } ;
114
+
45
115
export function getOperationalPointsWithTimes ( simulationReport : SimulationReportSheetProps ) : {
46
116
opId : string ;
47
117
positionOnPath : number ;
48
118
time : string | null ;
49
119
name : string | undefined ;
50
120
ch : string | undefined ;
51
121
stop : string | null | undefined ;
122
+ duration : number ;
52
123
departureTime : string ;
124
+ stopEndTime : string ;
125
+ trackName : string | undefined ;
53
126
} [ ] {
54
127
const operationalPoints = simulationReport . pathProperties ?. suggestedOperationalPoints || [ ] ;
55
128
const { simulation } = simulationReport . stdcmData ;
@@ -66,29 +139,7 @@ export function getOperationalPointsWithTimes(simulationReport: SimulationReport
66
139
// Parse departure time into hours and minutes
67
140
const [ departureHour , departureMinute ] = departureTime . split ( ':' ) . map ( Number ) ;
68
141
69
- // Function to add minutes to the departure time
70
- const addMinutesToTime = ( baseHour : number , baseMinute : number , minutesToAdd : number ) : string => {
71
- const totalMinutes = baseHour * 60 + baseMinute + minutesToAdd ;
72
- const finalHour = Math . floor ( totalMinutes / 60 ) % 24 ;
73
- const finalMinutes = totalMinutes % 60 ;
74
- return `${ String ( finalHour ) . padStart ( 2 , '0' ) } :${ String ( finalMinutes ) . padStart ( 2 , '0' ) } ` ;
75
- } ;
76
-
77
- const getTimeAtPosition = (
78
- trainPosition : number ,
79
- trainPositions : number [ ] ,
80
- trainTimes : number [ ] ,
81
- trainDepartureHour : number ,
82
- trainDepartureMinute : number
83
- ) : string | null => {
84
- const index = trainPositions . findIndex ( ( pos ) => pos >= trainPosition ) ;
85
- if ( index === - 1 ) return null ;
86
- const timeInMillis = trainTimes [ index ] ;
87
- const timeInMinutes = Math . floor ( timeInMillis / 60000 ) ;
88
- return addMinutesToTime ( trainDepartureHour , trainDepartureMinute , timeInMinutes ) ;
89
- } ;
90
-
91
- // Map operational points with their positions and times
142
+ // Map operational points with their positions, times, and stop durations
92
143
const opResults = operationalPoints . map ( ( op ) => {
93
144
const formattedTime = getTimeAtPosition (
94
145
op . positionOnPath ,
@@ -98,14 +149,22 @@ export function getOperationalPointsWithTimes(simulationReport: SimulationReport
98
149
departureMinute
99
150
) ;
100
151
152
+ const duration = getStopDurationBetweenToPositions ( op . positionOnPath , positions , times ) ;
153
+ const durationInSeconds = duration !== null ? duration / 1000 : 0 ;
154
+ const durationToString = secondsToTimeString ( durationInSeconds ) ;
155
+ const stopEndTime = computeStopDepartureTime ( formattedTime , durationToString ) ;
156
+
101
157
return {
102
158
opId : op . opId ,
103
159
positionOnPath : op . positionOnPath ,
104
160
time : formattedTime ,
105
161
name : op . name ,
106
162
ch : op . ch ,
107
163
stop : op . stopFor ,
164
+ duration : durationInSeconds ,
108
165
departureTime,
166
+ stopEndTime,
167
+ trackName : op . metadata ?. trackName ,
109
168
} ;
110
169
} ) ;
111
170
0 commit comments