minotor 1.0.2 → 1.0.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.
- package/.prettierignore +1 -0
- package/CHANGELOG.md +2 -2
- package/dist/cli/minotor.d.ts +1 -1
- package/dist/cli/utils.d.ts +1 -1
- package/dist/{bundle.cjs.js → parser.cjs.js} +11 -433
- package/dist/parser.cjs.js.map +1 -0
- package/dist/parser.d.ts +3 -0
- package/dist/{bundle.esm.js → parser.esm.js} +12 -426
- package/dist/parser.esm.js.map +1 -0
- package/dist/router.cjs.js +2 -0
- package/dist/router.cjs.js.map +1 -0
- package/dist/router.esm.js +2 -0
- package/dist/router.esm.js.map +1 -0
- package/dist/{bundle.umd.js → router.umd.js} +1 -1
- package/dist/{bundle.umd.js.map → router.umd.js.map} +1 -1
- package/dist/routing/result.d.ts +1 -1
- package/dist/routing/router.d.ts +1 -1
- package/package.json +13 -8
- package/rollup.config.js +22 -11
- package/src/cli/minotor.ts +1 -1
- package/src/cli/repl.ts +1 -1
- package/src/cli/utils.ts +1 -1
- package/src/parser.ts +4 -0
- package/src/{umdIndex.ts → router.ts} +0 -4
- package/src/routing/result.ts +1 -1
- package/src/routing/router.ts +1 -1
- package/dist/bundle.cjs.js.map +0 -1
- package/dist/bundle.esm.js.map +0 -1
- package/dist/index.d.ts +0 -12
- package/src/index.ts +0 -34
- /package/dist/{umdIndex.d.ts → router.d.ts} +0 -0
package/dist/parser.d.ts
ADDED
|
@@ -12132,7 +12132,7 @@ const StopTimes = {
|
|
|
12132
12132
|
function createBaseRoute() {
|
|
12133
12133
|
return { stopTimes: [], stops: [], serviceRouteId: "" };
|
|
12134
12134
|
}
|
|
12135
|
-
const Route
|
|
12135
|
+
const Route = {
|
|
12136
12136
|
encode(message, writer = new BinaryWriter()) {
|
|
12137
12137
|
for (const v of message.stopTimes) {
|
|
12138
12138
|
StopTimes.encode(v, writer.uint32(10).fork()).join();
|
|
@@ -12205,7 +12205,7 @@ const Route$1 = {
|
|
|
12205
12205
|
return obj;
|
|
12206
12206
|
},
|
|
12207
12207
|
create(base) {
|
|
12208
|
-
return Route
|
|
12208
|
+
return Route.fromPartial(base !== null && base !== undefined ? base : {});
|
|
12209
12209
|
},
|
|
12210
12210
|
fromPartial(object) {
|
|
12211
12211
|
var _a, _b, _c;
|
|
@@ -12255,7 +12255,7 @@ const RoutesAdjacency = {
|
|
|
12255
12255
|
return {
|
|
12256
12256
|
routes: isObject(object.routes)
|
|
12257
12257
|
? Object.entries(object.routes).reduce((acc, [key, value]) => {
|
|
12258
|
-
acc[key] = Route
|
|
12258
|
+
acc[key] = Route.fromJSON(value);
|
|
12259
12259
|
return acc;
|
|
12260
12260
|
}, {})
|
|
12261
12261
|
: {},
|
|
@@ -12268,7 +12268,7 @@ const RoutesAdjacency = {
|
|
|
12268
12268
|
if (entries.length > 0) {
|
|
12269
12269
|
obj.routes = {};
|
|
12270
12270
|
entries.forEach(([k, v]) => {
|
|
12271
|
-
obj.routes[k] = Route
|
|
12271
|
+
obj.routes[k] = Route.toJSON(v);
|
|
12272
12272
|
});
|
|
12273
12273
|
}
|
|
12274
12274
|
}
|
|
@@ -12282,7 +12282,7 @@ const RoutesAdjacency = {
|
|
|
12282
12282
|
const message = createBaseRoutesAdjacency();
|
|
12283
12283
|
message.routes = Object.entries((_a = object.routes) !== null && _a !== undefined ? _a : {}).reduce((acc, [key, value]) => {
|
|
12284
12284
|
if (value !== undefined) {
|
|
12285
|
-
acc[key] = Route
|
|
12285
|
+
acc[key] = Route.fromPartial(value);
|
|
12286
12286
|
}
|
|
12287
12287
|
return acc;
|
|
12288
12288
|
}, {});
|
|
@@ -12298,7 +12298,7 @@ const RoutesAdjacency_RoutesEntry = {
|
|
|
12298
12298
|
writer.uint32(10).string(message.key);
|
|
12299
12299
|
}
|
|
12300
12300
|
if (message.value !== undefined) {
|
|
12301
|
-
Route
|
|
12301
|
+
Route.encode(message.value, writer.uint32(18).fork()).join();
|
|
12302
12302
|
}
|
|
12303
12303
|
return writer;
|
|
12304
12304
|
},
|
|
@@ -12320,7 +12320,7 @@ const RoutesAdjacency_RoutesEntry = {
|
|
|
12320
12320
|
if (tag !== 18) {
|
|
12321
12321
|
break;
|
|
12322
12322
|
}
|
|
12323
|
-
message.value = Route
|
|
12323
|
+
message.value = Route.decode(reader, reader.uint32());
|
|
12324
12324
|
continue;
|
|
12325
12325
|
}
|
|
12326
12326
|
}
|
|
@@ -12334,7 +12334,7 @@ const RoutesAdjacency_RoutesEntry = {
|
|
|
12334
12334
|
fromJSON(object) {
|
|
12335
12335
|
return {
|
|
12336
12336
|
key: isSet(object.key) ? globalThis.String(object.key) : "",
|
|
12337
|
-
value: isSet(object.value) ? Route
|
|
12337
|
+
value: isSet(object.value) ? Route.fromJSON(object.value) : undefined,
|
|
12338
12338
|
};
|
|
12339
12339
|
},
|
|
12340
12340
|
toJSON(message) {
|
|
@@ -12343,7 +12343,7 @@ const RoutesAdjacency_RoutesEntry = {
|
|
|
12343
12343
|
obj.key = message.key;
|
|
12344
12344
|
}
|
|
12345
12345
|
if (message.value !== undefined) {
|
|
12346
|
-
obj.value = Route
|
|
12346
|
+
obj.value = Route.toJSON(message.value);
|
|
12347
12347
|
}
|
|
12348
12348
|
return obj;
|
|
12349
12349
|
},
|
|
@@ -12354,7 +12354,7 @@ const RoutesAdjacency_RoutesEntry = {
|
|
|
12354
12354
|
var _a;
|
|
12355
12355
|
const message = createBaseRoutesAdjacency_RoutesEntry();
|
|
12356
12356
|
message.key = (_a = object.key) !== null && _a !== undefined ? _a : "";
|
|
12357
|
-
message.value = (object.value !== undefined && object.value !== null) ? Route
|
|
12357
|
+
message.value = (object.value !== undefined && object.value !== null) ? Route.fromPartial(object.value) : undefined;
|
|
12358
12358
|
return message;
|
|
12359
12359
|
},
|
|
12360
12360
|
};
|
|
@@ -16078,419 +16078,5 @@ const chGtfsProfile = {
|
|
|
16078
16078
|
platformParser,
|
|
16079
16079
|
};
|
|
16080
16080
|
|
|
16081
|
-
|
|
16082
|
-
|
|
16083
|
-
this.result = result;
|
|
16084
|
-
}
|
|
16085
|
-
/**
|
|
16086
|
-
* Plots the path three as a DOT for debugging purposes.
|
|
16087
|
-
*
|
|
16088
|
-
* @returns A string representing the DOT graph of the path tree.
|
|
16089
|
-
*/
|
|
16090
|
-
plotDotGraph() {
|
|
16091
|
-
const earliestArrivalsPerRound = this.result.earliestArrivalsPerRound;
|
|
16092
|
-
const dotParts = [
|
|
16093
|
-
'digraph PathTree {',
|
|
16094
|
-
' graph [overlap=false];',
|
|
16095
|
-
' node [shape=ellipse style=filled fillcolor=lightgrey];',
|
|
16096
|
-
];
|
|
16097
|
-
earliestArrivalsPerRound.forEach((arrivalsInRound, round) => {
|
|
16098
|
-
arrivalsInRound.forEach((tripLeg) => {
|
|
16099
|
-
const { origin, leg } = tripLeg;
|
|
16100
|
-
if (!leg)
|
|
16101
|
-
return; // Skip if leg is undefined
|
|
16102
|
-
const fromStop = this.result['stopsIndex'].findStopById(leg.from.id);
|
|
16103
|
-
const toStop = this.result['stopsIndex'].findStopById(leg.to.id);
|
|
16104
|
-
const originStop = this.result['stopsIndex'].findStopById(origin);
|
|
16105
|
-
if (fromStop && toStop && originStop) {
|
|
16106
|
-
const fromName = fromStop.platform
|
|
16107
|
-
? `${fromStop.name} (Pl. ${fromStop.platform})`
|
|
16108
|
-
: fromStop.name;
|
|
16109
|
-
const toName = toStop.platform
|
|
16110
|
-
? `${toStop.name} (Pl. ${toStop.platform})`
|
|
16111
|
-
: toStop.name;
|
|
16112
|
-
const originName = originStop.platform
|
|
16113
|
-
? `${originStop.name} (Pl. ${originStop.platform})`
|
|
16114
|
-
: originStop.name;
|
|
16115
|
-
const isVehicle = 'route' in leg;
|
|
16116
|
-
const routeLabelContent = isVehicle
|
|
16117
|
-
? `${leg.route.name}\n${leg.departureTime.toString()} - ${leg.arrivalTime.toString()}`
|
|
16118
|
-
: leg.minTransferTime
|
|
16119
|
-
? leg.minTransferTime.toString()
|
|
16120
|
-
: '';
|
|
16121
|
-
const intermediateNode = `IntermediateNode${fromStop.id}_${toStop.id}`;
|
|
16122
|
-
const lineColor = isVehicle ? '' : ', color="red", fontcolor="red"';
|
|
16123
|
-
const labelColor = isVehicle ? '' : ' fontcolor="red"';
|
|
16124
|
-
dotParts.push(` "${fromName} (Origin: ${originName}) [R${round}]\n(${fromStop.id})" -> "${intermediateNode}" [shape=point${lineColor}];`);
|
|
16125
|
-
dotParts.push(` "${intermediateNode}" [label="${routeLabelContent}" shape=rect style=filled fillcolor=white${labelColor} border=0];`);
|
|
16126
|
-
dotParts.push(` "${intermediateNode}" -> "${toName} (Origin: ${originName}) [R${round}]\n(${toStop.id})" [${lineColor.replace(', ', '')}];`);
|
|
16127
|
-
}
|
|
16128
|
-
});
|
|
16129
|
-
});
|
|
16130
|
-
dotParts.push('}');
|
|
16131
|
-
return dotParts.join('\n');
|
|
16132
|
-
}
|
|
16133
|
-
}
|
|
16134
|
-
|
|
16135
|
-
class Query {
|
|
16136
|
-
constructor(builder) {
|
|
16137
|
-
this.from = builder.fromValue;
|
|
16138
|
-
this.to = builder.toValue;
|
|
16139
|
-
this.departureTime = builder.departureTimeValue;
|
|
16140
|
-
this.options = builder.optionsValue;
|
|
16141
|
-
}
|
|
16142
|
-
}
|
|
16143
|
-
Query.Builder = class {
|
|
16144
|
-
constructor() {
|
|
16145
|
-
// lastDepartureTimeValue?: Date;
|
|
16146
|
-
// via: StopId[] = [];
|
|
16147
|
-
this.optionsValue = {
|
|
16148
|
-
maxTransfers: 5,
|
|
16149
|
-
minTransferTime: Duration.fromSeconds(120),
|
|
16150
|
-
transportModes: ALL_TRANSPORT_MODES,
|
|
16151
|
-
};
|
|
16152
|
-
}
|
|
16153
|
-
from(from) {
|
|
16154
|
-
this.fromValue = from;
|
|
16155
|
-
return this;
|
|
16156
|
-
}
|
|
16157
|
-
to(to) {
|
|
16158
|
-
this.toValue = Array.isArray(to) ? to : [to];
|
|
16159
|
-
return this;
|
|
16160
|
-
}
|
|
16161
|
-
departureTime(departureTime) {
|
|
16162
|
-
this.departureTimeValue = departureTime;
|
|
16163
|
-
return this;
|
|
16164
|
-
}
|
|
16165
|
-
maxTransfers(maxTransfers) {
|
|
16166
|
-
this.optionsValue.maxTransfers = maxTransfers;
|
|
16167
|
-
return this;
|
|
16168
|
-
}
|
|
16169
|
-
minTransferTime(minTransferTime) {
|
|
16170
|
-
this.optionsValue.minTransferTime = minTransferTime;
|
|
16171
|
-
return this;
|
|
16172
|
-
}
|
|
16173
|
-
transportModes(transportModes) {
|
|
16174
|
-
this.optionsValue.transportModes = transportModes;
|
|
16175
|
-
return this;
|
|
16176
|
-
}
|
|
16177
|
-
build() {
|
|
16178
|
-
return new Query(this);
|
|
16179
|
-
}
|
|
16180
|
-
};
|
|
16181
|
-
|
|
16182
|
-
class Route {
|
|
16183
|
-
constructor(legs) {
|
|
16184
|
-
if (legs.length === 0) {
|
|
16185
|
-
throw new Error('There must be at least one leg in a route');
|
|
16186
|
-
}
|
|
16187
|
-
this.legs = legs;
|
|
16188
|
-
}
|
|
16189
|
-
departureTime() {
|
|
16190
|
-
const cumulativeTransferTime = Duration.zero();
|
|
16191
|
-
for (let i = 0; i < this.legs.length; i++) {
|
|
16192
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
16193
|
-
const leg = this.legs[i];
|
|
16194
|
-
if ('departureTime' in leg) {
|
|
16195
|
-
return leg.departureTime.minus(cumulativeTransferTime);
|
|
16196
|
-
}
|
|
16197
|
-
if ('minTransferTime' in leg && leg.minTransferTime) {
|
|
16198
|
-
cumulativeTransferTime.add(leg.minTransferTime);
|
|
16199
|
-
}
|
|
16200
|
-
}
|
|
16201
|
-
throw new Error('No vehicle leg found in route');
|
|
16202
|
-
}
|
|
16203
|
-
arrivalTime() {
|
|
16204
|
-
let lastVehicleArrivalTime = Time.origin();
|
|
16205
|
-
const totalTransferTime = Duration.zero();
|
|
16206
|
-
let vehicleLegFound = false;
|
|
16207
|
-
for (let i = this.legs.length - 1; i >= 0; i--) {
|
|
16208
|
-
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
16209
|
-
const leg = this.legs[i];
|
|
16210
|
-
if ('arrivalTime' in leg && !vehicleLegFound) {
|
|
16211
|
-
lastVehicleArrivalTime = leg.arrivalTime;
|
|
16212
|
-
vehicleLegFound = true;
|
|
16213
|
-
}
|
|
16214
|
-
else if ('minTransferTime' in leg &&
|
|
16215
|
-
leg.minTransferTime &&
|
|
16216
|
-
vehicleLegFound) {
|
|
16217
|
-
totalTransferTime.add(leg.minTransferTime);
|
|
16218
|
-
}
|
|
16219
|
-
}
|
|
16220
|
-
if (!vehicleLegFound) {
|
|
16221
|
-
throw new Error('No vehicle leg found in route');
|
|
16222
|
-
}
|
|
16223
|
-
return lastVehicleArrivalTime.plus(totalTransferTime);
|
|
16224
|
-
}
|
|
16225
|
-
totalDuration() {
|
|
16226
|
-
if (this.legs.length === 0)
|
|
16227
|
-
return Duration.zero();
|
|
16228
|
-
return this.arrivalTime().diff(this.departureTime());
|
|
16229
|
-
}
|
|
16230
|
-
print() {
|
|
16231
|
-
return this.legs
|
|
16232
|
-
.map((leg, index) => {
|
|
16233
|
-
var _a, _b;
|
|
16234
|
-
if ('route' in leg) {
|
|
16235
|
-
return `Leg ${index + 1}: ${leg.from.name} to ${leg.to.name}
|
|
16236
|
-
via route ${leg.route.type} ${leg.route.name},
|
|
16237
|
-
departs at ${leg.departureTime.toString()}, arrives at ${leg.arrivalTime.toString()}`;
|
|
16238
|
-
}
|
|
16239
|
-
return `Leg ${index + 1}: Transfer from ${leg.from.name} to ${leg.to.name},
|
|
16240
|
-
minimum transfer time: ${(_b = (_a = leg.minTransferTime) === null || _a === undefined ? undefined : _a.toString()) !== null && _b !== undefined ? _b : 'not specified'}`;
|
|
16241
|
-
})
|
|
16242
|
-
.join('\n');
|
|
16243
|
-
}
|
|
16244
|
-
}
|
|
16245
|
-
|
|
16246
|
-
class Result {
|
|
16247
|
-
constructor(query, earliestArrivals, earliestArrivalsPerRound, stopsIndex) {
|
|
16248
|
-
this.query = query;
|
|
16249
|
-
this.earliestArrivals = earliestArrivals;
|
|
16250
|
-
this.earliestArrivalsPerRound = earliestArrivalsPerRound;
|
|
16251
|
-
this.stopsIndex = stopsIndex;
|
|
16252
|
-
}
|
|
16253
|
-
/**
|
|
16254
|
-
* Reconstructs the best route to a stop.
|
|
16255
|
-
* (to any stop reachable in less time / transfers than the destination(s) of the query)
|
|
16256
|
-
*
|
|
16257
|
-
* @param to The destination stop. Defaults to the destination of the original query.
|
|
16258
|
-
* @returns a route to the destination stop if it exists.
|
|
16259
|
-
*/
|
|
16260
|
-
bestRoute(to) {
|
|
16261
|
-
var _a, _b, _c;
|
|
16262
|
-
const destinationList = Array.isArray(to) ? to : to ? [to] : this.query.to;
|
|
16263
|
-
const destinations = destinationList.flatMap((destination) => this.stopsIndex.equivalentStops(destination));
|
|
16264
|
-
let fastestDestination = undefined;
|
|
16265
|
-
let fastestTime = undefined;
|
|
16266
|
-
for (const destination of destinations) {
|
|
16267
|
-
const arrivalTime = this.earliestArrivals.get(destination);
|
|
16268
|
-
if (arrivalTime !== undefined) {
|
|
16269
|
-
if (fastestTime === undefined ||
|
|
16270
|
-
arrivalTime.time.toSeconds() < fastestTime.time.toSeconds()) {
|
|
16271
|
-
fastestDestination = destination;
|
|
16272
|
-
fastestTime = arrivalTime;
|
|
16273
|
-
}
|
|
16274
|
-
}
|
|
16275
|
-
}
|
|
16276
|
-
if (!fastestDestination || !fastestTime) {
|
|
16277
|
-
return undefined;
|
|
16278
|
-
}
|
|
16279
|
-
const route = [];
|
|
16280
|
-
let currentStop = fastestDestination;
|
|
16281
|
-
let round = fastestTime.legNumber;
|
|
16282
|
-
while (fastestTime.origin !== currentStop) {
|
|
16283
|
-
const tripLeg = (_a = this.earliestArrivalsPerRound[round]) === null || _a === undefined ? undefined : _a.get(currentStop);
|
|
16284
|
-
if (!(tripLeg === null || tripLeg === undefined ? undefined : tripLeg.leg)) {
|
|
16285
|
-
throw new Error(`No leg found for a trip leg: start stop=${(_c = (_b = tripLeg === null || tripLeg === undefined ? undefined : tripLeg.leg) === null || _b === undefined ? undefined : _b.from.id) !== null && _c !== undefined ? _c : 'unknown'}, end stop=${currentStop}, round=${round}, origin=${fastestTime.origin}`);
|
|
16286
|
-
}
|
|
16287
|
-
route.unshift(tripLeg.leg);
|
|
16288
|
-
currentStop = tripLeg.leg.from.id;
|
|
16289
|
-
if ('route' in tripLeg.leg) {
|
|
16290
|
-
round -= 1;
|
|
16291
|
-
}
|
|
16292
|
-
}
|
|
16293
|
-
return new Route(route);
|
|
16294
|
-
}
|
|
16295
|
-
/**
|
|
16296
|
-
* Returns the arrival time at any stop reachable in less time / transfers than the destination(s) of the query)
|
|
16297
|
-
*
|
|
16298
|
-
* @param stop The target stop for which to return the arrival time.
|
|
16299
|
-
* @param maxTransfers The optional maximum number of transfers allowed.
|
|
16300
|
-
* @returns The arrival time if the target stop is reachable, otherwise undefined.
|
|
16301
|
-
*/
|
|
16302
|
-
arrivalAt(stop, maxTransfers) {
|
|
16303
|
-
const equivalentStops = this.stopsIndex.equivalentStops(stop);
|
|
16304
|
-
let earliestArrival = undefined;
|
|
16305
|
-
const relevantArrivals = maxTransfers !== undefined
|
|
16306
|
-
? // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
|
16307
|
-
this.earliestArrivalsPerRound[maxTransfers - 1]
|
|
16308
|
-
: this.earliestArrivals;
|
|
16309
|
-
for (const equivalentStop of equivalentStops) {
|
|
16310
|
-
const arrivalTime = relevantArrivals.get(equivalentStop);
|
|
16311
|
-
if (arrivalTime !== undefined) {
|
|
16312
|
-
if (earliestArrival === undefined ||
|
|
16313
|
-
arrivalTime.time.toSeconds() < earliestArrival.time.toSeconds()) {
|
|
16314
|
-
earliestArrival = arrivalTime;
|
|
16315
|
-
}
|
|
16316
|
-
}
|
|
16317
|
-
}
|
|
16318
|
-
return earliestArrival;
|
|
16319
|
-
}
|
|
16320
|
-
}
|
|
16321
|
-
|
|
16322
|
-
const UNREACHED = Time.infinity();
|
|
16323
|
-
class Router {
|
|
16324
|
-
constructor(timetable, stopsIndex) {
|
|
16325
|
-
this.timetable = timetable;
|
|
16326
|
-
this.stopsIndex = stopsIndex;
|
|
16327
|
-
}
|
|
16328
|
-
/**
|
|
16329
|
-
* Evaluates possible transfers for a given query on a transport
|
|
16330
|
-
* network, updating the earliest arrivals at various stops and marking new
|
|
16331
|
-
* stops that can be reached through these transfers.
|
|
16332
|
-
*/
|
|
16333
|
-
considerTransfers(query, markedStops, arrivalsAtCurrentRound, earliestArrivals, round) {
|
|
16334
|
-
var _a, _b, _c, _d;
|
|
16335
|
-
const { options } = query;
|
|
16336
|
-
const newlyMarkedStops = new Set();
|
|
16337
|
-
for (const stop of markedStops) {
|
|
16338
|
-
for (const transfer of this.timetable.getTransfers(stop)) {
|
|
16339
|
-
let transferTime;
|
|
16340
|
-
if (transfer.minTransferTime) {
|
|
16341
|
-
transferTime = transfer.minTransferTime;
|
|
16342
|
-
}
|
|
16343
|
-
else if (transfer.type === 'IN_SEAT') {
|
|
16344
|
-
transferTime = Duration.zero();
|
|
16345
|
-
}
|
|
16346
|
-
else {
|
|
16347
|
-
transferTime = options.minTransferTime;
|
|
16348
|
-
}
|
|
16349
|
-
const arrivalAfterTransfer = arrivalsAtCurrentRound
|
|
16350
|
-
.get(stop)
|
|
16351
|
-
.time.plus(transferTime);
|
|
16352
|
-
const originalArrival = (_b = (_a = arrivalsAtCurrentRound.get(transfer.destination)) === null || _a === undefined ? undefined : _a.time) !== null && _b !== undefined ? _b : UNREACHED;
|
|
16353
|
-
if (arrivalAfterTransfer.toSeconds() < originalArrival.toSeconds()) {
|
|
16354
|
-
const origin = (_d = (_c = arrivalsAtCurrentRound.get(stop)) === null || _c === undefined ? undefined : _c.origin) !== null && _d !== undefined ? _d : stop;
|
|
16355
|
-
arrivalsAtCurrentRound.set(transfer.destination, {
|
|
16356
|
-
time: arrivalAfterTransfer,
|
|
16357
|
-
legNumber: round,
|
|
16358
|
-
origin: origin,
|
|
16359
|
-
leg: {
|
|
16360
|
-
from: this.stopsIndex.findStopById(stop),
|
|
16361
|
-
to: this.stopsIndex.findStopById(transfer.destination),
|
|
16362
|
-
minTransferTime: transfer.minTransferTime,
|
|
16363
|
-
},
|
|
16364
|
-
});
|
|
16365
|
-
earliestArrivals.set(transfer.destination, {
|
|
16366
|
-
time: arrivalAfterTransfer,
|
|
16367
|
-
legNumber: round,
|
|
16368
|
-
origin: origin,
|
|
16369
|
-
});
|
|
16370
|
-
newlyMarkedStops.add(transfer.destination);
|
|
16371
|
-
}
|
|
16372
|
-
}
|
|
16373
|
-
}
|
|
16374
|
-
for (const newStop of newlyMarkedStops) {
|
|
16375
|
-
markedStops.add(newStop);
|
|
16376
|
-
}
|
|
16377
|
-
}
|
|
16378
|
-
/**
|
|
16379
|
-
* The main Raptor algorithm implementation.
|
|
16380
|
-
*
|
|
16381
|
-
* @param query The query containing the main parameters for the routing.
|
|
16382
|
-
* @returns A result object containing data structures allowing to reconstruct routes and .
|
|
16383
|
-
*/
|
|
16384
|
-
route(query) {
|
|
16385
|
-
var _a, _b, _c, _d, _e, _f, _g;
|
|
16386
|
-
const { from, to, departureTime, options } = query;
|
|
16387
|
-
// Consider children or siblings of the "from" stop as potential origins
|
|
16388
|
-
const origins = this.stopsIndex.equivalentStops(from);
|
|
16389
|
-
// Consider children or siblings of the "to" stop(s) as potential destinations
|
|
16390
|
-
const destinations = to.flatMap((destination) => this.stopsIndex.equivalentStops(destination));
|
|
16391
|
-
const earliestArrivals = new Map();
|
|
16392
|
-
const earliestArrivalsWithoutAnyLeg = new Map();
|
|
16393
|
-
const earliestArrivalsPerRound = [earliestArrivalsWithoutAnyLeg];
|
|
16394
|
-
// Stops that have been improved at round k-1
|
|
16395
|
-
const markedStops = new Set();
|
|
16396
|
-
for (const originStop of origins) {
|
|
16397
|
-
markedStops.add(originStop);
|
|
16398
|
-
earliestArrivals.set(originStop, {
|
|
16399
|
-
time: departureTime,
|
|
16400
|
-
legNumber: 0,
|
|
16401
|
-
origin: originStop,
|
|
16402
|
-
});
|
|
16403
|
-
earliestArrivalsWithoutAnyLeg.set(originStop, {
|
|
16404
|
-
time: departureTime,
|
|
16405
|
-
legNumber: 0,
|
|
16406
|
-
origin: originStop,
|
|
16407
|
-
});
|
|
16408
|
-
}
|
|
16409
|
-
// on the first round we need to first consider transfers to discover all possible route origins
|
|
16410
|
-
this.considerTransfers(query, markedStops, earliestArrivalsWithoutAnyLeg, earliestArrivals, 0);
|
|
16411
|
-
for (let round = 1; round <= options.maxTransfers + 1; round++) {
|
|
16412
|
-
const arrivalsAtCurrentRound = new Map();
|
|
16413
|
-
earliestArrivalsPerRound.push(arrivalsAtCurrentRound);
|
|
16414
|
-
const arrivalsAtPreviousRound = earliestArrivalsPerRound[round - 1];
|
|
16415
|
-
// Routes that contain at least one stop reached with at least round - 1 legs
|
|
16416
|
-
// together with corresponding hop on stop index (earliest marked stop)
|
|
16417
|
-
const reachableRoutes = this.timetable.findReachableRoutes(markedStops, options.transportModes);
|
|
16418
|
-
markedStops.clear();
|
|
16419
|
-
// for each route that can be reached with at least round - 1 trips
|
|
16420
|
-
for (const [routeId, hopOnStop] of reachableRoutes.entries()) {
|
|
16421
|
-
const route = this.timetable.getRoute(routeId);
|
|
16422
|
-
let currentTrip = undefined;
|
|
16423
|
-
const hopOnIndex = route.stopIndices.get(hopOnStop);
|
|
16424
|
-
// for each stops in the route starting with the hop-on one
|
|
16425
|
-
for (let i = hopOnIndex; i < route.stops.length; i++) {
|
|
16426
|
-
const currentStop = route.stops[i];
|
|
16427
|
-
const stopNumbers = route.stops.length;
|
|
16428
|
-
if (currentTrip !== undefined) {
|
|
16429
|
-
const currentStopTimes = route.stopTimes[currentTrip.trip * stopNumbers + i];
|
|
16430
|
-
const earliestArrivalAtCurrentStop = (_b = (_a = earliestArrivals.get(currentStop)) === null || _a === undefined ? undefined : _a.time) !== null && _b !== undefined ? _b : UNREACHED;
|
|
16431
|
-
let arrivalToImprove = earliestArrivalAtCurrentStop;
|
|
16432
|
-
if (destinations.length > 0) {
|
|
16433
|
-
const earliestArrivalsAtDestinations = [];
|
|
16434
|
-
// if multiple destinations are specified, the target pruning
|
|
16435
|
-
// should compare to the earliest arrival at any of them
|
|
16436
|
-
for (const destinationStop of destinations) {
|
|
16437
|
-
const earliestArrivalAtDestination = (_d = (_c = earliestArrivals.get(destinationStop)) === null || _c === undefined ? undefined : _c.time) !== null && _d !== undefined ? _d : UNREACHED;
|
|
16438
|
-
earliestArrivalsAtDestinations.push(earliestArrivalAtDestination);
|
|
16439
|
-
}
|
|
16440
|
-
const earliestArrivalAtDestination = Time.min(...earliestArrivalsAtDestinations);
|
|
16441
|
-
arrivalToImprove = Time.min(earliestArrivalAtCurrentStop, earliestArrivalAtDestination);
|
|
16442
|
-
}
|
|
16443
|
-
if (currentStopTimes.dropOffType !== 'NOT_AVAILABLE' &&
|
|
16444
|
-
currentStopTimes.arrival.toSeconds() <
|
|
16445
|
-
arrivalToImprove.toSeconds()) {
|
|
16446
|
-
const bestHopOnStopIndex = route.stopIndices.get(currentTrip.bestHopOnStop);
|
|
16447
|
-
const bestHopOnStopTimes = route.stopTimes[currentTrip.trip * stopNumbers + bestHopOnStopIndex];
|
|
16448
|
-
arrivalsAtCurrentRound.set(currentStop, {
|
|
16449
|
-
time: currentStopTimes.arrival,
|
|
16450
|
-
legNumber: round,
|
|
16451
|
-
origin: currentTrip.origin,
|
|
16452
|
-
leg: {
|
|
16453
|
-
from: this.stopsIndex.findStopById(currentTrip.bestHopOnStop),
|
|
16454
|
-
to: this.stopsIndex.findStopById(currentStop),
|
|
16455
|
-
departureTime: bestHopOnStopTimes.departure,
|
|
16456
|
-
arrivalTime: currentStopTimes.arrival,
|
|
16457
|
-
route: this.timetable.getServiceRoute(route.serviceRouteId),
|
|
16458
|
-
},
|
|
16459
|
-
});
|
|
16460
|
-
earliestArrivals.set(currentStop, {
|
|
16461
|
-
time: currentStopTimes.arrival,
|
|
16462
|
-
legNumber: round,
|
|
16463
|
-
origin: currentTrip.origin,
|
|
16464
|
-
});
|
|
16465
|
-
markedStops.add(currentStop);
|
|
16466
|
-
}
|
|
16467
|
-
}
|
|
16468
|
-
// check if we can catch a previous trip at the current stop
|
|
16469
|
-
// if there was no current trip, find the first one reachable
|
|
16470
|
-
const earliestArrivalOnPreviousRound = (_e = arrivalsAtPreviousRound.get(currentStop)) === null || _e === undefined ? undefined : _e.time;
|
|
16471
|
-
if (earliestArrivalOnPreviousRound !== undefined &&
|
|
16472
|
-
(currentTrip === undefined ||
|
|
16473
|
-
earliestArrivalOnPreviousRound.toSeconds() <=
|
|
16474
|
-
route.stopTimes[currentTrip.trip * stopNumbers + i].departure.toSeconds())) {
|
|
16475
|
-
const earliestTrip = this.timetable.findEarliestTrip(route, currentStop, currentTrip === null || currentTrip === undefined ? undefined : currentTrip.trip, earliestArrivalOnPreviousRound);
|
|
16476
|
-
if (earliestTrip !== undefined) {
|
|
16477
|
-
currentTrip = {
|
|
16478
|
-
trip: earliestTrip,
|
|
16479
|
-
// we need to keep track of the best hop-on stop to reconstruct the route at the end
|
|
16480
|
-
bestHopOnStop: currentStop,
|
|
16481
|
-
origin: (_g = (_f = arrivalsAtPreviousRound.get(currentStop)) === null || _f === undefined ? undefined : _f.origin) !== null && _g !== undefined ? _g : currentStop,
|
|
16482
|
-
};
|
|
16483
|
-
}
|
|
16484
|
-
}
|
|
16485
|
-
}
|
|
16486
|
-
}
|
|
16487
|
-
this.considerTransfers(query, markedStops, arrivalsAtCurrentRound, earliestArrivals, round);
|
|
16488
|
-
if (markedStops.size === 0)
|
|
16489
|
-
break;
|
|
16490
|
-
}
|
|
16491
|
-
return new Result(query, earliestArrivals, earliestArrivalsPerRound, this.stopsIndex);
|
|
16492
|
-
}
|
|
16493
|
-
}
|
|
16494
|
-
|
|
16495
|
-
export { GtfsParser, Plotter, Query, Result, Route, Router, StopsIndex, Time, Timetable, chGtfsProfile };
|
|
16496
|
-
//# sourceMappingURL=bundle.esm.js.map
|
|
16081
|
+
export { GtfsParser, chGtfsProfile };
|
|
16082
|
+
//# sourceMappingURL=parser.esm.js.map
|