Библиотека геометрии

Оптимизируйте свои подборки Сохраняйте и классифицируйте контент в соответствии со своими настройками.
  1. Обзор
  2. Понятия сферической геометрии
    1. Функции расстояния и площади
    2. Функции навигации
  3. Кодирование геометрии
  4. Функции многоугольника и полилинии
    1. содержитместоположение()
    2. isLocationOnEdge()

Обзор

Концепции в этом документе относятся к функциям, доступным только в библиотеке google.maps.geometry . Эта библиотека не загружается по умолчанию при загрузке Maps Javascript API, но ее необходимо явно указать с помощью параметра начальной загрузки libraries . Дополнительные сведения см. в разделе Обзор библиотек .

Библиотека геометрии Maps JavaScript API предоставляет служебные функции для вычисления геометрических данных о поверхности Земли. Библиотека включает в себя три пространства имен:

  • spherical содержит утилиты сферической геометрии, позволяющие вычислять углы, расстояния и площади по широте и долготе.
  • encoding содержит утилиты для кодирования и декодирования ломаных путей в соответствии с Encoded Polyline Algorithm .
  • poly содержит служебные функции для вычислений с участием полигонов и полилиний.

Библиотека google.maps.geometry не содержит классов; вместо этого библиотека содержит статические методы для указанных выше пространств имен.

Понятия сферической геометрии

Изображения в Maps JavaScript API являются двумерными и «плоскими». Земля, однако, трехмерна и часто представляется либо сплюснутым сфероидом , либо скорее сферой. В Maps API мы используем сферу, а для представления Земли на двумерной плоской поверхности — например, на экране вашего компьютера — Maps API использует проекцию .

В 2D-проекциях внешний вид иногда может быть обманчивым. Поскольку картографическая проекция обязательно требует некоторого искажения, простая евклидова геометрия часто неприменима. Например, кратчайшее расстояние между двумя точками на сфере — это не прямая линия, а большой круг (разновидность геодезической), а углы, составляющие треугольник на поверхности сферы, в сумме составляют более 180 градусов. .

Из-за этих различий геометрические функции на сфере (или на ее проекции) требуют использования сферической геометрии для расчета таких конструкций, как расстояние, направление и площадь. Утилиты для расчета этих сферических геометрических конструкций содержатся в пространстве имен google.maps.geometry.spherical API Карт. Это пространство имен предоставляет статические методы для вычисления скалярных значений из сферических координат (широты и долготы).

Функции расстояния и площади

Расстояние между двумя точками — это длина кратчайшего пути между ними. Этот кратчайший путь называется геодезической. На сфере все геодезические являются отрезками большого круга. Чтобы вычислить это расстояние, вызовите computeDistanceBetween() , передав ему два объекта LatLng .

Вместо этого вы можете использовать computeLength() для вычисления длины данного пути, если у вас есть несколько местоположений.

Результаты расстояния выражаются в метрах.

Чтобы вычислить площадь (в квадратных метрах) многоугольной области, вызовите computeArea() , передав массив объектов LatLng , определяющих замкнутый цикл.

При навигации по сфере курс представляет собой угол направления от фиксированной точки отсчета, обычно истинного севера. В Google Maps API направление определяется в градусах относительно истинного севера, где направления измеряются по часовой стрелке от истинного севера (0 градусов). Вы можете вычислить этот заголовок между двумя местоположениями с помощью computeHeading() , передав его два from и to объекты LatLng .

Учитывая определенный курс, исходное местоположение и расстояние (в метрах), вы можете вычислить координаты пункта назначения, используя computeOffset() .

Имея два объекта LatLng и значение от 0 до 1, вы также можете вычислить пункт назначения между ними, используя метод interpolate() , который выполняет сферическую линейную интерполяцию между двумя местоположениями, где значение указывает дробное расстояние, которое нужно пройти по пути от точки. происхождения до места назначения.

В следующем примере создаются две полилинии, когда вы щелкаете две точки на карте — одну геодезическую и одну «прямую» линию, соединяющую два местоположения, — и вычисляется направление движения между двумя точками:

Машинопись

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

