While I was reading up on the controversial Northern Gateway pipeline, that oil company Enbridge wants to build to transport bitumen from Northern Alberta to the B.C. coast, I came across an interesting research paper by the Raincoast Conservation Foundation. The paper (published in October 2012) evaluated the possible impact of a potential pipeline spill to parks and protected areas downstream from the pipeline. It identified 34 areas that would be at risk in the event of a spill.
Since I had been wanting to try my hand at mapping for a while, I went ahead and built a map based on the results of the paper, with the goal of helping to convey the conclusions of this research. The map displays the areas listed in the research paper, along with all of BC’s parks and the proposed pipeline’s route.
I decided to build the map using MapBox, since I really like how easy they make it to change the visual design of the map (colours, line weights, etc.), and they have a ton of examples, which is always great when learning something new.
Also, because MapBox fully integrates the LeafletJS mapping library, the knowledge gained from learning how to use MapBox is also applicable when working with LeafletJS somewhere else.
Getting the data
In order to show something on a map, I first needed to get the geodata. Both Mapbox and Leaflet work together very well with GeoJSON, so that’s what I went looking for.
I needed three geodata sets to build this map: all the parks and protected areas in British Columbia, the protected areas at risk, and the pipeline route.
Parks: After looking around on various BC government sites, I found what I needed on DataBC. They offered a download of a GeoXML file containing the polygon data (i.e. boundaries of geographical areas) of all the parks and protected areas in British Columbia.
Protected areas at risk: I assembled a GeoJSON file myself, based on the parks’ listing in the research paper. I used OpenStreetMap’s awesome Nominatim geocoding service to get the geodata for these polygons and points.
Preparing the data
Not knowing any better, I started using find/replace and some regular expressions to convert the GeoXML file into a GeoJSON file. This quickly became cumbersome, since the GeoXML file was over 50M, so not exactly easy to work with in a text editor. After looking around for a Geodata conversion tool, I found ogr2ogr, a veritable swiss army knife for geodata, and easy to install and use on Ubuntu (it's part of the gdal-bin package, see this Mapbox documentation page for installation instructions). Ogr2ogr makes it easy to convert a ton of different geodata formats, applying all sorts of filters and operations during the conversion.
Using ogr2ogr, it was an absolute breeze to go from GeoXML to GeoJSON, a format that LeafletJS can display on a map extremely easily. For a quick intro on how to get Leaflet to show GeoJSON polygons (e.g. the parks and protected on my map), see this LeafletJS tutorial.
Once I had the data in the right format, there was still the problem of the data file size: having users download a file of more than 50MB, just to show something on a map, isn’t a good idea because it'd be extremely slow.
To help with the task of minimizing the B.C. parks geodata file, I used Topojson, a tool written by Mike Bostock. Put simply, it allows you to remove redundant geodata, greatly simplifying it and thereby drastically reducing its file size. For example, starting from over 50MB, I ended up with a 833kb geodata file, without any noticeable difference when displaying the polygons on the map. And just like GeoJSON, LeafletJS knows how to handle TopoJSON.
Putting it all together
After collecting all the data, putting it on the map was fairly straight forward. The LeafletJS API reference and examples along with the Mapbox' examples have a ton of information (should you have a question about the specifics of this map, don’t hesitate to post a comment at the bottom of this post).
Aside from the info for each park at risk, I’m pulling a photo from Flickr for each park (based on a Flickr geo search via the Flickr API), to make the map more visually interesting.
You can see the full result of this mapping experiment (above is a static screenshot) on GitHub pages. The code is available on GitHub as well. There are a bunch of things to add, improve, and clean up, but I’m pretty happy with how this turned out. It was an interesting learning project on many fronts. On to the next one!