Day 6 - Raster

November 8, 2024 · 3 min read

Hello, Boulder

Mapbox Tiling Service

The day 6 raster challenge is a bit of a plug for the product that I'm actively working on at Mapbox called the Mapbox Tiling Service (MTS). It allows you to upload vector and raster data to create custom tilesets which can then be rendered on a map. The steps explained below can be read about it in more detail in this guide for using MTS to process RGB imagery.

I wanted to stick to the theme of Boulder county as a lot of my previous posts have revolved around so I found some NAIP aerial imagery of Boulder on the USGS EarthExplorer. Thanks for showing me this, Bill!

After downloading a GeoTIFF of the area I was looking for, I uploaded it as a source into MTS. Once uploaded, I could then reference the source in the tileset recipe that I would end up using to process this tileset in MTS. Following the recipe specification for raster tilesets, we end up with a basic recipe like the one below. In this example I used a single source but you can specify a list of sources as well.

{
  "version": 1,
  "type": "raster",
  "minzoom": 12,
  "maxzoom": 18,
  "layers": {
    "RGB": {
      "source_rules": {
        "filter": [
          ["==", ["get", "colorinterp"], "Red"],
          ["==", ["get", "colorinterp"], "Green"],
          ["==", ["get", "colorinterp"], "Blue"]
        ]
      }
    }
  },
  "sources": [
    {
      "uri": "mapbox://tileset-source/YOUR_ACCOUNT/YOUR_SOURCE_NAME"
    }
  ]
}

The last step was to create a tileset and then publish it, after which we could reference the tileset in our map! Here's the little function I'm using in my react component to render this tileset.

const addSourceAndLayer = (map: mapboxgl.Map | null) => {
  if (!map) {
    return;
  }

  const source = map.getSource('raster-rgb-source') as RasterTileSource;
  if (!source) {
    map.addSource('raster-rgb-source', {
      type: 'raster',
      url: 'mapbox://${account}.${tilesetId}',
    });
  } else {
    map.setMaxBounds(source?.bounds as mapboxgl.LngLatBoundsLike);
  }

  if (!map.getLayer('rgb-raster-layer')) {
    map.addLayer({
      id: 'rgb-raster-layer',
      type: 'raster',
      source: 'raster-rgb-source',
    });
  }
};