Query terrain elevation
This example uses queryTerrainElevation
to display the elevation of a pin which follows a path.
It implements ES6 async
functions to increase readability of asynchronous code.
<!DOCTYPE html><html><head><meta charset="utf-8"><title>Query terrain elevation</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no"><link href="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.css" rel="stylesheet"><script src="https://api.mapbox.com/mapbox-gl-js/v2.14.1/mapbox-gl.js"></script><style>body { margin: 0; padding: 0; }#map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><script src="https://unpkg.com/@turf/turf@6/turf.min.js"></script><div id="map"></div><script> // TO MAKE THE MAP APPEAR YOU MUST // ADD YOUR ACCESS TOKEN FROM // https://account.mapbox.com mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN';(async () => {const map = new mapboxgl.Map({container: 'map',zoom: 13,center: [6.58968, 45.39701],pitch: 76,bearing: 150,// Choose from Mapbox's core styles, or make your own style with Mapbox Studiostyle: 'mapbox://styles/mapbox/satellite-streets-v12',interactive: false,hash: false}); // Start downloading the route data, and wait for map load to occur in parallelconst [pinRouteGeojson] = await Promise.all([fetch('https://docs.mapbox.com/mapbox-gl-js/assets/route-pin.geojson').then((response) => response.json()),map.once('style.load')]); // Set custom fogmap.setFog({'range': [-0.5, 2],'color': '#def','high-color': '#def','space-color': '#def'}); // Add terrain source, with slight exaggerationmap.addSource('mapbox-dem', {'type': 'raster-dem','url': 'mapbox://mapbox.terrain-rgb','tileSize': 512,'maxzoom': 14});map.setTerrain({ 'source': 'mapbox-dem', 'exaggeration': 1.5 }); const pinRoute = pinRouteGeojson.features[0].geometry.coordinates;// Create the marker and popup that will display the elevation queriesconst popup = new mapboxgl.Popup({ closeButton: false });const marker = new mapboxgl.Marker({color: 'red',scale: 0.8,draggable: false,pitchAlignment: 'auto',rotationAlignment: 'auto'}).setLngLat(pinRoute[0]).setPopup(popup).addTo(map).togglePopup(); // Add a line feature and layer. This feature will get updated as we progress the animationmap.addSource('line', {type: 'geojson',// Line metrics is required to use the 'line-progress' propertylineMetrics: true,data: pinRouteGeojson});map.addLayer({type: 'line',source: 'line',id: 'line',paint: {'line-color': 'rgba(0,0,0,0)','line-width': 5},layout: {'line-cap': 'round','line-join': 'round'}}); await map.once('idle');// The total animation duration, in millisecondsconst animationDuration = 20000;// Use the https://turfjs.org/ library to calculate line distances and// sample the line at a given percentage with the turf.along function.const path = turf.lineString(pinRoute);// Get the total line distanceconst pathDistance = turf.lineDistance(path);let start;function frame(time) {if (!start) start = time;const animationPhase = (time - start) / animationDuration;if (animationPhase > 1) {return;} // Get the new latitude and longitude by sampling along the pathconst alongPath = turf.along(path, pathDistance * animationPhase).geometry.coordinates;const lngLat = {lng: alongPath[0],lat: alongPath[1]}; // Sample the terrain elevation. We round to an integer value to// prevent showing a lot of digits during the animationconst elevation = Math.floor(// Do not use terrain exaggeration to get actual meter valuesmap.queryTerrainElevation(lngLat, { exaggerated: false })); // Update the popup altitude value and marker locationpopup.setHTML('Altitude: ' + elevation + 'm<br/>');marker.setLngLat(lngLat); // Reduce the visible length of the line by using a line-gradient to cutoff the line// animationPhase is a value between 0 and 1 that reprents the progress of the animationmap.setPaintProperty('line', 'line-gradient', ['step',['line-progress'],'red',animationPhase,'rgba(255, 0, 0, 0)']); // Rotate the camera at a slightly lower speed to give some parallax effect in the backgroundconst rotation = 150 - animationPhase * 40.0;map.setBearing(rotation % 360); window.requestAnimationFrame(frame);} window.requestAnimationFrame(frame);})();</script> </body></html>