minotor 11.2.1 → 11.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -34,6 +34,9 @@ export interface IRaptorState {
34
34
  */
35
35
  readonly destinationBest: Time;
36
36
 
37
+ /** Latest arrival time allowed by the current query/run. */
38
+ readonly maxArrivalTime: Time;
39
+
37
40
  /** Returns `true` if `stop` is one of the query's destination stops. */
38
41
  isDestination(stop: StopId): boolean;
39
42
 
@@ -212,6 +215,7 @@ export class Raptor {
212
215
 
213
216
  if (
214
217
  dropOffType !== NOT_AVAILABLE &&
218
+ arrivalTime <= state.maxArrivalTime &&
215
219
  arrivalTime < state.improvementBound(round, currentStop) &&
216
220
  arrivalTime < state.destinationBest
217
221
  ) {
@@ -282,6 +286,7 @@ export class Raptor {
282
286
 
283
287
  if (
284
288
  dropOffType !== NOT_AVAILABLE &&
289
+ arrivalTime <= state.maxArrivalTime &&
285
290
  arrivalTime < state.improvementBound(round, currentStop) &&
286
291
  arrivalTime < state.destinationBest
287
292
  ) {
@@ -334,17 +339,21 @@ export class Raptor {
334
339
  );
335
340
 
336
341
  if (firstBoardableTrip !== undefined) {
342
+ const departureTime = route.departureFrom(
343
+ currentStopIndex,
344
+ firstBoardableTrip,
345
+ );
337
346
  // At round 1, enforce maxInitialWaitingTime: skip boarding if the
338
347
  // traveler would have to wait longer than the allowed threshold at
339
348
  // the first boarding stop.
340
349
  const exceedsInitialWait =
341
350
  round === 1 &&
342
351
  options.maxInitialWaitingTime !== undefined &&
343
- route.departureFrom(currentStopIndex, firstBoardableTrip) -
344
- earliestArrivalOnPreviousRound >
352
+ departureTime - earliestArrivalOnPreviousRound >
345
353
  options.maxInitialWaitingTime;
354
+ const exceedsMaxDuration = departureTime > state.maxArrivalTime;
346
355
 
347
- if (!exceedsInitialWait) {
356
+ if (!exceedsInitialWait && !exceedsMaxDuration) {
348
357
  activeTripIndex = firstBoardableTrip;
349
358
  activeTripBoardStopIndex = currentStopIndex;
350
359
  activeTripStopOffset = route.tripStopOffset(firstBoardableTrip);
@@ -391,6 +400,7 @@ export class Raptor {
391
400
  const arrivalAfterTransfer = currentArrival.arrival + transferTime;
392
401
 
393
402
  if (
403
+ arrivalAfterTransfer <= state.maxArrivalTime &&
394
404
  arrivalAfterTransfer <
395
405
  state.improvementBound(round, transfer.destination) &&
396
406
  arrivalAfterTransfer < state.destinationBest
@@ -398,7 +408,7 @@ export class Raptor {
398
408
  arrivalsAtCurrentRound[transfer.destination] = {
399
409
  arrival: arrivalAfterTransfer,
400
410
  from: stop,
401
- to: transfer.destination,
411
+ to: transfer.destination, // TODO needed?
402
412
  minTransferTime: transferTime || undefined,
403
413
  type: transfer.type,
404
414
  } as TransferEdge;
@@ -33,7 +33,7 @@ export type VehicleEdge = TripStop & {
33
33
  export type TransferEdge = {
34
34
  arrival: Time;
35
35
  from: StopId;
36
- to: StopId;
36
+ to: StopId; // TODO remove
37
37
  type: TransferType;
38
38
  minTransferTime?: Duration;
39
39
  };
@@ -61,7 +61,16 @@ export class RoutingState implements IRaptorState {
61
61
  * Indexed as graph[round][stopId]. Entries are undefined for stops not
62
62
  * reached in that particular round.
63
63
  */
64
+ // TODO do not expose
64
65
  readonly graph: (RoutingEdge | undefined)[][];
66
+ // TODO Can use typed arrays to represent the graph
67
+ // Uint32 [(alightStopId -> ? =index/to), boardingStopId (stopIndex,from),
68
+ // RouteId/TransferId, TripId (if not transfer), (previous_round, previous_stop
69
+ // -> allows to reconstruct transfers incl. continuous]
70
+ // TODO should try to reuse them in range raptor and use only one init
71
+
72
+ // TODO take out arrival times from Graph
73
+ // private arrivalTimes: Uint16Array[];
65
74
 
66
75
  /**
67
76
  * Earliest arrival time at each stop (minutes from midnight), indexed by stop ID.
@@ -89,6 +98,18 @@ export class RoutingState implements IRaptorState {
89
98
  */
90
99
  private _destinationBest: Time = UNREACHED_TIME;
91
100
 
101
+ /**
102
+ * Maximum arrival time allowed for this run. Defaults to UNREACHED_TIME when
103
+ * the query has no maxDuration limit.
104
+ */
105
+ maxArrivalTime: Time = UNREACHED_TIME;
106
+
107
+ /**
108
+ * Query-level maximum duration, retained so resetFor() can recompute the
109
+ * absolute max arrival time for each departure-time iteration.
110
+ */
111
+ private readonly maxDuration?: Duration;
112
+
92
113
  /**
93
114
  * Every stop that has received an arrival improvement during the current run,
94
115
  * in the order the improvements occurred. Used by {@link resetFor} to clear
@@ -102,8 +123,12 @@ export class RoutingState implements IRaptorState {
102
123
  accessPaths: AccessPoint[],
103
124
  nbStops: number,
104
125
  maxRounds: number = 0,
126
+ maxDuration?: Duration,
105
127
  ) {
106
128
  this.destinations = destinations;
129
+ this.maxDuration = maxDuration;
130
+ this.maxArrivalTime =
131
+ maxDuration === undefined ? UNREACHED_TIME : departureTime + maxDuration;
107
132
  this.destinationSet = new Set(destinations);
108
133
  this.earliestArrivalTimes = new Uint16Array(nbStops).fill(UNREACHED_TIME);
109
134
  this.earliestArrivalLegs = new Uint8Array(nbStops);
@@ -126,6 +151,7 @@ export class RoutingState implements IRaptorState {
126
151
  const seededOrigins = new Set<StopId>();
127
152
  for (const access of accessPaths) {
128
153
  const arrival = depTime + access.duration;
154
+ if (arrival > this.maxArrivalTime) continue;
129
155
  const edge: OriginNode | AccessEdge =
130
156
  access.duration === 0
131
157
  ? { stopId: access.fromStopId, arrival: depTime }
@@ -224,6 +250,10 @@ export class RoutingState implements IRaptorState {
224
250
  }
225
251
  this.reachedStops.length = 0;
226
252
  this._destinationBest = UNREACHED_TIME;
253
+ this.maxArrivalTime =
254
+ this.maxDuration === undefined
255
+ ? UNREACHED_TIME
256
+ : depTime + this.maxDuration;
227
257
  this.seedAccessPaths(depTime, accessPaths);
228
258
  }
229
259
 
@@ -18,11 +18,8 @@ import { Route, RouteId, StopRouteIndex, TripRouteIndex } from './route.js';
18
18
  import { Duration, DURATION_ZERO, Time, TIME_ORIGIN } from './time.js';
19
19
  import { encode, TripStopId } from './tripStopId.js';
20
20
 
21
- export type TransferType =
22
- | 'RECOMMENDED'
23
- | 'GUARANTEED'
24
- | 'REQUIRES_MINIMAL_TIME'
25
- | 'IN_SEAT';
21
+ export type TransferType = // TODO use number to represent that.
22
+ 'RECOMMENDED' | 'GUARANTEED' | 'REQUIRES_MINIMAL_TIME' | 'IN_SEAT';
26
23
 
27
24
  export type Transfer = {
28
25
  destination: StopId;