Reputation: 7221
I make my first steps with mapbox with this example: https://docs.mapbox.com/help/tutorials/find-elevations-with-tilequery-api/
I use axios instead of ajax-fetch-api, but this should not be the problem.
You can find my demo under https://astridx.github.io/mapboxexamples/examples/find-elevations-with-tilequery-api.html and my code here:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Display driving directions</title>
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
<script src="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
<link href="https://api.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css" rel="stylesheet" />
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
<style>
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.eleInfo {
position: absolute;
background-color: #fff;
z-index: 1;
}
</style>
</head>
<body>
<div class="eleInfo">
<div>Longitude: <span id='lng'></span></div>
<div>Latitude: <span id='lat'></span></div>
<div>Elevation: <span id='ele'></span></div>
</div>
<div id="map"></div>
<script>
var lngDisplay = document.getElementById('lng');
var latDisplay = document.getElementById('lat');
var eleDisplay = document.getElementById('ele');
lngDisplay.textContent = 'Please click on map.';
latDisplay.textContent = '-';
eleDisplay.textContent = '-';
mapboxgl.accessToken = 'pk.eyJ1IjoibWFwYm94IiwiYSI6ImNpejY4M29iazA2Z2gycXA4N2pmbDZmangifQ.-g_vE53SD2WrJ6tFX7QHmA';
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [86.925278, 27.988056],
zoom: 15
});
function getElevation(lng, lat) {
var query = 'https://api.mapbox.com/v4/mapbox.mapbox-terrain-v2/tilequery/' + lng + ',' + lat + '.json?layers=contour&limit=50&access_token=' + mapboxgl.accessToken;
axios.get(query)
.then(function (response) {
console.log(response.data.features);
var elevations = [];
for (i = 0; i < response.data.features.length; i++) {
elevations.push(response.data.features[i].properties.ele);
}
var highestElevation = Math.max(...elevations);
eleDisplay.textContent = highestElevation + ' Meter';
lngDisplay.textContent = lng.toFixed(4) + '°';
latDisplay.textContent = lat.toFixed(4) + '°';
})
.catch(function (error) {
console.log(error);
})
.then(function () {
// immer
});
}
map.on('click', function (e) {
lng = e.lngLat.lng;
lat = e.lngLat.lat;
getElevation(e.lngLat.lng, e.lngLat.lat);
});
</script>
</body>
</html>
The elevation is correct for my hometown and for many other places. For Mount Everest, I only see values below 6000 meters. That should be over 8000, right? What am I doing wrong?
Upvotes: 3
Views: 549
Reputation: 126425
The problem is with the way the data is organised and limitations of this API. The contours are polygons stacked within each other. The JavaScript code is fetching a maximum of 50 of them, then displaying the highest elevation found.
The trouble is, Mt Everest is really high. Its summit sits within more than 50 concentric polygons, but the query isn't returning the highest ones. Unfortunately, the API is limited to returning no more than 50 results, and:
there is no way to sort results such that they are returned in the order they were queried
Long story short, although the data contains what you need, there is no way to use this API to achieve your aim.
Fortunately, there is a workaround: You can use the query-remote-tiles NPM package, which fetches a whole tile, before then returning the polygons that your point is within. I haven't tested it for the concentric-polygons use case, but hopefully it will work.
Upvotes: 3