Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 90 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,16 @@ const stopTimes = gtfs.getStopTimes({
- `directionId`: number - Filter by direction
- `limit`: number - Limit results

- `getShapes(filters?)`:
- `shapeId`: string | string[] - Filter by shape ID
- `routeId`: string | string[] - Filter by route (via trips table)
- `tripId`: string | string[] - Filter by trip
- `limit`: number - Limit results

- `getShapesToGeojson(filters?, precision?)`:
- Same filters as `getShapes`
- `precision`: number - Decimal places for coordinates (default: 6)

#### Get Stop Information

```typescript
Expand Down Expand Up @@ -611,6 +621,80 @@ const stops = gtfs.buildOrderedStopList(tripIds);
// Now you can create a timetable showing all stops with departure times
```

#### Get Shape Information

Shapes define the path a vehicle takes along a route. Use `getShapes()` to get raw shape point data and `getShapesToGeojson()` to get shapes as GeoJSON for mapping.

```typescript
// Get all shape points for a specific shape
const shapePoints = gtfs.getShapes({ shapeId: 'SHAPE_1' });
console.log(`Shape has ${shapePoints.length} points`);

// Get shapes for a specific route
const routeShapes = gtfs.getShapes({ routeId: 'ROUTE_1' });

// Get shapes for multiple trips
const tripShapes = gtfs.getShapes({ tripId: ['TRIP_1', 'TRIP_2'] });

// Each shape point contains:
// - shape_id: string
// - shape_pt_lat: number
// - shape_pt_lon: number
// - shape_pt_sequence: number
// - shape_dist_traveled?: number (optional)
```

#### Get Shapes as GeoJSON

Convert shapes to GeoJSON format for use with mapping libraries (Leaflet, Mapbox, etc.):

```typescript
// Get all shapes as GeoJSON FeatureCollection
const geojson = gtfs.getShapesToGeojson();

// Get shapes for a specific route
const routeGeojson = gtfs.getShapesToGeojson({ routeId: 'ROUTE_1' });

// Customize coordinate precision (default: 6 decimals = ~10cm)
const lowPrecision = gtfs.getShapesToGeojson({ routeId: 'ROUTE_1' }, 4); // ~11m precision

// GeoJSON structure:
// {
// type: 'FeatureCollection',
// features: [{
// type: 'Feature',
// properties: {
// shape_id: 'SHAPE_1',
// route_id: 'ROUTE_1',
// route_short_name: '1',
// route_long_name: 'Main Street',
// route_type: 3,
// route_color: 'FF0000',
// route_text_color: 'FFFFFF',
// agency_id: 'AGENCY_1'
// },
// geometry: {
// type: 'LineString',
// coordinates: [[-122.123456, 37.123456], [-122.234567, 37.234567], ...]
// }
// }]
// }

// Use with Leaflet
const geoJsonLayer = L.geoJSON(geojson, {
style: (feature) => ({
color: `#${feature.properties.route_color || '000000'}`,
weight: 3
})
}).addTo(map);
```

**Precision values:**
- `6` decimals: ~10cm precision (default)
- `5` decimals: ~1m precision
- `4` decimals: ~11m precision
- `3` decimals: ~111m precision

### GTFS Realtime Support

This library supports GTFS Realtime data (alerts, trip updates, and vehicle positions) with automatic merging into static schedule data.
Expand Down Expand Up @@ -1063,6 +1147,8 @@ All methods support flexible filtering with both single values and arrays:
- `getRoutes(filters?)` - Get routes (filters: routeId, agencyId, limit)
- `getTrips(filters?)` - Get trips (filters: tripId, routeId, serviceIds, directionId, agencyId, includeRealtime, limit, date)
- `getStopTimes(filters?)` - Get stop times (filters: tripId, stopId, routeId, serviceIds, directionId, agencyId, includeRealtime, limit, date)
- `getShapes(filters?)` - Get shape points (filters: shapeId, routeId, tripId, limit)
- `getShapesToGeojson(filters?, precision?)` - Get shapes as GeoJSON FeatureCollection (same filters, precision default: 6)
- `buildOrderedStopList(tripIds)` - Build an ordered list of stops from multiple trips (handles express/local variations)

#### Calendar Methods
Expand Down Expand Up @@ -1101,8 +1187,10 @@ This library is written in TypeScript and provides full type definitions for all
```typescript
import type {
// Static GTFS types
Stop, Route, Trip, StopTime,
TripFilters, StopTimeFilters,
Stop, Route, Trip, StopTime, Shape,
TripFilters, StopTimeFilters, ShapeFilters,
// GeoJSON types
GeoJsonFeatureCollection,
// GTFS-RT types
Alert, VehiclePosition, TripWithRealtime, StopTimeWithRealtime,
AlertFilters, VehiclePositionFilters,
Expand Down
102 changes: 101 additions & 1 deletion dist/index.d.mts
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,39 @@ interface StopTimeWithRealtime extends StopTime {
realtime?: StopTimeRealtime;
}

/**
* Shape Query Methods
*/

interface ShapeFilters {
shapeId?: string | string[];
routeId?: string | string[];
tripId?: string | string[];
limit?: number;
}
interface GeoJsonGeometry {
type: 'LineString';
coordinates: number[][];
}
interface GeoJsonFeature {
type: 'Feature';
properties: {
shape_id: string;
route_id?: string;
route_short_name?: string;
route_long_name?: string;
route_type?: number;
route_color?: string;
route_text_color?: string;
agency_id?: string;
};
geometry: GeoJsonGeometry;
}
interface GeoJsonFeatureCollection {
type: 'FeatureCollection';
features: GeoJsonFeature[];
}

interface TripUpdateFilters {
tripId?: string;
routeId?: string;
Expand Down Expand Up @@ -744,6 +777,73 @@ declare class GtfsSqlJs {
getTrips(filters?: TripFilters & {
date?: string;
}): Trip[];
/**
* Get shapes with optional filters
*
* @param filters - Optional filters
* @param filters.shapeId - Filter by shape ID (single value or array)
* @param filters.routeId - Filter by route ID (single value or array) - joins with trips table
* @param filters.tripId - Filter by trip ID (single value or array) - joins with trips table
* @param filters.limit - Limit number of results
*
* @example
* // Get all points for a specific shape
* const shapes = gtfs.getShapes({ shapeId: 'SHAPE_1' });
*
* @example
* // Get shapes for a specific route
* const shapes = gtfs.getShapes({ routeId: 'ROUTE_1' });
*
* @example
* // Get shapes for multiple trips
* const shapes = gtfs.getShapes({ tripId: ['TRIP_1', 'TRIP_2'] });
*/
getShapes(filters?: ShapeFilters): Shape[];
/**
* Get shapes as GeoJSON FeatureCollection
*
* Each shape is converted to a LineString Feature with route properties.
* Coordinates are in [longitude, latitude] format per GeoJSON spec.
*
* @param filters - Optional filters (same as getShapes)
* @param filters.shapeId - Filter by shape ID (single value or array)
* @param filters.routeId - Filter by route ID (single value or array)
* @param filters.tripId - Filter by trip ID (single value or array)
* @param filters.limit - Limit number of results
* @param precision - Number of decimal places for coordinates (default: 6, ~10cm precision)
*
* @returns GeoJSON FeatureCollection with LineString features
*
* @example
* // Get all shapes as GeoJSON
* const geojson = gtfs.getShapesToGeojson();
*
* @example
* // Get shapes for a route with lower precision
* const geojson = gtfs.getShapesToGeojson({ routeId: 'ROUTE_1' }, 5);
*
* @example
* // Result structure:
* // {
* // type: 'FeatureCollection',
* // features: [{
* // type: 'Feature',
* // properties: {
* // shape_id: 'SHAPE_1',
* // route_id: 'ROUTE_1',
* // route_short_name: '1',
* // route_long_name: 'Main Street',
* // route_type: 3,
* // route_color: 'FF0000'
* // },
* // geometry: {
* // type: 'LineString',
* // coordinates: [[-122.123456, 37.123456], ...]
* // }
* // }]
* // }
*/
getShapesToGeojson(filters?: ShapeFilters, precision?: number): GeoJsonFeatureCollection;
/**
* Get stop times with optional filters
*
Expand Down Expand Up @@ -1102,4 +1202,4 @@ declare function getCacheStats(entries: CacheEntry[]): {
newestEntry: number | null;
};

export { type Agency, type AgencyFilters, type Alert, AlertCause, AlertEffect, type AlertFilters, type Attribution, type CacheEntry, type CacheEntryWithData, type CacheMetadata, type CacheStore, type CacheStoreOptions, type Calendar, type CalendarDate, type ColumnDefinition, CongestionLevel, DEFAULT_CACHE_EXPIRATION_MS, type EntitySelector, type FareAttribute, type FareRule, type FeedInfo, FileSystemCacheStore, type Frequency, GTFS_SCHEMA, GtfsSqlJs, type GtfsSqlJsOptions, type IndexDefinition, IndexedDBCacheStore, type Level, OccupancyStatus, type Pathway, type Position, type RealtimeConfig, type Route, type RouteFilters, ScheduleRelationship, type Shape, type Stop, type StopFilters, type StopTime, type StopTimeEvent, type StopTimeFilters, type StopTimeRealtime, type StopTimeUpdate, type StopTimeUpdateFilters, type StopTimeWithRealtime, type TableSchema, type TimeRange, type Transfer, type TranslatedString, type Trip, type TripFilters, type TripRealtime, type TripUpdate, type TripUpdateFilters, type TripWithRealtime, type VehicleDescriptor, type VehiclePosition, type VehiclePositionFilters, VehicleStopStatus, computeChecksum, computeZipChecksum, filterExpiredEntries, generateCacheKey, getCacheStats, isCacheExpired };
export { type Agency, type AgencyFilters, type Alert, AlertCause, AlertEffect, type AlertFilters, type Attribution, type CacheEntry, type CacheEntryWithData, type CacheMetadata, type CacheStore, type CacheStoreOptions, type Calendar, type CalendarDate, type ColumnDefinition, CongestionLevel, DEFAULT_CACHE_EXPIRATION_MS, type EntitySelector, type FareAttribute, type FareRule, type FeedInfo, FileSystemCacheStore, type Frequency, GTFS_SCHEMA, type GeoJsonFeatureCollection, GtfsSqlJs, type GtfsSqlJsOptions, type IndexDefinition, IndexedDBCacheStore, type Level, OccupancyStatus, type Pathway, type Position, type RealtimeConfig, type Route, type RouteFilters, ScheduleRelationship, type Shape, type ShapeFilters, type Stop, type StopFilters, type StopTime, type StopTimeEvent, type StopTimeFilters, type StopTimeRealtime, type StopTimeUpdate, type StopTimeUpdateFilters, type StopTimeWithRealtime, type TableSchema, type TimeRange, type Transfer, type TranslatedString, type Trip, type TripFilters, type TripRealtime, type TripUpdate, type TripUpdateFilters, type TripWithRealtime, type VehicleDescriptor, type VehiclePosition, type VehiclePositionFilters, VehicleStopStatus, computeChecksum, computeZipChecksum, filterExpiredEntries, generateCacheKey, getCacheStats, isCacheExpired };
102 changes: 101 additions & 1 deletion dist/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -550,6 +550,39 @@ interface StopTimeWithRealtime extends StopTime {
realtime?: StopTimeRealtime;
}

/**
* Shape Query Methods
*/

interface ShapeFilters {
shapeId?: string | string[];
routeId?: string | string[];
tripId?: string | string[];
limit?: number;
}
interface GeoJsonGeometry {
type: 'LineString';
coordinates: number[][];
}
interface GeoJsonFeature {
type: 'Feature';
properties: {
shape_id: string;
route_id?: string;
route_short_name?: string;
route_long_name?: string;
route_type?: number;
route_color?: string;
route_text_color?: string;
agency_id?: string;
};
geometry: GeoJsonGeometry;
}
interface GeoJsonFeatureCollection {
type: 'FeatureCollection';
features: GeoJsonFeature[];
}

interface TripUpdateFilters {
tripId?: string;
routeId?: string;
Expand Down Expand Up @@ -744,6 +777,73 @@ declare class GtfsSqlJs {
getTrips(filters?: TripFilters & {
date?: string;
}): Trip[];
/**
* Get shapes with optional filters
*
* @param filters - Optional filters
* @param filters.shapeId - Filter by shape ID (single value or array)
* @param filters.routeId - Filter by route ID (single value or array) - joins with trips table
* @param filters.tripId - Filter by trip ID (single value or array) - joins with trips table
* @param filters.limit - Limit number of results
*
* @example
* // Get all points for a specific shape
* const shapes = gtfs.getShapes({ shapeId: 'SHAPE_1' });
*
* @example
* // Get shapes for a specific route
* const shapes = gtfs.getShapes({ routeId: 'ROUTE_1' });
*
* @example
* // Get shapes for multiple trips
* const shapes = gtfs.getShapes({ tripId: ['TRIP_1', 'TRIP_2'] });
*/
getShapes(filters?: ShapeFilters): Shape[];
/**
* Get shapes as GeoJSON FeatureCollection
*
* Each shape is converted to a LineString Feature with route properties.
* Coordinates are in [longitude, latitude] format per GeoJSON spec.
*
* @param filters - Optional filters (same as getShapes)
* @param filters.shapeId - Filter by shape ID (single value or array)
* @param filters.routeId - Filter by route ID (single value or array)
* @param filters.tripId - Filter by trip ID (single value or array)
* @param filters.limit - Limit number of results
* @param precision - Number of decimal places for coordinates (default: 6, ~10cm precision)
*
* @returns GeoJSON FeatureCollection with LineString features
*
* @example
* // Get all shapes as GeoJSON
* const geojson = gtfs.getShapesToGeojson();
*
* @example
* // Get shapes for a route with lower precision
* const geojson = gtfs.getShapesToGeojson({ routeId: 'ROUTE_1' }, 5);
*
* @example
* // Result structure:
* // {
* // type: 'FeatureCollection',
* // features: [{
* // type: 'Feature',
* // properties: {
* // shape_id: 'SHAPE_1',
* // route_id: 'ROUTE_1',
* // route_short_name: '1',
* // route_long_name: 'Main Street',
* // route_type: 3,
* // route_color: 'FF0000'
* // },
* // geometry: {
* // type: 'LineString',
* // coordinates: [[-122.123456, 37.123456], ...]
* // }
* // }]
* // }
*/
getShapesToGeojson(filters?: ShapeFilters, precision?: number): GeoJsonFeatureCollection;
/**
* Get stop times with optional filters
*
Expand Down Expand Up @@ -1102,4 +1202,4 @@ declare function getCacheStats(entries: CacheEntry[]): {
newestEntry: number | null;
};

export { type Agency, type AgencyFilters, type Alert, AlertCause, AlertEffect, type AlertFilters, type Attribution, type CacheEntry, type CacheEntryWithData, type CacheMetadata, type CacheStore, type CacheStoreOptions, type Calendar, type CalendarDate, type ColumnDefinition, CongestionLevel, DEFAULT_CACHE_EXPIRATION_MS, type EntitySelector, type FareAttribute, type FareRule, type FeedInfo, FileSystemCacheStore, type Frequency, GTFS_SCHEMA, GtfsSqlJs, type GtfsSqlJsOptions, type IndexDefinition, IndexedDBCacheStore, type Level, OccupancyStatus, type Pathway, type Position, type RealtimeConfig, type Route, type RouteFilters, ScheduleRelationship, type Shape, type Stop, type StopFilters, type StopTime, type StopTimeEvent, type StopTimeFilters, type StopTimeRealtime, type StopTimeUpdate, type StopTimeUpdateFilters, type StopTimeWithRealtime, type TableSchema, type TimeRange, type Transfer, type TranslatedString, type Trip, type TripFilters, type TripRealtime, type TripUpdate, type TripUpdateFilters, type TripWithRealtime, type VehicleDescriptor, type VehiclePosition, type VehiclePositionFilters, VehicleStopStatus, computeChecksum, computeZipChecksum, filterExpiredEntries, generateCacheKey, getCacheStats, isCacheExpired };
export { type Agency, type AgencyFilters, type Alert, AlertCause, AlertEffect, type AlertFilters, type Attribution, type CacheEntry, type CacheEntryWithData, type CacheMetadata, type CacheStore, type CacheStoreOptions, type Calendar, type CalendarDate, type ColumnDefinition, CongestionLevel, DEFAULT_CACHE_EXPIRATION_MS, type EntitySelector, type FareAttribute, type FareRule, type FeedInfo, FileSystemCacheStore, type Frequency, GTFS_SCHEMA, type GeoJsonFeatureCollection, GtfsSqlJs, type GtfsSqlJsOptions, type IndexDefinition, IndexedDBCacheStore, type Level, OccupancyStatus, type Pathway, type Position, type RealtimeConfig, type Route, type RouteFilters, ScheduleRelationship, type Shape, type ShapeFilters, type Stop, type StopFilters, type StopTime, type StopTimeEvent, type StopTimeFilters, type StopTimeRealtime, type StopTimeUpdate, type StopTimeUpdateFilters, type StopTimeWithRealtime, type TableSchema, type TimeRange, type Transfer, type TranslatedString, type Trip, type TripFilters, type TripRealtime, type TripUpdate, type TripUpdateFilters, type TripWithRealtime, type VehicleDescriptor, type VehiclePosition, type VehiclePositionFilters, VehicleStopStatus, computeChecksum, computeZipChecksum, filterExpiredEntries, generateCacheKey, getCacheStats, isCacheExpired };
Loading