Today we’ve launched the first step in our efforts to improve transportation symbology in MapBox Streets - custom icons for London’s Underground and light rail systems, as well as the National Rail lines throughout Great Britain. The signs for these stations are iconic and will be better recognized on maps than our previous generic rail icons.

The map style accounts for stations that service lines on multiple rail networks, such as Underground stations with connections to National Rail routes. The stylesheet also handles clustering icons to avoid duplicate labels, since many stations are represented by multiple nodes (perhaps one for each track, or one for each entrance). At medium scales stations are grouped by name, and as you zoom in they become grouped by name then network. In most cases this makes for much cleaner cartography with minimal loss in accuracy.

Comparison of clustered vs unclustered icons

Creating and assigning icons

We base the icons for a station on the contents of its ‘network’ tag. If a station services multiple networks, these will usually all be included separated by a semicolon, comma, or slash. Ordering is not necessarily consistent, so we normalize this tag by breaking it up into parts, stripping spaces, lowercasing everything, and assembling it back together in alphabetical order. This way two network tags that mean the same thing but are written differently will be made consistent.

Example network tag Normalized
London Underground;London Overground
London Overground / London Underground

For stations that require multiple network icons, we design single images for the individual networks and then have a script check the database to generate all the necessary combinations. The individual images are merged as necessary with ImageMagick, and the names of the resulting files match the normalized network tag. The Carto code for assigning the icons is dead simple:

#train_stations[zoom>=17] {
  ::icon {
    point-file: url("img/rail/[network]-12.png");
    [zoom=17] { point-file: url("img/rail/[network]-18.png"); }
    [zoom>17] { point-file: url("img/rail/[network]-24.png"); }
  /* ... label styles ... */

Mapnik replaces [network] in the image URL with the value of the current element’s network column, so only a few lines of code are required for potentially hundreds of different icons.

How the clustering works

We import OpenStreetMap data to a PostGIS database via Imposm. All railway stations are imported to their own table as points (even if a station exists in OpenStreetMap as an area, it is converted). The import process adds two columns, groupby_high and groupby_low, that are used at render time for clustering points. The first column contains a normalized version of the stations name if it has one, or its OSM ID if it does not. The second column is the normalized name concatenated with the normalized network. As you zoom in, this accounts for stations that are near each other and have the same name, but are actually separate and require different icons.

We use these columns to group by in our PostgreSQL select statements. We generate a centroid from grouped points for a single label, and re-normalize the grouped network tags

In my presentation at FOSS4G North America last month, I talked about how we like to do as much data processing as possible at the import stage for MapBox Streets. The clustering of station points is something that has to happen at render time, however, because we only want to be clustering points that are relatively close to each other. For example, there are many ‘Union Stations’ across North America that should not be clustered together simply because they have the same name. Waiting until render time means that only points within a particular metatile will be considered for the grouping.

Check it out

Custom icons for Great Britain are live in MapBox Streets now, which you can start using with a free MapBox account. We are planning on bringing local transportation icons to more cities in the future - where should we travel next? Tweet us @MapBox.