MapSnippets logoMapSnippets logo

3D Terrain with MapLibre GL JS

MapLibre GL JS

Enable 3D terrain rendering using MapTiler DEM tiles with adjustable exaggeration.

progress_activityLoading map...
const map = new maplibregl.Map({
  container: 'map',
  style: 'https://api.maptiler.com/maps/outdoor-v4/style.json?key=YOUR_MAPTILER_KEY',
  center: [7.66, 45.98],
  zoom: 12,
  pitch: 60,
  bearing: -20,
  maxPitch: 85
});
map.addControl(new maplibregl.NavigationControl());
map.on('load', () => {
  map.addSource('terrain-dem', {
    type: 'raster-dem',
    url: 'https://api.maptiler.com/tiles/terrain-rgb-v2/tiles.json?key=YOUR_MAPTILER_KEY',
    tileSize: 256
  });
  map.setTerrain({ source: 'terrain-dem', exaggeration: 1.5 });
  map.addLayer({
    id: 'sky',
    type: 'sky',
    paint: { 'sky-type': 'atmosphere', 'sky-atmosphere-sun': [0, 90], 'sky-atmosphere-sun-intensity': 15 }
  });
});

How it works

MapLibre supports 3D terrain by combining a raster-dem source with the setTerrain() method. MapTiler provides terrain RGB tiles that encode elevation data in RGB pixel values.

After adding the DEM source inside the load event, call setTerrain() with the source reference and an exaggeration factor. The exaggeration multiplies the real elevation: 1.0 is true scale, 1.5 makes mountains 50% taller for dramatic effect.

The sky layer adds an atmospheric gradient at the horizon, completing the 3D landscape effect. Set pitch and maxPitch to allow tilted camera views that reveal the terrain.

Key APIs

API Description Docs
raster-dem source DEM tiles for elevation data maplibre.org docs
map.setTerrain() Enable 3D terrain rendering maplibre.org docs
sky layer type Atmosphere/sky background maplibre.org docs

FAQ

How do I disable terrain at runtime?

Call map.setTerrain(null) to return to a flat map.

What exaggeration value should I use?

For realistic terrain, use 1.0. For data visualization or dramatic landscapes, 1.5 to 2.5 works well. Going above 3.0 looks unrealistic.

Can I combine terrain with 3D buildings?

Yes. Add a fill-extrusion layer alongside terrain. Buildings will sit on top of the elevated terrain surface.

Common mistakes

  • Calling setTerrain() before the load event: the source is not yet available
  • Setting pitch: 0: terrain is invisible from directly above
  • Forgetting tileSize: 256 on the raster-dem source: incorrect tile size causes visual artifacts
auto_awesome

Build maps using MapLibre GL JS with AI

Generate code like this 3d terrain with maplibre gl js example using the MapLibre GL JS skill in your IDE.