Zoom-to-fit in Google Maps

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 thoughts on “Zoom-to-fit in Google Maps

  1. Chris

    Brilliant!!! Thanks!

  2. Dennis

    Thanks, works great.

  3. 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

    Sweet, works like a charm.

  5. Very nice… thanks for posting this!!!

  6. Anonymous

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

  7. Tyler

    Thank you!

  8. Iain Adams

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

  9. Uygar

    Thanks for snippet. It was very helpful.

  10. Thibaut

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

  11. Thibaut

    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. Thanks! I was looking for something very much like this… specifically, the undocumented getBoundsZoomLevel().

  13. daniel tygel

    Wonderful! Thanks a lot and greetings from Brasil!!

  14. vivek kumar

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

  15. Pierre

    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. Thanks Lot!
    It works really nice.

  17. Jori

    Thanks!

  18. 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. Awesome. Thanks a lot!

  20. meo

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

  21. MAGN

    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. 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

    You saved me :) Thanks..

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

  25. enrico

    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. Thanks Jerome! Very slick.

  27. Holy crap, you’re a genius! Thanks

  28. 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. thanks, exactly what I needed.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>