Google Maps API v3: Can I setZoom after fitBounds?

207,901

Solution 1

Edit: See Matt Diamond's comment below.

Got it! Try this:

map.fitBounds(bounds);
var listener = google.maps.event.addListener(map, "idle", function() { 
  if (map.getZoom() > 16) map.setZoom(16); 
  google.maps.event.removeListener(listener); 
});

Modify to your needs.

Solution 2

I solved a similar problem in one of my apps. I was a little confused by your description of the problem, but I think you have the same goal I had...

In my app I wanted to plot a one or more markers and ensure the map was showing them all. The problem was, if I relied solely on the fitBounds method, then the zoom-level would be maxed out when there was a single point - that was no good.

The solution was to use fitBounds when there was many points, and setCenter+setZoom when there was only one point.

if (pointCount > 1) {
  map.fitBounds(mapBounds);
}
else if (pointCount == 1) {
  map.setCenter(mapBounds.getCenter());
  map.setZoom(14);
}

Solution 3

I have come to this page multiple times to get the answer, and while all the existing answers were super helpful, they did not solve my problem exactly.

google.maps.event.addListenerOnce(googleMap, 'zoom_changed', function() {
    var oldZoom = googleMap.getZoom();
    googleMap.setZoom(oldZoom - 1); //Or whatever
});

Basically I found that the 'zoom_changed' event prevented the UI of the map from "skipping" which happened when i waited for the 'idle' event.

Hope this helps somebody!

Solution 4

I’ve just fixed this by setting maxZoom in advance, then removing it afterwards. For example:

map.setOptions({ maxZoom: 15 });
map.fitBounds(bounds);
map.setOptions({ maxZoom: null });

Solution 5

Please try this:

map.fitBounds(bounds);

// CHANGE ZOOM LEVEL AFTER FITBOUNDS
zoomChangeBoundsListener = google.maps.event.addListenerOnce(map, 'bounds_changed', function(event) {
  if (this.getZoom()){
    this.setZoom(15);
  }
});
setTimeout(function(){
  google.maps.event.removeListener(zoomChangeBoundsListener)
}, 2000);
Share:
207,901

Related videos on Youtube

chris
Author by

chris

Specialist in Javascript, Node.js, Vue.js, OpenText Content Server (formerly Livelink), Dart, Flutter, iOS (iPhone & iPad).

Updated on March 24, 2020

