Question

I'm trying to figure out a nice way to limit the rate at which I send geocode requests to the Google Maps API v3 geocoder service. I know that Javascript does not have any nice wait or sleep because its execution is, for the time being, single-threaded.

Each geocoder request is sent inside of a jQuery each function. So, the general code skeleton is:

$(xml).find('foo').each(function(){
    // do stuff
    ...

    geocoder.geocode(request, function(results, status) {/* do other stuff */});

    // do more stuff
    ...
}

How can I set a fixed interval to wait in between each call to geocode? If I send each request as fast as Javascript will run, then I quickly start receiving OVER_QUERY_LIMIT responses - even if I'm only sending 20 requests. This is expected, and I'm trying to make my client play nicely with Google's service.


An alternate route I'm willing to pursue is to completely abandon Javascript for geocoding, and write it all in Java. With Java it would be really easy to sleep in between requests.

However, I couldn't find a way to use Google's geocoding service (specifically, using version 3 of the API) in Java. GeoGoogle seems to be more than a year out of date, and uses v2.

Can it be done in Java, and if so, how?

Was it helpful?

Solution

Your best bet to implement some sort of rate-limited submissions would be to use a timer object and a queue. The timer is scheduled at a fixed rate to run indefinitely (jQuery has some very nice timer implementations) and in the body of that timer, you pop something off the queue and submit it and then finish. You other code then adds things to that queue as needed.

OTHER TIPS

Google is actively developing v2 and v3 of the Maps API separately. v3 is a much slimmer version suitable for devices with limited processing power or basic mapping tasks (and doesn't need an API key to work).

In either case, if you're geocoding many things you should probably look at using Google's HTTP geocoding service (http://code.google.com/apis/maps/documentation/geocoding/index.html). This will avoid the rate limiting issue.

And fwiw: Javascript can do basic sleep/wait operations using setInterval() and setTimeout(). Just fire the request and reset the timer to do it again at the end of your callback processing.

Here is a snippet from my script, basically it tries again if it hits google.maps.GeocoderStatus.OVER_QUERY_LIMIT

function(results, status) {
    // If the limit is reached try again in a second
        if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {

            window.setTimeout(
                function() {self.resolveAddress(addr);},1000
            );
        } else if (status == google.maps.GeocoderStatus.OK) {
            // Do something clever
        } else if (status == google.maps.GeocoderStatus.ZERO_RESULTS) {
            self.reduce(addr); // Try removing something from addr
        } else {
            atira.log('Something terrible happened');
        }
    });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top