- Omówienie
- Pojęcia związane z geometrią sferyczną
- Kodowanie geometrii
- Funkcje wielokątów i linii łamanych
Przegląd
Pojęcia opisane w tym dokumencie odnoszą się tylko do funkcji dostępnych w bibliotece google.maps.geometry. Ta biblioteka nie jest wczytywana domyślnie podczas wczytywania interfejsu Maps JavaScript API, ale musi być wyraźnie określona za pomocą parametru bootstrap libraries. Więcej informacji znajdziesz w omówieniu bibliotek.
Biblioteka geometrii interfejsu Maps JavaScript API udostępnia funkcje użytkowe do obliczania danych geometrycznych na powierzchni Ziemi. Biblioteka zawiera 3 przestrzenie nazw:
sphericalzawiera narzędzia do geometrii sferycznej, które umożliwiają obliczanie kątów, odległości i obszarów na podstawie szerokości i długości geograficznej.encodingzawiera narzędzia do kodowania i dekodowania ścieżek linii łamanych zgodnie z algorytmem zakodowanej linii łamanej.polyzawiera funkcje użytkowe do obliczeń obejmujących wielokąty i linie łamane.
Biblioteka google.maps.geometry nie zawiera żadnych klas, ale zawiera metody statyczne w powyższych przestrzeniach nazw.
Pojęcia dotyczące geometrii sferycznej
Obrazy w interfejsie Maps JavaScript API są dwuwymiarowe i „płaskie”. Ziemia jest jednak trójwymiarowa i często jest przybliżana jako elipsoida obrotowa lub kula. W interfejsie API Map Google używamy kuli, a do przedstawienia Ziemi na dwuwymiarowej płaskiej powierzchni, takiej jak ekran komputera, interfejs API Map Google używa rzutu.
W przypadku projekcji 2D pozory mogą mylić. Ponieważ rzutowanie mapy wymaga pewnych zniekształceń, prosta geometria euklidesowa często nie ma zastosowania. Na przykład najkrótsza odległość między 2 punktami na kuli nie jest linią prostą, ale kołem wielkim (rodzajem linii geodezyjnej), a kąty tworzące trójkąt na powierzchni kuli dają w sumie więcej niż 180 stopni.
Z powodu tych różnic funkcje geometryczne na kuli (lub jej rzucie) wymagają użycia geometrii sferycznej do obliczania takich wartości jak odległość, kierunek i powierzchnia. Narzędzia do obliczania tych sferycznych konstrukcji geometrycznych znajdują się w przestrzeni nazw google.maps.geometry.spherical interfejsu API Map Google. Ta przestrzeń nazw udostępnia metody statyczne do obliczania wartości skalarnych na podstawie współrzędnych sferycznych (szerokości i długości geograficznej).
Funkcje pomiaru 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 nazywa się geodezyjną. Na sferze wszystkie geodezyjne są
segmentami wielkiego koła. Aby obliczyć tę odległość, wywołaj funkcję computeDistanceBetween(), przekazując jej 2 obiekty LatLng.
Jeśli masz kilka lokalizacji, możesz użyć
computeLength(), aby obliczyć długość danej ścieżki.
Wyniki odległości są wyrażone w metrach.
Aby obliczyć obszar (w metrach kwadratowych) obszaru wielokąta, wywołaj funkcję computeArea(), przekazując tablicę obiektów LatLng definiujących zamkniętą pętlę.
Funkcje nawigacji
Podczas nawigacji po kuli kierunek to kąt kierunku od stałego punktu odniesienia, zwykle północy geograficznej. W interfejsie API Map Google kierunek jest określany w stopniach od północy geograficznej, gdzie kierunki są mierzone zgodnie z ruchem wskazówek zegara od północy geograficznej (0 stopni). Możesz obliczyć ten kierunek między 2 lokalizacjami za pomocą metody computeHeading(), przekazując jej 2 obiekty from i to LatLng.
Jeśli masz określony kierunek, lokalizację początkową i odległość do przebycia (w metrach), możesz obliczyć współrzędne miejsca docelowego za pomocą metody computeOffset().
Jeśli masz 2 obiekty LatLng i wartość z zakresu od 0 do 1, możesz też obliczyć miejsce docelowe między nimi za pomocą metody interpolate(), która wykonuje sferyczną interpolację liniową między tymi 2 lokalizacjami, gdzie wartość wskazuje ułamkową odległość do przebycia wzdłuż ścieżki od punktu początkowego do miejsca docelowego.
W poniższym przykładzie po kliknięciu 2 punktów na mapie tworzone są 2 krzywe łamane – jedna geodezyjna i jedna „prosta” łącząca te 2 lokalizacje – oraz obliczany jest kierunek podróży między tymi 2 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;
Metody kodowania
Ścieżki w Maps JavaScript API są często określane jako Array obiektów LatLng. Jednak przekazywanie takiej tablicy jest często uciążliwe. Zamiast tego możesz użyć algorytmu kodowania linii łamanych Google, aby skompresować daną ścieżkę, którą możesz później zdekompresować przez dekodowanie.
Biblioteka geometry zawiera przestrzeń nazw encoding dla narzędzi do kodowania i dekodowania linii łamanych.
Metoda statyczna encodePath() koduje podaną ścieżkę.
Możesz przekazać tablicę LatLng lub MVCArray (zwracaną przez Polyline.getPath()).
Aby zdekodować zakodowaną ścieżkę, wywołaj metodę decodePath(), przekazując jej zakodowany ciąg znaków.
Poniższy przykład pokazuje mapę Oxfordu w Mississippi. Kliknięcie na mapie dodaje punkt do linii łamanej. Podczas tworzenia linii łamanej pod spodem pojawia się jej 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;
Funkcje wielokąta i linii łamanej
Przestrzeń nazw poly biblioteki geometrii zawiera funkcje użytkowe, które określają, czy dany punkt znajduje się wewnątrz wielokąta lub okręgu albo w pobliżu wielokąta lub linii łamanej.
containsLocation()
containsLocation(point:LatLng|LatLngLiteral, polygon:Polygon|Circle|CircleLiteral)
Aby sprawdzić, czy dany punkt znajduje się wewnątrz wielokąta lub okręgu, przekaż punkt i google.maps.Polygon, google.maps.Circle lub google.maps.CircleLiteral do google.maps.geometry.poly.containsLocation().
Funkcja zwraca wartość true, jeśli punkt znajduje się wewnątrz kształtu lub na jego krawędzi.
Poniższy kod zapisuje w konsoli przeglądarki wartość „true”, jeśli kliknięcie użytkownika mieści się w zdefiniowanym trójkącie, lub „false”, jeśli tak nie jest.
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 nastąpi w Trójkącie Bermudzkim, a w przeciwnym razie – czerwone koło:
isLocationOnEdge()
isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)
Aby określić, czy punkt znajduje się na linii łamanej lub w jej pobliżu albo na krawędzi wielokąta lub w jej pobliżu, przekaż punkt, linię łamaną lub wielokąt i opcjonalnie wartość tolerancji w stopniach do google.maps.geometry.poly.isLocationOnEdge(). Funkcja zwraca wartość true, jeśli odległość między punktem a najbliższym punktem na linii lub krawędzi mieści się w określonej tolerancji. Domyślna wartość tolerancji to 10-9 stopnia.
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);
Sprawdzanie promienia geofence i bezpiecznej strefy
Aby sprawdzić, czy współrzędne na żywo (np. pojazdu, zasobu lub lokalizacji użytkownika) znajdują się w obrębie geofence lub bezpiecznej strefy na mapie, połącz kształty na mapie z biblioteką geometry:
- Okrągły obszar geofence (sprawdzanie promienia): narysuj obwód za pomocą
google.maps.Circle(lub zdefiniujgoogle.maps.CircleLiteral) i przekaż współrzędne docelowe oraz okrąg dogoogle.maps.geometry.poly.containsLocation(). Jeśli potrzebujesz też odległości w metrach odCircle.getCenter(), przekaż współrzędne celu i środek dogoogle.maps.geometry.spherical.computeDistanceBetween(). - Geofence w kształcie wielokąta: narysuj obwód za pomocą
google.maps.Polygoni przekaż współrzędne docelowe oraz wielokąt dogoogle.maps.geometry.poly.containsLocation().