your you returned query over_query_limit over have google for exceeded error code address javascript geocoding google-maps

javascript - you - ¿Cómo geocodifica 20 direcciones sin recibir una respuesta OVER_QUERY_LIMIT?



over_query_limit angular (6)

Acabo de probar Google Geocoder y tengo el mismo problema que tiene. Me di cuenta de que solo obtengo el estado OVER_QUERY_LIMIT una vez cada 12 solicitudes. Por lo tanto, espero 1 segundo (ese es el retraso mínimo para esperar) Disminuye la velocidad de la aplicación pero menos de 1 segundo cada solicitud

info = getInfos(getLatLng(code)); //In here I call Google API record(code, info); generated++; if(generated%interval == 0) { holdOn(delay); // Every x requests, I sleep for 1 second }

Con el método básico de holdOn:

private void holdOn(long delay) { try { Thread.sleep(delay); } catch (InterruptedException ex) { // ignore } }

Espero eso ayude

Si utilizo Google Geocoder v3, si trato de geocodificar 20 direcciones, obtengo un OVER_QUERY_LIMIT a menos que los calcule con ~ 1 segundo de diferencia, pero luego pasan 20 segundos antes de que mis marcadores estén colocados.

¿Hay alguna otra forma de hacerlo, aparte de almacenar las coordenadas por adelantado?


EDITAR:

Olvidé decir que esta solución está en js puro, lo único que necesita es un navegador que admita las promesas https://developer.mozilla.org/it/docs/Web/JavaScript/Reference/Global_Objects/Promise

Para aquellos que todavía necesitan lograrlo, he escrito mi propia solución que combina promesas con tiempos de espera.

Código:

/* class: Geolocalizer - Handles location triangulation and calculations. -- Returns various prototypes to fetch position from strings or coords or dragons or whatever. */ var Geolocalizer = function () { this.queue = []; // queue handler.. this.resolved = []; this.geolocalizer = new google.maps.Geocoder(); }; Geolocalizer.prototype = { /* @fn: Localize @scope: resolve single or multiple queued requests. @params: <array> needles @returns: <deferred> object */ Localize: function ( needles ) { var that = this; // Enqueue the needles. for ( var i = 0; i < needles.length; i++ ) { this.queue.push(needles[i]); } // return a promise and resolve it after every element have been fetched (either with success or failure), then reset the queue. return new Promise ( function (resolve, reject) { that.resolveQueueElements().then(function(resolved){ resolve(resolved); that.queue = []; that.resolved = []; }); } ); }, /* @fn: resolveQueueElements @scope: resolve queue elements. @returns: <deferred> object (promise) */ resolveQueueElements: function (callback) { var that = this; return new Promise( function(resolve, reject) { // Loop the queue and resolve each element. // Prevent QUERY_LIMIT by delaying actions by one second. (function loopWithDelay(such, queue, i){ console.log("Attempting the resolution of " +queue[i-1]); setTimeout(function(){ such.find(queue[i-1], function(res){ such.resolved.push(res); }); if (--i) { loopWithDelay(such,queue,i); } }, 1000); })(that, that.queue, that.queue.length); // Check every second if the queue has been cleared. var it = setInterval(function(){ if (that.queue.length == that.resolved.length) { resolve(that.resolved); clearInterval(it); } }, 1000); } ); }, /* @fn: find @scope: resolve an address from string @params: <string> s, <fn> Callback */ find: function (s, callback) { this.geolocalizer.geocode({ "address": s }, function(res, status){ if (status == google.maps.GeocoderStatus.OK) { var r = { originalString: s, lat: res[0].geometry.location.lat(), lng: res[0].geometry.location.lng() }; callback(r); } else { callback(undefined); console.log(status); console.log("could not locate " + s); } }); } };

Tenga en cuenta que es solo una parte de una biblioteca más grande que escribí para manejar cosas de Google Maps, por lo tanto, los comentarios pueden ser confusos.

El uso es bastante simple, el enfoque, sin embargo, es ligeramente diferente: en lugar de iterar y resolver una dirección a la vez, tendrá que pasar una serie de direcciones a la clase y manejará la búsqueda por sí mismo, devolviendo una promesa que Cuando se resuelve, devuelve una matriz que contiene toda la dirección resuelta (y no resuelta).

Ejemplo:

var myAmazingGeo = new Geolocalizer(); var locations = ["Italy","California","Dragons are thugs...","China","Georgia"]; myAmazingGeo.Localize(locations).then(function(res){ console.log(res); });

Salida de la consola:

Attempting the resolution of Georgia Attempting the resolution of China Attempting the resolution of Dragons are thugs... Attempting the resolution of California ZERO_RESULTS could not locate Dragons are thugs... Attempting the resolution of Italy

Objeto devuelto:

Toda la magia sucede aquí:

(function loopWithDelay(such, queue, i){ console.log("Attempting the resolution of " +queue[i-1]); setTimeout(function(){ such.find(queue[i-1], function(res){ such.resolved.push(res); }); if (--i) { loopWithDelay(such,queue,i); } }, 750); })(that, that.queue, that.queue.length);

Básicamente, bucles cada elemento con un retraso de 750 milisegundos entre cada uno de ellos, por lo tanto, cada 750 milisegundos se controla una dirección.

Hice algunas pruebas adicionales y descubrí que incluso a los 700 milisegundos a veces recibía el error QUERY_LIMIT, mientras que con 750 no he tenido ningún problema.

En cualquier caso, siéntase libre de editar los 750 anteriores si siente que está seguro al manejar un retraso menor.

Espero que esto ayude a alguien en el futuro cercano;)


En realidad, no tiene que esperar un segundo completo para cada solicitud. Descubrí que si espero 200 milisegundos entre cada solicitud, puedo evitar la respuesta OVER_QUERY_LIMIT y la experiencia del usuario es pasable. Con esta solución puedes cargar 20 elementos en 4 segundos.

$(items).each(function(i, item){ setTimeout(function(){ geoLocate("my address", function(myLatlng){ ... }); }, 200 * i); }


Lamentablemente, esta es una restricción del servicio de mapas de Google.

Actualmente estoy trabajando en una aplicación que utiliza la función de geocodificación, y estoy guardando cada dirección única por usuario. Genero la información de la dirección (ciudad, calle, estado, etc.) en base a la información devuelta por los mapas de Google, y luego guardo la información lat / long en la base de datos también. Esto evita que tenga que volver a codificar cosas y le da direcciones con buen formato.

Otra razón por la que desea hacer esto es porque existe un límite diario en el número de direcciones que se pueden geocodificar desde una dirección IP en particular. No desea que su aplicación falle para una persona por ese motivo.


Me enfrenta el mismo problema al tratar de geocodificar 140 direcciones.

Mi solución fue agregar usleep (100000) para cada ciclo de la próxima solicitud de geocodificación. Si el estado de la solicitud es OVER_QUERY_LIMIT, el usleep se incrementa en 50000 y la solicitud se repite, y así sucesivamente.

Y de por qué todos los datos recibidos (lat / long) se almacenan en un archivo XML para no ejecutar la solicitud cada vez que se carga la página.


No, en realidad no hay otra forma: si tiene muchas ubicaciones y desea mostrarlas en un mapa, la mejor solución es:

  • busca la latitud + longitud, usando el geocodificador, cuando se crea una ubicación
  • almacene esos en su base de datos, junto con la dirección
  • y usa los latitude + longitude almacenados cuando quieras mostrar el mapa.

Esto es, por supuesto, considerando que tiene mucha menos creación / modificación de ubicaciones que consultas de ubicaciones.


Sí, significa que tendrá que trabajar un poco más al guardar las ubicaciones, pero también significa:

  • Podrás buscar por coordenadas geográficas
    • es decir, " Quiero una lista de puntos que están cerca de donde estoy ahora "
  • Mostrar el mapa será mucho más rápido
    • Incluso con más de 20 ubicaciones en él
  • Ah, y, también (por último pero no menos importante) : esto funcionará ;-)
    • Es menos probable que llegue al límite de X llamadas de geocodificador en N segundos.
    • Y es menos probable que llegue al límite de las llamadas al geocodificador Y por día.