@golemio/pid
Version:
Golemio PID Module
116 lines • 5.52 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SkipHelper = void 0;
const RouteTypeEnums_1 = require("../../../../helpers/RouteTypeEnums");
const RunHelper_1 = require("./RunHelper");
const const_1 = require("./const");
/** Extracts the last numeric sequence from strings like:
* Os 1111 -> 1111
* Os 1111 B -> 1111
* Rx 1/1111 A -> 1111
*/
const TRIP_NUMBER_REGEX = /(\d+)(?!.*\d)/;
class SkipHelper {
/**
* Used exclusively in transfer boards to skip transfers for the current trip
* (i.e., transfers within the vehicle where the transfer board is located)
*/
static isMatchingTripNumber(departure, tripNumber) {
const tripShortName = departure.trip_short_name;
if (!tripShortName) {
return false;
}
const lastNumber = tripShortName.match(TRIP_NUMBER_REGEX)?.[1];
return !!lastNumber && lastNumber === tripNumber;
}
static hasNoDelayInfo(departure) {
return !departure.is_delay_available;
}
/**
* Used exclusively in departure boards when skip[]=missing is requested (without untracked)
*/
static isVehicleMissing(departure, runScheduleMap, untrackedTrips, nowDate = new Date()) {
// Not missing if essential trip data is missing or if delay information is available
if (!("trip.start_timestamp" in departure) ||
departure["trip.start_timestamp"] === null ||
departure.run_number === null ||
departure.route_id === null ||
departure.is_delay_available) {
return false;
}
const startTimestamp = new Date(departure["trip.start_timestamp"]);
const minutesToStart = (startTimestamp.getTime() - nowDate.getTime()) / 60000;
/// Not missing if departure is too far in the future (threshold varies for metro)
if (this.isOutsideStartThreshold(minutesToStart, departure.route_type)) {
return false;
}
// Missing if the trip should have already started
else if (this.hasAlreadyDeparted(minutesToStart)) {
return true;
}
// Cannot determine missing status without run schedule information
const runSchedule = runScheduleMap?.get(RunHelper_1.RunHelper.composeRunId(departure.route_id, departure.run_number));
if (!runSchedule) {
return false;
}
// Not missing if this is the first trip in the run or if trip isn't found
const runTripIndex = runSchedule.findIndex((trip) => trip.trip_id === departure.trip_id);
if (runTripIndex === -1 || runTripIndex === 0) {
return false;
}
// Not missing if there's a significant gap after the previous trip
const previousRunTripEnd = new Date(runSchedule[runTripIndex - 1].end_timestamp);
if (this.hasLargeTimegapBetweenTrips(previousRunTripEnd, startTimestamp)) {
return false;
}
// Not missing if the previous trip has delay information available
const isPreviousUntracked = untrackedTrips?.has(runSchedule[runTripIndex - 1].trip_id);
if (!isPreviousUntracked) {
return false;
}
const previousStartTimestamp = new Date(runSchedule[runTripIndex - 1].start_timestamp);
const previousMinutesToStart = (previousStartTimestamp.getTime() - nowDate.getTime()) / 60000;
// Missing if previous trip should have already started
if (this.hasAlreadyDeparted(previousMinutesToStart)) {
return true;
}
// Check position of previous trip in the run
const previousRunTripIndex = runTripIndex - 1;
if (previousRunTripIndex === -1 || previousRunTripIndex === 0) {
return false;
}
// Check for gaps before the previous trip
const previousPreviousRunTripEnd = new Date(runSchedule[previousRunTripIndex - 1].end_timestamp);
if (this.hasLargeTimegapBetweenTrips(previousPreviousRunTripEnd, previousStartTimestamp)) {
return false;
}
// If we reach here, the previous untracked trip is likely missing,
// which implies the current trip is also missing
return true;
}
static isTripCanceled(departure) {
return !!departure.is_canceled;
}
static isVehicleAtStop(departure) {
if (!("arrival_datetime" in departure)) {
return false;
}
const isAtStop = departure.stop_sequence === departure["trip.last_position.this_stop_sequence"];
const isPassStop = !!departure["trip.last_position.last_stop_sequence"] &&
departure.stop_sequence <= departure["trip.last_position.last_stop_sequence"];
return isAtStop || isPassStop;
}
static isOutsideStartThreshold(minutesToStart, routeType) {
const isMetro = routeType === RouteTypeEnums_1.GTFSRouteTypeEnum.METRO;
return isMetro ? minutesToStart >= const_1.START_SOON_METRO_MINUTES_THRESHOLD : minutesToStart >= const_1.START_SOON_MINUTES_THRESHOLD;
}
static hasAlreadyDeparted(minutesToStart) {
return minutesToStart < const_1.DEPARTURED_MINUTES_THRESHOLD;
}
static hasLargeTimegapBetweenTrips(endTimestamp, startTimestamp) {
const minutesAfterPrevious = (startTimestamp.getTime() - endTimestamp.getTime()) / 60000;
return minutesAfterPrevious >= const_1.TRIP_GAP_MINUTES_THRESHOLD;
}
}
exports.SkipHelper = SkipHelper;
//# sourceMappingURL=SkipHelper.js.map