Wyśrodkuj / ustaw powiększenie mapy, aby pokryć wszystkie widoczne znaczniki?

352

Ustawiam wiele znaczników na mojej mapie i mogę ustawić statycznie poziomy powiększenia i środek, ale chcę, aby pokryć wszystkie znaczniki i powiększyć jak najwięcej, mając wszystkie rynki widoczne

Dostępne metody są następujące

setZoom(zoom:number)

i

setCenter(latlng:LatLng)

Nie setCenterobsługuje danych wejściowych z wielu lokalizacji ani tablicy lokalizacji, ani setZoomnie ma tego typu funkcji

wprowadź opis zdjęcia tutaj

Trikaldarshi
źródło
1
Zobacz stackoverflow.com/questions/2362337/…
palmsey 10.10.2013
musisz dodać latlngdo boundsobiektu za każdym razem, gdy dodajesz znacznik i ustaw mapę tak, aby pasowała do ostatecznych granic. Zobacz odpowiedź tutaj: stackoverflow.com/questions/1556921/...
Suvi Vignarajah,

Odpowiedzi:

678

Musisz użyć tej fitBounds()metody.

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

Dokumentacja od developers.google.com/maps/documentation/javascript :

fitBounds(bounds[, padding])

Parametry:

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

Wartość zwracana: brak

Ustawia rzutnię tak, aby zawierała określone granice.
Uwaga : Gdy mapa jest ustawiona na display: none, fitBoundsfunkcja odczytuje rozmiar mapy jako 0x0i dlatego nic nie robi. Aby zmienić rzutnię, gdy mapa jest ukryta, ustaw ją na visibility: hidden, zapewniając w ten sposób rozmiar div mapy.

Adam
źródło
3
Skąd getPositionpochodzi ta metoda?
Pratheep
6
@Pratheep - jest częścią klasy google.maps.Marker; developers.google.com/maps/documentation/javascript/…
Adam
Działa jak urok! Dzięki
Joseph N.
9
Tak na marginesie dla początkujących, z tym samym pytaniem co Pratheep ... Wiesz o tym, jeśli masz doświadczenie w korzystaniu z API Maps, ale zawsze możesz przekazać LatLngLiteralzamiast instancji Markera. np bounds.extend({lat: 123, lng: 456}).
Kyle Baker,
1
Dodatkowa wskazówka dla wszystkich zainteresowanych. Możesz zdefiniować wypełnienie za pomocą, fitBounds(bounds, int)co pozwoli ci mieć trochę odstępu między znacznikami a krawędziami mapy (lub mniej miejsca, jeśli potrzebujesz). Zobacz dokumentację
MickelsonMichael
178

Aby rozszerzyć podaną odpowiedź o kilka przydatnych sztuczek:

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

AKTUALIZACJA:
Dalsze badania w tym temacie pokazują, że fitBounds () jest funkcją asynchroniczną i najlepiej wywołać manipulację Zoom za pomocą detektora przed wywołaniem Fit Bounds.
Dzięki @Tim, @ xr280xr, więcej przykładów na ten temat: 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);
d.raev
źródło
4
Dobre dodatki. Dzięki!
paneer_tikka
1
Miałem niezdefiniowane zwrócenie przez .getZoom (). Ta odpowiedź pomogła mi go rozwiązać, używając przycisku addListenerOnceon zoom_changeddo ustawienia powiększenia po zainicjowaniu jego wartości.
xr280xr
1
Dzięki @ d.raev, ale ustawienie maksymalnego powiększenia, gdy granice są już ustawione, nie działa. Musisz tylko ustawić opcję „maxZoom” podczas inicjowania mapy. developers.google.com/maps/documentation/javascript/…
Tim
1
W części dotyczącej manipulacji powiększeniem ( UPDATE ) miksujesz kilka zmiennych i zakresów. Używać yourMap, mapi this. Może dobrym pomysłem jest uczynienie go bardziej spójnym.
Gustavo Straube
11

Rozmiar tablicy musi być większy od zera. Ο w przeciwnym razie będziesz mieć nieoczekiwane wyniki.

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);
    }
}
Fotis. Tsilfoglou
źródło
8

Jest to MarkerClusterernarzędzie po stronie klienta dostępne dla Google Map, jak określono tutaj w artykułach dla programistów Map Google , oto krótkie informacje na temat jego użycia:

Istnieje wiele podejść do robienia tego, o co prosiłeś:

  • Klastrowanie oparte na siatce
  • Grupowanie na podstawie odległości
  • Zarządzanie znacznikami rzutni
  • Stoły Fusion
  • Klaster znaczników
  • MarkerManager

Możesz o nich przeczytać pod podanym linkiem powyżej.

Marker Clustererużywa klastrowania opartego na siatce do grupowania wszystkich znaczników, które chcą siatki. Grupowanie oparte na siatce polega na dzieleniu mapy na kwadraty o określonym rozmiarze (rozmiar zmienia się przy każdym powiększeniu), a następnie grupowaniu znaczników w każdym kwadracie siatki.

Przed grupowaniem Przed grupowaniem

Po klastrowaniu Po klastrowaniu

Mam nadzieję, że tego właśnie szukałeś i to rozwiąże Twój problem :)

iyogeshjoshi
źródło