UNPKG

minotor

Version:

A lightweight client-side transit routing library.

100 lines (93 loc) 2.48 kB
import { Latitude, LocationType, Longitude, Platform, SourceStopId, Stop, } from '../stops/stops.js'; import { parseCsv } from './utils.js'; export type GtfsLocationType = | 0 // simple stop or platform (can also be empty) | 1 // station | 2 // entrance / exit | 3 // generic node | 4; // boarding area export type StopEntry = { stop_id: SourceStopId; stop_name: string; stop_lat?: Latitude; stop_lon?: Longitude; location_type?: GtfsLocationType; parent_station?: SourceStopId; platform_code?: Platform; }; type ParsedStop = Stop & { parentSourceId?: SourceStopId; }; export type GtfsStopsMap = Map<SourceStopId, ParsedStop>; /** * Parses the stops.txt file from a GTFS feed. * * @param stopsStream The readable stream containing the stops data. * @return A mapping of stop IDs to corresponding stop details. */ export const parseStops = async ( stopsStream: NodeJS.ReadableStream, ): Promise<GtfsStopsMap> => { const parsedStops = new Map<SourceStopId, ParsedStop>(); let i = 0; for await (const rawLine of parseCsv(stopsStream, [ 'stop_lat', 'stop_lon', 'location_type', ])) { const line = rawLine as StopEntry; const stop: ParsedStop = { id: i, sourceStopId: line.stop_id, name: line.stop_name, lat: line.stop_lat, lon: line.stop_lon, locationType: line.location_type ? parseGtfsLocationType(line.location_type) : 'SIMPLE_STOP_OR_PLATFORM', ...(line.platform_code && { platform: line.platform_code }), children: [], ...(line.parent_station && { parentSourceId: line.parent_station }), }; parsedStops.set(line.stop_id, stop); i = i + 1; } for (const [sourceStopId, stop] of parsedStops) { if (stop.parentSourceId) { const parentStop = parsedStops.get(stop.parentSourceId); if (!parentStop) { console.warn( `Cannot find parent stop ${stop.parentSourceId} of ${sourceStopId}`, ); continue; } stop.parent = parentStop.id; parentStop.children.push(stop.id); } } return parsedStops; }; const parseGtfsLocationType = ( gtfsLocationType: GtfsLocationType, ): LocationType => { switch (gtfsLocationType) { case 0: default: return 'SIMPLE_STOP_OR_PLATFORM'; case 1: return 'STATION'; case 2: return 'ENTRANCE_EXIT'; case 3: return 'GENERIC_NODE'; case 4: return 'BOARDING_AREA'; } };