2010-06-07 5 views
56

Je dessine une série de marqueurs sur une carte (en utilisant la v3 des cartes api).Google Maps v3: Enforcing min. niveau de zoom lors de l'utilisation de fitBounds

Dans 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 ce beau travail pour assurer qu'il y avait toujours un niveau de détail approprié affiché sur la carte.

Je suis en train de dupliquer cette fonctionnalité dans v3, mais le 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 la setZoom, pour exemple) mais rien de ce que je fais avec setZoom ne semble affecter la carte. Est-ce que je manque quelque chose? Y a-t-il un moyen de faire cela?

Répondre

105

Je me suis trouvé à la recherche de la même chose :)

A cette discussion sur Google Groups j'ai découvert que, fondamentalement, quand vous faites un fitBounds, le zoom se de façon asynchrone, vous devez capturer le zoom et les limites événement de changement. Le code dans le post final a fonctionné pour moi avec une petite modification ... dans l'état actuel il vous arrête de zoomer plus de 15 complètement, donc utilisé l'idée du quatrième post pour avoir un drapeau réglé pour le faire seulement 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); 

espoir qui aide,

Anthony.

+0

Merci! Je me bats avec ça depuis quelques heures! Cela semble pourtant être un bug. – chris

+3

C'est une bonne méthode. Une autre méthode consiste à vérifier les limites actuelles et à étendre les limites, c'est-à-dire http://stackoverflow.com/questions/3334729/google-maps-v3-fitbounds-zoom-too-close-for-single-marker/5345708#5345708 . Bien que la réponse liée ici ne fasse qu'étendre les limites d'une fraction, vous pouvez utiliser la même méthode pour augmenter les limites d'un nombre plus grand; J'ai trouvé que l'ajout de 7 à tous les coins fait du bon travail. –

+0

Ceci est une solution cool. J'ai remarqué, cependant, que cela fonctionne bien pour moi en chrome, c'est-à-dire, et firefox sans utiliser map.initialZoom. – Andrew

43

Sans essayer, je dirais que vous devriez être en mesure de le faire tout en ayant fitBounds() avant d'obtenir le niveau de zoom, à savoir

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(api-reference) comme ceci:

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

cela garderait la carte de zoom plus loin lors de l'utilisation fitBounds().

+0

belle solution simple et élégante! – Falantar014

+0

Merci à Flygenring –

+2

La définition des valeurs minZoom et maxZoom empêche l'utilisateur de zoomer au-delà de ces valeurs, ce qui n'aide pas si vous voulez que le zoom initial soit quelque chose de raisonnable (ce que je pense OP parlait de) – Izazael

13

La solution d'Anthony est très belle. Je ne devais fixer le zoom pour la charge de la page inital (veiller à ce que vous pas trop loin 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); 
+5

Au lieu de supprimer l'écouteur, vous pouvez utiliser 'addListenerOnce', mais j'utilise cette solution. –

6

Dans mon cas, je voulais simplement Réglez le niveau de zoom sur un de moins que ce que Google Maps a choisi pour moi pendant FitBounds. Le but était d'utiliser fitBounds, mais aussi de s'assurer qu'aucun marqueur ne se trouvait sous les outils de mappage, 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.

Ceci est dans le bloc initial dans lequel l'objet carte est créé à l'origine ...

var mapZoom = null; 

Ensuite, ceci est ajouté à chaque bloc où un marqueur est ajouté, juste avant le map.fitBounds est appelé .. .

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 le contrôle en place, la carte zoomée une fois pour chaque marqueur, peu importe que ce soit nécessaire ou non. Inversement, lorsque j'utilisais 'zoom_changed', j'avais parfois des marqueurs sous les outils de mappage car le zoom ne changeait pas réellement. Maintenant, il est toujours déclenché, mais le contrôle garantit qu'il ne fait qu'un zoom arrière une fois et seulement si nécessaire.

Espérons que cela aide.

+0

Cela semble être la seule réponse qui devrait réellement utiliser 'addListener' au lieu de répéter (et en se basant sur le fait de se souvenir) de' addListenerOnce' avant chaque 'map.fitBounds()' – Flygenring

9

Lorsque vous appelez map.fitBounds() sur un élément - la carte peut zoomer de trop près. Pour corriger cela, il suffit d'ajouter « maxZoom » à mapOptions ...

var mapOptions = { 
    maxZoom: 15 
}; 
2

Depuis Google Maps V3 est event driven, vous pouvez dire à l'API pour remettre le zoom à une quantité appropriée lorsque le zoom_changed déclencheurs d'événements :

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

I utilisé initial pour rendre la carte ne zoom trop quand les éventuels fitBounds est permorfed, mais de laisser le zoom utilisateur autant qu'il/elle veut. Sans cette condition, tout événement zoom supérieur à 11 serait possible pour l'utilisateur.

11

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

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