Centrer / Définir le zoom de la carte pour couvrir tous les marqueurs visibles?

352

Je mets plusieurs marqueurs sur ma carte et je peux définir statiquement les niveaux de zoom et le centre mais ce que je veux, c'est couvrir tous les marqueurs et zoomer autant que possible en ayant tous les marchés visibles

Les méthodes disponibles sont les suivantes

setZoom(zoom:number)

et

setCenter(latlng:LatLng)

Ni setCenterprend en charge plusieurs emplacements ou entrée de tableau d'emplacement, ni setZoomce type de fonctionnalité

entrez la description de l'image ici

Trikaldarshi
la source
vous devez ajouter le latlngà un boundsobjet chaque fois que vous ajoutez un marqueur et que votre carte correspond aux limites finales. Voir la réponse ici: stackoverflow.com/questions/1556921/…
Suvi Vignarajah

Réponses:

678

Vous devez utiliser la fitBounds()méthode.

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

Documentation de developers.google.com/maps/documentation/javascript :

fitBounds(bounds[, padding])

Paramètres:

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

Valeur de retour: aucune

Définit la fenêtre pour contenir les limites données.
Remarque : Lorsque la carte est définie sur display: none, la fitBoundsfonction lit la taille de la carte sous la forme 0x0et ne fait donc rien. Pour modifier la fenêtre d'affichage alors que la carte est masquée, définissez la carte sur visibility: hidden, garantissant ainsi que la div de la carte a une taille réelle.

Adam
la source
3
D'où vient la getPositionméthode?
Pratheep
6
@Pratheep - cela fait partie de la classe google.maps.Marker; developers.google.com/maps/documentation/javascript/…
Adam
A fonctionné comme un charme! Merci
Joseph N.
9
Juste pour les débutants, avec la même question que Pratheep ... Vous le savez si vous êtes expérimenté avec l'API Maps, mais vous pouvez toujours passer un LatLngLiteralau lieu d'avoir une instance de marqueur. par exemple bounds.extend({lat: 123, lng: 456}).
Kyle Baker le
1
Un conseil supplémentaire pour toute personne intéressée. Vous pouvez définir un remplissage en utilisant fitBounds(bounds, int)ce qui vous permettra d'avoir un peu d'espace entre les marqueurs et les bords de la carte (ou moins d'espace si vous en avez besoin). Voir la documentation
MickelsonMichael
178

Pour étendre la réponse donnée avec quelques astuces utiles:

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

MISE À JOUR:
D'autres recherches dans le sujet montrent que fitBounds () est un asynchrone et il est préférable de faire une manipulation Zoom avec un écouteur défini avant d'appeler Fit Bounds.
Merci @Tim, @ xr280xr, plus d'exemples sur le sujet: 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
la source
4
Bons ajouts. Merci!
paneer_tikka
1
J'avais undefined retourné par .getZoom (). Cette réponse m'a aidé à le résoudre en utilisant addListenerOnceon zoom_changedpour régler le zoom une fois sa valeur initialisée.
xr280xr
1
Merci @ d.raev mais la définition du zoom maximum lorsque les limites sont déjà définies ne fonctionne pas. Ce que vous devez faire est de définir l'option "maxZoom" lors de l'initialisation de votre carte. developers.google.com/maps/documentation/javascript/...
Tim
1
Dans la partie sur la manipulation du zoom ( UPDATE ), vous mélangez quelques vars et scopes. Vous utilisez yourMap, mapet this. C'est peut-être une bonne idée de le rendre plus cohérent.
Gustavo Straube
11

La taille du tableau doit être supérieure à zéro. Sinon, vous obtiendrez des résultats inattendus.

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
la source
8

Il y a cet MarkerClustererutilitaire côté client disponible pour google map comme spécifié ici dans les articles pour développeurs Google Map , voici un bref aperçu de son utilisation:

Il existe de nombreuses approches pour faire ce que vous avez demandé:

  • Clustering basé sur une grille
  • Clustering basé sur la distance
  • Gestion des marqueurs de fenêtre
  • Tables de fusion
  • Clusterer de marqueurs
  • MarkerManager

Vous pouvez les lire sur le lien fourni ci-dessus.

Marker Clustererutilise le clustering basé sur une grille pour regrouper tous les marqueurs souhaitant la grille. Le regroupement basé sur une grille fonctionne en divisant la carte en carrés d'une certaine taille (la taille change à chaque zoom), puis en regroupant les marqueurs dans chaque carré de la grille.

Avant le clustering Avant le clustering

Après le clustering Après le clustering

J'espère que c'est ce que vous cherchiez et que cela résoudra votre problème :)

iyogeshjoshi
la source