Generating pretty maps to visualize current and proposed transit

Eddy Ionescu
8 min readSep 18, 2018

--

An accessible, fast, and frequent public transit system is vital for ensuring sustainable growth and for allowing residents of all backgrounds to access opportunities, allowing for more equitable outcomes.

It can be hard to tell how good or bad transit service really is. Many suburban areas have coverage-oriented routes that might look good on a map, but are in practice inaccessible due to their low frequencies. Likewise, urban areas often have many peak-only express routes but limited service at night and in off-peak periods.

Motivated by the MTC’s (regional transportation agency for the San Francisco Bay Area) Horizon Request for Transformative Projects contest, Jason Lee and I decided to make a detailed, thought-out, and intuitive blueprint for the transportation network that will be vital in allowing the Bay Area to grow sustainably. It’s called Move Bay Area and you can check it out here.

This post will show you how to generate the pretty maps included in the proposal. It’ll also cover the steps I took to turn generating maps from a manual and tedious ordeal to one that is simple and flexible — which should be of interest if you’re looking to make more customizations.

My goal is to enable those with non-technical backgrounds to generate maps that look exactly the same as the ones below — so if there’s anything confusing please feel free to leave a comment!

Regional Transit

The first part of Move Bay Area looks at regional mobility, and proposes creating a heavy-rail Transbay tube, adding high-frequency rail to the existing San Jose — San Francisco — Sacramento rail corridor, using eBART style DMU to extend BART’s reach, and in adding regional bus service as to fill gaps in the regional rail system.

The most effective way of conveying transit proposals is to draw them on a map — and that’s exactly what we set out to do. We used My Maps (in the more section of Google Drive) to draw new tracks and to add in existing systems (like BART, Muni Metro, and VTA, … SMART) — steps on doing this are explained later on.

Bold lines represent new construction or significant improvements on existing corridors. Grey lines represent regional bus routes.

Local Transit

New routes are easy to show on a map; however, the same isn’t true for existing routes with improved service. To visualize the impact of the service improvements we proposed, we generated before and after maps containing all the lines that run frequently enough that they can be relied on.

Current transit lines that run every 15 (red) and 20 (green) minutes or better, all day, every day.
Proposed transit lines that run every 15 (red) and 20 (green) minutes or better, all day, every day.

And a closer look at SF and Oakland:

Current transit lines that run every 15 (red) and 20 (green) minutes or better, all day, every day.
Proposed transit lines that run every 15 (red) and 20 (green) minutes or better, all day, every day.

And here are the proposed increased service hours, with the routes shown operating both longer and more frequently:

How you can make them

Gone are the days when you had to manually draw out existing transit lines. There are existing formats, like GTFS, KML, and GeoJSON that allow us to import transit lines at the touch of a button.

  1. Getting the transit data

KML is the file format that Google Earth generates as to store shapes, pins, and lines. It’s useful as you can edit it right in Google Earth, import it in My Maps, and is supported by many other applications, like ArcGIS.

Some agencies, like the SFMTA have multiple formats of their routes available while others unfortunately don’t have any. Fortunately, there’s GTFS to the rescue. GTFS (General Transit Feed Specification) is an industry-standard format designed by Google and TriMet to standardize the sharing of transit schedules, routes, stops, and fares.

GTFS files for agencies can be usually found in the developers section of the desired agency’s website or by searching for them online — they use the .zip file extension.

511 (run by the MTC) contains the GTFS files for the (all 32 of them!) transit agencies in the Bay Area. You can see them with the following link: http://api.511.org/transit/gtfsoperators?api_key=MY_API_KEY, replacing MY_API_KEY for the token you got from their developers page. You can then download the GTFS file for your desired agency with the following link: http://api.511.org/transit/datafeeds?api_key=MY_API_KEY&operator_id=AGENCY_ID, substituting AGENCY_ID with the two digit ID you saw in the previous link.

2. Importing GTFS transit networks into My Maps

If your desired transit agency has KML files available and you don’t want to make any customizations like showing certain routes or setting route colours, skip to step 4. You can also import it straight into My Maps and modify it there.

If your desired transit agency has KML files available but you’d like to make a small number of customizations like showing certain routes, setting route colours, or only showing part of a route, simply open the KML file in Google Earth, modify it, and then save it. Then skip to step 4.

Note: Proceeding through this step and the next will require a tiny bit of technical experience (ie. using the command-line). If you’re using a Mac, simply copy the instructions. If you’re using Windows, first install the Git command line tools, and then install Python using this guide. Then you can copy the commands below into the Git command-line.

We can’t use GTFS files directly, so we’ll convert them to a popular format — in this case, KML. Google made a package called transitfeed that does just that, you can find it here: https://github.com/EddyIonescu/transitfeed. I’ve added some features and sample files to it; my changes are described here.

