0

We have a purchased Google Map API key. In our Angular code, we are trying to use "google.maps.Geocode().geocode" that uses agm/core angular library to do a reverse geocoding for a list of latitude/longitude. In a second, we wanted to send around 20-30 requests so that we can get the valid response and display the address in our web portal. But we are getting the below error: "OVER_QUERY_LIMIT" for geocode api call.

Here is the code snippet for the same:

return Observable.create((observer: Observer<object>) => {
if (geocoder) {
       new google.maps.Geocoder().geocode({ 'location': latlng }, function (results, status) {
       console.log(status);
       if (status === 'OK') {
           console.log(results[0].formatted_address);
       }
    });
}});

We tried the same using the java script and getting the same error. I am not sure if we need to send any additional parameters to avoid this error. I appreciate if you can guide us in resolving the issue.

Thanks in Advance.

Gnan
  • 1
  • 1
  • 2
  • possible duplicate of https://stackoverflow.com/questions/14014074/google-maps-api-over-query-limit-per-second-limit – Safiyya Feb 27 '18 at 22:49

1 Answers1

1

Thanks for giving the community a chance to help you out here. Now, you could approach this problem in two different ways. I'd use both approaches as one is meant to keep you from reaching your QPS limit, and the other is to help you manage the situation when you are at "that bridge and you are ready to cross it", so-to-speak.

1) You could potentially cache all of your results as permitted by Google's Standard ToS.

Google Maps APIs Terms of Service specifies that you can temporarily cache Google Maps data, for a period of up to 30 days, to improve performance of your application. By caching web service responses, your application can avoid sending duplicate requests over short periods of time. In fact, web service responses always include the Cache-Control HTTP header, which indicates the period for which you can cache the result—for example, Cache-Control: public, max-age=86400. For efficiency, ensure your application always caches results for at least the amount of time specified in this header, but no more than the maximum time specified in the Google Maps APIs Terms of Service.

2) You could throttle your request using a timeout and/or jitter requests at random intervals between responses as described in Google Docs, and a JS Timeout with the full sample code below, provided by @Andrew Leach.

// delay between geocode requests - at the time of writing, 100 miliseconds seems to work well
var delay = 100;


  // ====== Create map objects ======
  var infowindow = new google.maps.InfoWindow();
  var latlng = new google.maps.LatLng(-34.397, 150.644);
  var mapOptions = {
    zoom: 8,
    center: latlng,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  }
  var geo = new google.maps.Geocoder(); 
  var map = new google.maps.Map(document.getElementById("map"), mapOptions);
  var bounds = new google.maps.LatLngBounds();

  // ====== Geocoding ======
  function getAddress(search, next) {
    geo.geocode({address:search}, function (results,status)
      { 
        // If that was successful
        if (status == google.maps.GeocoderStatus.OK) {
          // Lets assume that the first marker is the one we want
          var p = results[0].geometry.location;
          var lat=p.lat();
          var lng=p.lng();
          // Output the data
            var msg = 'address="' + search + '" lat=' +lat+ ' lng=' +lng+ '(delay='+delay+'ms)<br>';
            document.getElementById("messages").innerHTML += msg;
          // Create a marker
          createMarker(search,lat,lng);
        }
        // ====== Decode the error status ======
        else {
          // === if we were sending the requests to fast, try this one again and increase the delay
          if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
            nextAddress--;
            delay++;
          } else {
            var reason="Code "+status;
            var msg = 'address="' + search + '" error=' +reason+ '(delay='+delay+'ms)<br>';
            document.getElementById("messages").innerHTML += msg;
          }   
        }
        next();
      }
    );
  }

       // ======= Function to create a marker
 function createMarker(add,lat,lng) {
   var contentString = add;
   var marker = new google.maps.Marker({
     position: new google.maps.LatLng(lat,lng),
     map: map,
     zIndex: Math.round(latlng.lat()*-100000)<<5
   });

  google.maps.event.addListener(marker, 'click', function() {
     infowindow.setContent(contentString); 
     infowindow.open(map,marker);
   });

   bounds.extend(marker.position);

 }

  // ======= An array of locations that we want to Geocode ========
  var addresses = [
           '251 Pantigo Road Hampton Bays NY 11946',
           'Amagensett Quiogue NY 11978',
           '789 Main Street Hampton Bays NY 11946',
           '30 Abrahams Path Hampton Bays NY 11946',
           '3 Winnebogue Ln Westhampton NY 11977',
           '44 White Oak Lane Montauk NY 11954',
           '107 stoney hill road Bridgehampton NY 11932',
           '250 Pantigo Rd Hampton Bays NY 11946',
           '250 Pantigo Rd Hampton Bays NY 11946',
           '44 Woodruff Lane Wainscott NY 11975',
           'Address East Hampton NY 11937',
           'Address Amagansett NY 11930',
           'Address Remsenburg NY 11960 ',
           'Address Westhampton NY 11977',
           'prop address Westhampton Dunes NY 11978',
           'prop address East Hampton NY 11937',
           'Address East Hampton NY 11937',
           'Address Southampton NY 11968',
           'Address Bridgehampton NY 11932',
           'Address Sagaponack NY 11962',
            "A totally bogus address"
  ];

  // ======= Global variable to remind us what to do next
  var nextAddress = 0;

  // ======= Function to call the next Geocode operation when the reply comes back

  function theNext() {
    if (nextAddress < addresses.length) {
      setTimeout('getAddress("'+addresses[nextAddress]+'",theNext)', delay);
      nextAddress++;
    } else {
      // We're done. Show map bounds
      map.fitBounds(bounds);
    }
  }

  // ======= Call that function for the first time =======
  theNext();
Iavor
  • 1,997
  • 16
  • 27
Omar
  • 180
  • 1
  • 15