Ошибка в высотах с API Mapbox Tilequery

#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, который извлекает целую плитку, а затем возвращает полигоны, в которых находится ваша точка. Я не тестировал его для варианта использования концентрических полигонов, но, надеюсь, это сработает.