Comments

  • chris
    chris about 4 years

    I have a set of points I want to plot on an embedded Google Map (API v3). I'd like the bounds to accommodate all points unless the zoom level is too low (i.e., zoomed out too much). My approach has been like this:

    var bounds = new google.maps.LatLngBounds();
    
    // extend bounds with each point
    
    gmap.fitBounds(bounds); 
    gmap.setZoom( Math.max(6, gmap.getZoom()) );
    

    This doesn't work. The last line "gmap.setZoom()" doesn't change the zoom level of the map if called directly after fitBounds.

    Is there a way to get the zoom level of a bounds without applying it to the map? Other ideas to solve this?

    • Mawg says reinstate Monica
      Mawg says reinstate Monica about 10 years
      See stackoverflow.com/questions/4523023/using-setzoom-after-usin‌​g-fitbounds-with-goo‌​gle-maps-api-v3
  • CrazyEnigma
    CrazyEnigma almost 14 years
    Alternately, I did all the work without knowing that there is an extend() method on the LatLngBounds object. This would be much easier.
  • FR6
    FR6 over 13 years
    Your answer have solve my problem with Google Maps V3. Thanks!
  • Viktor
    Viktor over 13 years
    map.setCenter accepts only one attribute, latlng, and map has no function like getBoundsZoomLevel
  • Allov
    Allov over 13 years
    I hate to say this, but as weird as this answer looked like, it's the only thing that worked so far and I've been searching for 4-5hrs on a 3 days span. Will still be searching for a better solution though.
  • Matt Diamond
    Matt Diamond over 13 years
    Great solution, totally saved me a lot of a trouble. Just wanted to add that you could simplify it further by using the addListenerOnce method... that way, you don't have to save the listener and manually remove it, as the method will take care of that for you.
  • Geert-Jan
    Geert-Jan about 13 years
    Excellent, I had the 'skipping / auto-zooming' behavior as well. Just as a note for other readers: be sure to use "addListenerOnce" as Benjamin does above instead of "addListener", or break your head on why your browser crashes all the time ;-)
  • gapple
    gapple over 12 years
    Also note that the listener should be added before calling fitBounds() if using zoom_changed
  • daveoncode
    daveoncode over 12 years
    I was trying the same approach by myself but it did not work because I wasn't invoking setCenter() before setting the zoom... I'm still wondering why this step is needed, but anyway now it works... thanks a lot Jim!
  • sedran
    sedran over 11 years
    I thought there is a function like getBoundsZoomLevel after I see this post, and I am disappointed after I realized there is not.
  • Richard
    Richard over 11 years
    Thanks for this, seems like v4 should have a fitBounds(bounds,minZoomLevel) :)
  • Benjamin Sussman
    Benjamin Sussman over 11 years
    This has the behavior of seeing the map "skip". Instead listen for the "zoom_change" event, and set it up before calling fitBounds(). See my answer below
  • Tomas
    Tomas almost 11 years
    Benjamin, I think it is better to use bounds_changed, because zoom_changed doesn't have to be triggered in the case when fitBounds keeps the zoom level. My attempt jsfiddle.net/rHeMp/10 doesn't confirm that, but one should not rely on undefined behaviour.
  • jjwdesign
    jjwdesign over 10 years
    Thanks! google.maps.event.addListenerOnce(map, "idle", function() { } --> worked great for my maps package for SugarCRM.
  • Henrik Erlandsson
    Henrik Erlandsson about 10 years
    The listener doesn't get triggered for me. I tried this in document.ready and window.load. Any ideas? map object is OK and tried addListener also: ` var map=$("#js-main-map-canvas"); var listener = google.maps.event.addListenerOnce(map, "idle", function() { alert('hello'); });`
  • Rafael
    Rafael about 10 years
    Henrik, try $("#js-main-map-canvas")[0] or $("#js-main-map-canvas").get(0);
  • Henrik Erlandsson
    Henrik Erlandsson about 10 years
    Rafael, didn't help. I do get an object with my code, with yours I get a HTMLdivelement. This is in document.ready.
  • Kush
    Kush almost 10 years
    i think getBoundsZoomLevel() was available in Google Maps V2 API and not in V3 API
  • LGT
    LGT almost 10 years
    @Henrik Sorry for the late reply. With your code, you get an object that's not a Google Map object but a jQuery object (or whatever they are called). Try to use the pointer/reference that you get when you create the map, like so: var map = new google.maps.Map(document.getElementById("gmap-canvas"), options);
  • Micer
    Micer over 9 years
    Works for me, but I'm not using minLatSpan - I need to set zoom only when 1 marker is in the map. Therefore I'm only checking if there're more then 1 markers.
  • testpattern
    testpattern over 9 years
    This is nice because you don't have to deal with the animation jump of the accepted answer.
  • user2605793
    user2605793 over 9 years
    The best solution by far for preventing zooming in too much. Simple and intuitive. No drawing and re-drawing of map.
  • Kanak Singhal
    Kanak Singhal over 8 years
    in case map.fitBounds(bounds); didn't update the map (in my case i was merging some points and sometimes it does not change the bounds) then ideal event doesn't get triggered at that time, it gets triggered after next change_bound event may that be a manual operation. this is how i did it: stackoverflow.com/a/33050755/3666966
  • tempranova
    tempranova about 8 years
    If fitBounds isn't causing the 'bounds_changed' event to fire, then use 'center_changed' instead. It changes every time the fitBounds() function is called. See stackoverflow.com/questions/35761416/…
  • thdoan
    thdoan about 8 years
    Or you can set the maxZoom option when you first initiate the map (new google.maps.Map(...)).
  • Downhillski
    Downhillski about 8 years
    This is indeed the best walkaround so far.
  • Gus Hogg-Blake
    Gus Hogg-Blake about 7 years
    I found that this doesn't work if you reset maxZoom immediately after calling fitBounds, because the zoom happens asynchronously (so maxZoom is back to null by the time it zooms in). Waiting until "idle" to reset it would fix this though I guess.
  • BGBRUNO
    BGBRUNO about 7 years
    With event "bounds_changed" is zoom animations more quick and smooth.
  • Akshay Gundewar
    Akshay Gundewar almost 5 years
    You can use addListnerOnce to avoid the logic to remove it.
  • Kevin From
    Kevin From over 4 years
    Honestly, this fixed my problem with just pasting - thanks a lot!
  • alexkovelsky
    alexkovelsky almost 4 years
    Still relevant!!