- Visão geral
- Conceitos de geometria esférica
- Codificação de geometria
- Funções de polígonos e polilinhas
Visão geral
Os conceitos neste documento se referem aos recursos disponíveis apenas na biblioteca google.maps.geometry
. Essa biblioteca não é carregada por padrão quando você carrega a API Maps JavaScript, mas deve ser explicitamente especificada por meio do uso de um parâmetro de inicialização libraries
. Para mais informações, consulte a Visão geral das bibliotecas.
A biblioteca de geometria da API Maps JavaScript fornece funções utilitárias para o cálculo de dados geométricos na superfície da Terra. A biblioteca inclui três namespaces:
- O
spherical
contém utilitários de geometria esférica que permitem calcular ângulos, distâncias e áreas de latitudes e longitudes. - O
encoding
contém utilitários para codificação e decodificação de caminhos de polilinha, de acordo com o algoritmo de polilinha codificada. - O
poly
contém funções utilitárias para cálculos envolvendo polígonos e polilinhas.
A biblioteca google.maps.geometry
não contém classes. Em vez disso, ela contém métodos estáticos sobre os namespaces acima.
Conceitos de geometria esférica
As imagens na API Maps JavaScript são bidimensionais e "fixas". No entanto, a Terra é tridimensional e frequentemente aproximada como um esferoide achatado ou, simplesmente, uma esfera. Na API Maps, usamos uma esfera. Para representar a Terra em uma superfície achatada e bidimensional, como a tela do computador, a API Maps usa uma projeção.
Em projeções 2D, as aparências podem enganar. Como a projeção do mapa exige alguma distorção, muitas vezes a geometria euclidiana simples não é relevante. Por exemplo, a menor distância entre dois pontos em uma esfera não é uma linha reta, mas um grande círculo (um tipo de geodésica), e os ângulos que formam um triângulo na superfície de uma esfera somam mais de 180 graus.
Devido a essas diferenças, as funções geométricas em uma esfera (ou na projeção dela) precisam usar Spherical Geometry para calcular unidades como distância, orientação e área. Os utilitários usados para calcular essas unidades geométricas esféricas ficam no namespace google.maps.geometry.spherical
da API Maps. Esse namespace oferece métodos estáticos para calcular valores escalares de coordenadas esféricas (latitudes e longitudes).
Funções de distância e área
A distância entre dois pontos é o comprimento do caminho mais curto entre eles. Esse caminho mais curto é denominado geodésica. Em uma esfera, todas as geodésicas são segmentos de um grande círculo. Para computar essa distância, chame computeDistanceBetween()
, passando seus dois objetos LatLng
.
Em vez disso, também é possível usar computeLength()
para calcular o comprimento de um determinado caminho, se você tiver vários locais.
Os resultados de distância são expressos em metros.
Para calcular a área de uma região poligonal (em metros quadrados), chame computeArea()
, transmitindo a matriz de objetos LatLng
que definem um loop fechado.
Funções de navegação
Na navegação em uma esfera, uma orientação é o ângulo de uma rota em relação a um ponto de referência fixo, normalmente o norte verdadeiro. Com a API Google Maps, uma orientação é definida em graus em relação ao norte verdadeiro, onde as orientações são medidas no sentido horário a partir do norte verdadeiro (0 grau). Você pode computar essa orientação entre dois locais com o método computeHeading()
, passando seus dois objetos from
e to
LatLng
.
Com uma posição específica, um local de origem e a distância para viajar (em metros), você pode calcular as coordenadas de destino usando o computeOffset()
.
Com dois objetos LatLng
e um valor entre 0 e 1, você também pode calcular um destino entre eles usando o método interpolate()
. Esse método realiza a interpolação linear esférica entre os dois locais, onde o valor indica a distância fracionária para viajar ao longo do caminho desde a origem até o destino.
O exemplo a seguir cria duas polilinhas quando você clica em dois pontos no mapa (uma linha geodésica e uma "reta" que liga as duas localidades) e calcula a orientação para viajar entre os dois pontos:
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;
Testar amostra
Métodos de codificação
Os caminhos na API Maps JavaScript geralmente são especificados como um Array
de objetos LatLng
. No entanto, essa matriz é volumosa demais para ser passada. Em vez disso, use um algoritmo de polilinha codificada do Google para compactar um caminho específico, que poderá ser descompactado posteriormente por meio da decodificação.
A biblioteca geometry
contém um namespace encoding
para que os utilitários codifiquem e decodifiquem polilinhas.
O método estático encodePath()
codifica o caminho fornecido.
Você pode passar uma matriz de LatLng
s ou MVCArray
(que é retornada por Polyline.getPath()
).
Para decodificar um caminho, chame decodePath()
transmitindo o método à string codificada.
O exemplo a seguir exibe um mapa de Oxford, Mississippi. Um clique no mapa adiciona um ponto a uma polilinha. À medida que a polilinha é construída, a codificação é exibida abaixo.
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;
Testar amostra
Funções de polígono e polilinha
O namespace da biblioteca de geometria poly
contém funções utilitárias que determinam se um ponto específico está dentro ou perto de um polígono ou de uma polilinha.
containsLocation()
containsLocation(point:LatLng, polygon:Polygon)
Para saber se um determinado ponto está dentro de um polígono, passe o ponto e o polígono para google.maps.geometry.poly.containsLocation()
. A função retorna true quando o ponto está dentro ou na borda do polígono.
O código a seguir escreve "true" no console do navegador quando o clique do usuário acontece dentro do triângulo definido. Caso contrário, ele escreve "false".
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);
Outra versão desse código vai desenhar um triângulo azul no mapa se o clique acontecer dentro do Triângulo das Bermudas. Caso contrário, um círculo vermelho será usado:
isLocationOnEdge()
isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)
Para determinar se um ponto está sobre ou perto de uma polilinha ou de uma borda de polígono, passe o ponto, a polilinha ou o polígono e, opcionalmente um valor de tolerância em graus para google.maps.geometry.poly.isLocationOnEdge()
A função retorna true se a distância entre o ponto e o ponto mais próximo na linha ou borda está dentro da tolerância especificada. A tolerância padrão é de 10 a 9 graus.
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);