Служба Elevation

Обзор

Сервис Elevation предоставляет сведения о высоте для точек на земной поверхности, включая глубины океана (в этом случае возвращаются отрицательные значения). Если у Google нет точных высотных данных для интересующей вас точки, сервис использует интерполяцию и возвращает усредненное значение по четырем ближайшим точкам.

Объект ElevationService реализует простой интерфейс, позволяющий запрашивать данные о высоте разных точек земной поверхности. Кроме того, можно выборочно запросить высотные данные для некоторого пути. Это позволяет вычислить изменения высоты в равноудаленных друг от друга точках маршрута. Объект ElevationService взаимодействует с сервисом Elevation в Google Maps API, который получает запросы о высоте и возвращает соответствующие данные.

С помощью сервиса Elevation можно разрабатывать приложения для пешего и велосипедного туризма, приложения мобильного позиционирования или приложения для топографической съемки с низким разрешением.

Начало работы

Прежде чем использовать сервис Elevation в Maps JavaScript API, убедитесь, что в Google Cloud Console включен Elevation API в том же проекте, который вы установили для Maps JavaScript API.

Чтобы посмотреть список включенных API:

  1. Войдите в Google Cloud Console.
  2. Нажмите кнопку Select a project (Выбрать проект), затем выберите тот же проект, который вы установили для Maps JavaScript API, и нажмите Open (Открыть).
  3. В списке API на панели управления поищите Elevation API.
  4. Если этот API присутствует в списке – все установлено. Если API в списке нет, включите его:
    1. Вверху страницы нажмите Enable API (Включить API), чтобы перейти на вкладку Library (Библиотека). Вы также можете выбрать в меню слева пункт Library (Библиотека).
    2. Введите поисковый запрос Elevation API и выберите API из списка результатов.
    3. Нажмите Enable (Включить). Когда процесс завершится, Elevation API появится в списке API на панели управления.

Цены и правила

Цены

С 16 июля 2018 года действует новый тарифный план с оплатой по мере использования для API Maps, Routes и Places. Узнать больше о новых ценах и лимитах на использование сервиса JavaScript Elevation можно в статье Статистика использования и оплата для Elevation API.

Ограничения частоты запросов

Учитывайте описанные ниже ограничения частоты дополнительных запросов:

Ограничение применяется к каждому пользовательскому сеансу, независимо от количества пользователей проекта. При первой загрузке API вам выделяется исходная квота запросов. Как только она будет израсходована, API задает ограничение на число дополнительных запросов в секунду. Если за определенный период времени их будет отправлено слишком много, API вернет вашему приложению код ответа OVER_QUERY_LIMIT.

Ограничение частоты запросов за один сеанс не позволяет использовать сервисы на стороне клиента для пакетных запросов. Если требуется рассчитать высоту над уровнем моря для известных статических местоположений, используйте веб-сервис Elevation API.

Правила

Сервис Elevation нужно использовать в соответствии с правилами для Elevation API.

Запросы данных о высоте

Доступ к службе Elevation осуществляется асинхронно, поскольку Google Maps API требуется отправить вызов на внешний сервер. По этой причине необходимо передавать метод обратного вызова, который будет выполняться по завершении запроса Этот метод обратного вызова должен обработать результаты. Обратите внимание, что сервис Elevation возвращает код статуса (ElevationStatus) и массив отдельных объектов ElevationResult.

Объект ElevationService обрабатывает следующие два типа запросов:

  • Запросы для отдельных местоположений с помощью метода getElevationForLocations(), которому передается список из одного или нескольких местоположений в объекте LocationElevationRequest.
  • Запросы данных о высоте в последовательности соединенных точек вдоль пути с помощью метода getElevationAlongPath(), которому передается упорядоченный набор точек маршрута в объекте PathElevationRequest. При запросе данных о высоте пунктов пути необходимо также передать параметр, указывающий число точек выборки вдоль пути.

Каждый из этих методов также должен передать метод обратного вызова для обработки возвращаемых объектов ElevationResult и ElevationStatus.

Запросы данных о высоте места

Литерал объекта LocationElevationRequest содержит следующее поле:

{
  locations[]: LatLng
}

locations (обязательный параметр) задает одну или несколько точек на земной поверхности, высоту которых требуется получить. Этот параметр принимает массив LatLng.

В массиве можно передать любое число координат, но в пределах квот сервиса. Обратите внимание, что при передаче координат нескольких точек точность полученных данных может быть ниже, чем при запросе данных для одной точки.

Образцы запросов данных о высоте пути

Литерал объекта PathElevationRequest содержит следующие поля:

{
  path[]: LatLng,
  samples: Number
}

Назначение этих полей объясняется ниже.

  • path (обязательный параметр) определяет путь на земной поверхности, для которого требуются данные о высоте. Параметр path определяет набор из одной или нескольких упорядоченных пар {широта,долгота} с помощью массива из двух и более объектов LatLng.
  • samples (обязательный параметр) указывает число точек выборки вдоль пути, для которого требуются данные о высоте. Параметр samples делит заданный параметром path путь на отрезки на ряд равноудаленных точек.

