Geometry-Bibliothek

  1. Übersicht
  2. Konzepte der sphärischen Geometrie
    1. Funktionen für Entfernung und Fläche
    2. Navigationsfunktionen
  3. Geometry-Codierung
  4. Funktionen für Polygone und Polylinien
    1. containsLocation()
    2. isLocationOnEdge()

Übersicht

Die Konzepte in diesem Dokument beziehen sich auf Funktionen, die nur in der google.maps.geometry-Bibliothek verfügbar sind. Diese Bibliothek wird nicht standardmäßig geladen, wenn Sie die Maps JavaScript API laden. Sie muss explizit mithilfe eines libraries-Bootstrap-Parameters definiert werden. Weitere Informationen finden Sie in der Übersicht zu Bibliotheken.

Die Geometry-Bibliothek der Maps JavaScript API enthält Dienstfunktionen für die Berechnung geometrischer Daten auf der Erdoberfläche. Sie umfasst drei Namespaces:

  • spherical enthält Dienstfunktionen für die sphärische Geometrie, mit denen Sie Winkel, Entfernungen und Flächen anhand von Breiten- und Längengraden berechnen können.
  • encoding enthält Dienstfunktionen zum Codieren und Decodieren von Polylinienpfaden gemäß dem Algorithmus für codierte Polylinien.
  • poly enthält Dienstfunktionen für Berechnungen zu Polygonen und Polylinien.

Die google.maps.geometry-Bibliothek enthält keine Klassen, sondern statische Methoden für die oben genannten Namespaces.

Konzepte der sphärischen Geometrie

Die Bilder in der Maps JavaScript API sind zweidimensional und flach. Die Erde ist jedoch dreidimensional und wird häufig entweder als abgeplattetes Rotationsellipsoid oder als Kugel dargestellt. In der Maps API wird eine Kugel verwendet. Um die Erde auf einer zweidimensionalen, flachen Oberfläche – wie z. B. einem Computerbildschirm – darzustellen, wird in der Maps API eine Projektion eingesetzt.

2D-Projektionen können manchmal trügerisch sein. Da für die Kartenprojektion zwangsläufig eine gewisse Verzerrung erforderlich ist, ist die einfache euklidische Geometrie oft nicht anwendbar. So ist zum Beispiel die kürzeste Entfernung zwischen zwei Punkten auf einer Kugel keine gerade Linie, sondern ein Großkreis (eine Art Geodäte). Außerdem ergibt die Summe der Winkel, die ein Dreieck auf einer Kugeloberfläche bilden, mehr als 180 Grad.

Aufgrund dieser Unterschiede muss zum Berechnen von Konstrukten wie Entfernung, Richtung und Fläche auf einer Kugel (oder ihrer Projektion) die sphärische Geometrie herangezogen werden. Der google.maps.geometry.spherical-Namespace der Maps API enthält Dienstfunktionen zur Berechnung dieser sphärischen geometrischen Konstrukte. Er bietet statische Methoden zur Berechnung von skalaren Werten aus sphärischen Koordinaten (Breiten- und Längengraden).

Funktionen für Entfernung und Fläche

Die Entfernung zwischen zwei Punkten ist die Länge der kürzesten Verbindung zwischen diesen Punkten. Diese Verbindung wird als Geodäte bezeichnet. Auf einer Kugel sind alle Geodäten Segmente eines Großkreises. Um diese Entfernung zu berechnen, müssen Sie computeDistanceBetween() aufrufen und dabei zwei LatLng-Objekte übergeben.

Bei mehreren Orten können Sie stattdessen computeLength() verwenden, um die Länge eines bestimmten Pfades zu berechnen.

Entfernungen werden in Metern zurückgegeben.

Um die Fläche (in Quadratmetern) einer polygonalen Fläche zu berechnen, rufen Sie computeArea() auf und übergeben das Array der LatLng-Objekte, die eine geschlossene Schleife definieren.

Bei der Navigation auf einer Kugel ist eine Richtung der Winkel zu einem festen Bezugspunkt, in der Regel dem geografischen Norden. In der Google Maps API wird die Richtung in Grad vom geografischen Norden aus definiert und im Uhrzeigersinn vom geografischen Norden (0 Grad) aus gemessen. Sie können die Richtung zwischen zwei Orten mit der computeHeading()-Methode berechnen. Dazu müssen Sie zwei from- und to-LatLng-Objekte übergeben.

