Tribune DataViz

Matters of interest, from the data reporters and developers across Tribune Publishing

Making maps, part 5: Overlay on a Google Map and deploy

with 9 comments

This is part five of a five-part series about our recent explorations making choropleth maps using PostGIS, TileMill, Mapnik and Google Maps. Read parts one, two, three and four for the full effect. Bonus post: part six! The impatient may grab the source code from GitHub, or try out the demo.

Running the render script should have created a mess of directories and images. Let’s finally put them on a Google map. The key bits of javascript are relatively simple. You create a callback function to hand off the URL of any given tile to Google, and configure a new overlay map, and push it onto the stack, like so:

snip from census-demo/map.js

function fetch_tile(coord, zoom) {
    return "http://localhost:8000/census-demo/.tiles/" + zoom + "/" + coord.x + "/" + coord.y + ".png";
    //return "" + zoom + "/" + coord.x + "/" + coord.y + ".png";


$(document).ready(function() {

    census_demo_options = {
        getTileUrl: fetch_tile,
        tileSize: new google.maps.Size(256, 256),
        isPng: true
    census_demo = new google.maps.ImageMapType(census_demo_options);

    map_options = {
        minZoom: 7,
        maxZoom: 10,
        zoom: 7,
        center: center,
        mapTypeControl: false,
        mapTypeId: "simple"

    simple = new google.maps.StyledMapType(backdrop_styles, { name: "Illinois population 2010" });
    map = new google.maps.Map(document.getElementById("map_canvas"), map_options);
    map.mapTypes.set("simple", simple);

You may have noticed a mysterious variable, backdrop_styles, in the code above. We do a few tricky things to make the base map look nicer with an overlay — turning off some labels, etc.:

snip from census-demo/map.js

backdrop_styles = [
            featureType: "administrative",
            elementType: "labels",
            stylers: [
                { lightness: 10 }
            featureType: "poi",
            elementType: "labels",
            stylers: [
                { visibility: "off" }
            featureType: "poi.park",
            elementType: "geometry",
            stylers: [
                { visibility: "off" }
            featureType: "road",
            elementType: "geometry",
            stylers: [
                { visibility: "simplified" },
                { saturation: -100 },
                { lightness: 0 }
            featureType: "road.arterial",
            elementType: "labels",
            stylers: [
                { gamma: 10 }

The geo search, the legend and the tricky hash-URLs are left as an exercise to the reader. It’s all in the demo code.

(Not to miss: The legend background color is the same background color as the base map, and the legend opacity matches the overlay opacity. This ensures that the colors in the legend match the colors on the map.)

To try it all out, fire up your handy one-line web server in the project directory…

Run in your project directory

python -m SimpleHTTPServer

…and point your browser at http://localhost:8000/census-demo/


Deploying your map

Finally, something simple. Just copy the census-demo directory (containing your HTML, Javascript, styles and tiles) out to Amazon’s cheap and easy S3 hosting service and if you’ve got all the paths right, it’ll work like a charm. You can also grab a few VPSes from Hostgator or another major provider – using some sort of HostGator Black Friday Deal 2016 coupon always saves you a few bucks. No fancy servers necessary.

Beware: Deploying to S3 seems quick until you try to push out a ton of files. The number of tiles you cut increases exponentially with each zoom level. Our census map of northeast Illinois, max zoom level 16, amounted to more than 130,000 tiles, and took several hours to deploy.

We’re working on strategies to speed up rendering and deployment. Stay tuned to the apps blog for further developments. We’ll post it when we’ve got it.

« Previous: Render with Mapnik

Written by Brian Boyer

March 8, 2011 at 2:10 pm

9 Responses

Subscribe to comments with RSS.

  1. Outstanding writeup guys. As great as your projects are, this blog is worth its weight in gold.

    Matt Hart

    March 8, 2011 at 2:51 pm

  2. First, great write-up.

    Second, when you’ve watched educated people try and fail to figure out how to zoom and pan a Google map, paralyzed by the fear they will break something, you acquire a new appreciation of onHover–giving extra information without the moral commitment of a mouse-click. Of course the RIA crowd goes wild with the concept, but in 2011 you still can’t automatically assume they’ll know how to zoom in and read your labels.

    But angels-on-the-head-of-pin discussion aside, great stuff.


    Brian Timoney

    March 10, 2011 at 9:13 am

  3. @brian I suppose that is the other option. Kill the pan and zoom and go hover-only. Let’s hope it doesn’t come to that. :) Thx.

    Brian Boyer

    March 10, 2011 at 9:24 am


    Thank you for the excellent write up -bookmarked!


    July 8, 2011 at 6:47 am

  5. […] maps using PostGIS, TileMill, Mapnik and Google Maps. Read parts one, two, three, four and five for the full effect. The impatient may grab the source code from GitHub, or try out the […]

  6. […] Maps blog post series: parts one, two, three, four, five, […]

  7. […] The legend is HTML/CSS, which I copied heavily off of the Chicago Tribune News App and their wonderful map walkthrough. When you get the hang of Fusion Tables, check it out. Their maps are much prettier than […]

  8. […] the by, I also just learned about this nice five part tutorial by the Chicago Tribune which deals with TileMill and many other tools to create an attractive […]

  9. I’d love to see a version of this how-to that uses openLayers, possibly with some custom OSM tiles as a base map. It seems like a shame to put such a nice set of public data on top of a locked-down service like Google, especially after most of your excellent work was done with OSS tools.

    John Sanderson

    September 11, 2012 at 12:34 pm

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: