23

In API v2, the map object had a handy method getBoundsZoomLevel(). I used it to get the zoom level which fits the bounds best, then manipulated this optimal zoom level somehow and finally set the desired zoom level.

I cannot find similar function in API v3. (What a continuous frustrating experience when moving from v2 to v3)

Do I really have to use map.fitBounds(), map.getZoom(), manipulate and setZoom() again? That's really stupid!

Engineer
  • 47,849
  • 12
  • 88
  • 91
Tomas
  • 57,621
  • 49
  • 238
  • 373
  • 3
    take a look at http://stackoverflow.com/questions/6048975/google-maps-v3-how-to-calculate-the-zoom-level-for-a-given-bounds – Dr.Molle Mar 24 '12 at 00:57
  • Thanks @Dr.Molle. It's a pitty you must write your own function for that, so in this case I prefered the stupid solution I presented above. But I will use your link for [another problem](http://stackoverflow.com/questions/9843732/how-to-affect-the-grace-margin-of-map-fitbounds), thanks!! – Tomas Mar 24 '12 at 07:51
  • +1 - I'm surprised you haven't received more up-votes. – Edward J Beckett Mar 24 '13 at 01:49
  • what are you missing from map.fitBounds()? so far that seems to do a pretty good job centering the map on the bounds, and going to a zoom level thats fitting for the map size and bounds size – chrismarx May 22 '13 at 04:29

1 Answers1

36

Below is a function I have implemented:

/**
* Returns the zoom level at which the given rectangular region fits in the map view. 
* The zoom level is computed for the currently selected map type. 
* @param {google.maps.Map} map
* @param {google.maps.LatLngBounds} bounds 
* @return {Number} zoom level
**/
function getZoomByBounds( map, bounds ){
  var MAX_ZOOM = map.mapTypes.get( map.getMapTypeId() ).maxZoom || 21 ;
  var MIN_ZOOM = map.mapTypes.get( map.getMapTypeId() ).minZoom || 0 ;

  var ne= map.getProjection().fromLatLngToPoint( bounds.getNorthEast() );
  var sw= map.getProjection().fromLatLngToPoint( bounds.getSouthWest() ); 

  var worldCoordWidth = Math.abs(ne.x-sw.x);
  var worldCoordHeight = Math.abs(ne.y-sw.y);

  //Fit padding in pixels 
  var FIT_PAD = 40;

  for( var zoom = MAX_ZOOM; zoom >= MIN_ZOOM; --zoom ){ 
      if( worldCoordWidth*(1<<zoom)+2*FIT_PAD < $(map.getDiv()).width() && 
          worldCoordHeight*(1<<zoom)+2*FIT_PAD < $(map.getDiv()).height() )
          return zoom;
  }
  return 0;
}
Engineer
  • 47,849
  • 12
  • 88
  • 91
  • Thank you! Your code produces the same values as the old v2 getZoomByBounds – Kirk Ouimet Jan 23 '13 at 04:34
  • One can use (map.getDiv()).style.width instead of $(map.getDiv()).width(), same as height also. – Jaykishan Dec 17 '13 at 09:22
  • 1
    @Jaykishan I think you mean .offsetWidth and .offsetHeight (the style attributes may not be set) – Mark Feb 01 '14 at 21:50
  • @Mark Yes buddy, because sometimes $(map.getDiv()).width() returns undefined so one can go with (map.getDiv()).style.width also. – Jaykishan Feb 03 '14 at 05:20
  • I wondered it wasn't working in first place, but then I figured out it needed a "projection_changed"-Event Listener. Now it works like a charm. Just mentioning it if anyone else has the same problem. – user2718671 Jan 18 '16 at 13:21
  • 1
    I have been looking for this for over 3 hours. I even wrote a checker that would check random bounds and this function works out of the 20,000 random checks I've done. Seems to always match what google says the bounded zoom will be. – ParoX Mar 06 '16 at 07:40
  • How can I give it padding in only one direction? lets say padding from bottom of map – alt255 May 09 '20 at 01:49