- 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
sphericalcontém utilitários de geometria esférica que permitem calcular ângulos, distâncias e áreas de latitudes e longitudes. - O
encodingcontém utilitários para codificação e decodificação de caminhos de polilinha, de acordo com o algoritmo de polilinha codificada. - O
polyconté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;
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 LatLngs 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;
Funções de polígono e polilinha
O namespace poly da biblioteca de geometria contém funções utilitárias que determinam se um ponto específico está dentro de um polígono ou círculo ou perto de um polígono ou polilinha.
containsLocation()
containsLocation(point:LatLng|LatLngLiteral, polygon:Polygon|Circle|CircleLiteral)
Para saber se um determinado ponto está dentro de um polígono ou círculo, passe o ponto e o google.maps.Polygon, google.maps.Circle ou google.maps.CircleLiteral para google.maps.geometry.poly.containsLocation().
A função retorna true se o ponto estiver dentro da forma ou na
borda dela.
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);
Verificações de fronteira geográfica virtual e raio de zona segura
Para verificar se uma coordenada em tempo real (como a localização de um veículo, recurso ou usuário) está dentro de uma fronteira geográfica virtual ou de um perímetro de zona segura em um mapa, combine formas de mapa com a biblioteca geometry:
- Fronteira geográfica virtual circular (verificação de raio): desenhe o perímetro com
google.maps.Circle(ou defina umgoogle.maps.CircleLiteral) e transmita a coordenada de destino e o círculo paragoogle.maps.geometry.poly.containsLocation(). Se você também precisar da distância em metros deCircle.getCenter(), transmita a coordenada de destino e o centro paragoogle.maps.geometry.spherical.computeDistanceBetween(). - Fronteira geográfica virtual poligonal:desenhe o perímetro com
google.maps.Polygone transmita a coordenada de destino e o polígono paragoogle.maps.geometry.poly.containsLocation().