Once you’ve navigated to the page, open terminal and run

git clone https://github.com/EddyIonescu/transitfeed.git

cd transitfeed

python kmlwriter.py input_gtfs output_kml.kml

where input_gtfs is the name of your GTFS file (ie. muni_gtfs.zip) that must also be in the transitfeed folder and output_kml.kml is the name of your output file (ie. muni_kml.zip).

Go to My Maps, go to import, and select the KML file that was generated. Once it loads, you can open it in the side-panel and hide routes you don’t want to be visible and change the style.

3. Customizing the KML output

My Maps lets you customize each segment of each route, but doing this at scale (ie. for 100 routes) is just really tedious and time-consuming.

I’ve added a module to transitfeed that lets you provide a CSV file that customizes the visibility and colour of routes.

You can create a CSV file in Excel by exporting in the CSV file format. Ensure that your cell values are in the same format as the one used for local transit here — and that it includes all the column names in the same format, even if you’re not using them. Note that leaving out a route ID will cause it to not appear.

For the colour column, you must provide a hexadecimal colour code. You can generate one for your desired colour here.

The intention of the Hidden_Shapes column is to allow you to hide certain segments of routes. For example, say a frequent route has a branch that only runs at peak hours — we’d like to hide that branch as it doesn’t run all the time. As you’ll see in the sample CSV, the cell value is a comma-separated string. Each value in that string represents the ID of a shape in the GTFS. Since each route contains multiple shapes, you can use this to make routes only partially visible. To get the desired IDs, open the generated KML into Google Earth, and select the line segment you’d like to remove — the ID is in its layer name.

Save your CSV to the route_styles folder in transitfeed. Then run:

python kmlwriter.py --agency_id YOUR_AGENCY_NAME --style_csv_path './route_styles/YOUR_CSV_NAME.csv' YOUR_GTFS_FILENAME.zip output_map.kml

where YOUR_AGENCY_NAME is the same as the one used in the first column of your CSV file, and is surrounded in single-quotes, YOUR_CSV_NAME is the filename of your CSV file, and YOUR_GTFS_FILENAME is the filename of the GTFS file you downloaded in step 2.

Now import output_map.kml in My Maps or Google Earth and you’ll see the customizations.

You can also modify some properties in the GTFS file directly. Just navigate to routes.txt and open it in Excel (for the delimiter, select comma) or edit it directly in your favourite code editor.

4. Convert to GeoJSON

While KML is a widely-used file format that can be easily edited in Google Earth, its complexity limits its use in web-apps. That’s why we’ll be using GeoJSON, which can be easily read by web-apps. To convert your KML to GeoJSON, you can use this online tool by Mapbox.

5. Get your Google Maps API key

The background used was actually a Google Maps style; for example, the first local transit map (for current frequent routes) can be found here and you can zoom in and out by scrolling. You can get an API key here.

6. Make the pretty map

Go to https://github.com/EddyIonescu/move-bay-area-map and clone or download it. Then, open sample_key.json, replace YOUR_API_KEY with the one from step 5, and save it as key.json.

Then, open index.html using at line 301 using a code-editor like VS-Code or Sublime, and add the names of your files to the list. Line 301 should look like this:

let geojson_links = [‘your_output_1.json', ‘your_output_2.json’];

Opening index.html will show an empty map (unless you opened it in Firefox). Why? Because websites aren’t allowed to use files from your computer (for security reasons), and it’s enforced by browsers via a policy called CORS. We have three options.

Option 1: Open it in Firefox

This works because Firefox will allow you to open local files as long as your webpage is also local, so there’s no security risk.

Option 2: Use Github Pages (or deploy to a web host — you can also use S3 static website hosting on AWS)

Push your changes to a fork you’ve made of the repo on Github. Then, go to settings, scroll down, and enable Github Pages. Your site should be available in a few minutes. Note that you will have to include the key.json file (with the actual API key), so either use a private repo or remember to disable or refresh your API key after you’re done.

Then open index.html and see the map. You can scroll to zoom in and out, and then take a screenshot to save an image. Here’s an example of how it should look (map of all the frequent transit routes in the Bay Area — red for every 15 minutes, green for every 20 minutes, all day every day).

Generating pretty maps shouldn’t require deep technical skill nor require countless hours to be spent drawing transit routes that already exist. I hope that my experiences using (and modifying) these open-source tools made it easy for you to follow along. If there are any steps that are confusing you, or if you’d like to report a bug or make a feature request, leave a comment or send me an email by going to my Github page — https://github.com/EddyIonescu.

Lastly, did this help you make some pretty maps? Share them in the comment section below :)

--

--

Eddy Ionescu

Waterloo CS student interested in transportation and urban planning. Formerly at Metrolinx, TTC, Yelp.