32

I am using Google Maps API to display about 50 locations on the map. I am using client side geocoding. I am using window.setTimeout to control the number of geocode requests that the application sends per second. If I send more than 1 request per second, I am getting an OVER QUERY LIMIT response.

Question: Isn't this limit supposed to be 10 queries per second? If yes, then what could I be doing wrong? If no, then does Business API has more generous queries per second limit?

Please note that our application is not going to hit the 25,000 queries per day.

BenMorel
  • 34,448
  • 50
  • 182
  • 322
user544192
  • 695
  • 2
  • 10
  • 23

4 Answers4

32

The geocoder has quota and rate limits. From experience, you can geocode ~10 locations without hitting the query limit (the actual number probably depends on server loading). The best solution is to delay when you get OVER_QUERY_LIMIT errors, then retry. See these similar posts:

Community
  • 1
  • 1
geocodezip
  • 158,664
  • 13
  • 220
  • 245
  • 4
    Thanks geocodezip. I did try delaying it using window.setTimeout but it worked only with a delay of 1 second. Now, I changed the code so that I issue the geocode requests until I get an OVER_QUERY_LIMIT response. After that I pause for 3 secondsd and then repeat. This strategy seems to resolve 50 requests in a about 26 seconds (rather than 50 seconds). I am all ears if there is a better strategy. – user544192 Dec 24 '12 at 04:44
5

Often when you need to show so many points on the map, you'd be better off using the server-side approach, this article explains when to use each:

Geocoding Strategies: https://developers.google.com/maps/articles/geocodestrat

The client-side limit is not exactly "10 requests per second", and since it's not explained in the API docs I wouldn't rely on its behavior.

miguev
  • 4,481
  • 21
  • 41
1

This approach is not correct beacuse of Google Server Overload. For more informations see https://gis.stackexchange.com/questions/15052/how-to-avoid-google-map-geocode-limit#answer-15365


By the way, if you wish to proceed anyway, here you can find a code that let you load multiple markers ajax sourced on google maps avoiding OVER_QUERY_LIMIT error.

I've tested on my onw server and it works!:

var lost_addresses = [];
    geocode_count  = 0;
    resNumber = 0;
    map = new GMaps({
       div: '#gmap_marker',
       lat: 43.921493,
       lng: 12.337646,
    });

function loadMarkerTimeout(timeout) {
    setTimeout(loadMarker, timeout)
}

function loadMarker() { 
    map.setZoom(6);         
    $.ajax({
            url: [Insert here your URL] ,
            type:'POST',
            data: {
                "action":   "loadMarker"
            },
            success:function(result){

                /***************************
                 * Assuming your ajax call
                 * return something like: 
                 *   array(
                 *      'status' => 'success',
                 *      'results'=> $resultsArray
                 *   );
                 **************************/

                var res=JSON.parse(result);
                if(res.status == 'success') {
                    resNumber = res.results.length;
                    //Call the geoCoder function
                    getGeoCodeFor(map, res.results);
                }
            }//success
    });//ajax
};//loadMarker()

$().ready(function(e) {
  loadMarker();
});

//Geocoder function
function getGeoCodeFor(maps, addresses) {
        $.each(addresses, function(i,e){                
                GMaps.geocode({
                    address: e.address,
                    callback: function(results, status) {
                            geocode_count++;        

                            if (status == 'OK') {       

                                //if the element is alreay in the array, remove it
                                lost_addresses = jQuery.grep(lost_addresses, function(value) {
                                    return value != e;
                                });


                                latlng = results[0].geometry.location;
                                map.addMarker({
                                        lat: latlng.lat(),
                                        lng: latlng.lng(),
                                        title: 'MyNewMarker',
                                    });//addMarker
                            } else if (status == 'ZERO_RESULTS') {
                                //alert('Sorry, no results found');
                            } else if(status == 'OVER_QUERY_LIMIT') {

                                //if the element is not in the losts_addresses array, add it! 
                                if( jQuery.inArray(e,lost_addresses) == -1) {
                                    lost_addresses.push(e);
                                }

                            } 

                            if(geocode_count == addresses.length) {
                                //set counter == 0 so it wont's stop next round
                                geocode_count = 0;

                                setTimeout(function() {
                                    getGeoCodeFor(maps, lost_addresses);
                                }, 2500);
                            }
                    }//callback
                });//GeoCode
        });//each
};//getGeoCodeFor()