Anhand der Richtung, des Startpunkts und der Entfernung (in Metern) können Sie die Zielkoordinaten mit computeOffset() berechnen.

Anhand von zwei LatLng-Objekten und einem Wert zwischen 0 und 1 können Sie mit der Methode interpolate() auch ein Ziel zwischen diesen Objekten berechnen. Die Methode führt eine sphärische lineare Interpolation zwischen den beiden Orten durch. Dabei gibt der Wert den Anteil der Entfernung an, der auf dem Weg vom Start zum Ziel zurückzulegen ist.

Im folgenden Beispiel werden zwei Polylinien erstellt, wenn zwei Punkte auf der Karte angeklickt werden – eine Geodäte und eine gerade Linie, die beide Orte verbindet. Außerdem wird die Reiserichtung zwischen den beiden Punkten berechnet.

TypeScript

// 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;
Beispiel ansehen

Testbeispiel

Codierungsmethoden

In der Maps JavaScript API werden Pfade oft als Array mit LatLng-Objekten angegeben. Das Weitergeben eines solchen Arrays ist jedoch oft sehr ressourcenintensiv. Sie können stattdessen den Algorithmus für codierte Polylinien von Google verwenden, um einen gegebenen Pfad zu komprimieren, und diesen später wieder decodieren, um ihn zu dekomprimieren.

Die geometry-Bibliothek enthält einen encoding-Namespace für Dienstfunktionen zum Codieren und Decodieren von Polylinien.

Die statische Methode encodePath() codiert den angegebenen Pfad. Sie können entweder ein Array mit LatLng-Objekten oder ein MVCArray (wird von Polyline.getPath() zurückgegeben) übergeben.

Um einen codierten Pfad zu decodieren, rufen Sie decodePath() auf und übergeben der Methode den codierten String.

Mit folgendem Beispiel wird eine Karte von Oxford, Mississippi angezeigt. Wird auf die Karte geklickt, wird ein Punkt zu einer Polylinie hinzugefügt. Beim Erstellen der Polylinie wird ihre Codierung darunter angezeigt.

TypeScript

// 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;
Beispiel ansehen

Testbeispiel

Funktionen für Polygone und Polylinien

Der poly-Namespace der Geometry-Bibliothek enthält Dienstfunktionen, mit denen ermittelt wird, ob sich ein bestimmter Punkt innerhalb oder in der Nähe eines Polygons oder einer Polylinie befindet.

containsLocation()

containsLocation(point:LatLng, polygon:Polygon)

Um herauszufinden, ob ein bestimmter Punkt innerhalb eines Polygons liegt, übergeben Sie den Punkt und das Polygon an google.maps.geometry.poly.containsLocation(). Wenn die Funktion „true“ zurückgibt, liegt der Punkt innerhalb des Polygons oder an seinem Rand.

Mit folgendem Code wird „true“ in der Browserkonsole ausgegeben, wenn der Klick des Nutzers innerhalb des definierten Dreiecks erfolgt. Ansonsten wird „false“ ausgegeben.

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);

Mit einer anderen Version des Codes wird ein blaues Dreieck auf die Karte gezeichnet, wenn der Nutzer auf das Bermudadreieck klickt, und andernfalls ein roter Kreis:

Beispiel ansehen

isLocationOnEdge()

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

Um herauszufinden, ob sich ein Punkt auf oder in der Nähe einer Polylinie bzw. auf oder in der Nähe des Rands eines Polygons befindet, übergeben Sie den Punkt, die Polylinie bzw. das Polygon und optional einen Toleranzwert in Grad an google.maps.geometry.poly.isLocationOnEdge(). Die Funktion gibt den Wert „true“ zurück, wenn die Entfernung zwischen dem Punkt und dem nächstgelegenen Punkt auf der Linie oder dem Rand innerhalb des angegebenen Toleranzbereichs liegt. Der Standardwert für den Toleranzbereich ist 10-9 Grad.

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);