Overview
Create a new skill maplibre-terrain-patterns covering terrain and hillshade rendering in MapLibre GL JS — from choosing and configuring a DEM source through to 3D terrain, hillshade, and dynamic contour lines.
Evidence: Terrain hits 50+ GitHub issues and 52 discussions in maplibre-gl-js. The single highest-viewed Stack Overflow question in the MapLibre tag is terrain setup. The Terrarium vs. Mapbox RGB encoding distinction is a documented AI failure zone — the default is "mapbox" but most open/free sources use Terrarium, and declaring the wrong encoding produces silently incorrect elevation values. Terrain content is currently fragmented across tile-sources, pmtiles-patterns, and the data-visualization skill outline; consolidating it gives developers a single place for the complete workflow. This also allows #13 (data-visualization-patterns) to stay tightly focused on data overlays (choropleth, heatmap, clustering, fill-extrusion).
When to Use This Skill
- Adding hillshade or 3D terrain to a MapLibre map
- Choosing a
raster-dem source and understanding encoding formats
- Migrating from Mapbox terrain tiles to an open alternative
- Adding dynamic contour lines from terrain data
- Self-hosting terrain tiles (PMTiles or XYZ)
Content Outline
raster-dem source type: What it is, how it differs from raster; the encoding property — "terrarium" vs. "mapbox" use different pixel-to-elevation formulas; the default is "mapbox" but most open/free sources use Terrarium; wrong encoding produces silently incorrect values (style spec)
- Open DEM tile sources:
- AWS/Tilezen (
s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png) — the original Mapzen Terrarium dataset, now on AWS Open Data; free, no key; 256px PNG; can be slow from the browser
- Mapterhorn — Terrarium WebP PMTiles; free, no key; 512px; up to z12 global; open source; NLnet-funded; led by former MapLibre board member Oliver Wipfli
- Stadia Maps Terrarium — key required for production
- MapTiler terrain-rgb — Mapbox encoding; key required
demotiles.maplibre.org — in official MapLibre examples; not for production
- Hillshade layer:
hillshade layer type; hillshade-illumination-direction; common style settings
- 3D terrain:
map.setTerrain({ source, exaggeration }); sky layer; camera pitch; performance implications
- Dynamic contour lines:
maplibre-contour (onthegomap/maplibre-contour) — registers a custom protocol handler that generates contour vector tiles from a raster-dem source; listed in awesome-maplibre; 261 stars; v0.1.0 December 2024; powers onthegomap.com terrain mode
- Generating your own DEM tiles: Overview — source DEM → GDAL reproject to EPSG:3857 → RGB encode (Terrarium or Mapbox via
rio-rgbify) → tile with gdal2tiles.py → optionally package as PMTiles; cross-reference to maplibre-pmtiles-patterns for hosting
Key Resources
Requirements
- Follow CONTRIBUTING.md for skill structure
- Cross-reference
maplibre-tile-sources for general source setup, maplibre-pmtiles-patterns for self-hosted PMTiles
- Cross-reference
maplibre-data-visualization-patterns for fill-extrusion (building extrusions as data layers, not terrain)
- Encoding distinction must be documented with both formulas or clear links — this is the primary AI failure zone for terrain
Overview
Create a new skill maplibre-terrain-patterns covering terrain and hillshade rendering in MapLibre GL JS — from choosing and configuring a DEM source through to 3D terrain, hillshade, and dynamic contour lines.
Evidence: Terrain hits 50+ GitHub issues and 52 discussions in maplibre-gl-js. The single highest-viewed Stack Overflow question in the MapLibre tag is terrain setup. The Terrarium vs. Mapbox RGB encoding distinction is a documented AI failure zone — the default is
"mapbox"but most open/free sources use Terrarium, and declaring the wrong encoding produces silently incorrect elevation values. Terrain content is currently fragmented across tile-sources, pmtiles-patterns, and the data-visualization skill outline; consolidating it gives developers a single place for the complete workflow. This also allows #13 (data-visualization-patterns) to stay tightly focused on data overlays (choropleth, heatmap, clustering, fill-extrusion).When to Use This Skill
raster-demsource and understanding encoding formatsContent Outline
raster-demsource type: What it is, how it differs fromraster; theencodingproperty —"terrarium"vs."mapbox"use different pixel-to-elevation formulas; the default is"mapbox"but most open/free sources use Terrarium; wrong encoding produces silently incorrect values (style spec)s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png) — the original Mapzen Terrarium dataset, now on AWS Open Data; free, no key; 256px PNG; can be slow from the browserdemotiles.maplibre.org— in official MapLibre examples; not for productionhillshadelayer type;hillshade-illumination-direction; common style settingsmap.setTerrain({ source, exaggeration }); sky layer; camera pitch; performance implicationsmaplibre-contour(onthegomap/maplibre-contour) — registers a custom protocol handler that generates contour vector tiles from araster-demsource; listed in awesome-maplibre; 261 stars; v0.1.0 December 2024; powers onthegomap.com terrain moderio-rgbify) → tile withgdal2tiles.py→ optionally package as PMTiles; cross-reference tomaplibre-pmtiles-patternsfor hostingKey Resources
onthegomap/maplibre-contourmapbox/rio-rgbify— Mapbox RGB encoding toolRequirements
maplibre-tile-sourcesfor general source setup,maplibre-pmtiles-patternsfor self-hosted PMTilesmaplibre-data-visualization-patternsfor fill-extrusion (building extrusions as data layers, not terrain)