ProPublica

Journalism in the Public Interest

Cancel

The ProPublica Nerd Blog

Introducing Simple Tiles: Our New Mapping Library

Newsrooms have been publishing maps for a long time. However, mapping on the web is very difficult due to the sheer amount of data involved. Some of the largest datasets available to journalists are geospatial. The U.S. TIGER/Line roads database, for example, tips the scale at 9.2 gigabytes, and the USGS’s national hydrography data set is 17 gigabytes compressed.

The data needed to analyze legislative redistricting is similarly huge. In California alone there are 700,000 Census blocks. When we started covering redistricting last year, we knew we would need an easy way to present vast amounts data quickly. We took a serious look at both Mapnik and Mapserver — who are still leaders in the field — but the Ruby bindings support in both, at the time, weren’t as robust and stable as we needed them to be.

So we wrote a mapping framework of our own called Simple Tiles, which we are open sourcing today.

How it Works

Maps on the web are made up of thousands of square images, which are dynamically loaded into your browser as you drag around a map or zoom to different zoom levels. By chopping up a big map into a grid, servers can parallelize rendering, which would be impossible with a single large image.

Simple Tiles creates such images, called tiles, from spatial data, and provides an easy way to generate each map tile based on x, y, and z coordinates. Those coordinates are typically generated by JavaScript mapping frameworks like Leaflet.js.

At its base, Simple Tiles, which is written in C, is a wrapper around the OGR Simple Feature Library, which handles geospatial sources, and Cairo, which produces the final images for the web. Both libraries are fantastic to work with and have deep APIs, which keeps Simple Tiles very small.

Simple Tiles is designed to be very lightweight, and will continue to be so. It won’t do any fancy translation (outside of projection) or analysis of spatial data, and it also does not include a separate stylesheet language or a server for serving images. It is meant to be embedded in dynamic languages like Ruby through language bindings.

The Simple Tiles API is small and easy to use. Here’s an example, from the repository’s test/api.c:

  #include <stdlib.h>
  #include <assert.h>
  #include <simple-tiles/simple_tiles.h>
  #include <simple-tiles/filter.h>
  #include <simple-tiles/layer.h>

  int
  main(){
    simplet_map_t *map;
    if(!(map = simplet_map_new()))
      exit(1);

    simplet_map_set_slippy(map, 0, 0, 0);
    simplet_map_set_size(map, 1000, 1000);
    simplet_map_set_bgcolor(map, "#ddeeff");

    simplet_layer_t *layer   = simplet_map_add_layer(map, "../data/ne_10m_admin_0_countries.shp");
    simplet_filter_t *filter = simplet_layer_add_filter(layer,  "SELECT * from 'ne_10m_admin_0_countries'");
    simplet_filter_add_style(filter, "stroke", "#226688");
    simplet_filter_add_style(filter, "line-join", "round");
    simplet_filter_add_style(filter, "weight", "3");

    simplet_filter_t *filter2 = simplet_layer_add_filter(layer, "SELECT * from 'ne_10m_admin_0_countries'");
    simplet_filter_add_style(filter2, "weight", "0.5");
    simplet_filter_add_style(filter2, "fill", "#d3e46f");
    simplet_filter_add_style(filter2, "stroke", "#ffffff");
    simplet_filter_add_style(filter2, "line-join", "round");

    simplet_filter_add_style(filter2, "text-field", "NAME");
    simplet_filter_add_style(filter2, "font", "Lucida Grande, Regular 8");
    simplet_filter_add_style(filter2, "color", "#444444ff");
    simplet_filter_add_style(filter2, "text-outline-color", "#ffffffcc");
    simplet_filter_add_style(filter2, "text-outline-weight", "2");
    simplet_filter_add_style(filter2, "letter-spacing", "1");

    if(simplet_map_is_valid(map))
      simplet_map_render_to_png(map, "./out.png");
    simplet_map_free(map);
  }

which produces this map:

How to Get Simple Tiles

Go ahead and kick the tires over on GitHub. We’ll be releasing the Ruby bindings in the coming weeks. If you want to help us cross the finish line on the Ruby bindings, or if you might be interested in writing Python bindings, send us an e-mail.

As with all new projects there are bound to be bugs and things that will make Simple Tiles work better, so please post any you notice in our issue tracker — and if you use it in a project, please let us know!

Awesome!

Thanks so much for your contributions to free software!

Rich Jones, Gun.io

great work and thanks for this and the other work you have done. 

fyi- the link to Tiger Line seems to be broken.  You point back at this page instead of to Tiger Line.

Ooh, I’m going to need to play with this soon.  Don’t know what I’ll use it for, but that’s hardly the point.

If I free up the time, I’ll be in contact about the Ruby bindings.

Gekke Neef: thanks for the heads up! Fixed it.

Add a comment

Email me when someone responds to this article.