Zoom-to-fit in Google Maps

8 Feb

I am currently extensively using the Google Maps API for a project.

Their API is great, but good documentation is often lacking. More often than not, I have to google around to find some hints.

Anyway, here’s a little tip for some simple Javascript code in Google Maps API (v2) to zoom-to-fit the map for the best fit on a series of points you use for markers.

function fitMap( map, points ) {
   var bounds = new GLatLngBounds();
   for (var i=0; i< points.length; i++) {
      bounds.extend(points[i]);
   }
   map.setZoom(map.getBoundsZoomLevel(bounds));
   map.setCenter(bounds.getCenter());
}

The code takes the map (GMap2) object to target and an array of points (GLatLng)  you want to fit the window for. It uses the undocumented method getBoundsZoomLevel().

30 Responses to “Zoom-to-fit in Google Maps”

  1. Chris 28. Mar, 2007 at 6:08 pm #

    Brilliant!!! Thanks!

  2. Dennis 18. May, 2007 at 10:47 pm #

    Thanks, works great.

  3. Archatas 16. Jan, 2008 at 5:56 am #

    Thanks. It works perfectly and is much cleaner solution than the ones I found in Google Maps API groups:

    http://groups.google.com/group/Google-Maps-API/browse_thread/thread/996f83e075e51fdf/d1d67c0e17c5a490

  4. KC 18. Jan, 2008 at 4:01 pm #

    Sweet, works like a charm.

  5. Josh 08. May, 2008 at 10:56 am #

    Very nice… thanks for posting this!!!

  6. Anonymous 08. Jun, 2008 at 10:23 pm #

    Wow this was exactly what I needed. Thanks a lot!

  7. Tyler 11. Jun, 2008 at 11:51 pm #

    Thank you!

  8. Iain Adams 26. Jun, 2008 at 12:44 pm #

    This was really helpful. If only I had found it earlier!!

  9. Uygar 06. Jul, 2008 at 6:28 pm #

    Thanks for snippet. It was very helpful.

  10. Thibaut 25. Jul, 2008 at 1:28 pm #

    Can you explain how you build your element “points”?
    Thanks a lot.
    Thibaut

  11. Thibaut 26. Jul, 2008 at 2:52 am #

    In fact, I have this code, and i don’t understand why it doesn’t work properly (zoom & setcenter)

    Thanks in advance.
    Thibaut

    <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”>
    <html xmlns=”http://www.w3.org/1999/xhtml” xmlns:v=”urn:schemas-microsoft-com:vml” xml:lang=”fr”>
    <head>
    <title>Google Maps – Géolocalisation – Marqueur déplaçable</title>
    <meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″ />
    <meta name=”verify-v1″ content=”UH7d4dS+XX/ckd+TCOfKWT565LTdpiky+0JgByndxbo=” />
    <script src=”http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=ABQIAAAAPLdH6K8_HyRf55XN_UI37xSk2wsyJAPJSxu3srC7H01KGALGNRTEUmLJO_wjNHvQL34MtTxaxJGWmw” type=”text/javascript”></script>

    <script type=’text/javascript’>
    //<![CDATA[
    var MaCarte;
    var geocoder = null;
    var LatitudeCarteClick;
    var LongitudeCarteClick;
    var point;
    var points=new Array(5);
    var indice=-1;
    var bounds=new GLatLngBounds();

    function load() {
    if (GBrowserIsCompatible()) {
    MaCarte = new GMap2(document.getElementById('EmplacementDeMacarte'));
    MaCarte.setCenter(new GLatLng(47, 3), 6);
    MaCarte.addControl(new GLargeMapControl());
    MaCarte.addControl(new GMapTypeControl());
    MaCarte.addControl(new GOverviewMapControl());
    MaCarte.addControl(new GScaleControl());
    MaCarte.enableScrollWheelZoom()
    geocoder = new GClientGeocoder();
    }else{
    alert("D&eacute;sol&eacute;, mais votre navigateur n'est pas compatible avec Google Maps");
    }
    }

    function AfficheGPS(marker){
    center = marker.getPoint();
    LatitudeCarteClick = center.lat();
    LongitudeCarteClick = center.lng();
    document.getElementById('idLatitude').innerHTML = LatitudeCarteClick;
    document.getElementById('idLongitude').innerHTML = LongitudeCarteClick;
    }

    function recentrerCarte(){
    window.setTimeout(function(){MaCarte.panTo(new GLatLng(LatitudeCarteClick, LongitudeCarteClick));}, 1000);
    }

    function createMarker(point,html) {
    var marker = new GMarker(point);
    GEvent.addListener(marker, "click", function() {
    marker.openInfoWindowHtml(html);
    });
    return marker;
    }

    function AfficherAdresse(addresse) {
    if (geocoder) {
    geocoder.getLatLng(
    addresse,
    function(point) {
    if (!point) {
    alert('Impossible de geolocaliser cette adresse' + addresse);
    } else {
    var marker = new createMarker(point, addresse);
    MaCarte.addOverlay(marker);
    MaCarte.setCenter(point, 6);
    indice=indice+1;
    points[indice]=point;
    }
    }
    );
    }

    }
    function afficherTout(){

    MaCarte.clearOverlays();
    AfficherAdresse(“Bastille, Paris”);
    AfficherAdresse(“35000 Rennes”);
    AfficherAdresse(“rue de Lausanne, Geneve”);
    AfficherAdresse(“New york city”);
    }

    function zoomcarte(){
    MaCarte.setZoom(MaCarte.getBoundsZoomLevel(bounds));
    MaCarte.setCenter(bounds.getCenter());
    }

    function fitMap(points) {
    var bounds = new GLatLngBounds();
    for (var i=0; i< points.length; i++) {
    bounds.extend(points[i]);
    }
    MaCarte.setZoom(MaCarte.getBoundsZoomLevel(bounds));
    MaCarte.setCenter(bounds.getCenter());
    }
    //]]>
    </script>
    </head>
    <body onload=”load();afficherTout();fitMap(points);” onunload=”GUnload()”>

    <center>
    <div id=”EmplacementDeMacarte” style=”width: 740px; height: 400px”></div>
    <div id=”fenetre1″></div>
    <div id=”fenetre2″></div>
    <div id=”fenetre3″></div>
    <div id=”fenetre4″></div>
    <div id=”fenetre5″></div>
    </body>
    </html>

  12. Lars 05. Aug, 2008 at 3:13 pm #

    Thanks! I was looking for something very much like this… specifically, the undocumented getBoundsZoomLevel().

  13. daniel tygel 30. Aug, 2008 at 10:27 am #

    Wonderful! Thanks a lot and greetings from Brasil!!

  14. vivek kumar 01. Nov, 2008 at 7:12 am #

    hi
    above code is not working in my project
    any one plz suggest urgent

  15. Pierre 28. Nov, 2008 at 12:49 pm #

    Thanks a lot man ! just to help those who dont know to create a point :
    var mypoint=new GLatLng(48.0000,2.0000);
    with the two parameters being the lattitude and longitude (i dont know the order)
    Anyway, very good and important post from you !

  16. Supriya 23. Dec, 2008 at 1:43 am #

    Thanks Lot!
    It works really nice.

  17. Jori 06. Feb, 2009 at 10:45 am #

    Thanks!

  18. Danish Backer 19. Mar, 2009 at 6:54 am #

    Great Work Mr. Jerome

    It worked fine for me with little change
    like
    bounds.extend(new GLatLng(lon,lat));
    where lon and lat are variables for longitude and latitude respectievely.

    Nice Work! :D

  19. Seth Thomas Rasmussen 22. Mar, 2009 at 7:00 pm #

    Awesome. Thanks a lot!

  20. meo 03. Jun, 2009 at 9:21 pm #

    nice… thanks for posting this.. very elegant…:)

  21. MAGN 12. Jun, 2009 at 1:35 am #

    Hi thanks a lot by your helps, it was very useful. Please check and updated version which create marker and update the bound.extend based on php query:

    function init()
    {
    if (GBrowserIsCompatible())
    {
    map = new GMap2(document.getElementById(“map”));
    map.addControl(new GLargeMapControl());
    map.addControl(new GHierarchicalMapTypeControl());
    map.addControl(new GOverviewMapControl());
    map.addControl(new GScaleControl());

    var bounds = new GLatLngBounds();
    var points = [];
    for(id in markers)
    {
    addMarker(markers[id].latitude, markers[id].longitude, markers[id].name, markers[id].icon);
    points[id] = new GLatLng(markers[id].latitude, markers[id].longitude);
    bounds.extend(points[id]);
    }
    map.setCenter(bounds.getCenter());
    map.setZoom(map.getBoundsZoomLevel(bounds));

  22. Aaron Newton 13. Jul, 2009 at 10:41 am #

    Good stuff.

    I find that the calculated zoom level always shows right at the edge of markers (logically), so that if you’re using icons you’ll need to use something like:

    map.setZoom(map.getBoundsZoomLevel(bounds)-1);

    Also, if you’re using an array of markerslike I was it might interest you to know that you can invoke a new GLatLng inside the bounds.extend like this:

    var bounds = new GLatLngBounds();
    for (GLoop in Markers) {
    bounds.extend(new GLatLng(Markers[GLoop]["Longitude"],Markers[GLoop]["Latitude"]));
    }
    map.setZoom(map.getBoundsZoomLevel(bounds)-1);
    map.setCenter(bounds.getCenter());

  23. Swanty 08. Sep, 2009 at 12:48 pm #

    You saved me :) Thanks..

  24. Jeremy Roberts 21. Oct, 2009 at 9:45 pm #

    Thanks man! This function really helped me out. And yeah, I agree, the documentation in the Google Maps API is very confusing.

  25. enrico 29. Oct, 2009 at 8:09 am #

    Hi, how could I integrate this feature in the Google Maps extension for MediaWiki? http://www.mediawiki.org/wiki/Extension:Google_Maps

    thank you so much

  26. mgropel 12. Nov, 2009 at 4:43 pm #

    Thanks Jerome! Very slick.

  27. David Hudson 27. Nov, 2009 at 12:52 am #

    Holy crap, you’re a genius! Thanks

  28. Airman 13. Dec, 2009 at 12:39 pm #

    Hi,

    Sorry if I’m being dumb but I would be very grateful if someone could help with getting this type of thing to work when I haven’t got LAT and LNG co-ords – i.e. I’m using geocoder to display markers based on converting supplied address details.

    Cheers.

  29. Radek 18. Feb, 2010 at 2:51 pm #

    thanks, exactly what I needed.

  30. Phillip Harrington 16. Jun, 2010 at 8:30 pm #

    I could kiss you! I won’t, but I could.

Leave a Reply