Centrar / Establecer zoom del mapa para cubrir todos los marcadores visibles?

352

Estoy configurando varios marcadores en mi mapa y puedo establecer estáticamente los niveles de zoom y el centro, pero lo que quiero es cubrir todos los marcadores y hacer el mayor zoom posible teniendo todos los mercados visibles

Los métodos disponibles son los siguientes

setZoom(zoom:number)

y

setCenter(latlng:LatLng)

Ni setCenteradmite entrada de ubicación múltiple o matriz de ubicación ni setZoomtiene este tipo de funcionalidad

ingrese la descripción de la imagen aquí

Trikaldarshi
fuente
debe agregarlo latlnga un boundsobjeto cada vez que agregue un marcador y configure su mapa para que se ajuste a los límites finales. Vea la respuesta aquí: stackoverflow.com/questions/1556921/…
Suvi Vignarajah

Respuestas:

678

Necesitas usar el fitBounds()método.

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

Documentación de developers.google.com/maps/documentation/javascript :

fitBounds(bounds[, padding])

Parámetros:

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

Valor de retorno: ninguno

Establece la vista para contener los límites dados.
Nota : Cuando el mapa se establece en display: none, la fitBoundsfunción lee el tamaño del mapa como 0x0y, por lo tanto, no hace nada. Para cambiar la ventana gráfica mientras el mapa está oculto, establezca el mapa en visibility: hidden, asegurando así que el div del mapa tenga un tamaño real.

Adán
fuente
3
¿De dónde vino el getPositionmétodo?
Pratheep
66
@Pratheep: es parte de la clase google.maps.Marker; developers.google.com/maps/documentation/javascript/…
Adam
¡Trabajado como un encanto! Gracias
Joseph N.
99
Solo como un aparte para los novatos, con la misma pregunta que Pratheep ... Sabes esto si tienes experiencia con la API de Maps, pero siempre puedes pasar en LatLngLiterallugar de tener una instancia de Marker. por ejemplo, bounds.extend({lat: 123, lng: 456}).
Kyle Baker, el
1
Un consejo extra para cualquier persona interesada. Puede definir un relleno utilizando el fitBounds(bounds, int)que le permitirá tener un poco de espacio entre los marcadores y los bordes del mapa (o menos espacio si lo necesita). Ver documentación
MickelsonMichael
178

Para extender la respuesta dada con algunos trucos útiles:

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

ACTUALIZACIÓN:
La investigación adicional en el tema muestra que fitBounds () es asincrónico y es mejor hacer una manipulación de Zoom con un oyente definido antes de llamar a Fit Bounds.
Gracias @Tim, @ xr280xr, más ejemplos sobre el tema: 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
fuente
44
Buenas adiciones. ¡Gracias!
paneer_tikka
1
Estaba teniendo indefinido devuelto por .getZoom (). Esta respuesta me ayudó a resolverlo usando addListenerOnceon zoom_changedpara establecer el zoom después de que se haya inicializado su valor.
xr280xr
1
Gracias @ d.raev, pero establecer el zoom máximo cuando los límites ya están establecidos no funciona. Lo que debe hacer es configurar la opción "maxZoom" al inicializar su mapa. developers.google.com/maps/documentation/javascript/…
Tim
1
En la parte sobre la manipulación del zoom ( ACTUALIZACIÓN ), está mezclando un par de variables y ámbitos. Utiliza yourMap, mapy this. Tal vez sea una buena idea hacerlo más consistente.
Gustavo Straube
11

El tamaño de la matriz debe ser mayor que cero. De lo contrario, tendrá resultados inesperados.

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
fuente
8

Existe esta MarkerClustererutilidad del lado del cliente disponible para Google Map, tal como se especifica aquí en los Artículos para desarrolladores de Google Map , a continuación se describe brevemente cuál es su uso:

Hay muchos enfoques para hacer lo que solicitó:

  • Clustering basado en cuadrícula
  • Clustering basado en distancia
  • Gestión de marcadores de ventana gráfica
  • Tablas Fusion
  • Grupo de marcadores
  • MarkerManager

Puede leer sobre ellos en el enlace proporcionado arriba.

Marker Clustererutiliza agrupación basada en cuadrícula para agrupar todos los marcadores que desean la cuadrícula. La agrupación basada en cuadrículas funciona al dividir el mapa en cuadrados de cierto tamaño (el tamaño cambia en cada zoom) y luego agrupar los marcadores en cada cuadrado de cuadrícula.

Antes de agrupar Antes de agrupar

Después de agrupar Después de agrupar

Espero que esto sea lo que estabas buscando y esto resolverá tu problema :)

iyogeshjoshi
fuente