Biblioteka geometryczna

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.
  1. Omówienie
  2. Pojęcia o geometrii sferycznej
    1. Funkcje odległości i powierzchni
    2. Funkcje nawigacji
  3. Kodowanie geometryczne
  4. Funkcje wielokątów i linii łamanych
    1. containsLocation()
    2. isLocationOnEdge().

Opis

Pojęcia widoczne w tym dokumencie odnoszą się tylko do funkcji dostępnych w bibliotece google.maps.geometry. Ta biblioteka nie jest domyślnie wczytywana podczas wczytywania interfejsu Maps JavaScript API, ale musi być wyraźnie określona za pomocą parametru rozruchowego libraries. Więcej informacji znajdziesz w artykule Omówienie bibliotek.

Biblioteka geometrii Maps JavaScript API udostępnia funkcje wykonawcze do obliczania danych geometrycznych na powierzchni Ziemi. Biblioteka zawiera 3 przestrzenie nazw:

  • spherical zawiera narzędzia geometryczne sferyczne, które umożliwiają obliczanie kątów, odległości i powierzchni na podstawie szerokości i długości geograficznej.
  • encoding zawiera narzędzia do kodowania i dekodowania ścieżek liniowych zgodnie z algorytmem enkodowanym zakodowanym w formacie.
  • poly zawiera funkcje narzędziowe do obliczeń obejmujących wielokąty i linie.

Biblioteka google.maps.geometry nie zawiera żadnych klas. Może ona zawierać statyczne metody w przestrzeniach nazw.

Pojęcia geometryczne

Obrazy w interfejsie Maps JavaScript API są dwuwymiarowe & "flat." Ziemia jest jednak wielowymiarowa i często jest określana jako przestarzały sferyczny lub więcej jako sfera. W interfejsie API Map Google stosujemy sferę i reprezentujemy Ziemię na dwuwymiarowej płaskiej powierzchni, np. na ekranie komputera. Interfejs ten wykorzystuje projekcję .

W ramach odwzorowania 2D wyglądy mogą czasami być mylące. Projekcja mapy musi być zniekształcona, więc często nie sprawdza się jej geometria Euklidyana. Na przykład najkrótsza odległość między 2 punktami na kuli nie jest prostą linią, ale wielki okrąg (typ geodezyjny) i kąty, które składają się z trójkąta na powierzchni kuli, wynoszą ponad 180 stopni.

Ze względu na te różnice funkcje geometryczne na sferze (lub na jej odcinku) wymagają użycia geometrii sferycznej do obliczenia takich konstrukcji jako odległości, nagłówka i powierzchni. Narzędzia do obliczania tych konstrukcji kulistycznych są zawarte w przestrzeni nazw google.maps.geometry.spherical interfejsu API Map Google. Ta przestrzeń nazw udostępnia statyczne metody obliczania wartości skalarnych na podstawie współrzędnych sferycznych (szerokość i długość geograficzna).

Funkcje odległości i powierzchni

Odległość między 2 punktami to długość najkrótszej ścieżki między nimi. Ta najkrótsza ścieżka nosi nazwę geodesyjności. W sferze wszystkie geodemie to segmenty wielkiego okręgu. Aby obliczyć odległość, wywołaj obiekt computeDistanceBetween(), przekazując 2 obiekty LatLng.

Zamiast tego możesz użyć computeLength() do obliczenia długości ścieżki, jeśli masz kilka lokalizacji.

Wyniki dystansu są wyrażone w metrach.

Aby obliczyć obszar (w metrach kwadratowych) wielokąta, wywołaj computeArea(), przekazując tablicę obiektów LatLng definiujących pętlę zamkniętą.

Gdy poruszasz się po kuli, nagłówek to kąt kierunku stałego, który jest zwykle prawdziwym północem. W interfejsie API Map Google nagłówek jest zdefiniowany w stopniach od północy prawdziwej, gdzie nagłówki są mierzone zgodnie z ruchem wskazówek zegara od północy (0 stopni). Możesz obliczyć ten nagłówek między 2 lokalizacjami, korzystając z metody computeHeading(), przekazując dwa obiekty from i to LatLng.

Biorąc pod uwagę konkretny nagłówek, lokalizację punktu początkowego i odległość (w metrach), możesz obliczyć współrzędne miejsca docelowego za pomocą computeOffset().

Biorąc pod uwagę 2 obiekty LatLng i wartość od 0 do 1, możesz też obliczyć miejsce docelowe między nimi za pomocą metody interpolate(), która przeprowadza sferyczną interpolację między obiema lokalizacjami, gdzie wartość wskazuje ułamkową odległość, jaką musi pokonać ścieżka od punktu początkowego do miejsca docelowego.

Poniższy przykład pokazuje 2 linie po kliknięciu na mapie 2 punktów – jedną geodemiczną i jedną (prostą) i obliczanie nagłówka dla podróży między tymi punktami:

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;
Zobacz przykład

Fragment

Metody kodowania

Ścieżki w interfejsie Maps JavaScript API są często określone jako Array obiektów LatLng. Przekazywanie takich tablic jest często jednak bardzo duże. Zamiast tego możesz skompresować daną ścieżkę, korzystając z algorytmu kodu Poliline, który można później zdekompresować przez dekodowanie.

Biblioteka geometry zawiera przestrzeń nazw encoding narzędzi do kodowania i dekodowania linii łamanych.

Statyczna metoda encodePath() koduje daną ścieżkę. Możesz przekazać tablicę LatLng lub MVCArray (zwracaną przez funkcję Polyline.getPath()).

Aby zdekodować zakodowaną ścieżkę, wywołaj decodePath(), przekazując metodę zakodowanego ciągu.

W tym przykładzie widać mapę Oxfordu, Missisipi. Kliknięcie mapy powoduje dodanie punktu do linii łamanej. Po utworzeniu linii łamanej pojawia się pod nią kodowanie.

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;
Zobacz przykład

Fragment

Funkcje wielokąta i linii łamanej

Przestrzeń nazw poly geometrii zawiera funkcje, które określają, czy dany punkt znajduje się w obrębie wielokąta, linii łamanej, czy w jej pobliżu.

zawiera lokalizację()

containsLocation(point:LatLng, polygon:Polygon)

Aby sprawdzić, czy dany punkt należy do wielokąta, przenieś go i do wielokąta do google.maps.geometry.poly.containsLocation(). Funkcje zwracają wartość „prawda”, jeśli punkt znajduje się w kształcie wielokąta lub jego krawędzi.

Jeśli użytkownik znajdzie się w określonym trójkątze, kod wpisze &&33;true' w konsoli przeglądarki.

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

Inna wersja tego kodu rysuje na mapie niebieski trójkąt, jeśli kliknięcie należy do trójkąta Bermudów, a czerwone kółko:

Zobacz przykład

isLocationOnEdge()

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

Aby określić, czy punkt znajduje się na linii łamanej, w jej pobliżu lub w pobliżu krawędzi wielokąta, przekaż punkt, łamaną lub wielokąta i opcjonalnie podaj tolerancję w stopniach do google.maps.geometry.poly.isLocationOnEdge(). Ta funkcja zwraca wartość „prawda”, jeśli odległość między punktami a najbliższy punkt na linii lub krawędzi mieści się w określonej tolerancji. Domyślna wartość tolerancji to 10–9 stopni.

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