Map of Biodiversity Importance, NatureServe

Demonstration of generating and serving static raster tiles with GDAL using Map of Biodiversity Importance (MOBI) data from NatureServe, (2022) https://www.natureserve.org/map-biodiversity-importance, original data files from https://geohub-natureserve.opendata.arcgis.com/search?q=mobi
Product Details
Visibility
Public
Created
20 Mar 2024
Last Updated
3 Apr 2025
README

Data

Demonstration of generating and serving static raster tiles with GDAL using Map of Biodiversity Importance (MOBI) data from NatureServe, (2022)

Example Interactive Maps

Zoomable maps rendered with static tiles (via map.py):

https://data.source.coop/cboettig/mobi/tiles/grey/species-richness-all/{z}/{x}/{y}.png
https://data.source.coop/cboettig/mobi/tiles/red/species-richness-all/{z}/{x}/{y}.png
https://data.source.coop/cboettig/mobi/tiles/green/range-size-rarity-all/{z}/{x}/{y}.png

Creating a Static Tile Server

We recommend using the latest release of GDAL, built with support for python for these examples. It can easily be installed with pip, e.g.:

pip install -U --find-links https://girder.github.io/large_image_wheels GDAL

Standard raster formats including cloud-optimized geotiffs provide an excellent format for analysis-ready geospatial data, where precise quantitative values along a geospatial grid can be encoded digitally.

To provide efficient visualization on interactive, zoomable maps however, it is more common to use a more lightweight approach that divides a potentially very large single tiff file into smaller PNG tiles, optimized for visual display in a web browser rather than for computational analysis on pixel values. By pre-computing a complete layer of tiles at each zoom level, client-side javascript maps such as leaflet can quickly and smoothly request new tiles as the user zooms and pans around the map.

A static tileserver simply pre-computes these tiles and serves them through a high bandwidth storage platform like Source.coop.

To create png tiles, we must first represent our geotiff raster in Byte type, which can mostly easily do in gdal using gdaltranslate to create a GDAL virtual dataset (VRT):

gdal_translate -of VRT -ot Byte -scale /vsicurl/https://data.source.coop/cboettig/mobi/species-richness-all/SpeciesRichness_All.tif temp.vrt

From this VRT, we can now create a whole suite of tiles. Here we indicate the --xyz format (used by leaflet etc), we --exclude any tiles that contain only missing data, and we compute tiles for 10 different zoom levels. Note that each higher zoom level is exponentially larger, which means more files and more space required. This can be computationally intensive but is easily parallelized to multiple processes using the --processes option. Lastly, we specify a target directory path that will be created to store all the PNGs. these are organized by subfolders {z}/{y}/{x}.png indicating the zoom and x/y tile positions.

gdal2tiles.py --xyz --zoom=1-10 --exclude --processes=24 temp.vrt tiles/grey/species-richness-all

Color scales

In this example, or geotif consists of a single band of data representing the species richness observed in a pixel (i.e. as an integer between 0 and 32 in this case). The gdal2tiles.py will by default map those numeric values to a greyscale color ramp. Unlike typical raster images where we can provide mappings from data values to color aesthetics when rendering our maps, remember that map tiles are entirely pre-rendered, so we get only the colors those original png files come with. If we want to add a color ramp, we need to declare that in the VRT before we generate all the png tiles. We can do this with gdaldem:

gdaldem color-relief -of GTiff temp.vrt color.txt colored-temp.vrt -alpha 

Where color.txt is a text file indicating the band byte value followed by the red, blue, green, and alpha (transparency) values (on a scale of 0 to 255) in the colorscale. Note that we can often generate color.txt programmatically, e.g. see colormap.R.
Then we can recreated the tiles

gdal2tiles.py --xyz --zoom=1-10 --exclude --processes=24 colored-temp.vrt tiles/red/species-richness-all

Likewise we can process the other variables. Note that we need to calibrate the colormap appropriately.

gdal_translate -of VRT -ot Byte -scale range-size-rarity-all/RSR_All.tif temp.vrt
gdaldem color-relief -of GTiff temp.vrt color.txt colored-temp.vrt -alpha
gdal2tiles.py --xyz --zoom=1-10 --exclude --processes=24 colored-temp.vrt tiles/green/range-size-rarity-all

Leaflet rendering

Once we have rendered our tiles, we simply need to point our mapping tool to the corresponding URL template. For instance:

import leafmap.foliumap as leafmap

m = leafmap.Map(center=[35, -100], zoom=5)
m.add_basemap("CartoDB.DarkMatter")
m.add_tile_layer(
    url="https://minio.carlboettiger.info/shared-data/mobi-tiles/grey/{z}/{x}/{y}.png",
    name="Imperiled Species Richness (Greyscale)",
    attribution="NatureServe",
    opacity=0.99
)
m.to_html("mobi-grey.html")
m

Generates the greyscale interactive map

Changing to the red tiles (and a lighter basemap) we can see the colored version

License

The Map of Biodiversity Data Importance is a data product of NatureServe, cc-by-nc-nd

Source Cooperative is a Radiant Earth project