minotor 6.0.0 → 7.0.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 -8
- package/dist/cli.mjs +121 -98
- package/dist/cli.mjs.map +1 -1
- package/dist/parser.cjs.js +99 -88
- package/dist/parser.cjs.js.map +1 -1
- package/dist/parser.esm.js +99 -88
- 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 +1 -1
- package/dist/timetable/route.d.ts +2 -11
- package/dist/timetable/timetable.d.ts +1 -1
- package/package.json +1 -1
- package/src/__e2e__/timetable/timetable.bin +1 -1
- package/src/gtfs/trips.ts +10 -4
- package/src/routing/router.ts +22 -10
- package/src/stops/stopsIndex.ts +24 -22
- package/src/timetable/__tests__/route.test.ts +0 -19
- package/src/timetable/io.ts +39 -19
- package/src/timetable/proto/timetable.proto +2 -2
- package/src/timetable/proto/timetable.ts +6 -6
- package/src/timetable/route.ts +25 -54
- package/src/timetable/timetable.ts +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
## [7.0.1](https://github.com/aubryio/minotor/compare/v7.0.0...v7.0.1) (2025-09-23)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
###
|
|
4
|
+
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
### BREAKING CHANGES
|
|
10
|
-
|
|
11
|
-
* Stops and timetable binary format was updated and is not compatible with the old ones.
|
|
6
|
+
* address corner cases with boarding conditions ([#27](https://github.com/aubryio/minotor/issues/27)) ([cd5fe68](https://github.com/aubryio/minotor/commit/cd5fe682ca359872a6bac46dbdc30ec9d603c8ef))
|
package/dist/cli.mjs
CHANGED
|
@@ -16079,20 +16079,15 @@ const serializeLocationType = (locationType) => {
|
|
|
16079
16079
|
*/
|
|
16080
16080
|
class StopsIndex {
|
|
16081
16081
|
constructor(stops) {
|
|
16082
|
+
var _a;
|
|
16082
16083
|
this.stops = stops;
|
|
16083
16084
|
this.sourceStopsMap = new Map();
|
|
16084
|
-
stops.forEach((stop, id) => {
|
|
16085
|
-
this.sourceStopsMap.set(stop.sourceStopId, id);
|
|
16086
|
-
});
|
|
16087
|
-
this.textIndex = lt({
|
|
16088
|
-
fields: ['name'],
|
|
16089
|
-
storeFields: ['id'],
|
|
16090
|
-
searchOptions: { prefix: true, fuzzy: 0.2 },
|
|
16091
|
-
processTerm: generateAccentVariants,
|
|
16092
|
-
});
|
|
16093
16085
|
const stopsSet = new Map();
|
|
16094
|
-
|
|
16095
|
-
|
|
16086
|
+
this.stopPoints = [];
|
|
16087
|
+
for (let id = 0; id < stops.length; id++) {
|
|
16088
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
16089
|
+
const stop = stops[id];
|
|
16090
|
+
this.sourceStopsMap.set(stop.sourceStopId, id);
|
|
16096
16091
|
const effectiveStopId = (_a = stop.parent) !== null && _a !== void 0 ? _a : id;
|
|
16097
16092
|
if (!stopsSet.has(effectiveStopId)) {
|
|
16098
16093
|
stopsSet.set(effectiveStopId, {
|
|
@@ -16101,22 +16096,26 @@ class StopsIndex {
|
|
|
16101
16096
|
name: stop.parent ? this.stops[stop.parent].name : stop.name,
|
|
16102
16097
|
});
|
|
16103
16098
|
}
|
|
16099
|
+
if (stop.lat && stop.lon) {
|
|
16100
|
+
this.stopPoints.push({
|
|
16101
|
+
id: id,
|
|
16102
|
+
lat: stop.lat,
|
|
16103
|
+
lon: stop.lon,
|
|
16104
|
+
});
|
|
16105
|
+
}
|
|
16106
|
+
}
|
|
16107
|
+
this.textIndex = lt({
|
|
16108
|
+
fields: ['name'],
|
|
16109
|
+
storeFields: ['id'],
|
|
16110
|
+
searchOptions: { prefix: true, fuzzy: 0.2 },
|
|
16111
|
+
processTerm: generateAccentVariants,
|
|
16104
16112
|
});
|
|
16105
16113
|
const stopsArray = Array.from(stopsSet.values());
|
|
16106
16114
|
q(this.textIndex, stopsArray);
|
|
16107
|
-
this.stopPoints = this.stops
|
|
16108
|
-
.filter((stop) => {
|
|
16109
|
-
if (stop.lat && stop.lon)
|
|
16110
|
-
return true;
|
|
16111
|
-
return false;
|
|
16112
|
-
})
|
|
16113
|
-
.map((stop, id) => ({
|
|
16114
|
-
id: id,
|
|
16115
|
-
lat: stop.lat,
|
|
16116
|
-
lon: stop.lon,
|
|
16117
|
-
}));
|
|
16118
16115
|
this.geoIndex = new KDBush(this.stopPoints.length);
|
|
16119
|
-
for (
|
|
16116
|
+
for (let i = 0; i < this.stopPoints.length; i++) {
|
|
16117
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
16118
|
+
const { lat, lon } = this.stopPoints[i];
|
|
16120
16119
|
this.geoIndex.add(lon, lat);
|
|
16121
16120
|
}
|
|
16122
16121
|
this.geoIndex.finish();
|
|
@@ -16629,7 +16628,7 @@ const StopAdjacency = {
|
|
|
16629
16628
|
}
|
|
16630
16629
|
writer.uint32(18).fork();
|
|
16631
16630
|
for (const v of message.routes) {
|
|
16632
|
-
writer.
|
|
16631
|
+
writer.uint32(v);
|
|
16633
16632
|
}
|
|
16634
16633
|
writer.join();
|
|
16635
16634
|
return writer;
|
|
@@ -16650,13 +16649,13 @@ const StopAdjacency = {
|
|
|
16650
16649
|
}
|
|
16651
16650
|
case 2: {
|
|
16652
16651
|
if (tag === 16) {
|
|
16653
|
-
message.routes.push(reader.
|
|
16652
|
+
message.routes.push(reader.uint32());
|
|
16654
16653
|
continue;
|
|
16655
16654
|
}
|
|
16656
16655
|
if (tag === 18) {
|
|
16657
16656
|
const end2 = reader.uint32() + reader.pos;
|
|
16658
16657
|
while (reader.pos < end2) {
|
|
16659
|
-
message.routes.push(reader.
|
|
16658
|
+
message.routes.push(reader.uint32());
|
|
16660
16659
|
}
|
|
16661
16660
|
continue;
|
|
16662
16661
|
}
|
|
@@ -16713,7 +16712,7 @@ const ServiceRoute = {
|
|
|
16713
16712
|
}
|
|
16714
16713
|
writer.uint32(26).fork();
|
|
16715
16714
|
for (const v of message.routes) {
|
|
16716
|
-
writer.
|
|
16715
|
+
writer.uint32(v);
|
|
16717
16716
|
}
|
|
16718
16717
|
writer.join();
|
|
16719
16718
|
return writer;
|
|
@@ -16741,13 +16740,13 @@ const ServiceRoute = {
|
|
|
16741
16740
|
}
|
|
16742
16741
|
case 3: {
|
|
16743
16742
|
if (tag === 24) {
|
|
16744
|
-
message.routes.push(reader.
|
|
16743
|
+
message.routes.push(reader.uint32());
|
|
16745
16744
|
continue;
|
|
16746
16745
|
}
|
|
16747
16746
|
if (tag === 26) {
|
|
16748
16747
|
const end2 = reader.uint32() + reader.pos;
|
|
16749
16748
|
while (reader.pos < end2) {
|
|
16750
|
-
message.routes.push(reader.
|
|
16749
|
+
message.routes.push(reader.uint32());
|
|
16751
16750
|
}
|
|
16752
16751
|
continue;
|
|
16753
16752
|
}
|
|
@@ -17302,27 +17301,6 @@ let Route$1 = class Route {
|
|
|
17302
17301
|
: byte & 0x03; // Lower 2 bits for first pair
|
|
17303
17302
|
return toPickupDropOffType(dropOffValue);
|
|
17304
17303
|
}
|
|
17305
|
-
/**
|
|
17306
|
-
* Iterates over the stops in the route, starting from an optional specified stop.
|
|
17307
|
-
* If no start stop is provided, the iteration begins from the first stop in the route.
|
|
17308
|
-
*
|
|
17309
|
-
* @param [startStopId] - (Optional) The StopId of the stop to start the iteration from.
|
|
17310
|
-
* @returns An IterableIterator of StopIds, starting from the specified stop or the first stop.
|
|
17311
|
-
* @throws An error if the specified start stop is not found in the route.
|
|
17312
|
-
*/
|
|
17313
|
-
stopsIterator(startStopId) {
|
|
17314
|
-
const startIndex = startStopId !== undefined ? this.stopIndices.get(startStopId) : 0;
|
|
17315
|
-
if (startIndex === undefined) {
|
|
17316
|
-
throw new Error(`Start stop ${startStopId} not found in route ${this.serviceRouteId}`);
|
|
17317
|
-
}
|
|
17318
|
-
function* generator(stops, startIndex) {
|
|
17319
|
-
for (let i = startIndex; i < stops.length; i++) {
|
|
17320
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
17321
|
-
yield stops[i];
|
|
17322
|
-
}
|
|
17323
|
-
}
|
|
17324
|
-
return generator(this.stops, startIndex);
|
|
17325
|
-
}
|
|
17326
17304
|
/**
|
|
17327
17305
|
* Finds the earliest trip that can be taken from a specific stop on a given route,
|
|
17328
17306
|
* optionally constrained by a latest trip index and a time before which the trip
|
|
@@ -17336,29 +17314,35 @@ let Route$1 = class Route {
|
|
|
17336
17314
|
* @returns The index of the earliest trip meeting the criteria, or undefined if no such trip is found.
|
|
17337
17315
|
*/
|
|
17338
17316
|
findEarliestTrip(stopId, after = Time.origin(), beforeTrip) {
|
|
17339
|
-
|
|
17340
|
-
? Math.min(beforeTrip - 1, this.nbTrips - 1)
|
|
17341
|
-
: this.nbTrips - 1;
|
|
17342
|
-
if (maxTripIndex < 0) {
|
|
17317
|
+
if (this.nbTrips <= 0)
|
|
17343
17318
|
return undefined;
|
|
17344
|
-
|
|
17345
|
-
|
|
17346
|
-
|
|
17347
|
-
|
|
17348
|
-
|
|
17349
|
-
|
|
17350
|
-
|
|
17351
|
-
|
|
17352
|
-
|
|
17353
|
-
|
|
17354
|
-
|
|
17355
|
-
|
|
17319
|
+
let hi = this.nbTrips - 1;
|
|
17320
|
+
if (beforeTrip !== undefined)
|
|
17321
|
+
hi = Math.min(hi, beforeTrip - 1);
|
|
17322
|
+
if (hi < 0)
|
|
17323
|
+
return undefined;
|
|
17324
|
+
let lo = 0;
|
|
17325
|
+
let lb = -1;
|
|
17326
|
+
while (lo <= hi) {
|
|
17327
|
+
const mid = (lo + hi) >>> 1;
|
|
17328
|
+
const depMid = this.departureFrom(stopId, mid);
|
|
17329
|
+
if (depMid.isBefore(after)) {
|
|
17330
|
+
lo = mid + 1;
|
|
17356
17331
|
}
|
|
17357
17332
|
else {
|
|
17358
|
-
|
|
17333
|
+
lb = mid;
|
|
17334
|
+
hi = mid - 1;
|
|
17359
17335
|
}
|
|
17360
17336
|
}
|
|
17361
|
-
|
|
17337
|
+
if (lb === -1)
|
|
17338
|
+
return undefined;
|
|
17339
|
+
for (let t = lb; t < (beforeTrip !== null && beforeTrip !== void 0 ? beforeTrip : this.nbTrips); t++) {
|
|
17340
|
+
const pickup = this.pickUpTypeFrom(stopId, t);
|
|
17341
|
+
if (pickup !== 'NOT_AVAILABLE') {
|
|
17342
|
+
return t;
|
|
17343
|
+
}
|
|
17344
|
+
}
|
|
17345
|
+
return undefined;
|
|
17362
17346
|
}
|
|
17363
17347
|
/**
|
|
17364
17348
|
* Retrieves the index of a stop within the route.
|
|
@@ -17472,31 +17456,48 @@ const serializeServiceRoutesMap = (serviceRoutes) => {
|
|
|
17472
17456
|
});
|
|
17473
17457
|
};
|
|
17474
17458
|
const deserializeStopsAdjacency = (protoStopsAdjacency) => {
|
|
17475
|
-
|
|
17476
|
-
|
|
17477
|
-
|
|
17459
|
+
const result = [];
|
|
17460
|
+
for (let i = 0; i < protoStopsAdjacency.length; i++) {
|
|
17461
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
17462
|
+
const value = protoStopsAdjacency[i];
|
|
17463
|
+
const transfers = [];
|
|
17464
|
+
for (let j = 0; j < value.transfers.length; j++) {
|
|
17465
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
17466
|
+
const transfer = value.transfers[j];
|
|
17467
|
+
const newTransfer = Object.assign({ destination: transfer.destination, type: parseTransferType(transfer.type) }, (transfer.minTransferTime !== undefined && {
|
|
17478
17468
|
minTransferTime: Duration.fromSeconds(transfer.minTransferTime),
|
|
17479
|
-
}))
|
|
17469
|
+
}));
|
|
17470
|
+
transfers.push(newTransfer);
|
|
17471
|
+
}
|
|
17472
|
+
result.push({
|
|
17473
|
+
transfers: transfers,
|
|
17480
17474
|
routes: value.routes,
|
|
17481
|
-
};
|
|
17482
|
-
}
|
|
17475
|
+
});
|
|
17476
|
+
}
|
|
17477
|
+
return result;
|
|
17483
17478
|
};
|
|
17484
17479
|
const deserializeRoutesAdjacency = (protoRoutesAdjacency) => {
|
|
17485
17480
|
const routesAdjacency = [];
|
|
17486
|
-
protoRoutesAdjacency.
|
|
17481
|
+
for (let i = 0; i < protoRoutesAdjacency.length; i++) {
|
|
17482
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
17483
|
+
const value = protoRoutesAdjacency[i];
|
|
17487
17484
|
const stops = bytesToUint32Array(value.stops);
|
|
17488
17485
|
routesAdjacency.push(new Route$1(bytesToUint16Array(value.stopTimes), value.pickUpDropOffTypes, stops, value.serviceRouteId));
|
|
17489
|
-
}
|
|
17486
|
+
}
|
|
17490
17487
|
return routesAdjacency;
|
|
17491
17488
|
};
|
|
17492
17489
|
const deserializeServiceRoutesMap = (protoServiceRoutes) => {
|
|
17493
|
-
|
|
17494
|
-
|
|
17490
|
+
const result = [];
|
|
17491
|
+
for (let i = 0; i < protoServiceRoutes.length; i++) {
|
|
17492
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
17493
|
+
const value = protoServiceRoutes[i];
|
|
17494
|
+
result.push({
|
|
17495
17495
|
type: parseRouteType(value.type),
|
|
17496
17496
|
name: value.name,
|
|
17497
17497
|
routes: value.routes,
|
|
17498
|
-
};
|
|
17499
|
-
}
|
|
17498
|
+
});
|
|
17499
|
+
}
|
|
17500
|
+
return result;
|
|
17500
17501
|
};
|
|
17501
17502
|
const parseTransferType = (type) => {
|
|
17502
17503
|
switch (type) {
|
|
@@ -17588,7 +17589,7 @@ const ALL_TRANSPORT_MODES = new Set([
|
|
|
17588
17589
|
'TROLLEYBUS',
|
|
17589
17590
|
'MONORAIL',
|
|
17590
17591
|
]);
|
|
17591
|
-
const CURRENT_VERSION = '0.0.
|
|
17592
|
+
const CURRENT_VERSION = '0.0.7';
|
|
17592
17593
|
/**
|
|
17593
17594
|
* The internal transit timetable format.
|
|
17594
17595
|
*/
|
|
@@ -17696,7 +17697,8 @@ class Timetable {
|
|
|
17696
17697
|
return [];
|
|
17697
17698
|
}
|
|
17698
17699
|
const routes = [];
|
|
17699
|
-
for (
|
|
17700
|
+
for (let i = 0; i < stopData.routes.length; i++) {
|
|
17701
|
+
const routeId = stopData.routes[i];
|
|
17700
17702
|
const route = this.routesAdjacency[routeId];
|
|
17701
17703
|
if (route) {
|
|
17702
17704
|
routes.push(route);
|
|
@@ -17715,12 +17717,15 @@ class Timetable {
|
|
|
17715
17717
|
*/
|
|
17716
17718
|
findReachableRoutes(fromStops, transportModes = ALL_TRANSPORT_MODES) {
|
|
17717
17719
|
const reachableRoutes = new Map();
|
|
17718
|
-
|
|
17720
|
+
const fromStopsArray = Array.from(fromStops);
|
|
17721
|
+
for (let i = 0; i < fromStopsArray.length; i++) {
|
|
17722
|
+
const originStop = fromStopsArray[i];
|
|
17719
17723
|
const validRoutes = this.routesPassingThrough(originStop).filter((route) => {
|
|
17720
17724
|
const serviceRoute = this.getServiceRouteInfo(route);
|
|
17721
17725
|
return transportModes.has(serviceRoute.type);
|
|
17722
17726
|
});
|
|
17723
|
-
for (
|
|
17727
|
+
for (let j = 0; j < validRoutes.length; j++) {
|
|
17728
|
+
const route = validRoutes[j];
|
|
17724
17729
|
const hopOnStop = reachableRoutes.get(route);
|
|
17725
17730
|
if (hopOnStop) {
|
|
17726
17731
|
if (route.isBefore(originStop, hopOnStop)) {
|
|
@@ -20135,8 +20140,12 @@ const buildStopsAdjacencyStructure = (serviceRoutes, routes, transfersMap, nbSto
|
|
|
20135
20140
|
for (let i = 0; i < nbStops; i++) {
|
|
20136
20141
|
stopsAdjacency[i] = { routes: [], transfers: [] };
|
|
20137
20142
|
}
|
|
20138
|
-
routes.
|
|
20139
|
-
|
|
20143
|
+
for (let index = 0; index < routes.length; index++) {
|
|
20144
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20145
|
+
const route = routes[index];
|
|
20146
|
+
for (let j = 0; j < route.getNbStops(); j++) {
|
|
20147
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20148
|
+
const stop = route.stops[j];
|
|
20140
20149
|
if (activeStops.has(stop)) {
|
|
20141
20150
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20142
20151
|
stopsAdjacency[stop].routes.push(index);
|
|
@@ -20147,9 +20156,11 @@ const buildStopsAdjacencyStructure = (serviceRoutes, routes, transfersMap, nbSto
|
|
|
20147
20156
|
throw new Error(`Service route ${route.serviceRoute()} not found for route ${index}.`);
|
|
20148
20157
|
}
|
|
20149
20158
|
serviceRoute.routes.push(index);
|
|
20150
|
-
}
|
|
20159
|
+
}
|
|
20151
20160
|
for (const [stop, transfers] of transfersMap) {
|
|
20152
|
-
for (
|
|
20161
|
+
for (let i = 0; i < transfers.length; i++) {
|
|
20162
|
+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20163
|
+
const transfer = transfers[i];
|
|
20153
20164
|
if (activeStops.has(stop) || activeStops.has(transfer.destination)) {
|
|
20154
20165
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
20155
20166
|
stopsAdjacency[stop].transfers.push(transfer);
|
|
@@ -20796,7 +20807,7 @@ class Result {
|
|
|
20796
20807
|
|
|
20797
20808
|
const UNREACHED = Time.infinity();
|
|
20798
20809
|
/**
|
|
20799
|
-
* A public transportation network router
|
|
20810
|
+
* A public transportation network router implementing the RAPTOR algorithm for
|
|
20800
20811
|
* efficient journey planning and routing. For more information on the RAPTOR
|
|
20801
20812
|
* algorithm, refer to its detailed explanation in the research paper:
|
|
20802
20813
|
* https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/raptor_alenex.pdf
|
|
@@ -20815,7 +20826,9 @@ class Router {
|
|
|
20815
20826
|
var _a, _b;
|
|
20816
20827
|
const { options } = query;
|
|
20817
20828
|
const newlyMarkedStops = new Set();
|
|
20818
|
-
|
|
20829
|
+
const markedStopsArray = Array.from(markedStops);
|
|
20830
|
+
for (let i = 0; i < markedStopsArray.length; i++) {
|
|
20831
|
+
const stop = markedStopsArray[i];
|
|
20819
20832
|
const currentArrival = arrivalsAtCurrentRound.get(stop);
|
|
20820
20833
|
if (!currentArrival)
|
|
20821
20834
|
continue;
|
|
@@ -20824,7 +20837,9 @@ class Router {
|
|
|
20824
20837
|
if (previousLeg && !('route' in previousLeg)) {
|
|
20825
20838
|
continue;
|
|
20826
20839
|
}
|
|
20827
|
-
|
|
20840
|
+
const transfers = this.timetable.getTransfers(stop);
|
|
20841
|
+
for (let j = 0; j < transfers.length; j++) {
|
|
20842
|
+
const transfer = transfers[j];
|
|
20828
20843
|
let transferTime;
|
|
20829
20844
|
if (transfer.minTransferTime) {
|
|
20830
20845
|
transferTime = transfer.minTransferTime;
|
|
@@ -20859,7 +20874,9 @@ class Router {
|
|
|
20859
20874
|
}
|
|
20860
20875
|
}
|
|
20861
20876
|
}
|
|
20862
|
-
|
|
20877
|
+
const newlyMarkedStopsArray = Array.from(newlyMarkedStops);
|
|
20878
|
+
for (let i = 0; i < newlyMarkedStopsArray.length; i++) {
|
|
20879
|
+
const newStop = newlyMarkedStopsArray[i];
|
|
20863
20880
|
markedStops.add(newStop);
|
|
20864
20881
|
}
|
|
20865
20882
|
}
|
|
@@ -20873,7 +20890,8 @@ class Router {
|
|
|
20873
20890
|
earliestArrivalAtAnyStop(earliestArrivals, destinations) {
|
|
20874
20891
|
var _a, _b;
|
|
20875
20892
|
let earliestArrivalAtAnyDestination = UNREACHED;
|
|
20876
|
-
for (
|
|
20893
|
+
for (let i = 0; i < destinations.length; i++) {
|
|
20894
|
+
const destination = destinations[i];
|
|
20877
20895
|
const arrival = (_b = (_a = earliestArrivals.get(destination.id)) === null || _a === void 0 ? void 0 : _a.arrival) !== null && _b !== void 0 ? _b : UNREACHED;
|
|
20878
20896
|
earliestArrivalAtAnyDestination = Time.min(earliestArrivalAtAnyDestination, arrival);
|
|
20879
20897
|
}
|
|
@@ -20897,7 +20915,8 @@ class Router {
|
|
|
20897
20915
|
const earliestArrivalsPerRound = [earliestArrivalsWithoutAnyLeg];
|
|
20898
20916
|
// Stops that have been improved at round k-1
|
|
20899
20917
|
const markedStops = new Set();
|
|
20900
|
-
for (
|
|
20918
|
+
for (let i = 0; i < origins.length; i++) {
|
|
20919
|
+
const originStop = origins[i];
|
|
20901
20920
|
markedStops.add(originStop.id);
|
|
20902
20921
|
earliestArrivals.set(originStop.id, {
|
|
20903
20922
|
arrival: departureTime,
|
|
@@ -20921,9 +20940,13 @@ class Router {
|
|
|
20921
20940
|
const reachableRoutes = this.timetable.findReachableRoutes(markedStops, options.transportModes);
|
|
20922
20941
|
markedStops.clear();
|
|
20923
20942
|
// for each route that can be reached with at least round - 1 trips
|
|
20924
|
-
|
|
20943
|
+
const reachableRoutesArray = Array.from(reachableRoutes.entries());
|
|
20944
|
+
for (let i = 0; i < reachableRoutesArray.length; i++) {
|
|
20945
|
+
const [route, hopOnStop] = reachableRoutesArray[i];
|
|
20925
20946
|
let currentTrip = undefined;
|
|
20926
|
-
|
|
20947
|
+
const startIndex = route.stopIndex(hopOnStop);
|
|
20948
|
+
for (let j = startIndex; j < route.getNbStops(); j++) {
|
|
20949
|
+
const currentStop = route.stops[j];
|
|
20927
20950
|
// If we're currently on a trip,
|
|
20928
20951
|
// check if arrival at the stop improves the earliest arrival time
|
|
20929
20952
|
if (currentTrip !== undefined) {
|
|
@@ -20959,8 +20982,8 @@ class Router {
|
|
|
20959
20982
|
const earliestArrivalOnPreviousRound = (_c = arrivalsAtPreviousRound.get(currentStop)) === null || _c === void 0 ? void 0 : _c.arrival;
|
|
20960
20983
|
if (earliestArrivalOnPreviousRound !== undefined &&
|
|
20961
20984
|
(currentTrip === undefined ||
|
|
20962
|
-
earliestArrivalOnPreviousRound.isBefore(route.
|
|
20963
|
-
earliestArrivalOnPreviousRound.equals(route.
|
|
20985
|
+
earliestArrivalOnPreviousRound.isBefore(route.departureFrom(currentStop, currentTrip.tripIndex)) ||
|
|
20986
|
+
earliestArrivalOnPreviousRound.equals(route.departureFrom(currentStop, currentTrip.tripIndex)))) {
|
|
20964
20987
|
const earliestTrip = route.findEarliestTrip(currentStop, earliestArrivalOnPreviousRound, currentTrip === null || currentTrip === void 0 ? void 0 : currentTrip.tripIndex);
|
|
20965
20988
|
if (earliestTrip !== undefined) {
|
|
20966
20989
|
currentTrip = {
|