Hi out there,
A couple of months ago I needed to set the zoom level of a Google Map so that all markers in the map are visible. After hours of reading the API documentation, I did not find any solution on that issue, so I wrote a little Javascript function that does exactly that.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
/**
* Center map and set zoom level so that all markers are visible
* global markers array required
*/
centerMap = function() {
/* if an infoWindow is open, do not center map (return / do nothing) */
var iW = map.getInfoWindow();
if(iW.getContentContainers().length > 0 && !iW.isHidden())
return;
for(var i in markers) {
var this_lat = markers[i].getLatLng().lat() || null;
var this_lng = markers[i].getLatLng().lng() || null;
if(
(this_lat && !isNaN(this_lat)) &&
(this_lng && !isNaN(this_lng))
) {
var minLat = minLat || this_lat;
var maxLat = maxLat || this_lat;
var minLng = minLng || this_lng;
var maxLng = maxLng || this_lng;
//get min and max markers and save in variables
minLat = Math.min(minLat, this_lat);
maxLat = Math.max(maxLat, this_lat);
minLng = Math.min(minLng, this_lng);
maxLng = Math.max(maxLng, this_lng);
}
}
//avg of the coordinates
var centerLat = minLat + ((maxLat - minLat) / 2);
var centerLng = minLng + ((maxLng - minLng) / 2);
//what's the distance of our coordinates? (in kilometers)
var dist = (6371 *
Math.acos(
Math.sin(minLat / 57.2958) *
Math.sin(maxLat / 57.2958) + (
Math.cos(minLat / 57.2958) *
Math.cos(maxLat / 57.2958) *
Math.cos(maxLng / 57.2958 - minLng / 57.2958)
)
)
);
//default zoom level
var zoomLvl = 10;
//determine the zoom level out of the calculated distance
if(dist < 24576)
zoomLvl = 1;
if(dist < 12288)
zoomLvl = 2;
if(dist < 6144)
zoomLvl = 3;
if(dist < 3072)
zoomLvl = 4;
if(dist < 1536)
zoomLvl = 5;
if(dist < 768)
zoomLvl = 6;
if(dist < 384)
zoomLvl = 7;
if(dist < 192)
zoomLvl = 8;
if(dist < 96)
zoomLvl = 9;
if(dist < 48)
zoomLvl = 10;
if(dist < 24)
zoomLvl = 11;
if(dist < 11)
zoomLvl = 12;
if(dist < 4.8)
zoomLvl = 13;
if(dist < 3.2)
zoomLvl = 14;
if(dist < 1.6)
zoomLvl = 15;
if(dist < 0.8)
zoomLvl = 16;
if(dist < 0.3)
zoomLvl = 17;
//center map and set zoomLvl
var point = new GLatLng(centerLat, centerLng);
map.setCenter(point, zoomLvl);
}; |
This function has to be called after all markers have been inserted into the map.
Here I set up a quick example: http://www.adick.at/wp-content/uploads/map/
EDIT:
The above example is deprecated. It is based on a function I wrote some months ago -
now there is a better and more common way for doing this: http://econym.org.uk/gmap/example_map14.htm
Cheers
Alex
Hey,
Check this one, its is the better one i got succesfullly placed
http://econym.googlepages.com/basic14.htm
Posted by Mohan | 14. Januar 2009, 19:53Hi Mohan,
thanks for this! Actually, the time I wrote this post I did some research on that issue again and I then found these “native” Google-funtions for doing that. I simply wanted to post my own solution anyway, maybe I should mention the safer and more common way in the post!
Posted by Alex | 14. Januar 2009, 21:23Hi,
i try the Mohan method but sometimes function of map.setCenter(bounds.getCenter());
didn’t return the correct value.
Alex, don’t you consider the size google map display, because hardcode is risky.
check this out for your reference.
http://aiskahendra.blogspot.com/2009/01/set-zoom-level-of-google-map-base-on.html
Thank you all.
Posted by Aiska Hendra | 29. Januar 2009, 12:10Hi Aiska,
it’s a pity that google’s functions do not work properly.
Your formula for getting the zoom level looks very promising – does it work 100%?
Posted by Alex | 29. Januar 2009, 12:30Hi Alex,
Ahh… you’re right
i miss to divide 57.2958 in each point when i calculating distance
so the formula is not 100% work. especially in lower zoom.
so i change the formula :
var zoom = Math.floor(8 – Math.log(1.6446*dist / Math.sqrt(2 * (mapdisplay * mapdisplay))) / Math.log (2));
i hope this formula work.
Thank you for your advice.
Posted by Aiska Hendra | 29. Januar 2009, 17:33Hi Alex. Probably, the native way that you’ve found is similar with below, isn’t it?
//server side returns marker information by JSON type
function loadAllMarkers(url, target_map)
{
jQuery.ajax({
url: url,
type: “get”,
dataType: “json”,
success: function(markers) {
var bound = new GLatLngBounds();
markers.each(function(marker) {
var latlng = new GLatLng(marker.latitude, marker.longitude);
bound.extend(latlng);
target_map.addOverlay(new GMarker(latlng, {title:marker.name}));
});
target_map.setCenter(bound.getCenter());
target_map.setZoom(map.getBoundsZoomLevel(bound));
}
});
}
Posted by Jin-young | 6. Juli 2009, 06:33Yes, Jin-young, that’s the “native” way
I did it like that in some recent projects, worked very well!
Posted by Alex | 7. Juli 2009, 22:46Here is an adaptation of this code I made for API v3 :
http://grapsus.net/blog/post/Google-API-v3-fit-map-zoom-and-bounds-to-all-markers
Posted by Grapsus | 30. Juli 2010, 16:17Hi,
I am using the cluster marker to show the different plants of an organization across the world. My problem is in the database, there are some plants which have the same name, though with different IDs. So, when I click that cluster, the markers aren’t shown for that location. Could someone help me with this please? Thanks a ton.
Posted by Ashriya | 22. September 2010, 06:28