- Descripción general
- Conceptos de geometría esférica
- Codificación de geometría
- Funciones de polígonos y polilíneas
Descripción general
Los conceptos que se incluyen en este documento hacen referencia a funciones que solo están disponibles en la biblioteca google.maps.geometry
. Esta biblioteca no se carga de forma predeterminada cuando cargas la API de Maps JavaScript, sino que debe especificarse de forma explícita mediante el uso de un parámetro de arranque libraries
. Para obtener más información, consulta el artículo Descripción general de las bibliotecas.
La biblioteca de geometría de la API de Maps JavaScript proporciona funciones de utilidad para el cálculo de datos geométricos sobre la superficie de la Tierra. En la biblioteca se incluyen tres espacios de nombres:
spherical
contiene utilidades de geometría esférica que te permiten calcular ángulos, distancias y áreas a partir de latitudes y longitudes.encoding
contiene utilidades para codificar y decodificar rutas de polilíneas según el algoritmo de polilínea codificada.poly
contiene funciones de utilidad para hacer cálculos que incluyen polígonos y polilíneas.
La biblioteca google.maps.geometry
no contiene clases. En su lugar, tiene métodos estáticos relacionados con los espacios de nombres anteriores.
Conceptos de geometría esférica
Las imágenes de la API de Maps JavaScript son bidimensionales y "planas". Sin embargo, la Tierra es tridimensional y a menudo se la concibe como un esferoide oblato o como una esfera. En la API de Google Maps, usamos una esfera y, para representar la Tierra en una superficie plana bidimensional (como la pantalla de una computadora), usamos una proyección.
En las proyecciones 2D, las apariencias a veces pueden ser engañosas. Dado que la proyección del mapa requiere algún grado de distorsión, a menudo no es posible aplicar la geometría euclidiana simple. Por ejemplo, la distancia más corta entre dos puntos de una esfera no es una línea recta, sino un círculo máximo (un tipo de línea geodésica), y los ángulos que componen un triángulo en la superficie de una esfera suman más de 180 grados.
Debido a estas diferencias, las funciones geométricas en una esfera (o en su proyección) requieren el uso de geometría esférica para calcular construcciones como la distancia, la orientación y el área. El espacio de nombres google.maps.geometry.spherical
de la API de Google Maps incluye utilidades para calcular estas construcciones geométricas esféricas. Este espacio de nombres proporciona métodos estáticos para el cálculo de valores escalares a partir de coordenadas esféricas (latitudes y longitudes).
Funciones de distancia y área
La distancia entre dos puntos es la extensión de la ruta más corta entre ellos. Esta ruta se conoce como línea geodésica. En una esfera, todas las líneas geodésicas son segmentos de un círculo máximo. Para calcular esta distancia, llama a computeDistanceBetween()
y pásale dos objetos LatLng
.
En lugar de ello, puedes usar computeLength()
para calcular la extensión de una ruta determinada si hay varias ubicaciones.
Los resultados de las distancias se expresan en metros.
Para calcular el área (en metros cuadrados) de un área poligonal, llama a computeArea()
y pasa el array de objetos LatLng
que definen un bucle cerrado.
Funciones de navegación
Al navegar en una esfera, la orientación es un ángulo de dirección a partir de un punto de referencia fijo, generalmente el norte geográfico. En la API de Google Maps, la orientación se define en grados a partir del norte geográfico, donde las orientaciones se miden en el sentido de las manecillas del reloj a partir del norte geográfico (0 grados). Puedes calcular la orientación entre dos ubicaciones con el método computeHeading()
y pasarle dos objetos from
y to
LatLng
.
A partir de una orientación en particular, una ubicación de origen y la distancia de viaje (en metros), puedes calcular las coordenadas de destino mediante computeOffset()
.
A partir de dos objetos LatLng
y un valor entre 0 y 1, también puedes calcular un destino entre ellos mediante el método interpolate()
. Este realiza una interpolación lineal esférica entre las dos ubicaciones, donde el valor indica la distancia fraccionaria que se recorrerá desde el origen hasta el destino.
En el siguiente ejemplo, se crean dos polilíneas cuando haces clic en dos puntos del mapa (una línea geodésica y una línea "recta" que conectan las dos ubicaciones) y se calcula la orientación del recorrido de un punto al otro:
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;
Prueba la muestra
Métodos de codificación
Las rutas de la API de Maps JavaScript a menudo se especifican como un Array
de objetos LatLng
. Sin embargo, este tipo de array suele ser muy pesado para pasarlo. En su lugar, puedes usar el algoritmo de codificación de polilínea de Google para comprimir una ruta determinada, que luego puedes descomprimir mediante decodificación.
La biblioteca geometry
contiene un espacio de nombres encoding
para que las utilidades codifiquen y decodifiquen polilíneas.
El método estático encodePath()
codifica la ruta proporcionada.
Puedes pasar un array de LatLng
o un MVCArray
(que muestra Polyline.getPath()
).
Para decodificar una ruta codificada, llama a decodePath()
y pasa la string codificada al método.
En el siguiente ejemplo, se muestra un mapa de Oxford, Misisipi. Cuando se hace clic en el mapa, se agrega un punto a una polilínea. A medida que se construye la polilínea, la codificación aparece debajo.
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;
Prueba la muestra
Funciones de polígonos y polilíneas
El espacio de nombres poly
de la biblioteca de geometría contiene funciones de utilidad que determinan si un punto determinado se encuentra dentro o cerca de un polígono o una polilínea.
containsLocation()
containsLocation(point:LatLng, polygon:Polygon)
Para saber si un punto determinado se encuentra dentro de un polígono, pasa el punto y el polígono a google.maps.geometry.poly.containsLocation()
. Las funciones muestran "true" si el punto se encuentra dentro del polígono o en su borde.
El siguiente código escribe "true" en la consola del navegador si el clic que realiza el usuario se encuentra dentro del triángulo definido. De lo contrario, escribe "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);
Otra versión de este código dibuja un triángulo azul en el mapa si se hace clic dentro del Triángulo de las Bermudas. De lo contrario, dibuja un círculo rojo:
isLocationOnEdge()
isLocationOnEdge(point:LatLng, poly:Polygon|Polyline, tolerance?:number)
Para determinar si un punto se encuentra en una polilínea o cerca de ella, o en el borde de un polígono o cerca de él, pasa el punto, la polilínea o el polígono y, opcionalmente, un valor de tolerancia en grados a google.maps.geometry.poly.isLocationOnEdge()
. La función muestra "true" si la distancia entre este punto y el punto más cercano de la línea o del borde se encuentra dentro del valor de tolerancia especificado. El valor de tolerancia predeterminado es de 10-9 grados.
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);