Yesterday my Project Manager asks me to embedded Google Map into the module.
It’s should be easy to do, but after I try so many times I failed to complete this task.
The main problem is I cannot set zoom level of Google Map that all markers are visible.
Then I search in Google and Google Map Documentation, and I still did not find any good solution,
So I decide to find my own solution. This is my solution
First think I do is get the minimum, maximum and center of the marker.
var minlat = [Minimum Latitude];
var maxlat = [Maximum Latitude];
var minlng = [Minimum Longitude];
var maxlng = [Maximum Longitude];
var ctrlng = [Center Longitude];
var ctrlng = [Center Longitude];
The second way is I calculate the distance of Minimum and Maximum Latitude and Longitude. After I search in Google I found formula to calculate distance in Google Map.
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)))));
Then I calculate Google Map distance for each Zoom Level by using of formula of distance.
Base on calculate of Google Map distance for each level, so I make formula to calculate zoom level. The formula is :
var zoom = Math.floor(8 - Math.log(1.6446 * dist / Math.sqrt(2 * (mapdisplay * mapdisplay))) / Math.log (2));
where :
dist = the distance of bound
mapdisplay = the square display of Google Map in pixel (I get from height or width of Google Map where is the smallest).
But I have a problem when Minimum and Maximum of Latitude is equal, and the zoom level become incorrect,
The problem is I calculate the horizontal marker, and calculate the diagonal of Google map where diagonal is more longer than horizontal or vertical, that's why zoom level is not correct.
So I decide to make all diagonal calculate. And I change the minimum and maximum of latitude and longitude. To the largest value so I can calculate the diagonal value.
var interval = 0;
If ((maxlat - minlat) > (maxlng - minlng)) {
interval = (maxlat - minlat) / 2;
minlng = ctrlng - interval;
maxlng = ctrlng + interval;
} else {
interval = (maxlng - minlng) / 2;
minlat = ctrlat - interval;
maxlat = ctrlat + interval;
}
Then I calculate again, and it’s work.
full code should be like this
var minlat = [Minimum Latitude];
var maxlat = [Maximum Latitude];
var minlng = [Minimum Longitude];
var maxlng = [Maximum Longitude];
var ctrlng = [Center Longitude];
var ctrlng = [Center Longitude];
var mapdisplay = 600;
var interval = 0;
If ((maxlat - minlat) > (maxlng - minlng)) {
interval = (maxlat - minlat) / 2;
minlng = ctrlng - interval;
maxlng = ctrlng + interval;
} else {
interval = (maxlng - minlng) / 2;
minlat = ctrlat - interval;
maxlat = ctrlat + interval;
}
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)))));
var zoom = Math.floor(8 - Math.log(1.6446 * dist / Math.sqrt(2 * (mapdisplay * mapdisplay))) / Math.log (2));
var map = new GMap2(document.getElementById("map"));
map.setCenter(new GLatLng(ctrlat, ctrlng), zoom);
Ok that’s all Thank you, and I hope this article can help you and others.
Thanks to Dusan for the formula and all Google Map Programmer for helping me to Finnish this task.
Subscribe to:
Post Comments (Atom)
Your formula for getting the zoom level looks very promising - does it work 100%?
Check out my approach too: http://www.adick.at/2008-12-30,set-zoom-level-of-a-google-map-so-that-all-markers-are-visible/
Thanks Alex you're inspire me to finish this task.
Why not trying this method
var mapUtil = {
minLat: null,
maxLat: null,
minLng: null,
maxLng: null,
calculateBorders: function(latitude, longitude) {
latitude = Number(latitude);
longitude = Number(longitude);
if(typeof(latitude) == 'number' && typeof(longitude) == 'number') {
if(mapUtil.minLat == null || mapUtil.minLat > latitude) {
mapUtil.minLat = latitude;
}
if(mapUtil.maxLat == null || mapUtil.maxLat < latitude) {
mapUtil.maxLat = latitude;
}
if(mapUtil.minLng == null || mapUtil.minLng > longitude) {
mapUtil.minLng = longitude;
}
if(mapUtil.minLax == null || mapUtil.maxLng < longitude) {
mapUtil.maxLng = longitude;
}
}
},
zoomToViewAll: function() {
var visibleBounds = mapUtil.getVisibleBounds();
if(visibleBounds) {
var boundsCentre = visibleBounds.getCenter();
var zoomLevel = mainMap.getBoundsZoomLevel(visibleBounds);
if(zoomLevel < 15 ) {
mainMap.setCenter(boundsCentre, zoomLevel);
}
else {
mainMap.setCenter(minBoundsCentre, 15);
}
}
},
getVisibleBounds: function() {
if(mapUtil.maxLng) {
var swLatLng = new GLatLng(mapUtil.minLat, mapUtil.minLng);
var neLatLng = new GLatLng(mapUtil.maxLat, mapUtil.maxLng);
var minBounds = new GLatLngBounds(swLatLng, neLatLng);
return minBounds;
}
return null;
}
}
use the
mapUtil.calculateBorders(lat, lng); for each marker
then call the mapUtil.zoomToViewAll()
the mainMap is the variable containing GMap2
Hi Tnx A lot 4 ur code.......................
horray! good solution, works for me.
i did implement it server-side only the calculation of the zoom level using:
int mapdisplay = Math.min(pixelHeight, pixelWidth);
return (int) Math.floor(8 - Math.log(1.6446 * distance*2 / Math.sqrt(2 * (mapdisplay * mapdisplay))) / Math.log(2));
distance * 2 because of radius vs diameter...
Does this work when there is only one marker and it zoom too close?
Excellent! Thanks a lot for such a nice input.
Although I have only tested this in Firefox, but I hope it will work fine in other browsers too.
@Sujai SD, thanks for your code.
I guess that I fix it =)
http://www.mixd.com.br/irineu/gmaps/index.php
@Aiska, thanks a lot... excellent post.
Could any one let me know how to calculate the
center latitude and longitude.
May be I sound like a dumb, but that would be very grateful.
Thanks.
$ctrlat=($minLat+$maxLat)/2;
$ctrlng=($minLng+$maxLng)/2;
MYRE REalty Manager
You saved my life. Thanks you!
I just needed that piece of Zoom calculation from your program.. I could not find that anywhere.. did google have that formula somewhere??
Anyways, really appreciate you sharing that with us!
Thank you very much. This is worked.
Thank you!!! it really works.
Nice solution. I had a similar problem, but I just decided to only display markers inside the bounds of my map :P Sort of avoided the problem...
I'm using Google's V3 API like this:
var bounds = new google.maps.LatLngBounds();
bounds.extend(myMarker.getPosition());
myMap.fitBounds(bounds);
However, when having only a marker in the map I find it zooms in too close. I've been looking to calculate a circular distance of X meters from the marker without having to create a Circle or any other Overlay. e.g.
bounds.extend(new google.maps.Circle({map:map, radius:100}).getBounds());
<<< that would be the quick solution, but creating an unnecessary overlay.
I've been looking a way to reckon SW tangent and NE tangent points, so I can achieve a nice zoom level.
How would you do this?
I found the answer to my problem. I anybody is interested refer to: movable-type.co.uk/scripts/latlong.html -> "Destination point given distance and bearing from start point"
Thank you!
You did a great job!
All well calculate, look: http://map.vashotdyh.com/
Sincerely, Alexander.
I can confirm this works beautifully!
Thanks!
Nice work, that's saved me a bunch of time!
Just a quick note to say that the casing is inconsistent in the javascript so doesn't work straight away. E.g minlat in top two blocks of code and minLat in bottom formulas.
Very nice, saved me a whole lot of time, THANK YOU!
It worked perfectly for me..Thank you very much Aiska...
This is an excellent solution, thank you so much for your help. Works great, I multiplied the Distance by 2 as suggested by Comment 5 above.
This code saved my day, thank you.
Saya pke plugin jQuery, jd critanya klo ngatur zoom level pke GLatLngBounds harus ngoprek plugin.
Ketemu hitungan ini memecahkan msalah saya.
Makasih buat solusinya!
Thanks for the code — it helped a lot and saved me lots of time. I ported it to PHP and now I can get Google Static Maps with an appropriate zoom level.
Thanks a lot for your code. Worked almost perfectly.
nice write up.Calculate area of any building with Google maps.