6

I've created a custom map with around 150 markers. It only plots around 20 or so before it hits the geocode limit.

What can I incorporate into my code to avoid hitting the limit?

UPDATE: How can I add a time delay to each request say 0.25seconds (or whatever the lowest I can get away with)?

I've tried a few different suggestions but I can't seem to get them to work with my code so please could any examples use my code.

Rob
  • 6,304
  • 24
  • 83
  • 189
  • You might also consider this answer: http://stackoverflow.com/questions/2419219/how-do-i-geocode-20-addresses-without-receiving-a-over-query-limit-response, which suggests you fetch them all and store their lat/lng in a database (or array) so you can create the markers without the reverse lookup. – Jack B Nimble Oct 04 '11 at 17:26

2 Answers2

20

So instead of sending all the requests almost instantly in a for-loop, I thought it might be better that when a geocode returns a result, to send the next one. If the result coming back is a OVER_QUERY_LIMIT, resend the request with an increase on the delay. I haven't found the sweet spot timeout that produces the fewest OVER_QUERY_LIMIT's, but at least it will create all the markers (for valid addresses). It takes about 45 seconds or so to finish on my machine.

<!DOCTYPE html>
<html>
<head>
<link href="http://code.google.com/apis/maps/documentation/javascript/examples/default.css"
rel="stylesheet" type="text/css" />
<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
var geocoder;
var map;
var infowindow = new google.maps.InfoWindow();

var places = [];
var popup_content = [ /* all your popup_content */];
var address = [/* all of your addresses */];
var address_position = 0;

var timeout = 600;

function initialize() {
    geocoder = new google.maps.Geocoder();
    var latlng = new google.maps.LatLng(52.40, -3.61);
    var myOptions = {
      zoom: 8,
      center: latlng,
      mapTypeId: 'roadmap'
    }
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
    addMarker(address_position);
}

function addMarker(position)
{
    geocoder.geocode({'address': address[position]}, function(results, status)
    {
        if (status == google.maps.GeocoderStatus.OK) {
            places[position] = results[0].geometry.location;

            var marker = new google.maps.Marker({
                position: places[position],
                map: map
            });

            google.maps.event.addListener(marker, 'click', function() {
                if (!infowindow) {
                    infowindow = new google.maps.InfoWindow();
                }
                infowindow.setContent(popup_content[position]);
                infowindow.open(map, marker);
            });
        }
        else
        {
            if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT)
            {
                setTimeout(function() { addMarker(position); }, (timeout * 3));
            }
        }
        address_position++;
        if (address_position < address.length)
        {
            setTimeout(function() { addMarker(address_position); }, (timeout));
        }
    });
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="height: 80%; top:10px; border: 1px solid black;"></div>
</body>
</html>
Jack B Nimble
  • 5,039
  • 4
  • 40
  • 62
  • Thanks for the answer, is it possible to show that incorporated into my code? I'm not quite sure how to do it. – Rob Oct 04 '11 at 20:13
  • I used your code as the basis for my code, however I do not see your code example anymore. – Jack B Nimble Oct 21 '11 at 16:21
  • I stumbled upon this, and it's brilliantly solving my problem! However, I had a question for you Jack: Is there a reason you put the address_position increment and the call to addMarker outside the status check? It seems to me you'd want to put it inside of the "OK" block, as you'd only want to schedule it again and increment a successful address position if you've confirmed that a geocode came back. Is there a reason to put it outside of the status check altogether? I'm imagining a case in which the request is over the limit, and it seems the position would increment anyway. Am I wrong? – NateDSaint Oct 26 '11 at 20:42
  • At least in Chrome, with the increment inside the "OK" block it hangs after the second marker. I don't know why that happens, so I moved it out and it solved the problem. – Jack B Nimble Oct 26 '11 at 21:43
  • @JackBNimble is this your ultimate solution? Have you found a better timeout? – Emanuele Greco Jun 04 '12 at 16:36
  • @EmanueleGreco That is as far as I took it. I recently tried some other timeouts but it didn't seem to improve anything. – Jack B Nimble Aug 08 '12 at 00:03
1

i'm certainly no codemaster, but instead of using a timeout i just keep calling the function from within the function (resource hog i'm sure). i iterate through my counter if i'm successful, otherwise i call my function with the current counter value if unsuccessful. at this rate, i may loop 1000 times for my 37 polylines (or markers if that's what your drawing), but i believe it will finish at the earliest time possible. here's an example - i first call my plot function onclick as plot(0):

function plot(k)
{
...
if (status == google.maps.GeocoderStatus.OK)
        {
            draw(r.routes[0]);
            if(k<origArray.length) plot(k++);
        }
else plot(k)
...
}
shanerooni
  • 11
  • 1