Google Maps V3 - How to calculate the zoom level for a given bounds
google-maps, google-maps-api-3, javascript
Solution
A similar question has been asked on the Google group: http://groups.google.com/group/google-maps-js-api-v3/browse_thread/thread/e6448fc197c3c892
The zoom levels are discrete, with the scale doubling in each step. So in general you cannot fit the bounds you want exactly (unless you are very lucky with the particular map size).
Another issue is the ratio between side lengths e.g. you cannot fit the bounds exactly to a thin rectangle inside a square map.
There's no easy answer for how to fit exact bounds, because even if you are willing to change the size of the map div, you have to choose which size and corresponding zoom level you change to (roughly speaking, do you make it larger or smaller than it currently is?).
If you really need to calculate the zoom, rather than store it, this should do the trick:
The Mercator projection warps latitude, but any difference in longitude always represents the same fraction of the width of the map (the angle difference in degrees / 360). At zoom zero, the whole world map is 256x256 pixels, and zooming each level doubles both width and height. So after a little algebra we can calculate the zoom as follows, provided we know the map's width in pixels. Note that because longitude wraps around, we have to make sure the angle is positive.
var GLOBE_WIDTH = 256; // a constant in Google's map projection
var west = sw.lng();
var east = ne.lng();
var angle = east - west;
if (angle < 0) {
angle += 360;
}
var zoom = Math.round(Math.log(pixelWidth * 360 / angle / GLOBE_WIDTH) / Math.LN2);
Problem
I'm looking for a way to calculate the zoom level for a given bounds using the Google Maps V3 API, similar to `getBoundsZoomLevel()` in the V2 API. Here is what I want to do: ``` // These are exact bounds previously captured from the map object var sw = new google.maps.LatLng(42.763479, -84.338918); var ne = new google.maps.LatLng(42.679488, -84.524313); var bounds = new google.maps.LatLngBounds(sw, ne); var zoom = // do some magic to calculate the zoom level // Set the map to these exact bounds map.setCenter(bounds.getCenter()); map.setZoom(zoom); // NOTE: fitBounds() will not work ``` Unfortunately, I can't use the `fitBounds()` method for my particular use case. It works well for fitting markers on the map, but it does not work well for setting exact bounds. Here is an example of why I can't use the `fitBounds()` method. ``` map.fitBounds(map.getBounds()); // not what you expect ```