Как и в запросах для отдельных точек, параметр path указывает набор значений широты и долготы. Однако, в отличие от запросов для отдельных точек, в параметре path указывается упорядоченный набор вершин ломаной кривой. Запрос пути не просто возвращает данные о высоте в каждой вершине. Производится выборка вдоль пути, где все точки равноудалены друг от друга (включая конечные точки).

Ответы на запросы о высоте

Для каждого допустимого запроса сервис Elevation возвращает указанному обратному вызову набор объектов ElevationResult наряду с объектом ElevationStatus.

Состояния сервиса Elevation

Каждый запрос данных о высоте возвращает код ElevationStatus в своей функции обратного вызова. Этот код status содержит одно из следующих значений:

  • OK означает, что запрос к сервису успешно выполнен;
  • INVALID_REQUEST означает, что запрос к сервису сформирован неправильно;
  • OVER_QUERY_LIMIT означает, что запрашивающее приложение превысило квоту;
  • REQUEST_DENIED означает, что сервис не выполнил запрос, вероятнее всего, из-за недопустимого параметра;
  • UNKNOWN_ERROR означает неизвестную ошибку.

Успешное выполнение обратного вызова следует проверять по коду статуса OK.

Результаты сервиса Elevation

При успешном выполнении запроса аргумент results функции обратного вызова будет содержать набор объектов ElevationResult. Эти объекты содержат следующие элементы:

  • Элемент location (содержащий объекты LatLng) той точки, для которой вычисляются данные о высоте. Обратите внимание, что для запросов пути набор элементов location будет содержать выборку точек вдоль пути.
  • Элемент elevation, указывающий высоту точки над уровнем моря в метрах.
  • Значение resolution, указывающее максимальное расстояние (в метрах) между точками данных, на основании которых интерполируется значение высоты. Если разрешение неизвестно, это свойство отсутствует. Обратите внимание, что если передается много точек, точность высотных данных снижается (более высокие значения элемента resolution). Чтобы получить максимально точное значение высоты для точки, следует запрашивать его независимо от других точек.

Примеры использования сервиса Elevation

Следующий код с помощью объекта LocationElevationRequest переводит клик по карте в запрос высотных данных:

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 8,
      center: { lat: 63.333, lng: -150.5 }, // Denali.
      mapTypeId: "terrain",
    }
  );
  const elevator = new google.maps.ElevationService();
  const infowindow = new google.maps.InfoWindow({});

  infowindow.open(map);

  // Add a listener for the click event. Display the elevation for the LatLng of
  // the click inside the infowindow.
  map.addListener("click", (event) => {
    displayLocationElevation(event.latLng, elevator, infowindow);
  });
}

function displayLocationElevation(
  location: google.maps.LatLng,
  elevator: google.maps.ElevationService,
  infowindow: google.maps.InfoWindow
) {
  // Initiate the location request
  elevator
    .getElevationForLocations({
      locations: [location],
    })
    .then(({ results }) => {
      infowindow.setPosition(location);

      // Retrieve the first result
      if (results[0]) {
        // Open the infowindow indicating the elevation at the clicked position.
        infowindow.setContent(
          "The elevation at this point <br>is " +
            results[0].elevation +
            " meters."
        );
      } else {
        infowindow.setContent("No results found");
      }
    })
    .catch((e) =>
      infowindow.setContent("Elevation service failed due to: " + e)
    );
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 8,
    center: { lat: 63.333, lng: -150.5 },
    mapTypeId: "terrain",
  });
  const elevator = new google.maps.ElevationService();
  const infowindow = new google.maps.InfoWindow({});

  infowindow.open(map);
  // Add a listener for the click event. Display the elevation for the LatLng of
  // the click inside the infowindow.
  map.addListener("click", (event) => {
    displayLocationElevation(event.latLng, elevator, infowindow);
  });
}

function displayLocationElevation(location, elevator, infowindow) {
  // Initiate the location request
  elevator
    .getElevationForLocations({
      locations: [location],
    })
    .then(({ results }) => {
      infowindow.setPosition(location);
      // Retrieve the first result
      if (results[0]) {
        // Open the infowindow indicating the elevation at the clicked position.
        infowindow.setContent(
          "The elevation at this point <br>is " +
            results[0].elevation +
            " meters."
        );
      } else {
        infowindow.setContent("No results found");
      }
    })
    .catch((e) =>
      infowindow.setContent("Elevation service failed due to: " + e)
    );
}

window.initMap = initMap;
Посмотреть пример

Примеры кода

В следующем примере из заданного набора координат строится ломаная линия и отображаются данные о высоте вдоль этого пути с использованием API визуализации Google. Этот API необходимо загрузить с помощью Google Common Loader. Запрос данных о высоте создается с помощью PathElevationRequest:

TypeScript

// Load the Visualization API and the columnchart package.
// @ts-ignore TODO update to newest visualization library
google.load("visualization", "1", { packages: ["columnchart"] });