let marker1: google.maps.Marker, marker2: google.maps.Marker;
let poly: google.maps.Polyline, geodesicPoly: google.maps.Polyline;

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 4,
      center: { lat: 34, lng: -40.605 },
    }
  );

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(
    document.getElementById("info") as HTMLElement
  );

  marker1 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 40.714, lng: -74.006 },
  });

  marker2 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 48.857, lng: 2.352 },
  });

  const bounds = new google.maps.LatLngBounds(
    marker1.getPosition() as google.maps.LatLng,
    marker2.getPosition() as google.maps.LatLng
  );

  map.fitBounds(bounds);

  google.maps.event.addListener(marker1, "position_changed", update);
  google.maps.event.addListener(marker2, "position_changed", update);

  poly = new google.maps.Polyline({
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    map: map,
  });

  geodesicPoly = new google.maps.Polyline({
    strokeColor: "#CC0099",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    geodesic: true,
    map: map,
  });

  update();
}

function update() {
  const path = [
    marker1.getPosition() as google.maps.LatLng,
    marker2.getPosition() as google.maps.LatLng,
  ];

  poly.setPath(path);
  geodesicPoly.setPath(path);

  const heading = google.maps.geometry.spherical.computeHeading(
    path[0],
    path[1]
  );

  (document.getElementById("heading") as HTMLInputElement).value =
    String(heading);
  (document.getElementById("origin") as HTMLInputElement).value = String(
    path[0]
  );
  (document.getElementById("destination") as HTMLInputElement).value = String(
    path[1]
  );
}

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

JavaScript

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
let marker1, marker2;
let poly, geodesicPoly;

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 4,
    center: { lat: 34, lng: -40.605 },
  });

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(
    document.getElementById("info")
  );
  marker1 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 40.714, lng: -74.006 },
  });
  marker2 = new google.maps.Marker({
    map,
    draggable: true,
    position: { lat: 48.857, lng: 2.352 },
  });

  const bounds = new google.maps.LatLngBounds(
    marker1.getPosition(),
    marker2.getPosition()
  );

  map.fitBounds(bounds);
  google.maps.event.addListener(marker1, "position_changed", update);
  google.maps.event.addListener(marker2, "position_changed", update);
  poly = new google.maps.Polyline({
    strokeColor: "#FF0000",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    map: map,
  });
  geodesicPoly = new google.maps.Polyline({
    strokeColor: "#CC0099",
    strokeOpacity: 1.0,
    strokeWeight: 3,
    geodesic: true,
    map: map,
  });
  update();
}

function update() {
  const path = [marker1.getPosition(), marker2.getPosition()];

  poly.setPath(path);
  geodesicPoly.setPath(path);

  const heading = google.maps.geometry.spherical.computeHeading(
    path[0],
    path[1]
  );

  document.getElementById("heading").value = String(heading);
  document.getElementById("origin").value = String(path[0]);
  document.getElementById("destination").value = String(path[1]);
}

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

Попробуйте образец

Методы кодирования

Пути в Maps JavaScript API часто указываются как Array объектов LatLng . Однако передача такого массива часто громоздка. Вместо этого вы можете использовать алгоритм кодирования ломаной линии Google для сжатия заданного пути, который вы можете позже распаковать с помощью декодирования.

Библиотека geometry содержит пространство имен encoding для утилит для кодирования и декодирования полилиний.

Статический метод encodePath() кодирует заданный путь. Вы можете передать массив LatLng или MVCArray (который возвращается Polyline.getPath() ).

Чтобы декодировать закодированный путь, вызовите decodePath() , передав методу закодированную строку.

В следующем примере показана карта Оксфорда, штат Миссисипи. Щелчок по карте добавляет точку к полилинии. По мере построения полилинии ее кодировка появляется внизу.

Машинопись

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 14,
      center: { lat: 34.366, lng: -89.519 },
    }
  );
  const poly = new google.maps.Polyline({
    strokeColor: "#000000",
    strokeOpacity: 1,
    strokeWeight: 3,
    map: map,
  });

  // Add a listener for the click event
  google.maps.event.addListener(map, "click", (event) => {
    addLatLngToPoly(event.latLng, poly);
  });
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * Updates the encoding text area with the path's encoded values.
 */
