web-dev-qa-db-fra.com

Google Maps v3: Application min. niveau de zoom lors de l'utilisation de fitBounds

Je dessine une série de marqueurs sur une carte (en utilisant la v3 de l'api des cartes).

En v2, j'avais le code suivant:

  bounds = new GLatLngBounds();

  ... loop thru and put markers on map ...
  bounds.extend(point);
  ... end looping

  map.setCenter(bounds.getCenter());
  var level = map.getBoundsZoomLevel(bounds);
  if ( level == 1 ) 
    level = 5;
  map.setZoom(level > 6 ? 6 : level);

Et cela fonctionne très bien pour s'assurer qu'il y avait toujours un niveau de détail approprié affiché sur la carte.

J'essaie de dupliquer cette fonctionnalité dans la v3, mais setZoom et fitBounds ne semblent pas coopérer:

... loop thru and put markers on the map
  var ll = new google.maps.LatLng(p.lat,p.lng);
  bounds.extend(ll);
... end loop

var zoom = map.getZoom();
map.setZoom(zoom > 6 ? 6 : zoom);
map.fitBounds(bounds);

J'ai essayé différentes permutations (déplacer les fitBounds avant le setZoom, par exemple) mais rien de ce que je fais avec setZoom ne semble affecter la carte. Suis-je en train de manquer quelque chose? Y a-t-il un moyen de faire cela?

69
chris

À cette discussion sur Google Groupes j'ai découvert que, fondamentalement, lorsque vous effectuez un fitBounds, le zoom se produit de manière asynchrone, vous devez donc capturer l'événement de changement de zoom et de limites. Le code dans le post final a fonctionné pour moi avec une petite modification ... en l'état, il vous empêche de zoomer complètement au-dessus de 15, alors utilisez l'idée du quatrième post pour avoir un indicateur défini pour ne le faire que la première fois.

// Do other stuff to set up map
var map = new google.maps.Map(mapElement, myOptions);
// This is needed to set the zoom after fitbounds, 
google.maps.event.addListener(map, 'zoom_changed', function() {
    zoomChangeBoundsListener = 
        google.maps.event.addListener(map, 'bounds_changed', function(event) {
            if (this.getZoom() > 15 && this.initialZoom == true) {
                // Change max/min zoom here
                this.setZoom(15);
                this.initialZoom = false;
            }
        google.maps.event.removeListener(zoomChangeBoundsListener);
    });
});
map.initialZoom = true;
map.fitBounds(bounds);

J'espère que ça t'as aidé,

Anthony.

126
Malks

Sans l'essayer, je dirais que vous devriez pouvoir le faire simplement en ayant fitBounds() avant d'obtenir le niveau de zoom, c'est-à-dire.

map.fitBounds(bounds);
var zoom = map.getZoom();
map.setZoom(zoom > 6 ? 6 : zoom);

Si vous avez essayé et que cela n'a pas fonctionné, vous pouvez configurer votre carte avec minZoom dans le MapOptions (référence api) comme ça:

var map = new google.maps.Map(document.getElementById("map"), { minZoom: 6 });

Cela empêcherait la carte de zoomer davantage lorsque vous utilisez fitBounds().

56
Flygenring

La solution d'Anthony est très sympa. Je n'avais besoin que de fixer le zoom pour le chargement initial de la page (en vous assurant que vous n'étiez pas trop zoomé pour commencer) et cela a fait l'affaire pour moi:

var zoomChangeBoundsListener =
    google.maps.event.addListener(map, 'bounds_changed', function(event) {
        google.maps.event.removeListener(zoomChangeBoundsListener);
        map.setZoom( Math.min( 15, map.getZoom() ) );
    });


map.fitBounds( zoomBounds );
16
Angry Dan

Vous pouvez également définir l'option maxZoom juste avant d'appeler fitBounds () et réinitialiser la valeur par la suite:

if(!bounds.isEmpty()) {
    var originalMaxZoom = map.maxZoom;
    map.setOptions({maxZoom: 18});
    map.fitBounds(bounds);
    map.setOptions({maxZoom: originalMaxZoom});
}
14
Joost

Lorsque vous appelez map.fitBounds () sur un élément - la carte peut zoomer trop étroitement. Pour résoudre ce problème, ajoutez simplement 'maxZoom' à mapOptions ...

var mapOptions = {
  maxZoom: 15
};
11
Mark Swardstrom

Dans mon cas, je voulais simplement définir le niveau de zoom à un de moins que ce que Google Maps a choisi pour moi lors de fitBounds. Le but était d'utiliser fitBounds, mais également de s'assurer qu'aucun marqueur ne se trouvait sous aucun outil de carte, etc.

Ma carte est créée tôt, puis un certain nombre d'autres composants dynamiques de la page ont la possibilité d'ajouter des marqueurs, appelant fitBounds après chaque ajout.

C'est dans le bloc initial où l'objet de carte est créé à l'origine ...

var mapZoom = null;

Ensuite, cela est ajouté à chaque bloc où un marqueur est ajouté, juste avant l'appel à map.fitBounds ...

google.maps.event.addListenerOnce(map, 'bounds_changed', function() { 
    if (mapZoom != map.getZoom()) { 
        mapZoom = (map.getZoom() - 1); 
        map.setZoom(mapZoom); 
    } 
});

Lorsque vous utilisez 'bounds_changed' sans la vérification en place, la carte effectue un zoom arrière une fois pour chaque marqueur, qu'elle en ait besoin ou non. Inversement, lorsque j'utilisais 'zoom_changed', j'avais parfois des marqueurs sous les outils de carte car le zoom ne changeait pas réellement. Maintenant, il est toujours déclenché, mais la vérification garantit qu'il ne fait qu'un zoom arrière une fois et seulement lorsque cela est nécessaire.

J'espère que cela t'aides.

7
oucil

Étant donné que Google Maps V3 est piloté par les événements, vous pouvez indiquer à l'API de réinitialiser le zoom à une valeur appropriée lorsque l'événement zoom_changed se déclenche:

var initial = true
google.maps.event.addListener(map, "zoom_changed", function() {
    if (initial == true){
       if (map.getZoom() > 11) {
         map.setZoom(11);
         initial = false;
       }
    }
}); 

J'ai utilisé initial pour que la carte ne zoome pas trop lorsque l'éventuel fitBounds est permorfed, mais pour permettre à l'utilisateur de zoomer autant qu'il le souhaite. Sans cette condition, tout événement de zoom supérieur à 11 serait possible pour l'utilisateur.

3
tuned

J'ai trouvé que ce qui suit fonctionnait très bien. C'est une variante de Ryan's réponse à https: //stackoverflow.com/questions/3334729/... . Il garantit d'afficher une zone d'au moins deux fois la valeur de offset en degrés.

const center = bounds.getCenter()
const offset = 0.01
const northEast = new google.maps.LatLng(
    center.lat() + offset,
    center.lng() + offset
)
const southWest = new google.maps.LatLng(
    center.lat() - offset,
    center.lng() - offset
)
const minBounds = new google.maps.LatLngBounds(southWest, northEast)
map.fitBounds(bounds.union(minBounds))
1
Jan K.