Centra / imposta lo zoom della mappa per coprire tutti gli indicatori visibili?


352

Sto impostando più marcatori sulla mia mappa e posso impostare staticamente i livelli di zoom e il centro, ma quello che voglio è, per coprire tutti i marcatori e zoom il più possibile con tutti i mercati visibili

I metodi disponibili sono i seguenti

setZoom(zoom:number)

e

setCenter(latlng:LatLng)

setCentersupporta input multipli per posizione o array di posizione né setZoomha questo tipo di funzionalità

inserisci qui la descrizione dell'immagine



è necessario aggiungere l' oggetto latlnga un boundsoggetto ogni volta che si aggiunge un indicatore e si imposta la mappa in modo che si adatti ai limiti finali. Vedere la risposta qui: stackoverflow.com/questions/1556921/...
Suvi Vignarajah

Risposte:


678

Devi usare il fitBounds()metodo

var markers = [];//some array
var bounds = new google.maps.LatLngBounds();
for (var i = 0; i < markers.length; i++) {
 bounds.extend(markers[i]);
}

map.fitBounds(bounds);

Documentazione da developers.google.com/maps/documentation/javascript :

fitBounds(bounds[, padding])

parametri:

`bounds`:  [`LatLngBounds`][1]|[`LatLngBoundsLiteral`][1]
`padding` (optional):  number|[`Padding`][1]

Valore restituito: Nessuno

Imposta il viewport per contenere i limiti dati.
Nota : quando la mappa è impostata su display: none, la fitBoundsfunzione legge le dimensioni della mappa come 0x0, e quindi non fa nulla. Per modificare il viewport mentre la mappa è nascosta, impostare la mappa su visibility: hidden, assicurando in tal modo che il div della mappa abbia una dimensione effettiva.


3
Da dove viene il getPositionmetodo?
Pratheep,

6
@Pratheep: fa parte della classe google.maps.Marker; developers.google.com/maps/documentation/javascript/…
Adam

Ha funzionato come un fascino! Grazie
Joseph N.

9
A parte i neofiti là fuori, con la stessa domanda di Pratheep ... Lo sai se hai esperienza con l'API di Maps, ma puoi sempre passare a LatLngLiteralinvece di avere un'istanza Marker. ad es bounds.extend({lat: 123, lng: 456}).
Kyle Baker,

1
Un consiglio in più per chiunque sia interessato. Puoi definire un padding usando ciò fitBounds(bounds, int)che ti permetterà di avere un piccolo spazio tra i marker e i bordi della mappa (o meno spazio se necessario). Vedi documentazione
MickelsonMichael,

178

Per estendere la risposta data con alcuni trucchi utili:

var markers = //some array;
var bounds = new google.maps.LatLngBounds();
for(i=0;i<markers.length;i++) {
   bounds.extend(markers[i].getPosition());
}

//center the map to a specific spot (city)
map.setCenter(center); 

//center the map to the geometric center of all markers
map.setCenter(bounds.getCenter());

map.fitBounds(bounds);

//remove one zoom level to ensure no marker is on the edge.
map.setZoom(map.getZoom()-1); 

// set a minimum zoom 
// if you got only 1 marker or all markers are on the same address map will be zoomed too much.
if(map.getZoom()> 15){
  map.setZoom(15);
}

//Alternatively this code can be used to set the zoom for just 1 marker and to skip redrawing.
//Note that this will not cover the case if you have 2 markers on the same address.
if(count(markers) == 1){
    map.setMaxZoom(15);
    map.fitBounds(bounds);
    map.setMaxZoom(Null)
}

AGGIORNAMENTO:
Ulteriori ricerche sull'argomento mostrano che fitBounds () è un asincrono ed è meglio effettuare la manipolazione dello zoom con un listener definito prima di chiamare Fit Bounds.
Grazie @Tim, @ xr280xr, altri esempi sull'argomento: SO: setzoom-after-fitbounds

google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  this.setZoom(map.getZoom()-1);

  if (this.getZoom() > 15) {
    this.setZoom(15);
  }
});
map.fitBounds(bounds);

4
Buone aggiunte. Grazie!
paneer_tikka il

1
Avevo un indefinito restituito da .getZoom (). Questa risposta mi ha aiutato a risolverlo usando addListenerOnceon zoom_changedper impostare lo zoom dopo che il suo valore è stato inizializzato.
xr280xr,

1
Grazie a @ d.raev ma l'impostazione dello zoom massimo quando i limiti sono già impostati non funziona. Quello che devi fare è impostare l'opzione "maxZoom" durante l'inizializzazione della mappa. developers.google.com/maps/documentation/javascript/…
Tim

1
Nella parte relativa alla manipolazione dello zoom ( AGGIORNAMENTO ), stai mescolando un paio di var e ambiti. Tu usi yourMap, mape this. Forse è una buona idea renderlo più coerente.
Gustavo Straube,

11

La dimensione dell'array deve essere maggiore di zero. Altrimenti avrai risultati inaspettati.

function zoomeExtends(){
  var bounds = new google.maps.LatLngBounds();
  if (markers.length>0) { 
      for (var i = 0; i < markers.length; i++) {
         bounds.extend(markers[i].getPosition());
        }    
        myMap.fitBounds(bounds);
    }
}

8

Esiste questa MarkerClustererutilità lato client disponibile per google Map come specificato qui negli articoli per sviluppatori di Google Map , ecco una breve descrizione dell'uso:

Esistono molti approcci per fare ciò che hai chiesto:

  • Cluster basato su griglia
  • Clustering basato sulla distanza
  • Gestione dei marker delle finestre
  • Tavoli Fusion
  • Marker Clusterer
  • MarkerManager

Puoi leggere su di loro sul link fornito sopra.

Marker Clustererutilizza il clustering basato su griglia per raggruppare tutti i marker che desiderano la griglia. Il raggruppamento basato su griglia funziona dividendo la mappa in quadrati di una certa dimensione (la dimensione cambia ad ogni zoom) e quindi raggruppando i marcatori in ciascun quadrato della griglia.

Prima del clustering Prima del clustering

Dopo il clustering Dopo il clustering

Spero che questo sia quello che stavi cercando e questo risolverà il tuo problema :)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.