2010-08-19 15 views
29

Ho bisogno di sapere come recuperare il raggio del livello di zoom visualizzabile in google maps API v3.Raggio dell'area "visualizzabile" in google maps v3

Ad esempio, se sono al livello di zoom 3 e in base alla dimensione dello schermo degli utenti (diciamo solo 400x400 regione visualizzabile) come ottengo il cerchio "raggio" dell'area visibile.

In alternativa, attualmente sto utilizzando map.fitBounds() per tutti i punti che ho aggiunto alla mappa, quindi davvero tutto il BISOGNO è il raggio di tutti i limiti. Quello che voglio è qualcosa come "20 miglia" che posso alimentare nella mia app di database.

risposta

72

il raggio sarebbe uguale la distanza dal centro dei limiti ad una delle gli angoli del limite . Utilizzando la distanza ortodromica formula da the calculations from this page, mi si avvicinò con il seguente:

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)); 

Dopo aver giocato un po 'con questo, ho notato che map.getBounds() conterrà la mappa viewport pieno. Ma se il tuo LatLngBounds viene creato estendendo fino a includere i punti LatLng e quindi emetti uno map.fitBounds(bounds), l'api aumenta un po 'la finestra della mappa in modo che il "riquadro" bounds abbia un po' di riempimento.

Se si utilizza la finestra corrente della mappa, il raggio dal centro all'angolo della finestra potrebbe essere un raggio più lungo di quanto si desideri. Forse la distanza dal centro di visualizzazione al centro del margine più lontano della vista. (Se la mappa non è un quadrato perfetto)

+1

awesomesauce, proprio quello che mi serviva. Grazie! –

+0

Per fare in modo che questo esempio funzioni, le prime 3 righe devono essere 'var bounds = map.getBounds(); var center = bounds.getCenter(); var ne = bounds.getNorthEast();' –

21

Versione refactored di Eric's answer sopra usando lo spazio dei nomi google.maps.geometry.spherical (assicurarsi di aver caricato Geometry library per farlo funzionare).

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

Perfetto! Mi aiuta molto per mantenere le richieste di posti basse a no raggiungere la quota troppo velocemente. – kosemuckel

2

Ho anche riscritta la risposta di Eric, il mio è in funzione stand-alone, e sto tornando il risultato in metri (in base alle esigenze del 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 
}