@golemio/pid
Version:
Golemio PID Module
132 lines • 6.5 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.TransferBoardFilter = void 0;
const GtfsStopParser_1 = require("../../../helpers/GtfsStopParser");
const RouteTypeEnums_1 = require("../../../helpers/RouteTypeEnums");
const DEFAULT_TRANSFER_TIME_MS = 60 * 1000;
const TRANSFER_TIMES_MS = new Map([
[RouteTypeEnums_1.GTFSRouteTypeEnum.BUS, 60_000],
[RouteTypeEnums_1.GTFSRouteTypeEnum.EXT_MISCELLANEOUS, 60_000],
[RouteTypeEnums_1.GTFSRouteTypeEnum.FERRY, 120_000],
[RouteTypeEnums_1.GTFSRouteTypeEnum.FUNICULAR, 120_000],
[RouteTypeEnums_1.GTFSRouteTypeEnum.METRO, 120_000],
[RouteTypeEnums_1.GTFSRouteTypeEnum.TRAIN, 120_000],
[RouteTypeEnums_1.GTFSRouteTypeEnum.TRAM, 60_000],
[RouteTypeEnums_1.GTFSRouteTypeEnum.TROLLEYBUS, 60_000],
]);
const DIFFERENT_STOP_NAME_ALLOWED = new Map([
[RouteTypeEnums_1.GTFSRouteTypeEnum.BUS, false],
[RouteTypeEnums_1.GTFSRouteTypeEnum.EXT_MISCELLANEOUS, true],
[RouteTypeEnums_1.GTFSRouteTypeEnum.FERRY, true],
[RouteTypeEnums_1.GTFSRouteTypeEnum.FUNICULAR, true],
[RouteTypeEnums_1.GTFSRouteTypeEnum.METRO, true],
[RouteTypeEnums_1.GTFSRouteTypeEnum.TRAIN, true],
[RouteTypeEnums_1.GTFSRouteTypeEnum.TRAM, false],
[RouteTypeEnums_1.GTFSRouteTypeEnum.TROLLEYBUS, false],
]);
const TRANSFER_LINE_TYPES_TO_KEEP = new Set([
RouteTypeEnums_1.GTFSRouteTypeEnum.FERRY,
RouteTypeEnums_1.GTFSRouteTypeEnum.FUNICULAR,
RouteTypeEnums_1.GTFSRouteTypeEnum.METRO,
RouteTypeEnums_1.GTFSRouteTypeEnum.TRAIN,
]);
const ONE_HOUR_IN_MS = 60 * 60 * 1000;
class TransferBoardFilter {
static filterDepartures(transfers, limit, arrivalTimeMs, requestTimeFromMs) {
const filteredDepartures = [];
// compute minutes (as ms) between provided timeFrom and arrivalTime
const msBetweenRequestAndArrival = arrivalTimeMs - requestTimeFromMs;
const timeEndMs = requestTimeFromMs + msBetweenRequestAndArrival + ONE_HOUR_IN_MS;
const seenTripIds = new Set();
for (const transfer of transfers) {
if (filteredDepartures.length === limit) {
break;
}
if (seenTripIds.has(transfer.trip.id)) {
continue;
}
if (!TransferBoardFilter.isInRangeOrGuaranteed(transfer, requestTimeFromMs, timeEndMs)) {
continue;
}
seenTripIds.add(transfer.trip.id);
filteredDepartures.push(transfer);
}
// Departures are already sorted so that metro ones are first
return filteredDepartures;
}
static havingConnectionFromTripId(fromTripId, transfers, delayedTimeFrom) {
const delayedTimeFromMs = delayedTimeFrom.getTime();
return transfers.filter((t) => TransferBoardFilter.hasConnectionWaitingTimeBeforeArrival(t.departure, fromTripId, delayedTimeFromMs));
}
static hasConnectionWaitingTimeBeforeArrival(departure, tripId, arrivalTimeMs) {
return !!departure.connections?.some((con) => {
return (con.from_trip_id === tripId && arrivalTimeMs < TransferBoardFilter.shiftedDepartureMs(departure, con.max_wait_sec));
});
}
static shiftedDepartureMs(departure, maxWaitSec) {
const shiftedDeparture = new Date(departure.departure_datetime).getTime() + maxWaitSec * 1000;
return shiftedDeparture;
}
static shouldKeepTransferAlways(transfer) {
return TRANSFER_LINE_TYPES_TO_KEEP.has(transfer.departure.route_type);
}
static filterOutKeepAlwaysTransfer(transfers) {
return transfers.filter((t) => !TransferBoardFilter.shouldKeepTransferAlways(t));
}
static keepAlwaysLinesAndTripIds(transfers, tripIdsToKeep) {
return transfers.filter((t) => {
return TransferBoardFilter.shouldKeepTransferAlways(t) || tripIdsToKeep.has(t.departure.trip_id);
});
}
static minimalTransferTime(transfers, delayedTimeFrom, keepTripIds) {
const arrivalTime = delayedTimeFrom.getTime();
return transfers.filter((t) => {
if (keepTripIds.has(t.departure.trip_id)) {
return true;
}
const transferTimeMs = TRANSFER_TIMES_MS.get(t.departure.route_type) || DEFAULT_TRANSFER_TIME_MS;
if (t.departure.predictedDepartureTimestamp == null) {
return false;
}
return arrivalTime + transferTimeMs < t.departure.predictedDepartureTimestamp;
});
}
static sameStopNameTransfer(transfers, currentStopId, allowedStopIds, keepTripIds, keepDeparturesWithConnections) {
const allowedStopIdsAsws = new Set(allowedStopIds.map(GtfsStopParser_1.GtfsStopParser.normalizedStopId));
const currentStopAsw = GtfsStopParser_1.GtfsStopParser.normalizedStopId(currentStopId);
return transfers.filter((t) => {
if (keepTripIds?.has(t.departure.trip_id)) {
return true;
}
if (keepDeparturesWithConnections && t.departure.connections?.length) {
return true;
}
const departureStopAsw = GtfsStopParser_1.GtfsStopParser.normalizedStopId(t.departure.stop_id);
return TransferBoardFilter.allowedTransferOnStop(departureStopAsw, t.departure.route_type, currentStopAsw, allowedStopIdsAsws);
});
}
static allowedTransferOnStop(departureStopAsw, routeType, currentStopAsw, allowedStopAsws) {
if (departureStopAsw === currentStopAsw) {
return true;
}
if (DIFFERENT_STOP_NAME_ALLOWED.get(routeType)) {
return true;
}
return allowedStopAsws.has(departureStopAsw);
}
static isInRangeOrGuaranteed(departure, timeRangeStart, timeRangeEnd) {
if (departure.trip.is_guaranteed_transfer) {
return true;
}
// departureMinutes are relative to timeFrom request parameter
const departureMinutes = departure.departure_timestamp.minutes[0] === "<1" ? 1 : Number(departure.departure_timestamp.minutes[0]);
if (isNaN(departureMinutes))
return false;
// Calculate the departure time
const departureTime = timeRangeStart + departureMinutes * 60 * 1000;
// Check if departureTime is within the range
return timeRangeStart <= departureTime && departureTime <= timeRangeEnd;
}
}
exports.TransferBoardFilter = TransferBoardFilter;
//# sourceMappingURL=TransferBoardFilter.js.map