the successful significa returned query que over_query_limit over not google for following exceeded error code javascript google-maps-api-3

javascript - successful - over_query_limit angular



OVER_QUERY_LIMIT en Google Maps API v3: ¿cómo pause/delay en JavaScript para ralentizarlo? (5)

Estoy abordando un tema que se discute BIEN en estos foros, pero ninguna de las recomendaciones parece funcionar para mí, así que estoy buscando un javascript completo que funcione cuando se guarde como un archivo html.

El problema es que sigo pulsando el error OVER_QUERY_LIMIT cuando intento geocodificar> 11 ubicaciones en un mapa de Google utilizando las API de V3 llamadas por Javascript. Entiendo que hay un límite en la velocidad a la que puede llamar al geocodificador (además del límite diario del volumen total), por lo que debo introducir una pausa entre cada resultado en el conjunto.

Cualquier ayuda muy apreciada.

Aquí está mi código:

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript"> var geocoder; var map; var wait = false; function initialize() { geocoder = new google.maps.Geocoder(); var latlng = new google.maps.LatLng(51.32, 0.5); var myOptions = { zoom: 8, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP } map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); codeAddress(''KT16 8LA'' + '', UK''); codeAddress(''LS8 2LQ'' + '', UK''); codeAddress(''NE13 8AF'' + '', UK''); codeAddress(''KT12 2BE'' + '', UK''); codeAddress(''W1W 8AN'' + '', UK''); codeAddress(''EC3N 2LS'' + '', UK''); codeAddress(''BS9 3BH'' + '', UK''); codeAddress(''KA10 6LZ'' + '', UK''); codeAddress(''EC1V 9BW'' + '', UK''); codeAddress(''WD18 8YN'' + '', UK''); codeAddress(''HA3 6DQ'' + '', UK''); codeAddress(''W1U 3PL'' + '', UK''); codeAddress(''W1T 7QL'' + '', UK''); codeAddress(''W1S 1TD'' + '', UK''); codeAddress(''SW1X 8NX'' + '', UK''); codeAddress(''LE2 8ET'' + '', UK''); codeAddress(''BA3 4BH'' + '', UK''); codeAddress(''AL3 8JP'' + '', UK''); codeAddress(''DE55 4QJ'' + '', UK''); codeAddress(''W6 0QT'' + '', UK''); codeAddress(''LA1 1PP'' + '', UK''); codeAddress(''SW16 4DH'' + '', UK''); codeAddress(''WC2N 6DF'' + '', UK''); codeAddress(''RM6 6LS'' + '', UK''); codeAddress(''S25 3QZ'' + '', UK''); codeAddress(''WC2H 7LR'' + '', UK''); codeAddress(''BH24 1DW'' + '', UK''); codeAddress(''EC2N 6AR'' + '', UK''); codeAddress(''W1U 2FA'' + '', UK''); codeAddress(''B60 3DX'' + '', UK''); } function codeAddress(vPostCode) { if (geocoder) { geocoder.geocode( { ''address'': "''" + vPostCode + "''"}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } else { alert("Geocode was not successful for the following reason: " + status); } }); } } </script> <body style="margin:0px; padding:0px;" onload="initialize()"> <div id="map_canvas" style="width:100%; height:90%"></div> </body>

EDITAR: Esto es lo que he intentado hacer para ponerlo en pausa / esperar en la sección correspondiente, pero no hace nada:

