A few years ago I wrote a post about generating current-flow animations on map tiles from sparse vector data. I’ve since built a number of applications that had to deal with showing physical earth data on a map, and eventually I’ve put what I know together into an actual product: mercator, a gridded earth data API that serves weather, ocean, air quality and elevation data as map tiles.

The problem

There are a number of (paid) APIs on the internet that you can call to get data for a single lat/lon point on earth. You can obtain, say, ocean salinity at that point, or wave height, or wind direction and speed. But in order to show data on a map, you’ll want a grid of points, probably as many as 100x100, to render a smooth surface on your map. That would mean calling a point API 10,000 times, which is (a) very slow an (b) likely costly.

What’s needed here is a grid of points that you can download in a single API call, and then you do the interpolation between these points to present a smooth surface. This shouldn’t be hard to get - data offered by NOAA’s GFS, ocean state from HYCOM, air quality from Copernicus CAMS, elevation from GEBCO - it’s all already in grid form, just not in a suitable format for browser consumption. It’s heavy, world-spanning NetCDF files, or GRIBs. The missing piece is a way to get this data into the browser efficiently.

Values baked into pixels

The way to render data on a map is through map tiles. Using tiles, a massive raster can be delivered to the browser in a lazy way: when the users zooms, or pans (sufficiently), the map requests map tiles from the server and renders these. Only the data for the region that the user is looking at is downloaded, and only at the required zoom level. At any given time, 5-10 map tiles are downloaded (depending on the user’s screen resolution), and the total download is usually not more than ~100KB.

With map tiles established as the way to get data onto a map, the trick then is to pour all the NetCDF and GRIB data from different providers into map tiles, regularly (with data updated every 6 hours). Having such tiles at hand already solves part of the problem. But there’s a twist: we do better by not producing raster tiles that show an immutable image, but by encoding values into the image’s pixels. If each pixel doesn’t represent a color but a value, then the browser can decide how to map that value to a color on the user’s map.

This means that a dataset such as air temperature could be rendered in shades of blue, or using a red gradient, or a rainbow gradient, and the user could switch between these colors on the fly. All that’s necessary is to put a bit WebGL in the rendering pipeline that translates values to colors. Better yet, wind or ocean current speed tiles could encode not just scalar values, but vector u and v values. With wind direction known, a bit of WebGL code can render animated particles on a map, fast!

This approach isn’t new: Mapbox’s terrain RGB uses this, too. What’s new is applying it to a variety of datasets (ocean current speed, wind speed, water temperature etc.) and updating the information every 6 hours. Elevation can be offered as well (Mapbox-style), and doesn’t need refreshing every 6 hours, of course.

About Mercator

The product that offers all this is mercator.blue. It has two halves: the first is the tile service: an HTTP endpoint serving the value-encoded tiles plus a metadata.json that fully documents the encoding, so any developer can decode the pixels without my code. The second is an open-source SDK that ships the shader decoders and ready-made visualisations (colormapped rasters, animated wind and current streamlines, arrows, contours, value labels) for MapLibre, Mapbox, Leaflet, OpenLayers, deck.gl and React. If you decide to use one of these SDKs, then a few lines of code are enough to get an animated wind field or ocean current particles on a map.

Mercator offers a catalogue of datasets, all updated every 6 hours (with the exception of elevation, which is static). There is atmospheric weather, ocean currents and waves, air quality and elevation, all including forecasts (12h ahead, 24h ahead, 48h ahead). The whole thing follows the same shape as Mapbox GL JS or Deck.gl: the SDK is free and open (Apache-2.0), and the paid part is the data API, with a free tier of 10,000 tiles a month. Because the tile format is documented, you are never locked to my renderer.

Try it out

You’re welcome to test drive both the datasets and the SDK. The SDK is open source; the tiles have a free tier that allows you to experiment all the datasets (it’s 10K tiles free).

There is a live interactive globe on the homepage with wind streaming over it, a live playground for each framework, and the full tile-encoding and API docs if you want to decode the tiles yourself.