import * as fs from 'fs'; import * as path from 'path'; // Types export interface GtfsStop { stop_id: string; stop_code: string; stop_name: string; stop_lat: number; stop_lon: number; } export interface GtfsRoute { route_id: string; route_short_name: string; route_long_name: string; route_type?: string; } // CSV Parser function parseCSVLine(line: string): string[] { const result: string[] = []; let current = ''; let inQuotes = false; for (let i = 0; i < line.length; i++) { const char = line[i]; if (char === '"') { inQuotes = !inQuotes; } else if (char === ',' && !inQuotes) { result.push(current.trim()); current = ''; } else { current += char; } } result.push(current.trim()); return result; } // Load GTFS Stops export function loadGtfsStops(gtfsDir: string = 'gtfs'): Map { const stopsFile = path.join(process.cwd(), gtfsDir, 'stops.txt'); const content = fs.readFileSync(stopsFile, 'utf-8'); const lines = content.split('\n').filter(line => line.trim()); const stops = new Map(); for (let i = 1; i < lines.length; i++) { const values = parseCSVLine(lines[i]); if (values.length < 6) continue; const stop: GtfsStop = { stop_id: values[0], stop_code: values[1], stop_name: values[2], stop_lat: parseFloat(values[4]), stop_lon: parseFloat(values[5]), }; stops.set(stop.stop_id, stop); } return stops; } // Load GTFS Routes export function loadGtfsRoutes(gtfsDir: string = 'gtfs'): Map { const routesFile = path.join(process.cwd(), gtfsDir, 'routes.txt'); const content = fs.readFileSync(routesFile, 'utf-8'); const lines = content.split('\n').filter(line => line.trim()); const routes = new Map(); for (let i = 1; i < lines.length; i++) { const values = parseCSVLine(lines[i]); if (values.length < 5) continue; const route: GtfsRoute = { route_id: values[0], route_short_name: values[2], route_long_name: values[3], route_type: values[5] || undefined, }; routes.set(route.route_id, route); } return routes; }