2010-08-19 18 views
29

Necesito saber cómo recuperar el radio del nivel de zoom visible en google maps API v3.Radio de la región "visible" en google maps v3

Por ejemplo, si estoy en el nivel de zoom 3, y dependiendo del tamaño de la pantalla del usuario (digamos 400x400 región visible) cómo obtengo el círculo "radio" del área visible.

Alternativamente, actualmente estoy usando map.fitBounds() para todos los puntos que he agregado al mapa, así que realmente todos I NECESITAN es el radio de todos los límites. Lo que quiero es algo así como "20 millas" que puedo incluir en mi aplicación de base de datos.

Respuesta

72

el radio sería igual a la distancia desde el centro de los límites de una de las esquinas del límite . Utilizando la fórmula de distancia ortodrómica de the calculations from this page, me ocurrió lo siguiente:

var bounds = map.getBounds(); 

var center = bounds.getCenter(); 
var ne = bounds.getNorthEast(); 

// r = radius of the earth in statute miles 
var r = 3963.0; 

// Convert lat or lng from decimal degrees into radians (divide by 57.2958) 
var lat1 = center.lat()/57.2958; 
var lon1 = center.lng()/57.2958; 
var lat2 = ne.lat()/57.2958; 
var lon2 = ne.lng()/57.2958; 

// distance = circle radius from center to Northeast corner of bounds 
var dis = r * Math.acos(Math.sin(lat1) * Math.sin(lat2) + 
    Math.cos(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1)); 

Después de jugar un poco más con esto, me he dado cuenta que map.getBounds() contendrá el visor mapa completo. Pero si su LatLngBounds se construye extendiendo para incluir LatLng puntos, y luego emite un map.fitBounds(bounds), la API aumenta la ventana del mapa un poco para que la "caja" bounds tenga algo de relleno.

Si utiliza la vista actual del mapa, el radio desde el centro a la esquina de la ventana gráfica puede tener un radio más largo que el que desea. Tal vez la distancia desde el centro de la ventana gráfica hasta el medio del borde más alejado de la ventana gráfica. (Si el mapa no es un cuadrado perfecto)

+1

Awesomesauce, justo lo que necesitaba. Gracias! –

+0

Para que este ejemplo funcione, las primeras 3 líneas deberían ser 'var bounds = map.getBounds(); var center = bounds.getCenter(); var ne = bounds.getNorthEast();' –

21

Versión modificada de Eric's answer utilizando el espacio de nombres google.maps.geometry.spherical (asegúrese de haber cargado Geometry library para que funcione).

var bounds = map.getBounds(); 
var center = map.getCenter(); 
if (bounds && center) { 
    var ne = bounds.getNorthEast(); 
    // Calculate radius (in meters). 
    var radius = google.maps.geometry.spherical.computeDistanceBetween(center, ne); 
} 
+1

¡Perfecto! Me ayuda mucho para mantener las solicitudes de lugares bajos para no alcanzar la cuota demasiado rápido. – kosemuckel

2

También refactorizado respuesta de Eric, el mío es como una función independiente, y estoy devolviendo el resultado en metros (según sea necesario por el Places API search.

function getBoundsRadius(bounds){ 
    // r = radius of the earth in km 
    var r = 6378.8 
    // degrees to radians (divide by 57.2958) 
    var ne_lat = bounds.getNorthEast().lat()/57.2958 
    var ne_lng = bounds.getNorthEast().lng()/57.2958 
    var c_lat = bounds.getCenter().lat()/57.2958 
    var c_lng = bounds.getCenter().lng()/57.2958 
    // distance = circle radius from center to Northeast corner of bounds 
    var r_km = r * Math.acos(
    Math.sin(c_lat) * Math.sin(ne_lat) + 
    Math.cos(c_lat) * Math.cos(ne_lat) * Math.cos(ne_lng - c_lng) 
    ) 
    return r_km *1000 // radius in meters 
}