Thursday, October 12, 2017

Vector Tiles with Mapbox + Leaflet

A couple of weeks back, I finally got to really dig in on Mapbox's implementation of vector tiles, and using vector tiles in Leaflet.

Myself, I almost never get to use Mapbox Studio as the cartography work usually goes to one of my coworkers who has a good eye for that stuff. We're also coming in to vector tiles a bit late, having gotten a green-light that supporting older browsers (IE 8 on XP) and operating systems (Android 4.1) was not a requirement and that a few hours of R&D would be worth the very slick interface behaviors promised by vector tiles. As such, this was a learning experience all around.

The result was a map that is really quite slick, involving behaviors which traditionally would have required a server deployment and a WMS server, and with an outcome more slick than would have been achieved with those methods anyway. Best of all, it stayed well within Mapbox's generous free tier.

The Application

  • Rivers and waterways (line), about 50,000 records spanning the entire state, about 100 MB in size. It's not the whole state, just the waterways considered interesting.
  • Several thousand stream gauge locations (point).
  • Ten defined hydrology regions (polygons) covering the state. These are to be displayed as plain black outlines as well as a choropleth based on some statistic of the waterways.
  • In the UI, a list of those regions. Picking one will zoom to the region, and will also filter the gauges and waterways to that region. The gauges and waterways are tagged with their region, so that filtering should be easy.
  • Tooltips when we mouse over waterways and gauges, and more-detailed popups when they are clicked.
  • Unspecified other Leaflet controls to be added to the map as needed: geocoders, custom legend panel, GreenInfo credits, custom scalebar, probably more.
The datasets above are fairly hefty in size, so simple GeoJSON techniques would not be appropriate here. Failing that, filtering by region would classically be a server-side phenomenon e.g. a WMS service and less-smooth interactivity.

These days, Mapbox is full bore on vector tiles. Conceptually, vector tiles brings the benefits of GeoJSON such as slick interactivity and having attribute data already in memory, with the on-demand loading of tiles, plus the server-side processing involved in generating those vector tiles efficiently by not loading every vertex of every feature.

Let's see what Mapbox can do!


We love Mapbox. They have a habit of changing things fairly often and sometimes breaking things, but a lot more often, they get things just right and really shine.

I rarely get to dig in to Mapbox Studio (they usually give the cartography to someone else), so I had some learning to do:
  • A dataset is called a Tileset
  • Uploading a Tileset can take a couple of hours
    In one case, the spinner never went away but I came back the next morning to find it still spinning. I reloaded the page and it had loaded just fine
  • A collection of datasets plus filtering and classifications-and-colors, organized into layers, is called a Style
    (I think of class-and-color as a style, and a collection of layers as a map, but okay...)
  • Using the Mapbox GL API, layers can be hidden and shown, can have their filtering changed at runtime, etc.

Leaflet + Mapbox GL JS API

Mapbox of course recommends their own Mapbox GL JavaScript API. While their Mapbox API really is just Leaflet with a bunch of additions and so is almost-completely compatible with third-party Leaflet extensions, Mapbox GL API is not like that.

We have all sorts of custom needs which aren't defined yet: custom map controls for legends and geocoders, maybe even Leaflet Draw at some later iteration. We're always skittish about using a semi-proprietary API that won't let us use freely define custom controls and incorporate third-party offerings, since we're all about delivering highly custom solutions.

Fortunately, the folks at Mapbox have a semi-unofficial Leaflet adapter to Mapbox GL. It works pretty well, and almost everything went perfectly as planned: the layer goes onto the map, I can toggle layer visibility and apply filters, I can publish and see the updated Style, etc.

Spoiler Alert: It's Awesome

The application came along well, giving slick interactivity, good performance, filtering capabilities, easy cartography changes as needed, and also the flexibility to incorporate arbitrary Leaflet controls and behaviors.

Along the way I learned a lot, and what I learned is the topic of the next few days' postings.

No comments:

Post a Comment