function addLatLngToPoly(
  latLng: google.maps.LatLng,
  poly: google.maps.Polyline
) {
  const path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(latLng);

  // Update the text field to display the polyline encodings
  const encodeString = google.maps.geometry.encoding.encodePath(path);

  if (encodeString) {
    (document.getElementById("encoded-polyline") as HTMLInputElement).value =
      encodeString;
  }
}

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

JavaScript

// This example requires the Geometry library. Include the libraries=geometry
// parameter when you first load the API. For example:
// <script src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=geometry">
function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 14,
    center: { lat: 34.366, lng: -89.519 },
  });
  const poly = new google.maps.Polyline({
    strokeColor: "#000000",
    strokeOpacity: 1,
    strokeWeight: 3,
    map: map,
  });

  // Add a listener for the click event
  google.maps.event.addListener(map, "click", (event) => {
    addLatLngToPoly(event.latLng, poly);
  });
}

/**
 * Handles click events on a map, and adds a new point to the Polyline.
 * Updates the encoding text area with the path's encoded values.
 */
function addLatLngToPoly(latLng, poly) {
  const path = poly.getPath();

  // Because path is an MVCArray, we can simply append a new coordinate
  // and it will automatically appear
  path.push(latLng);

  // Update the text field to display the polyline encodings
  const encodeString = google.maps.geometry.encoding.encodePath(path);

  if (encodeString) {
    document.getElementById("encoded-polyline").value = encodeString;
  }
}

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

Попробуйте образец

Функции многоугольника и полилинии

Пространство имен poly библиотеки геометрии содержит служебные функции, которые определяют, находится ли данная точка внутри или рядом с многоугольником или ломаной линией.

содержитместоположение()

containsLocation(point:LatLng, polygon:Polygon)

Чтобы узнать, попадает ли данная точка в полигон, передайте точку и полигон в google.maps.geometry.poly.containsLocation() . Функции возвращают true, если точка находится внутри многоугольника или на его краю.

Следующий код записывает «true» в консоль браузера, если щелчок пользователя попадает в определенный треугольник; в противном случае он пишет «ложь».

function initialize() {
  var mapOptions = {
    zoom: 5,
    center: new google.maps.LatLng(24.886, -70.269),
    mapTypeId: 'terrain'
  };

  var map = new google.maps.Map(document.getElementById('map'),
      mapOptions);

  var bermudaTriangle = new google.maps.Polygon({
    paths: [
      new google.maps.LatLng(25.774, -80.190),
      new google.maps.LatLng(18.466, -66.118),
      new google.maps.LatLng(32.321, -64.757)
    ]
  });

  google.maps.event.addListener(map, 'click', function(event) {
    console.log(google.maps.geometry.poly.containsLocation(event.latLng, bermudaTriangle));
  });
}

google.maps.event.addDomListener(window, 'load', initialize);

Другая версия этого кода рисует на карте синий треугольник, если щелчок приходится на Бермудский треугольник, и красный кружок в противном случае:

Посмотреть пример

isLocationOnEdge()

isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)

Чтобы определить, находится ли точка на ломаной или рядом с ней, на краю многоугольника или рядом с ним, передайте точку, ломаную/многоугольник и, при необходимости, значение допуска в градусах в google.maps.geometry.poly.isLocationOnEdge() . Функция возвращает значение true, если расстояние между точкой и ближайшей точкой на линии или ребре находится в пределах указанного допуска. Значение допуска по умолчанию составляет 10 -9 градусов.

function initialize() {
  var myPosition = new google.maps.LatLng(46.0, -125.9);

  var mapOptions = {
    zoom: 5,
    center: myPosition,
    mapTypeId: 'terrain'
  };

  var map = new google.maps.Map(document.getElementById('map'),
      mapOptions);

  var cascadiaFault = new google.maps.Polyline({
    path: [
      new google.maps.LatLng(49.95, -128.1),
      new google.maps.LatLng(46.26, -126.3),
      new google.maps.LatLng(40.3, -125.4)
    ]
  });

  cascadiaFault.setMap(map);

  if (google.maps.geometry.poly.isLocationOnEdge(myPosition, cascadiaFault, 10e-1)) {
    alert("Relocate!");
  }
}

google.maps.event.addDomListener(window, 'load', initialize);