function codeAddress(vPostCode) { if (geocoder) { while (wait) { /* Just wait. */ }; geocoder.geocode( { ''address'': "''" + vPostCode + "''"}, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); /* When geocoding "fails", see if it was because of over quota error: */ } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) { wait = true; setTimeout("wait = true", 2000); //alert("OQL: " + status); } else { alert("Geocode was not successful for the following reason: " + status); } }); } }


Aquí he cargado 2200 marcadores. Lleva alrededor de 1 minuto agregar 2200 ubicaciones. https://jsfiddle.net/suchg/qm1pqunz/11/

//function to get random element from an array (function($) { $.rand = function(arg) { if ($.isArray(arg)) { return arg[$.rand(arg.length)]; } else if (typeof arg === "number") { return Math.floor(Math.random() * arg); } else { return 4; // chosen by fair dice roll } }; })(jQuery); //start code on document ready $(document).ready(function () { var map; var elevator; var myOptions = { zoom: 0, center: new google.maps.LatLng(35.392738, -100.019531), mapTypeId: google.maps.MapTypeId.ROADMAP }; map = new google.maps.Map($(''#map_canvas'')[0], myOptions); //get place from inputfile.js var placesObject = place; errorArray = []; //will fire 20 ajax request at a time and other will keep in queue var queuCounter = 0, setLimit = 20; //keep count of added markers and update at top totalAddedMarkers = 0; //make an array of geocode keys to avoid the overlimit error var geoCodKeys = [ ''AIzaSyCF82XXUtT0vzMTcEPpTXvKQPr1keMNr_4'', ''AIzaSyAYPw6oFHktAMhQqp34PptnkDEdmXwC3s0'', ''AIzaSyAwd0OLvubYtKkEWwMe4Fe0DQpauX0pzlk'', ''AIzaSyDF3F09RkYcibDuTFaINrWFBOG7ilCsVL0'', ''AIzaSyC1dyD2kzPmZPmM4-oGYnIH_0x--0hVSY8'' ]; //funciton to add marker var addMarkers = function(address, queKey){ var key = jQuery.rand(geoCodKeys); var url = ''https://maps.googleapis.com/maps/api/geocode/json?key=''+key+''&address=''+address+''&sensor=false''; var qyName = ''''; if( queKey ) { qyName = queKey; } else { qyName = ''MyQueue''+queuCounter; } $.ajaxq (qyName, { url: url, dataType: ''json'' }).done(function( data ) { var address = getParameterByName(''address'', this.url); var index = errorArray.indexOf(address); try{ var p = data.results[0].geometry.location; var latlng = new google.maps.LatLng(p.lat, p.lng); new google.maps.Marker({ position: latlng, map: map }); totalAddedMarkers ++; //update adde marker count $("#totalAddedMarker").text(totalAddedMarkers); if (index > -1) { errorArray.splice(index, 1); } }catch(e){ if(data.status = ''ZERO_RESULTS'') return false; //on error call add marker function for same address //and keep in Error ajax queue addMarkers( address, ''Errror'' ); if (index == -1) { errorArray.push( address ); } } }); //mentain ajax queue set queuCounter++; if( queuCounter == setLimit ){ queuCounter = 0; } } //function get url parameter from url string getParameterByName = function ( name,href ) { name = name.replace(/[/[]/,"///[").replace(/[/]]/,"///]"); var regexS = "[//?&]"+name+"=([^&#]*)"; var regex = new RegExp( regexS ); var results = regex.exec( href ); if( results == null ) return ""; else return decodeURIComponent(results[1].replace(//+/g, " ")); } //call add marker function for each address mention in inputfile.js for (var x = 0; x < placesObject.length; x++) { var address = placesObject[x][''City''] + '', '' + placesObject[x][''State'']; addMarkers(address); } });


El uso de "setInterval" y "clearInterval" soluciona el problema:

function drawMarkers(map, markers) { var _this = this, geocoder = new google.maps.Geocoder(), geocode_filetrs; _this.key = 0; _this.interval = setInterval(function() { _this.markerData = markers[_this.key]; geocoder.geocode({ address: _this.markerData.address }, yourCallback(_this.markerData)); _this.key++; if ( ! markers[_this.key]) { clearInterval(_this.interval); } }, 300); }


Estás utilizando setTimeout forma incorrecta. La (una de) la firma de la función es setTimeout(callback, delay) . Por lo tanto, puede especificar fácilmente qué código se debe ejecutar después de qué retraso.

var codeAddress = (function() { var index = 0; var delay = 100; function GeocodeCallback(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); new google.maps.Marker({ map: map, position: results[0].geometry.location, animation: google.maps.Animation.DROP }); console.log(results); } else alert("Geocode was not successful for the following reason: " + status); }; return function(vPostCode) { if (geocoder) setTimeout(geocoder.geocode.bind(geocoder, { ''address'': "''" + vPostCode + "''"}, GeocodeCallback), index*delay); index++; }; })();

De esta forma, cada llamada a codeAddress() dará como resultado que se llame a geocoder.geocode() 100 ms después de la llamada anterior.

También agregué la animación al marcador para que tenga un buen efecto de animación con los marcadores que se agregan al mapa uno tras otro. No estoy seguro de cuál es el límite de google actual, por lo que es posible que deba aumentar el valor de la variable de delay .

Además, si cada vez está geocodificando las mismas direcciones, en su lugar debe guardar los resultados de geocodificación en su base de datos y la próxima vez simplemente usarlos (por lo que ahorrará algo de tráfico y su aplicación será un poco más rápida)


La respuesta general a esta pregunta es:

No geocodifique ubicaciones conocidas cada vez que cargue su página. Geocodifíquelos fuera de línea y use las coordenadas resultantes para mostrar los marcadores en su página.

Los límites existen por una razón.

Si no puede geocodificar las ubicaciones fuera de línea, consulte esta página (Parte 17 geocodificación de varias direcciones) del tutorial v2 de Mike Williams, que describe un enfoque, el puerto que a la API v3.


Nada como estas dos líneas aparece en el tutorial de Mike Williams:

wait = true; setTimeout("wait = true", 2000);

Aquí hay un puerto de la Versión 3:

http://acleach.me.uk/gmaps/v3/plotaddresses.htm

El fragmento de código relevante es

// ====== 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(); } ); }