Having trouble with fitBounds()?

2,104 views
Skip to first unread message

Adam Stone

unread,
Sep 19, 2011, 8:36:22 AM9/19/11
to google-map...@googlegroups.com
Hi all,

I am attempting to plot an array of objects on Google Maps and then update the viewing boundary. It appears as though fitBounds() is being called before the addMarker() loop is complete?

Can somebody be of assistance?

Here is a link to JSFiddle...

Thank you kindly.

Bruce Bordelon

unread,
Sep 19, 2011, 4:15:45 PM9/19/11
to google-map...@googlegroups.com
It's probably because the browser is not waiting for all of the geocode requests to complete before calling fitBounds(), i.e. this for loop
  for (index in markersaddMarker(markers[index]);
completes within a few msecs, and then the browser moves on to the fitBounds call.

You could try something like this to wait until all geocodes have completed:
// Accepts an array of gigs  

var arraySize;
var geocodedAlready 0;

function initializeMap(gigs{

    arraySize gigs.length;
    
    var markers gigs;

    // Create geocoder
    var geocoder new google.maps.Geocoder();

    // Create the map
    var map new google.maps.Map(document.getElementById("gigpress-map"){
        mapTypeIdgoogle.maps.MapTypeId.ROADMAP
    });

    // Create infowindow
    var infowindow new google.maps.InfoWindow({
        content"holding..."
    });

    // Create boundary
    var bounds new google.maps.LatLngBounds();

    // Add markers to map
    for (index in markersaddMarker(markers[index]);

    function addMarker(data{
        // Geocoder
        geocoder.geocode({
            'address'data.city
        }function(resultsstatus{
            if (status == google.maps.GeocoderStatus.OK{
                var marker new google.maps.Marker({
                    positionresults[0].geometry.location,
                    mapmap,
                    titledata.venue
                });

                // Add to boundary
                bounds.extend(results[0].geometry.location);

                // Bind click event to each marker
                google.maps.event.addListener(marker"click"function({
                    infowindow.open(mapthis);
                });

            else {
                alert("Geocode was not successful for the following reason: " +status);
            }
            geocodedAlready++;
            if (geocodedAlready >= arraySize)
                map.fitBounds(bounds);
        });
    }

    // Zoom and center the map to fit the markers
//    map.fitBounds(bounds);
}


$(document).ready(function({
    initializeMap([
        {
        date'08/11/2011',
        venue'Notes',
        city'Newtown, NSW',
        ticket'http://noteslive.net.au/'},
    {
        date'10/11/2011',
        venue'Metro Theatre',
        city'Newcastle, NSW',
        ticket'http://metrotheatre.com.au/'}
    ]);
});


--
You received this message because you are subscribed to the Google Groups "Google Maps JavaScript API v3" group.
To view this discussion on the web visit https://groups.google.com/d/msg/google-maps-js-api-v3/-/AinWs_DCCjQJ.
To post to this group, send email to google-map...@googlegroups.com.
To unsubscribe from this group, send email to google-maps-js-a...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/google-maps-js-api-v3?hl=en.



--
Bruce Bordelon | Director, Enterprise Sales Engineering | bru...@google.com | 972-200-4420

This email and the information it contains are confidential and may
be privileged. If you have received this email in error please notify
me immediately and do not copy it for any purpose, or disclose its
contents to any other person. Internet communications are not secure
and, therefore, Google does not accept legal responsibility for the
contents of this message as it has been transmitted over a public
network. If you suspect the message may have been intercepted or
amended please call me.

Adam Stone

unread,
Sep 19, 2011, 6:46:06 PM9/19/11
to google-map...@googlegroups.com
Thanks Bruce!

So what you are saying is, the loop will fire all the lines of code, but the will execute while the loop continues? I am not a software developer, so I am trying to understand the core ;)

Adam Stone

unread,
Sep 19, 2011, 9:10:06 PM9/19/11
to google-map...@googlegroups.com
Hi again,

After tracing the code over and over, I finally understand the flow completely. You moved fitBounds into the success event to give the service time to return the requested data.

Many thanks!

BruceB

unread,
Sep 20, 2011, 10:51:39 AM9/20/11
to google-map...@googlegroups.com
Exactly.  It's the way that the browser processes the Javascript.  Your for loop calls the function addMarker(), which then makes a call to the geocoder and immediately returns control back to the for loop.  Later on when the geocoder responses are received, the anonymous callback function is called, which then sets the bounds and adds the markers, etc.  By that point, map.fitBounds has already been called.

Below is your original code with some logging added in (and a new DIV in the HTML for the logs).  If you run it, you should see output similar to the following under the map:
addMarker called for Newtown, NSW
addMarker called for Newcastle, NSW
Calling fitBounds()
After fitBounds()
Successful geocode returned for Newtown, NSW
Extending bounds for Newtown, NSW
Finished extending bounds for Newtown, NSW
Successful geocode returned for Newcastle, NSW
Extending bounds for Newcastle, NSW
Finished extending bounds for Newcastle, NSW


HTML: 
<script type="text/javascript" 
src="http://maps.googleapis.com/maps/api/js?sensor=false"
</script>

<div id="gigpress-map" style="width:600px; height:400px"></div>
<div id="log"></div>

Javascript:

// Accepts an array of gigs  


function initializeMap(gigs{


    var markers gigs;

    // Create geocoder
    var geocoder new google.maps.Geocoder();

    // Create the map
    var map new google.maps.Map(document.getElementById("gigpress-map"){
        mapTypeIdgoogle.maps.MapTypeId.ROADMAP
    });

    // Create infowindow
    var infowindow new google.maps.InfoWindow({
        content"holding..."
    });

    // Create boundary
    var bounds new google.maps.LatLngBounds();

    // Add markers to map
    for (index in markersaddMarker(markers[index]);

    function addMarker(data{
        // Geocoder
        log("addMarker called for " data.city);

        geocoder.geocode({
            'address'data.city
        }function(resultsstatus{
            if (status == google.maps.GeocoderStatus.OK{
               log("Successful geocode returned for " data.city);


                var marker new google.maps.Marker({
                    positionresults[0].geometry.location,
                    mapmap,
                    titledata.venue
                });

                // Add to boundary
                log("Extending bounds for " data.city);
                bounds.extend(results[0].geometry.location);
                log("Finished extending bounds for " data.city);


                // Bind click event to each marker
                google.maps.event.addListener(marker"click"function({
                    infowindow.open(mapthis);
                });

            else {
               log("Unsuccessful geocode returned for " data.city);

            }
        });
    }

    // Zoom and center the map to fit the markers
    log("Calling fitBounds()");
    map.fitBounds(bounds);
    log("After fitBounds()");
}

function log(text{
    document.getElementById("log").innerHTML += text "<br/>";

BruceB

unread,
Sep 20, 2011, 10:59:08 AM9/20/11
to google-map...@googlegroups.com
I meant to add.... take caution with this sort of approach, because you could quickly hit the geocoder's client-side QPS limits.
As I mentioned above, the for loop calls the addMarker() function, which calls the geocoder and immediately returns control back to the for loop -- which calls addMarker and the geocoder again.  Since you have two locations in your array, you're basically calling the geocoder at a rate of 2 queries per second.  If you had several more locations in the array, you'll probably start to see over quota responses from the geocoder:  google.maps.GeocoderStatus.OVER_QUERY_LIMIT
Reply all
Reply to author
Forward
0 new messages