Skip to content

Terrain Layer

A terrain layer renders a raster-dem source (RGB-encoded elevation tiles decoded on the GPU) or a quantized-mesh source (pre-meshed tiles, e.g. Cesium Ion) as the 3D globe surface. Rendering options are the same regardless of the source’s data format; all fetch/geometry config lives on the source.

PropertyTypeDescription
type"terrain"Layer type (required).
sourceSource | stringThe raster-dem or quantized-mesh source (required).
MaterialConfig keyDescription
TerrainMaterialterrainTerrain mesh appearance (shadows, skirts, …).
import ThreeView, { JAPAN_GSI_ELEVATION_DECODER } from "@navaramap/three";
const view = new ThreeView(/* options */);
await view.init();
const dem = view.addSource({
type: "raster-dem",
url: "https://cyberjapandata.gsi.go.jp/xyz/dem_png/{z}/{x}/{y}.png",
elevationDecoder: JAPAN_GSI_ELEVATION_DECODER(),
maxZoom: 15,
minZoom: 5,
});
view.addLayer({
type: "terrain",
source: dem,
terrain: { castShadow: true, receiveShadow: true },
});
const terrain = view.addSource({
type: "quantized-mesh",
url: "https://example.com/{z}/{x}/{y}.terrain",
requestVertexNormals: true,
requestWaterMask: true,
maxZoom: 18,
});
view.addLayer({
type: "terrain",
source: terrain,
terrain: { castShadow: true, receiveShadow: true },
});

A terrain layer provides only the 3D surface. Add a raster layer over it — its tiles are draped onto the mesh. Later layers render on top, so a higher-resolution overlay can refine a wider base layer.

const terrain = view.addSource({ type: "quantized-mesh", url: "https://example.com/{z}/{x}/{y}.terrain", maxZoom: 18 });
const satellite = view.addSource({ type: "raster-tile", url: "https://example.com/satellite/{z}/{x}/{y}.jpg", maxZoom: 15 });
view.addLayer({ type: "terrain", source: terrain });
view.addLayer({ type: "raster", source: satellite });

A vector layer whose polygon/polyline materials set clampToGround: true also drapes onto the terrain surface, hugging the mesh instead of floating at a fixed height. This works over any terrain source — both raster-dem (WebMercator) and quantized-mesh (geographic / EPSG:4326) terrain — so clamp-to-ground vectors stay glued to the ground regardless of the terrain’s tiling scheme.

const terrain = view.addSource({ type: "quantized-mesh", url: "https://example.com/{z}/{x}/{y}.terrain", maxZoom: 18 });
const tiles = view.addSource({ type: "vector-tile", url: "https://example.com/tiles/{z}/{x}/{y}.mvt", maxZoom: 16 });
view.addLayer({ type: "terrain", source: terrain });
view.addLayer({
type: "vector",
source: tiles,
sourceLayers: ["water"],
polygon: { color: new Color().setStyle("#00aaff"), clampToGround: true },
});