function initMap(): void {
  // The following path marks a path from Mt. Whitney, the highest point in the
  // continental United States to Badwater, Death Valley, the lowest point.
  const path = [
    { lat: 36.579, lng: -118.292 }, // Mt. Whitney
    { lat: 36.606, lng: -118.0638 }, // Lone Pine
    { lat: 36.433, lng: -117.951 }, // Owens Lake
    { lat: 36.588, lng: -116.943 }, // Beatty Junction
    { lat: 36.34, lng: -117.468 }, // Panama Mint Springs
    { lat: 36.24, lng: -116.832 },
  ]; // Badwater, Death Valley

  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 8,
      center: path[1],
      mapTypeId: "terrain",
    }
  );

  // Create an ElevationService.
  const elevator = new google.maps.ElevationService();

  // Draw the path, using the Visualization API and the Elevation service.
  displayPathElevation(path, elevator, map);
}

function displayPathElevation(
  path: google.maps.LatLngLiteral[],
  elevator: google.maps.ElevationService,
  map: google.maps.Map
) {
  // Display a polyline of the elevation path.
  new google.maps.Polyline({
    path: path,
    strokeColor: "#0000CC",
    strokeOpacity: 0.4,
    map: map,
  });

  // Create a PathElevationRequest object using this array.
  // Ask for 256 samples along that path.
  // Initiate the path request.
  elevator
    .getElevationAlongPath({
      path: path,
      samples: 256,
    })
    .then(plotElevation)
    .catch((e) => {
      const chartDiv = document.getElementById(
        "elevation_chart"
      ) as HTMLElement;

      // Show the error code inside the chartDiv.
      chartDiv.innerHTML = "Cannot show elevation: request failed because " + e;
    });
}

// Takes an array of ElevationResult objects, draws the path on the map
// and plots the elevation profile on a Visualization API ColumnChart.
function plotElevation({ results }: google.maps.PathElevationResponse) {
  const chartDiv = document.getElementById("elevation_chart") as HTMLElement;

  // Create a new chart in the elevation_chart DIV.
  const chart = new google.visualization.ColumnChart(chartDiv);

  // Extract the data from which to populate the chart.
  // Because the samples are equidistant, the 'Sample'
  // column here does double duty as distance along the
  // X axis.
  const data = new google.visualization.DataTable();

  data.addColumn("string", "Sample");
  data.addColumn("number", "Elevation");

  for (let i = 0; i < results.length; i++) {
    data.addRow(["", results[i].elevation]);
  }

  // Draw the chart using the data within its DIV.
  chart.draw(data, {
    height: 150,
    legend: "none",
    // @ts-ignore TODO update to newest visualization library
    titleY: "Elevation (m)",
  });
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// Load the Visualization API and the columnchart package.
// @ts-ignore TODO update to newest visualization library
google.load("visualization", "1", { packages: ["columnchart"] });

function initMap() {
  // The following path marks a path from Mt. Whitney, the highest point in the
  // continental United States to Badwater, Death Valley, the lowest point.
  const path = [
    { lat: 36.579, lng: -118.292 },
    { lat: 36.606, lng: -118.0638 },
    { lat: 36.433, lng: -117.951 },
    { lat: 36.588, lng: -116.943 },
    { lat: 36.34, lng: -117.468 },
    { lat: 36.24, lng: -116.832 },
  ]; // Badwater, Death Valley
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 8,
    center: path[1],
    mapTypeId: "terrain",
  });
  // Create an ElevationService.
  const elevator = new google.maps.ElevationService();

  // Draw the path, using the Visualization API and the Elevation service.
  displayPathElevation(path, elevator, map);
}

function displayPathElevation(path, elevator, map) {
  // Display a polyline of the elevation path.
  new google.maps.Polyline({
    path: path,
    strokeColor: "#0000CC",
    strokeOpacity: 0.4,
    map: map,
  });
  // Create a PathElevationRequest object using this array.
  // Ask for 256 samples along that path.
  // Initiate the path request.
  elevator
    .getElevationAlongPath({
      path: path,
      samples: 256,
    })
    .then(plotElevation)
    .catch((e) => {
      const chartDiv = document.getElementById("elevation_chart");

      // Show the error code inside the chartDiv.
      chartDiv.innerHTML = "Cannot show elevation: request failed because " + e;
    });
}

// Takes an array of ElevationResult objects, draws the path on the map
// and plots the elevation profile on a Visualization API ColumnChart.
function plotElevation({ results }) {
  const chartDiv = document.getElementById("elevation_chart");
  // Create a new chart in the elevation_chart DIV.
  const chart = new google.visualization.ColumnChart(chartDiv);
  // Extract the data from which to populate the chart.
  // Because the samples are equidistant, the 'Sample'
  // column here does double duty as distance along the
  // X axis.
  const data = new google.visualization.DataTable();

  data.addColumn("string", "Sample");
  data.addColumn("number", "Elevation");

  for (let i = 0; i < results.length; i++) {
    data.addRow(["", results[i].elevation]);
  }

  // Draw the chart using the data within its DIV.
  chart.draw(data, {
    height: 150,
    legend: "none",
    // @ts-ignore TODO update to newest visualization library
    titleY: "Elevation (m)",
  });
}

window.initMap = initMap;
Посмотреть пример

Примеры кода