Kevin Schaul

Visual journalist/hacker

How The Post is replacing Mapbox with open source solutions

February 16, 2023

Last week I published a story for The Washington Post that required an interactive slippy map. Lookup maps like this are a common pattern to show a geographic trend and let readers explore the data for their areas.

For about five years, my instinct when working on these stories is to reach for Mapbox, which has continually pushed the field ahead with innovations like vector tiles, a style specification and tools like tippecanoe. For some projects, I’m sure we’ll continue using Mapbox. But for most of our use cases, we don’t need the latest and greatest. And Mapbox has gotten expensive.

Here’s what we used instead:

OpenMapTiles for building tiles

OpenStreetMap is an incredible open, community-driven dataset of the world, but it’s tricky to work with. The project includes tons of data that is unnecessary for a basemap to put data visualizations over. The OpenMapTiles project is a set of scripts and tools that download data from OSM and NaturalEarth, load the parts you care about into a database and generate tilesets. It also has the most bonkers Makefile I have ever seen.

We used this project to generate a rough U.S. base tileset, and then combined that with other geo data to build a solid — if not barebones — basemap tileset.

Maputnik for style editing

Screenshot of Maputnik editor, showing map layers and controls on the left, and a preview of the map on the right.

Maputnik is an OSS editor for vector tiles, similar to Mapbox Studio. This tool lets you build out a style.json file that contains data sources, layers and style rules.

There’s a CLI you can install that boots up a local version of the editor. It can even synchronize style edits with a local style.json file.

# Install via Homebrew
$ brew install kevinschaul/homebrew-core/maputnik

# Start up the editor at http://localhost:8000/
$ maputnik

# Or, start the editor at http://localhost:8000/ while syncing changes
# to your style.json file
$ maputnik --file style.json

PMTiles for tile hosting

PMTiles are an exciting new concept for serving map tiles. Typically tiles are baked out into millions of individual files, organized into directories for zoom level, x and y. A PMTiles file is a single archive containing all of that tile data that’s optimized for tile lookups. Client-side maps can use HTTP Range Requests to download specific tiles directly from the PMTiles file — no intermediary necessary.

A screenshot of the PMTiles website, showing that three tiles were loaded using HTTP Range Requests

PMTiles are an impressive and elegant solution to tile hosting. Deploying a new tileset to a service like Amazon S3 requires uploading just one big file rather than millions — saving a ton of time. And we don’t need to run a tileserver to fetch tiles. It’s so smart.

For The Post, I set up an AWS Lambda behind Cloudfront that, given an z/x/y URL, returns a tile from a PMtiles file. The mapping frontend thinks the tiles are regular tiles. I generated PMTiles using Felt’s version of Tippecanoe, but you can also use the pmtiles CLI.

Big thanks Dylan Moriarty for sending me a link to PMTiles, and Brandon Liu for pushing the tech forward!

maplibre-gl-js for client-side rendering

Maplibre is JavaScript library that can render vector tiles. It’s a fork of mapbox-gl-js from before they moved to a non-OSS license. It works great.

For this story I implemented a new approach for touch devices: Users can interact with the map either by panning/zooming with two fingers, or by entering fullscreen mode. I think it works pretty well!

A demo of the map in the all cash story, showing the user entering an exiting fullscreen mode

All of these projects depend on the open source community to stay relevant. I’m lucky to have gotten to spend work hours contributing back. Hopefully in the near future I can share more about some custom tooling that strings these projects together.