Add Contour Lines.
This example shows how to add contour lines to your map from a raster-dem source. In this particular case, the contour lines are generated dynamically on the client side, specifically in the browser, through the utilization of the maplibre-contour plugin.
If you require accurate and precise contour lines, it is advisable to utilize the data derived from the Global Contours offered by MapTiler.
The Global Contours, created by MapTiler, contains contour lines for locations all around the globe in two widely used unit systems: meters and feet. With its global coverage, MapTiler’s contour lines can be utilized for various purposes, such as outdoor recreation planning, landscape analysis, and cartographic visualization.
NPM module setup
npm install --save @maptiler/sdk
import { Map, config } from '@maptiler/sdk';
import '@maptiler/sdk/dist/maptiler-sdk.css';
config.apiKey = 'YOUR_MAPTILER_API_KEY_HERE';
const map = new Map({
container: 'map',
style: DATAVIZ.LIGHT,
zoom: 13.42,
center: [-148.63567, 62.03381],
});
const demSource = new mlcontour.DemSource({
url: `https://api.maptiler.com/tiles/terrain-rgb-v2/{z}/{x}/{y}.webp?key=${config.apiKey}`,
encoding: 'mapbox',
maxzoom: 12,
// offload contour line computation to a web worker
worker: true
});
// calls maplibregl.addProtocol to register a dynamic vector tile provider that
// downloads raster-dem tiles, computes contour lines, and encodes as a vector
// tile for each tile request from maplibre
demSource.setupMaplibre(maptilersdk);
map.on('load', function () {
map.addSource("hillshadeSource", {
"type": "raster-dem",
// share cached raster-dem tiles with the contour source
tiles: [demSource.sharedDemProtocolUrl],
maxzoom: 14
});
map.addSource("contourSourceFeet", {
type: 'vector',
tiles: [
demSource.contourProtocolUrl({
// meters to feet
multiplier: 3.28084,
overzoom: 1,
thresholds: {
// zoom: [minor, major]
11: [200, 1000],
12: [100, 500],
13: [100, 500],
14: [50, 200],
15: [20, 100]
},
elevationKey: 'ele',
levelKey: 'level',
contourLayer: 'contours'
})
],
maxzoom: 15
});
map.addLayer({
id: 'hills',
type: 'hillshade',
source: 'hillshadeSource',
layout: { visibility: 'visible' },
paint: { 'hillshade-exaggeration': 0.25 }
});
map.addLayer({
id: 'contours',
type: 'line',
source: 'contourSourceFeet',
'source-layer': 'contours',
paint: {
'line-opacity': 0.5,
// "major" contours have level=1, "minor" have level=0
'line-width': ['match', ['get', 'level'], 1, 1, 0.5]
}
});
map.addLayer({
id: 'contour-text',
type: 'symbol',
source: 'contourSourceFeet',
'source-layer': 'contours',
filter: ['>', ['get', 'level'], 0],
paint: {
'text-halo-color': 'white',
'text-halo-width': 1
},
layout: {
'symbol-placement': 'line',
'text-size': 10,
'text-field': [
'concat',
['number-format', ['get', 'ele'], {}],
'\''
],
'text-font': ['Noto Sans Bold']
}
});
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="robots" content="noindex">
<title>Add Contour Lines. | NPM example</title>
<link rel="stylesheet" href="./style.css">
</head>
<body>
<div id="map"></div>
<script type="module" src="./main.js"></script>
</body>
</html>
body {margin: 0; padding: 0;}
#map {position: absolute; top: 0; bottom: 0; width: 100%;}
Related examples
Switch between contour lines heights in meters and feet
ExamplesSwitch map contour line altitude units between meters and feet.