Putting TopoJSON on a Google Map

For a recent project we needed to significantly reduce the file sizes of some of the GeoJSON files were were using so we turned to Mike Bostock’s amazing TopoJSON APIs. As described on the wiki page TopoJSON is an extension of GeoJSON that significantly reduces file sizes by reducing redundancy. For example, the border between two adjacent US states will only be represented once rather than twice (once for each state).

Fortunately for users, Mike Bostock provided both a client and server API as well as a command-line tool. The server API can be used to convert to TopoJSON from a variety different formats including (hallelujah!) shapefiles. For this brief example, we will show how we converted shapefiles directly to TopoJSON and then rendered them on a Google map using the client API.

Installing the command-line tool

Using Node.js installation of TopoJSON is a snap. We us -g to specify global installation:

 npm install -g topojson

Convert to TopoJSON

With the command-line tool installed converting a shapefile to TopoJSON is extremely easy. There are several different arguments that control simplification (details can be found here), properties to retain etc, but for the most part we will accept the defaults. The one exception is that we want to retain the id property (called ‘FIPS’ in this dataset) and several attributes (by default the TopoJSON command-line tool strips attributes). The conversion code looks something like this:

topojson -o county.json --id-property FIPS -p NAME,STATE_NAME,COUNTY_CD -- county.shp

where county.json is the output, ID is FIPS and the properties I want to retain are NAME, STATE and COUNTY_CD. The input is county.shp.

Put the data on a Google map

In March 2014 Google added direct support for GeoJSON but the API does not support TopoJSON. But using the TopoJSON client API converting the TopoJSON file to GeoJSON is relatively straightforward and can be seen in the following code snippet:

  $.getJSON("county.json", function(data){
        geoJsonObject = topojson.feature(data, data.objects.county)
        map.data.addGeoJson(geoJsonObject); 
      }); 

The magic happens with topojson.feature which returns the GeoJSON FeatureCollection for the input object. You might notice that the TopoJSON command line automatically created an object named 'county' from our input data (data.objects.county). The TopoJSON command-line tool allows you to simultaneously write multiple objects to a single TopoJSON file so you need to specifically name the object you want even if the TopoJSON file only contains a single object.

The map and the code

Here is what the map looks like and we included the GitHub Gist below with the full code.