Example:

map = new GMaps({
  div: '#gmap_marker',
  lat: 43.921493,
  lng: 12.337646,
});

var jsonData = {  
   "status":"success",
   "results":[  
  {  
     "customerId":1,
     "address":"Via Italia 43, Milano (MI)",
     "customerName":"MyAwesomeCustomer1"
  },
  {  
     "customerId":2,
     "address":"Via Roma 10, Roma (RM)",
     "customerName":"MyAwesomeCustomer2"
  }
   ]
};
   
function loadMarkerTimeout(timeout) {
  setTimeout(loadMarker, timeout)
}

function loadMarker() { 
  map.setZoom(6);
 
  $.ajax({
    url: '/echo/html/',
    type: "POST",
    data: jsonData,
    cache: false,
    success:function(result){

      var res=JSON.parse(result);
      if(res.status == 'success') {
        resNumber = res.results.length;
        //Call the geoCoder function
        getGeoCodeFor(map, res.results);
      }
    }//success
  });//ajax
  
};//loadMarker()

$().ready(function(e) {
  loadMarker();
});

//Geocoder function
function getGeoCodeFor(maps, addresses) {
  $.each(addresses, function(i,e){    
    GMaps.geocode({
      address: e.address,
      callback: function(results, status) {
        geocode_count++;  
        
        console.log('Id: '+e.customerId+' | Status: '+status);
        
        if (status == 'OK') {  

          //if the element is alreay in the array, remove it
          lost_addresses = jQuery.grep(lost_addresses, function(value) {
            return value != e;
          });


          latlng = results[0].geometry.location;
          map.addMarker({
            lat: latlng.lat(),
            lng: latlng.lng(),
            title: e.customerName,
          });//addMarker
        } else if (status == 'ZERO_RESULTS') {
          //alert('Sorry, no results found');
        } else if(status == 'OVER_QUERY_LIMIT') {

          //if the element is not in the losts_addresses array, add it! 
          if( jQuery.inArray(e,lost_addresses) == -1) {
            lost_addresses.push(e);
          }

        } 

        if(geocode_count == addresses.length) {
          //set counter == 0 so it wont's stop next round
          geocode_count = 0;

          setTimeout(function() {
            getGeoCodeFor(maps, lost_addresses);
          }, 2500);
        }
      }//callback
    });//GeoCode
  });//each
};//getGeoCodeFor()
#gmap_marker {
  min-height:250px;
  height:100%;
  width:100%;
  position: relative; 
  overflow: hidden;
 }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="http://maps.google.com/maps/api/js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gmaps.js/0.4.24/gmaps.min.js" type="text/javascript"></script>


<div id="gmap_marker"></div> <!-- /#gmap_marker -->
Community
  • 1
  • 1
1

Instead of client-side geocoding

geocoder.geocode({
    'address': your_address
  }, function (results, status) {
     if (status == google.maps.GeocoderStatus.OK) {
       var geo_data = results[0];
       // your code ...
   } 
})

I would go to server-side geocoding API

var apikey = YOUR_API_KEY;
var query = 'https://maps.googleapis.com/maps/api/geocode/json?address=' + address + '&key=' + apikey;
$.getJSON(query, function (data) {
  if (data.status === 'OK') { 
    var geo_data = data.results[0];
  } 
})
Peter.Wang
  • 2,051
  • 1
  • 19
  • 13