web-dev-qa-db-fra.com

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

Je mets plusieurs repères sur ma carte et je peux régler de manière statique les niveaux de zoom et le centre, mais ce que je veux, c'est couvrir tous les repères 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)

_ setCenter ne prend pas en charge plusieurs emplacements ou entrées de tableau d'emplacement, ni setZoom ne dispose de ce type de fonctionnalité.

enter image description here

326
Trikaldarshi

Vous devez utiliser la méthode fitBounds().

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

map.fitBounds(bounds);

Documentation à partir 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: Aucun

Définit la fenêtre d'affichage pour qu'elle contienne les limites données.
Remarque : Lorsque la carte est définie sur display: none, la fonction fitBounds lit la taille de la carte en tant que 0x0, et ne fait donc rien. Pour modifier la fenêtre d'affichage lorsque la carte est masquée, définissez la carte sur visibility: hidden, afin de vous assurer que la taille de la carte divisera bien.

640
Adam

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

UPDATE:
Des recherches ultérieures dans le sujet montrent que fitBounds () est asynchrone et qu'il est préférable d'effectuer la manipulation du zoom avec un auditeur défini avant d'appeler Fit Bounds.
Merci @Tim, @ xr280xr, d'autres 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);
168
d.raev

Il existe cet utilitaire côté client MarkerClusterer disponible pour Google Map, comme indiqué ici sur Articles pour les développeurs de 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 Viewport
  • Tables de fusion
  • Marqueur de cluster
  • MarkerManager

Vous pouvez en savoir plus sur le lien fourni ci-dessus.

Marker Clusterer utilise la mise en cluster par grille pour mettre en cluster tous les marqueurs souhaitant utiliser la grille. Le regroupement basé sur une grille consiste à diviser la carte en carrés d'une certaine taille (la taille change à chaque zoom), puis à regrouper les marqueurs dans chaque carré de la grille.

Avant le regroupement Before Clustering

Après le regroupement After Clustering

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

6
iyogeshjoshi

La taille du tableau doit être supérieure à zéro. Sinon, vous aurez 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);
    }
}
5
Fotis. Tsilfoglou