The one-call drop-in: fetch an Esri elevation ImageServer's metadata, register
the decode protocol, add a raster-dem source (with bounds + zoom range from
the service), and make it the map's terrain.
It is sugar over createEsriTerrain (a stack of one); reach for the controller when you want layered/composited datasets.
The MapLibre map to attach terrain to.
URL, the injected maplibregl namespace, and tuning; see
AddEsriTerrainOptions.
A handle to tune exaggeration or tear the terrain down; see EsriTerrainHandle.
Error if the metadata fetch is non-OK, or the service fails validation
(not Web Mercator / not single-band F32 / not LERC / bad tile size or origin /
no zoom range / no extent — see validateImageServerInfo).
import * as maplibregl from 'maplibre-gl';
import { prepareMapLibre, addEsriTerrain } from '@bitruvius/sdk-maplibre';
await prepareMapLibre(maplibregl); // v6: wires the worker module · v5: no-op
const map = new maplibregl.Map({ container: 'map', style, pitch: 60 });
const handle = await addEsriTerrain(map, {
url: 'https://elevation3d.arcgis.com/arcgis/rest/services/WorldElevation3D/Terrain3D/ImageServer',
exaggeration: 1.5,
maplibregl,
});
map.queryTerrainElevation([-84.5, 38.0]); // native elevation query, lng/lat degrees → metres
// handle.remove(); // tear down terrain + source + protocol
MapLibre GL bindings for Esri elevation terrain.
maplibre-glis only a type-only import here (erased at build), and the runtimemaplibreglnamespace is injected by the caller — so importing this never pulls maplibre-gl into the bundle.