Categorize GTFS data based on transport type using QGIS

Recently I discovered a tutorial on how to import GTFS data into QGIS. It describes how to convert the point-based stops.txt or shapes.txt into polylines of transport routes. Here is the gist:

  • Get a GTFS data set of your choice, i.e. from GTFS Data Exchange and extract it.
  • In QGIS, add the shapes.txt as a Delimited Text File. Make sure to select the correct columns for longitude (X-Field) and latitude (Y-Field).
  • To group the routes from your shapes.txt based on their "route_id", use the plugin Points to Paths.

Polylines of transport shapesTransport routes as polylines

This will result in a shapefile of your transport routes represented as polylines. I used a GTFS data set for the region Potsdam/Brandenburg. And this will be our starting point.

The Problem

OK, so now you've got a shapefile with single segments, representing the routes of single transport types, i.e. a single bus or tram route. But what is missing, is info on which particular bus or tram route you are looking at. To be precise, categorization is missing. Which route represents a single type of transportation?

Single transport route segmentSingle transport route missing attributes

The solution

A GTFS data set is basically an extract of a relational database. The information we need is stored in the file routes.txt. The column "route_short_name" contains the name of each route, i.e. a bus called 695 or a train with the name RE1. The column's"route_type" number represents the transport type, i.e. 2 for rail and 3 for bus.

Basic structure of GTFS data setsBasic structure of GTFS data sets - James Wong/Openplans

This means we need a connection between the file routes.txt and our shapes. "route_id" is found to the file trips.txt, which in turn contains the column "shape_id". "shape_id" for us now is called "group" in our shapefile, that we created in the beginning. So all we need to do is two simple joins between a shapefile and two tables.

  1. In QGIS, add trips.txt as a Delimited Text File, choosing "No geometry (attribute only table)".
    Add trips.txt as a layerAdd trips.txt as a layer

  2. Go to the properties of your shape layer and create a join to trips.txt based on the fields "shape_id" and "group". To reduce the size of the resulting file, select only the column "route_id" for the join.
    Create a join between the shapes and Create a join between the shapes and trips.txt

  3. We need another join. Save the result as a new layer, i.e. "shape_trip". For the next join, add routes.txt as a layer. Now, create a join between "shape_trip" and routes.txt based on the fields "route_id" and "trips_route_id". Again, save the result as a new shapefile.

And there you go, you've got yourself a shapefile with transport route segments and also attributes for transport names and type, which you could now style as you please.

Transport segments with correct attributationTransport segments with correct attributation

I created a simple webmap showing the resulting attributation. You can view it here.