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
int64
Unix timestamps totime.Time
values. -
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/zip
standard library package). -
40% of the time parsing the CSV files into strings (using the
encoding/csv
standard library package) -
30% of the time in this package performing the conversions from strings into types like
time.Duration
and linking related entities.
TBD