#mapbox #mapbox-gl-js #mapbox-api-tilequery
#mapbox #mapbox-gl-js #mapbox-api-tilequery
Вопрос:
Я делаю свои первые шаги с mapbox на этом примере: https://docs.mapbox.com/help/tutorials/find-elevations-with-tilequery-api /
Я использую axios вместо ajax-fetch-api, но это не должно быть проблемой.
Вы можете найти мою демонстрацию в разделе https://astridx.github.io/mapboxexamples/examples/find-elevations-with-tilequery-api.html и мой код здесь:
<!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=contouramp;limit=50amp;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>
Высота правильная для моего родного города и для многих других мест. Для Эвереста я вижу только значения ниже 6000 метров. Это должно быть более 8000, верно?
Что я делаю не так?
Ответ №1:
Проблема заключается в том, как организованы данные и ограничения этого API. Контуры представляют собой многоугольники, расположенные друг в друге. Код JavaScript извлекает максимум 50 из них, а затем отображает самую высокую найденную высоту.
Проблема в том, что гора Эверест действительно высока. Его вершина находится в пределах более чем 50 концентрических полигонов, но запрос не возвращает самые высокие. К сожалению, API ограничен возвратом не более 50 результатов, и:
невозможно отсортировать результаты таким образом, чтобы они возвращались в том порядке, в котором они были запрошены
Короче говоря, хотя данные содержат то, что вам нужно, нет способа использовать этот API для достижения вашей цели.
К счастью, есть обходной путь: вы можете использовать пакет NPM query-remote-tiles, который извлекает целую плитку, а затем возвращает полигоны, в которых находится ваша точка. Я не тестировал его для варианта использования концентрических полигонов, но, надеюсь, это сработает.