This is a Go package for parsing GTFS static and realtime feeds.
The static parser is pretty straightforward and simply maps fields in the GTFS static CSV files to associated Go types.
For realtime parsing this package offers two options.
Option 1 is to use the parser and types generated by the protobuf compiler which are available in the proto subpackage.
This saves you from having to compile the protobufs yourself.
Option 2 is to use the package's custom parser, which takes the protobuf output from option 1, does a bunch of post-processing, and then outputs the result in standard (non-proto) Go types. This post-processing does useful things like:
-
Converts some data fields to more idiomatic Go types - for example, times are converted from
int64Unix timestamps totime.Timevalues. -
Makes the representation of trips and vehicles more explicit. Each trip has a (nullable) pointer to the associated vehicle in the feed, if it exists, and vice-versa.
-
Implements business logic to map data in various GTFS realtime extensions to regular GTFS realtime fields.
Backwards compatibility warning:
this package is under active development and backwards incompatible changes are frequently made.
We're eventually planning to release a v1.0.0 version, and after that all changes
will be backwards compatible and consistent with semantic versioning.
Parse the GTFS static feed for the New York City Subway:
resp, _ := http.Get("http://web.mta.info/developers/data/nyct/subway/google_transit.zip")
b, _ := io.ReadAll(resp.Body)
staticData, _ := gtfs.ParseStatic(b, gtfs.ParseStaticOptions{})
fmt.Printf("The New York City subway has %d routes and %d stations\n", len(staticData.Routes), len(staticData.Stops))Parse the GTFS realtime feed for the San Francisco Bay Area BART:
resp, _ := http.Get("http://api.bart.gov/gtfsrt/tripupdate.aspx")
b, _ := io.ReadAll(resp.Body)
realtimeData, _ := gtfs.ParseRealtime(b, >fs.ParseRealtimeOptions{})
fmt.Printf("The SF BART currently has %d trains running or scheduled\n", len(realtimeData.Trips))Below is a list of the GTFS schedule files and whether they are currently supported. Progress for full support is being tracked in issue #4.
| File Name | Supported | Required by Spec | Notes |
|---|---|---|---|
| agency.txt | ✅ | Required | |
| stops.txt | ✅ | Conditionally Required | Always required by library |
| routes.txt | ✅ | Required | |
| trips.txt | ✅ | Required | |
| stop_times.txt | ✅ | Required | |
| calendar.txt | ✅ | Conditionally Required | Surfaced as a Service, always required by library |
| calendar_dates.txt | ✅ | Conditionally Required | Surfaced as part of a Service, always required by library |
| fare_attributes.txt | ❌ | Optional | |
| fare_rules.txt | ❌ | Optional | |
| timeframes.txt | ❌ | Optional | |
| fare_media.txt | ❌ | Optional | |
| fare_products.txt | ❌ | Optional | |
| fare_leg_rules.txt | ❌ | Optional | |
| fare_leg_join_rules.txt | ❌ | Optional | |
| fare_transfer_rules.txt | ❌ | Optional | |
| areas.txt | ❌ | Optional | |
| stop_areas.txt | ❌ | Optional | |
| networks.txt | ❌ | Conditionally Forbidden | |
| route_networks.txt | ❌ | Conditionally Forbidden | |
| location_groups.txt | ❌ | Conditionally Forbidden | |
| shapes.txt | ✅ | Optional | |
| frequencies.txt | ✅ | Optional | |
| transfers.txt | 🟨 | Optional | Partially implemented |
| pathways.txt | ❌ | Optional | |
| levels.txt | ❌ | Conditionally Required | |
| location_group_stops.txt | ❌ | Optional | |
| locations.geojson | ❌ | Optional | |
| booking_rules.txt | ❌ | Optional | |
| translations.txt | ❌ | Optional | |
| feed_info.txt | ❌ | Conditionally Required | |
| attributions.txt | ❌ | Optional |
The package is designed to be about as fast as possible without resorting to unreadable code.
A profiler for the package is in the performance directory.
The static parser has been performance optimized somewhat significantly. It takes about 3 seconds to parse the GTFS static data for the NYC buses (45 megabytes compressed, 360 megabytes uncompressed). The rough breakdown is:
-
30% of the time unzipping the archives (using the
archive/zipstandard library package). -
40% of the time parsing the CSV files into strings (using the
encoding/csvstandard library package) -
30% of the time in this package performing the conversions from strings into types like
time.Durationand linking related entities.
TBD