<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<title>Query Elevation (lines) | Sample | ArcGIS Maps SDK for JavaScript</title>
<!-- Load the ArcGIS Maps SDK for JavaScript from CDN -->
<script type="module" src="https://js.arcgis.com/5.0/"></script>
background-color: rgba(255, 255, 255, 0.85);
<arcgis-scene basemap="topo-vector" ground="world-elevation" center="7.9878, 46.3159" zoom="16">
<arcgis-zoom slot="top-left"></arcgis-zoom>
<arcgis-navigation-toggle slot="top-left"></arcgis-navigation-toggle>
<arcgis-compass slot="top-left"></arcgis-compass>
Click on the map to add stops. The route along the stops is calculated and elevation
values are queried to update the following route statistics:
<p>total distance: <span id="distanceValue">0</span> km</p>
<p>total ascent: <span id="ascValue">0</span> m</p>
<p>total descent: <span id="descValue">0</span> m</p>
const [Graphic, GraphicsLayer, route, RouteParameters, FeatureSet] = await $arcgis.import([
"@arcgis/core/Graphic.js",
"@arcgis/core/layers/GraphicsLayer.js",
"@arcgis/core/rest/route.js",
"@arcgis/core/rest/support/RouteParameters.js",
"@arcgis/core/rest/support/FeatureSet.js",
// get the reference to the Scene component and wait until ready
const viewElement = document.querySelector("arcgis-scene");
await viewElement.viewOnReady();
// Point the URL to a valid routing service
"https://route-api.arcgis.com/arcgis/rest/services/World/Route/NAServer/Route_World";
// The stops and route result will be stored in this layer
const routeLayer = new GraphicsLayer();
viewElement.map.add(routeLayer);
// prepare the route parameters
const routeParams = new RouteParameters({
// An authorization string used to access the routing service
apiKey: "YOUR_ACCESS_TOKEN",
// autocasts as new SpatialReference()
// the symbol used to mark stops on the route
type: "point-3d", // autocasts as new PointSymbol3D()
type: "object", // autocasts as new ObjectSymbol3DLayer()
// the symbol used to mark the paths between stops
type: "line-3d", // autocasts as new LineSymbol3D()
type: "path", // autocasts as new PathSymbol3DLayer()
width: 17, // If only the width is given, the height is set to the same value.
// Adds a graphic when the user clicks the map. If 2 or more points exist, route is solved.
viewElement.addEventListener("arcgisViewClick", addStop);
function addStop(event) {
if (!event.detail.mapPoint) {
// Add a marker at the location of the map click
const stop = new Graphic({
geometry: event.detail.mapPoint,
// Update the route and execute it if 2 or more stops are input
routeParams.stops.features.push(stop);
if (routeParams.stops.features.length >= 2) {
.solve(routeUrl, routeParams)
// if it fails, print the error to the console and remove the recently added point
routeParams.stops.features.pop();
function onRouteUpdated(data) {
const route = data.routeResults[0].route;
const geometry = route.geometry;
// do the actual elevation query
const elevationPromise = viewElement.map.ground.queryElevation(geometry);
// compute the total ascent and descent
for (let j = 0; j < result.geometry.paths.length; j++) {
const path = result.geometry.paths[j];
for (let i = 0; i < path.length - 1; i++) {
const d = path[i + 1][2] - path[i][2];
// update the text fields
document.getElementById("distanceValue").textContent =
Math.round(route.attributes.Total_Kilometers * 1000) / 1000;
document.getElementById("ascValue").textContent = Math.round(ascent * 100) / 100;
document.getElementById("descValue").textContent = Math.round(descent * 100) / 100;
// add a path symbol following the calculated route to the scene
geometry: result.geometry,