minotor 11.1.0 → 11.1.1
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.
- package/CHANGELOG.md +3 -3
- package/dist/cli.mjs +171 -74
- package/dist/cli.mjs.map +1 -1
- package/dist/parser.cjs.js +6 -0
- package/dist/parser.cjs.js.map +1 -1
- package/dist/parser.esm.js +6 -0
- package/dist/parser.esm.js.map +1 -1
- package/dist/router.cjs.js +1 -1
- package/dist/router.cjs.js.map +1 -1
- package/dist/router.esm.js +1 -1
- package/dist/router.esm.js.map +1 -1
- package/dist/router.umd.js +1 -1
- package/dist/router.umd.js.map +1 -1
- package/dist/routing/router.d.ts +5 -32
- package/dist/routing/state.d.ts +119 -0
- package/dist/timetable/timetable.d.ts +4 -0
- package/package.json +1 -1
- package/src/routing/__tests__/plotter.test.ts +47 -59
- package/src/routing/__tests__/result.test.ts +203 -267
- package/src/routing/plotter.ts +10 -7
- package/src/routing/result.ts +22 -20
- package/src/routing/router.ts +51 -90
- package/src/routing/state.ts +199 -0
- package/src/timetable/timetable.ts +7 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
## [11.1.1](https://github.com/aubryio/minotor/compare/v11.1.0...v11.1.1) (2026-04-18)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
###
|
|
4
|
+
### Performance Improvements
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* optimize routing state by swapping maps for arrays ([#64](https://github.com/aubryio/minotor/issues/64)) ([b37d086](https://github.com/aubryio/minotor/commit/b37d08653f115d22c4b49f88f15521efbcfdae62))
|
package/dist/cli.mjs
CHANGED
|
@@ -17025,7 +17025,6 @@ function isSet(value) {
|
|
|
17025
17025
|
return value !== null && value !== undefined;
|
|
17026
17026
|
}
|
|
17027
17027
|
|
|
17028
|
-
const TIME_INFINITY = Number.MAX_SAFE_INTEGER;
|
|
17029
17028
|
const TIME_ORIGIN = 0;
|
|
17030
17029
|
const DURATION_ZERO = 0;
|
|
17031
17030
|
/**
|
|
@@ -17763,6 +17762,12 @@ class Timetable {
|
|
|
17763
17762
|
isActive(stopId) {
|
|
17764
17763
|
return this.activeStops.has(stopId);
|
|
17765
17764
|
}
|
|
17765
|
+
/**
|
|
17766
|
+
* Returns the total number of stops in the timetable.
|
|
17767
|
+
*/
|
|
17768
|
+
nbStops() {
|
|
17769
|
+
return this.stopsAdjacency.length;
|
|
17770
|
+
}
|
|
17766
17771
|
/**
|
|
17767
17772
|
* Retrieves the route associated with the given route ID.
|
|
17768
17773
|
*
|
|
@@ -21224,8 +21229,8 @@ class Plotter {
|
|
|
21224
21229
|
* Determines station type (origin/destination) information.
|
|
21225
21230
|
*/
|
|
21226
21231
|
getStationInfo(stopId) {
|
|
21227
|
-
var _a
|
|
21228
|
-
const isOrigin = (
|
|
21232
|
+
var _a;
|
|
21233
|
+
const isOrigin = ((_a = this.result.routingState.graph[0]) === null || _a === void 0 ? void 0 : _a[stopId]) !== undefined;
|
|
21229
21234
|
const isDestination = this.result.routingState.destinations.includes(stopId);
|
|
21230
21235
|
return { isOrigin, isDestination };
|
|
21231
21236
|
}
|
|
@@ -21357,8 +21362,11 @@ class Plotter {
|
|
|
21357
21362
|
collectStations() {
|
|
21358
21363
|
const stations = new Set();
|
|
21359
21364
|
const graph = this.result.routingState.graph;
|
|
21360
|
-
for (const
|
|
21361
|
-
for (
|
|
21365
|
+
for (const roundEdges of graph) {
|
|
21366
|
+
for (let stopId = 0; stopId < roundEdges.length; stopId++) {
|
|
21367
|
+
const edge = roundEdges[stopId];
|
|
21368
|
+
if (edge === undefined)
|
|
21369
|
+
continue;
|
|
21362
21370
|
stations.add(stopId);
|
|
21363
21371
|
if (isVehicleEdge(edge)) {
|
|
21364
21372
|
const fromStopId = this.getVehicleEdgeFromStopId(edge);
|
|
@@ -21395,14 +21403,17 @@ class Plotter {
|
|
|
21395
21403
|
const continuationEdges = [];
|
|
21396
21404
|
const graph = this.result.routingState.graph;
|
|
21397
21405
|
for (let round = 0; round < graph.length; round++) {
|
|
21398
|
-
const
|
|
21399
|
-
if (!
|
|
21406
|
+
const roundEdges = graph[round];
|
|
21407
|
+
if (!roundEdges)
|
|
21400
21408
|
continue;
|
|
21401
21409
|
// Skip round 0 as it contains only origin nodes
|
|
21402
21410
|
if (round === 0) {
|
|
21403
21411
|
continue;
|
|
21404
21412
|
}
|
|
21405
|
-
for (
|
|
21413
|
+
for (let stopId = 0; stopId < roundEdges.length; stopId++) {
|
|
21414
|
+
const edge = roundEdges[stopId];
|
|
21415
|
+
if (edge === undefined)
|
|
21416
|
+
continue;
|
|
21406
21417
|
if (isVehicleEdge(edge)) {
|
|
21407
21418
|
edges.push(...this.createVehicleEdge(edge, round));
|
|
21408
21419
|
if (edge.continuationOf) {
|
|
@@ -21684,30 +21695,31 @@ class Result {
|
|
|
21684
21695
|
const destinationIterable = to instanceof Set ? to : to ? [to] : this.query.to;
|
|
21685
21696
|
// Find the fastest-reached destination across all equivalent stops.
|
|
21686
21697
|
let fastestDestination = undefined;
|
|
21687
|
-
let
|
|
21698
|
+
let fastestArrivalTime = undefined;
|
|
21699
|
+
let fastestLegNumber = undefined;
|
|
21688
21700
|
for (const sourceDestination of destinationIterable) {
|
|
21689
21701
|
const equivalentStops = this.stopsIndex.equivalentStops(sourceDestination);
|
|
21690
21702
|
for (const destination of equivalentStops) {
|
|
21691
|
-
const
|
|
21692
|
-
if (
|
|
21693
|
-
|
|
21694
|
-
|
|
21695
|
-
|
|
21696
|
-
|
|
21697
|
-
|
|
21703
|
+
const arrivalData = this.routingState.getArrival(destination.id);
|
|
21704
|
+
if (arrivalData !== undefined &&
|
|
21705
|
+
(fastestArrivalTime === undefined ||
|
|
21706
|
+
arrivalData.arrival < fastestArrivalTime)) {
|
|
21707
|
+
fastestDestination = destination.id;
|
|
21708
|
+
fastestArrivalTime = arrivalData.arrival;
|
|
21709
|
+
fastestLegNumber = arrivalData.legNumber;
|
|
21698
21710
|
}
|
|
21699
21711
|
}
|
|
21700
21712
|
}
|
|
21701
|
-
if (
|
|
21713
|
+
if (fastestDestination === undefined || fastestLegNumber === undefined) {
|
|
21702
21714
|
return undefined;
|
|
21703
21715
|
}
|
|
21704
21716
|
// Reconstruct the path by walking backwards through the routing graph.
|
|
21705
21717
|
const route = [];
|
|
21706
21718
|
let currentStop = fastestDestination;
|
|
21707
|
-
let round =
|
|
21719
|
+
let round = fastestLegNumber;
|
|
21708
21720
|
let previousVehicleEdge;
|
|
21709
21721
|
while (round > 0) {
|
|
21710
|
-
const edge = (_a = this.routingState.graph[round]) === null || _a === void 0 ? void 0 : _a
|
|
21722
|
+
const edge = (_a = this.routingState.graph[round]) === null || _a === void 0 ? void 0 : _a[currentStop];
|
|
21711
21723
|
if (!edge) {
|
|
21712
21724
|
throw new Error(`No edge arriving at stop ${currentStop} at round ${round}`);
|
|
21713
21725
|
}
|
|
@@ -21844,19 +21856,21 @@ class Result {
|
|
|
21844
21856
|
* @returns The arrival time if the target stop is reachable, otherwise undefined.
|
|
21845
21857
|
*/
|
|
21846
21858
|
arrivalAt(stop, maxTransfers) {
|
|
21847
|
-
var _a;
|
|
21859
|
+
var _a, _b;
|
|
21848
21860
|
const equivalentStops = this.stopsIndex.equivalentStops(stop);
|
|
21849
21861
|
let earliestArrival = undefined;
|
|
21850
21862
|
for (const equivalentStop of equivalentStops) {
|
|
21851
21863
|
let arrivalTime;
|
|
21852
|
-
if (maxTransfers === undefined
|
|
21853
|
-
|
|
21864
|
+
if (maxTransfers === undefined ||
|
|
21865
|
+
((_a = this.routingState.getArrival(equivalentStop.id)) === null || _a === void 0 ? void 0 : _a.legNumber) ===
|
|
21866
|
+
maxTransfers + 1) {
|
|
21867
|
+
arrivalTime = this.routingState.getArrival(equivalentStop.id);
|
|
21854
21868
|
}
|
|
21855
21869
|
else {
|
|
21856
21870
|
// We have no guarantee that the stop was visited in the last round,
|
|
21857
21871
|
// so we need to check all rounds if it's not found in the last one.
|
|
21858
21872
|
for (let i = maxTransfers + 1; i >= 0; i--) {
|
|
21859
|
-
const arrivalEdge = (
|
|
21873
|
+
const arrivalEdge = (_b = this.routingState.graph[i]) === null || _b === void 0 ? void 0 : _b[equivalentStop.id];
|
|
21860
21874
|
if (arrivalEdge !== undefined) {
|
|
21861
21875
|
arrivalTime = {
|
|
21862
21876
|
arrival: arrivalEdge.arrival,
|
|
@@ -21877,7 +21891,117 @@ class Result {
|
|
|
21877
21891
|
}
|
|
21878
21892
|
}
|
|
21879
21893
|
|
|
21880
|
-
|
|
21894
|
+
/**
|
|
21895
|
+
* Sentinel value used in the internal arrival-time array to mark stops not yet reached.
|
|
21896
|
+
* 0xFFFF = 65 535 minutes ≈ 45.5 days, safely beyond any realistic transit arrival time.
|
|
21897
|
+
*/
|
|
21898
|
+
const UNREACHED_TIME = 0xffff;
|
|
21899
|
+
/**
|
|
21900
|
+
* Encapsulates all mutable state for a single RAPTOR routing query.
|
|
21901
|
+
*/
|
|
21902
|
+
class RoutingState {
|
|
21903
|
+
/**
|
|
21904
|
+
* Initializes the routing state for a fresh query.
|
|
21905
|
+
*
|
|
21906
|
+
* All stops start as unreached. Each origin is immediately recorded at the
|
|
21907
|
+
* departure time with leg number 0, and a corresponding OriginNode is placed
|
|
21908
|
+
* in round 0 of the graph.
|
|
21909
|
+
*
|
|
21910
|
+
* @param origins Stop IDs to depart from (may be several equivalent stops).
|
|
21911
|
+
* @param destinations Stop IDs that count as the target of the query.
|
|
21912
|
+
* @param departureTime Earliest departure time in minutes from midnight.
|
|
21913
|
+
* @param nbStops Total number of stops in the timetable (sets array sizes).
|
|
21914
|
+
*/
|
|
21915
|
+
constructor(origins, destinations, departureTime, nbStops) {
|
|
21916
|
+
this.origins = origins;
|
|
21917
|
+
this.destinations = destinations;
|
|
21918
|
+
const earliestArrivalTimes = new Uint16Array(nbStops).fill(UNREACHED_TIME);
|
|
21919
|
+
const earliestArrivalLegs = new Uint8Array(nbStops); // zero-initialized = leg 0
|
|
21920
|
+
const graph0 = new Array(nbStops);
|
|
21921
|
+
for (const stop of origins) {
|
|
21922
|
+
earliestArrivalTimes[stop] = departureTime;
|
|
21923
|
+
graph0[stop] = { arrival: departureTime };
|
|
21924
|
+
}
|
|
21925
|
+
this.earliestArrivalTimes = earliestArrivalTimes;
|
|
21926
|
+
this.earliestArrivalLegs = earliestArrivalLegs;
|
|
21927
|
+
this.graph = [graph0];
|
|
21928
|
+
}
|
|
21929
|
+
/** Total number of stops in the timetable */
|
|
21930
|
+
get nbStops() {
|
|
21931
|
+
return this.earliestArrivalTimes.length;
|
|
21932
|
+
}
|
|
21933
|
+
/**
|
|
21934
|
+
* Returns the earliest known arrival time at a stop.
|
|
21935
|
+
* Returns UNREACHED_TIME if the stop has not been reached yet.
|
|
21936
|
+
*/
|
|
21937
|
+
arrivalTime(stop) {
|
|
21938
|
+
return this.earliestArrivalTimes[stop];
|
|
21939
|
+
}
|
|
21940
|
+
/**
|
|
21941
|
+
* Records a new earliest arrival at a stop.
|
|
21942
|
+
|
|
21943
|
+
*
|
|
21944
|
+
* @param stop The stop that was reached.
|
|
21945
|
+
* @param time The arrival time in minutes from midnight.
|
|
21946
|
+
* @param leg The round number (number of transit legs taken so far).
|
|
21947
|
+
*/
|
|
21948
|
+
updateArrival(stop, time, leg) {
|
|
21949
|
+
this.earliestArrivalTimes[stop] = time;
|
|
21950
|
+
this.earliestArrivalLegs[stop] = leg;
|
|
21951
|
+
}
|
|
21952
|
+
/**
|
|
21953
|
+
* Returns the earliest arrival at a stop as an {@link Arrival} object,
|
|
21954
|
+
* or undefined if the stop has not been reached.
|
|
21955
|
+
*/
|
|
21956
|
+
getArrival(stop) {
|
|
21957
|
+
const time = this.earliestArrivalTimes[stop];
|
|
21958
|
+
if (time >= UNREACHED_TIME)
|
|
21959
|
+
return undefined;
|
|
21960
|
+
return { arrival: time, legNumber: this.earliestArrivalLegs[stop] };
|
|
21961
|
+
}
|
|
21962
|
+
/**
|
|
21963
|
+
* Creates a {@link RoutingState} from fully-specified raw data.
|
|
21964
|
+
*
|
|
21965
|
+
* Use this in tests instead of constructing the object through the production
|
|
21966
|
+
* constructor, which is designed for incremental algorithm state.
|
|
21967
|
+
*
|
|
21968
|
+
* @param nbStops Total number of stops (sets array sizes).
|
|
21969
|
+
* @param origins Origin stop IDs.
|
|
21970
|
+
* @param destinations Destination stop IDs.
|
|
21971
|
+
* @param arrivals Each entry is `[stop, time, leg]` — the earliest arrival
|
|
21972
|
+
* time in minutes and the round number for one stop.
|
|
21973
|
+
* @param graph One element per round. Each round is a sparse list of
|
|
21974
|
+
* `[stop, edge]` pairs; stops absent from the list are
|
|
21975
|
+
* left as `undefined` in the dense output array.
|
|
21976
|
+
*
|
|
21977
|
+
* @internal For use in tests only.
|
|
21978
|
+
*/
|
|
21979
|
+
static fromTestData({ nbStops, origins = [], destinations = [], arrivals = [], graph = [], }) {
|
|
21980
|
+
const state = new RoutingState(origins, destinations, 0, nbStops);
|
|
21981
|
+
// Replace the arrival arrays with freshly built ones so the constructor's
|
|
21982
|
+
// origin-seeding doesn't bleed into the test state.
|
|
21983
|
+
const earliestArrivalTimes = new Uint16Array(nbStops).fill(UNREACHED_TIME);
|
|
21984
|
+
const earliestArrivalLegs = new Uint8Array(nbStops);
|
|
21985
|
+
for (const [stop, time, leg] of arrivals) {
|
|
21986
|
+
earliestArrivalTimes[stop] = time;
|
|
21987
|
+
earliestArrivalLegs[stop] = leg;
|
|
21988
|
+
}
|
|
21989
|
+
state.earliestArrivalTimes = earliestArrivalTimes;
|
|
21990
|
+
state.earliestArrivalLegs = earliestArrivalLegs;
|
|
21991
|
+
// Convert the sparse per-round representation to dense arrays and replace
|
|
21992
|
+
// the graph in-place.
|
|
21993
|
+
const denseRounds = graph.map((round) => {
|
|
21994
|
+
const arr = new Array(nbStops);
|
|
21995
|
+
for (const [stop, edge] of round) {
|
|
21996
|
+
arr[stop] = edge;
|
|
21997
|
+
}
|
|
21998
|
+
return arr;
|
|
21999
|
+
});
|
|
22000
|
+
state.graph.splice(0, state.graph.length, ...denseRounds);
|
|
22001
|
+
return state;
|
|
22002
|
+
}
|
|
22003
|
+
}
|
|
22004
|
+
|
|
21881
22005
|
/**
|
|
21882
22006
|
* A public transportation router implementing the RAPTOR algorithm.
|
|
21883
22007
|
* For more information on the RAPTOR algorithm,
|
|
@@ -21897,17 +22021,14 @@ class Router {
|
|
|
21897
22021
|
*/
|
|
21898
22022
|
route(query) {
|
|
21899
22023
|
const routingState = this.initRoutingState(query);
|
|
21900
|
-
const markedStops = new Set();
|
|
21901
|
-
for (const originStop of routingState.graph[0].keys()) {
|
|
21902
|
-
markedStops.add(originStop);
|
|
21903
|
-
}
|
|
22024
|
+
const markedStops = new Set(routingState.origins);
|
|
21904
22025
|
// Initial transfer consideration for origins
|
|
21905
22026
|
const newlyMarkedStops = this.considerTransfers(query, 0, markedStops, routingState);
|
|
21906
22027
|
for (const newStop of newlyMarkedStops) {
|
|
21907
22028
|
markedStops.add(newStop);
|
|
21908
22029
|
}
|
|
21909
22030
|
for (let round = 1; round <= query.options.maxTransfers + 1; round++) {
|
|
21910
|
-
const edgesAtCurrentRound = new
|
|
22031
|
+
const edgesAtCurrentRound = new Array(routingState.nbStops);
|
|
21911
22032
|
routingState.graph.push(edgesAtCurrentRound);
|
|
21912
22033
|
const reachableRoutes = this.timetable.findReachableRoutes(markedStops, query.options.transportModes);
|
|
21913
22034
|
markedStops.clear();
|
|
@@ -21946,13 +22067,13 @@ class Router {
|
|
|
21946
22067
|
/**
|
|
21947
22068
|
* Finds trip continuations for the given marked stops and edges at the current round.
|
|
21948
22069
|
* @param markedStops The set of marked stops.
|
|
21949
|
-
* @param edgesAtCurrentRound The
|
|
22070
|
+
* @param edgesAtCurrentRound The array of edges at the current round, indexed by stop ID.
|
|
21950
22071
|
* @returns An array of trip continuations.
|
|
21951
22072
|
*/
|
|
21952
22073
|
findTripContinuations(markedStops, edgesAtCurrentRound) {
|
|
21953
22074
|
const continuations = [];
|
|
21954
22075
|
for (const stopId of markedStops) {
|
|
21955
|
-
const arrival = edgesAtCurrentRound
|
|
22076
|
+
const arrival = edgesAtCurrentRound[stopId];
|
|
21956
22077
|
if (!arrival || !('routeId' in arrival))
|
|
21957
22078
|
continue;
|
|
21958
22079
|
const continuousTrips = this.timetable.getContinuousTrips(arrival.hopOffStopIndex, arrival.routeId, arrival.tripIndex);
|
|
@@ -21988,22 +22109,7 @@ class Router {
|
|
|
21988
22109
|
const destinations = Array.from(to)
|
|
21989
22110
|
.flatMap((destination) => this.stopsIndex.equivalentStops(destination))
|
|
21990
22111
|
.map((destination) => destination.id);
|
|
21991
|
-
|
|
21992
|
-
const earliestArrivalsWithoutAnyLeg = new Map();
|
|
21993
|
-
const earliestArrivalsPerRound = [earliestArrivalsWithoutAnyLeg];
|
|
21994
|
-
const initialState = {
|
|
21995
|
-
arrival: departureTime,
|
|
21996
|
-
legNumber: 0,
|
|
21997
|
-
};
|
|
21998
|
-
for (const originStop of origins) {
|
|
21999
|
-
earliestArrivals.set(originStop, initialState);
|
|
22000
|
-
earliestArrivalsWithoutAnyLeg.set(originStop, initialState);
|
|
22001
|
-
}
|
|
22002
|
-
return {
|
|
22003
|
-
destinations,
|
|
22004
|
-
earliestArrivals,
|
|
22005
|
-
graph: earliestArrivalsPerRound,
|
|
22006
|
-
};
|
|
22112
|
+
return new RoutingState(origins, destinations, departureTime, this.timetable.nbStops());
|
|
22007
22113
|
}
|
|
22008
22114
|
/**
|
|
22009
22115
|
* Scans a route to find the earliest possible trips (if not provided) and updates arrival times.
|
|
@@ -22020,7 +22126,6 @@ class Router {
|
|
|
22020
22126
|
* @param routingState The current routing state containing arrival times and marked stops
|
|
22021
22127
|
*/
|
|
22022
22128
|
scanRoute(route, hopOnStopIndex, round, routingState, options, tripContinuation) {
|
|
22023
|
-
var _a, _b;
|
|
22024
22129
|
const newlyMarkedStops = new Set();
|
|
22025
22130
|
let activeTrip = tripContinuation
|
|
22026
22131
|
? {
|
|
@@ -22032,7 +22137,7 @@ class Router {
|
|
|
22032
22137
|
const edgesAtCurrentRound = routingState.graph[round];
|
|
22033
22138
|
const edgesAtPreviousRound = routingState.graph[round - 1];
|
|
22034
22139
|
// Compute target pruning criteria only once per route
|
|
22035
|
-
const earliestArrivalAtAnyDestination = this.earliestArrivalAtAnyStop(routingState
|
|
22140
|
+
const earliestArrivalAtAnyDestination = this.earliestArrivalAtAnyStop(routingState);
|
|
22036
22141
|
for (let currentStopIndex = hopOnStopIndex; currentStopIndex < route.getNbStops(); currentStopIndex++) {
|
|
22037
22142
|
const currentStop = route.stops[currentStopIndex];
|
|
22038
22143
|
// If we're currently on a trip,
|
|
@@ -22040,7 +22145,7 @@ class Router {
|
|
|
22040
22145
|
if (activeTrip !== undefined) {
|
|
22041
22146
|
const arrivalTime = route.arrivalAt(currentStopIndex, activeTrip.tripIndex);
|
|
22042
22147
|
const dropOffType = route.dropOffTypeAt(currentStopIndex, activeTrip.tripIndex);
|
|
22043
|
-
const earliestArrivalAtCurrentStop =
|
|
22148
|
+
const earliestArrivalAtCurrentStop = routingState.arrivalTime(currentStop);
|
|
22044
22149
|
if (dropOffType !== NOT_AVAILABLE &&
|
|
22045
22150
|
arrivalTime < earliestArrivalAtCurrentStop &&
|
|
22046
22151
|
arrivalTime < earliestArrivalAtAnyDestination) {
|
|
@@ -22055,11 +22160,8 @@ class Router {
|
|
|
22055
22160
|
// In case of continuous trip, we set a pointer to the previous edge
|
|
22056
22161
|
edge.continuationOf = tripContinuation.previousEdge;
|
|
22057
22162
|
}
|
|
22058
|
-
edgesAtCurrentRound
|
|
22059
|
-
routingState.
|
|
22060
|
-
arrival: arrivalTime,
|
|
22061
|
-
legNumber: round,
|
|
22062
|
-
});
|
|
22163
|
+
edgesAtCurrentRound[currentStop] = edge;
|
|
22164
|
+
routingState.updateArrival(currentStop, arrivalTime, round);
|
|
22063
22165
|
newlyMarkedStops.add(currentStop);
|
|
22064
22166
|
}
|
|
22065
22167
|
}
|
|
@@ -22069,7 +22171,7 @@ class Router {
|
|
|
22069
22171
|
}
|
|
22070
22172
|
// check if we can board an earlier trip at the current stop
|
|
22071
22173
|
// if there was no current trip, find the first one reachable
|
|
22072
|
-
const previousEdge = edgesAtPreviousRound
|
|
22174
|
+
const previousEdge = edgesAtPreviousRound[currentStop];
|
|
22073
22175
|
const earliestArrivalOnPreviousRound = previousEdge === null || previousEdge === void 0 ? void 0 : previousEdge.arrival;
|
|
22074
22176
|
if (earliestArrivalOnPreviousRound !== undefined &&
|
|
22075
22177
|
(activeTrip === undefined ||
|
|
@@ -22146,12 +22248,11 @@ class Router {
|
|
|
22146
22248
|
* @param routingState The current routing state containing arrival times and marked stops
|
|
22147
22249
|
*/
|
|
22148
22250
|
considerTransfers(query, round, markedStops, routingState) {
|
|
22149
|
-
var _a, _b;
|
|
22150
22251
|
const { options } = query;
|
|
22151
22252
|
const arrivalsAtCurrentRound = routingState.graph[round];
|
|
22152
22253
|
const newlyMarkedStops = new Set();
|
|
22153
22254
|
for (const stop of markedStops) {
|
|
22154
|
-
const currentArrival = arrivalsAtCurrentRound
|
|
22255
|
+
const currentArrival = arrivalsAtCurrentRound[stop];
|
|
22155
22256
|
// Skip transfers if the last leg was also a transfer
|
|
22156
22257
|
if (!currentArrival || 'type' in currentArrival)
|
|
22157
22258
|
continue;
|
|
@@ -22170,19 +22271,16 @@ class Router {
|
|
|
22170
22271
|
transferTime = options.minTransferTime;
|
|
22171
22272
|
}
|
|
22172
22273
|
const arrivalAfterTransfer = currentArrival.arrival + transferTime;
|
|
22173
|
-
const originalArrival =
|
|
22274
|
+
const originalArrival = routingState.arrivalTime(transfer.destination);
|
|
22174
22275
|
if (arrivalAfterTransfer < originalArrival) {
|
|
22175
|
-
arrivalsAtCurrentRound
|
|
22276
|
+
arrivalsAtCurrentRound[transfer.destination] = {
|
|
22176
22277
|
arrival: arrivalAfterTransfer,
|
|
22177
22278
|
from: stop,
|
|
22178
22279
|
to: transfer.destination,
|
|
22179
22280
|
minTransferTime: transfer.minTransferTime,
|
|
22180
22281
|
type: transfer.type,
|
|
22181
|
-
}
|
|
22182
|
-
routingState.
|
|
22183
|
-
arrival: arrivalAfterTransfer,
|
|
22184
|
-
legNumber: round,
|
|
22185
|
-
});
|
|
22282
|
+
};
|
|
22283
|
+
routingState.updateArrival(transfer.destination, arrivalAfterTransfer, round);
|
|
22186
22284
|
newlyMarkedStops.add(transfer.destination);
|
|
22187
22285
|
}
|
|
22188
22286
|
}
|
|
@@ -22192,17 +22290,16 @@ class Router {
|
|
|
22192
22290
|
/**
|
|
22193
22291
|
* Finds the earliest arrival time at any stop from a given set of destinations.
|
|
22194
22292
|
*
|
|
22195
|
-
* @param
|
|
22196
|
-
* @param destinations An array of destination stops to evaluate.
|
|
22293
|
+
* @param routingState The routing state containing arrival times and destinations.
|
|
22197
22294
|
* @returns The earliest arrival time among the provided destinations.
|
|
22198
22295
|
*/
|
|
22199
|
-
earliestArrivalAtAnyStop(
|
|
22200
|
-
|
|
22201
|
-
let
|
|
22202
|
-
|
|
22203
|
-
|
|
22204
|
-
|
|
22205
|
-
|
|
22296
|
+
earliestArrivalAtAnyStop(routingState) {
|
|
22297
|
+
let earliestArrivalAtAnyDestination = UNREACHED_TIME;
|
|
22298
|
+
for (let i = 0; i < routingState.destinations.length; i++) {
|
|
22299
|
+
const arrival = routingState.arrivalTime(routingState.destinations[i]);
|
|
22300
|
+
if (arrival < earliestArrivalAtAnyDestination) {
|
|
22301
|
+
earliestArrivalAtAnyDestination = arrival;
|
|
22302
|
+
}
|
|
22206
22303
|
}
|
|
22207
22304
|
return earliestArrivalAtAnyDestination;
|
|
22208
22305
|
}
|