The Road to GTFS

By chimo on (updated on )

Pretty much every blog post here relates to Project Autonomous in a way or another. This blog post does as well. This time, I'm telling the story of how came about.

TL;DR: I want to self-host the public transportation data I'm interested in. Navitia is really, really cool, but also way overkill for this particular project. So I built a simple, private "API" (it only has a single function at the moment) over the database created by the `pygtfs2db` utility.


The logical step after self-hosting a bunch of services was to find Android apps that can integrate with them. While working on my Android Stack, I ran into the excellent Transportr app. I'm not self-hosting the service behind Transportr, but having a FLOSS public transport app is a big win.

Transportr didn't support my region at first but digging into how the app works, I discovered that it uses Navitia as a data source. After a bit of fiddling around, I submitted a pull-request to have the region added.

As mentioned, I learned about navitia while poking around the Transportr app. One thing that caught my eye was the fact that Navitia itself is Free Software. At some point, mostly just for fun, I had a local instance of navitia running for the province I live in. This was a very interesting experiment, but with the limited hardware that I have, it's not viable for me to keep running this for essentially a single user using a single transit agency.

GTFS and pygtfs

Naturally, diving into how Navitia works I ran into GTFS data, which is pretty interesting on its own. Since this is really all I need for this use-case, I looked for a utility to convert GTFS into a working database. One of them was pygtfs.

Using `pygtfs`'s `pygtfs2db` utility, I periodically get a copy of my transit's GTFS data and import it into a PostgreSQL database. A simple simple PHP script takes requests (an agency ID and a stop ID), queries the database and spits out the next three trips at the given bus stop. This, along with the GPS live-tracking API provided by my transit agency is all I need on a day-to-day basis.