¿Evitar el límite de geocodificación de Google Maps?

32

Estoy creando un mapa de google personalizado que tiene 125 marcadores trazados a través de un cms. Al cargar el mapa recibo este mensaje:

El geocódigo no tuvo éxito por el siguiente motivo: OVER_QUERY_LIMIT

Estoy bastante seguro de que es la forma en que he geocodificado los marcadores.

¿Cómo puedo evitar estas advertencias y existe una forma más eficiente de geocodificar los resultados?

ACTUALIZACIÓN: Este es mi intento de respuesta de Casey, en este momento estoy recibiendo una página en blanco.

<script type="text/javascript"> 
(function() { 

window.onload = function() { 
 var mc;
// Creating an object literal containing the properties we want to pass to the map 
var options = { 
zoom: 10, 
center: new google.maps.LatLng(52.40, -3.61), 
mapTypeId: google.maps.MapTypeId.ROADMAP 
}; 

// Creating the map 
var map = new google.maps.Map(document.getElementById('map'), options); 

// Creating a LatLngBounds object 
var bounds = new google.maps.LatLngBounds(); 

// Creating an array that will contain the addresses 
var places = []; 

// Creating a variable that will hold the InfoWindow object 
var infowindow; 
mc = new MarkerClusterer(map);
<?php
$pages = get_pages(array('child_of' => $post->ID, 'sort_column' => 'menu_order'));
$popup_content = array();
foreach($pages as $post)
    {
    setup_postdata($post);
    $fields = get_fields(); 
    $popup_content[] = '<p>'.$fields->company_name.'</p><img src="'.$fields->company_logo.'" /><br /><br /><a href="'.get_page_link($post->ID).'">View profile</a>';
    $comma = ", ";
    $full_address = "{$fields->address_line_1}{$comma}{$fields->address_line_2}{$comma}{$fields->address_line_3}{$comma}{$fields->post_code}";
    $address[] = $full_address;
    }
wp_reset_query();
echo 'var popup_content = ' . json_encode($popup_content) . ';';
echo 'var address = ' . json_encode($address) . ';';
?>

var geocoder = new google.maps.Geocoder(); 

var markers = [];

// Adding a LatLng object for each city  
for (var i = 0; i < address.length; i++) { 
    (function(i) { 
        geocoder.geocode( {'address': address[i]}, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                places[i] = results[0].geometry.location;

                // Adding the markers 
                var marker = new google.maps.Marker({position: places[i], map: map});
                markers.push(marker);
                mc.addMarker(marker);

                // Creating the event listener. It now has access to the values of i and marker as they were during its creation
                google.maps.event.addListener(marker, 'click', function() {
                    // Check to see if we already have an InfoWindow
                    if (!infowindow) {
                        infowindow = new google.maps.InfoWindow();
                    }

                    // Setting the content of the InfoWindow
                    infowindow.setContent(popup_content[i]);

                    // Tying the InfoWindow to the marker 
                    infowindow.open(map, marker);
                });

                // Extending the bounds object with each LatLng 
                bounds.extend(places[i]); 

                // Adjusting the map to new bounding box 
                map.fitBounds(bounds) 
            } else { 
            alert("Geocode was not successful for the following reason: " + status); 
            }

        });

    })(i);

} 
var markerCluster = new MarkerClusterer(map, markers); 
} 
})
(); 
</script> 

Realmente no importa cuál sea la solución, siempre que los marcadores se carguen instantáneamente y no rompa ningún término ni condición.

Robar
fuente
No dice por qué o con qué frecuencia está haciendo estas búsquedas. ¿No estás tratando de geocodificar los mismos puntos que cada página render? Si ese es el caso, debería considerar usar la API para hacer estas búsquedas del lado del servidor una sola vez, cuando la ubicación se agrega por primera vez a la base de datos.
Peter
Si quieres probar @ consejo de Pedro, hay una herramienta sencilla aquí que codificar geográficamente los puntos en una hoja de cálculo Google. Esto le permitiría escribir el lat / long para las ciudades en el CMS, por lo que no necesitaría usar el geocodificador en tiempo de ejecución.
Stephen Lead
@Peter En realidad, eso suena como una gran idea. Estoy un poco desgarrado ya que disminuirá la usabilidad de mi cms. Si el cliente tiene que averiguar lat / long por empresa en lugar de simplemente ingresar la dirección, entonces no es muy fácil de usar. ¿Estoy entendiendo eso correctamente?
Rob
Vea mi nueva respuesta más abajo para una función php.
Peter
2
@rob FWIW Creo que Ragi tiene el enfoque correcto. La respuesta de Casey todavía requiere que geocodifique cada punto, cada vez que se dibuja el mapa, lo que no parece ser necesario para su conjunto de datos estático
Stephen Lead

Respuestas:

57

Como todos los demás, podría darte una respuesta con código, pero no creo que alguien te haya explicado que estás haciendo algo que es fundamentalmente incorrecto .

¿Por qué estás golpeando este error? ¡Porque está llamando a geocode cada vez que alguien ve su página y no está almacenando en caché sus resultados en ninguna parte de la base de datos!

La razón por la que existe ese límite es para evitar el abuso de los recursos de Google (ya sea voluntaria o involuntariamente), que es exactamente lo que está haciendo :)

Aunque el geocódigo de Google es rápido, si todos lo usaran así, eliminaría sus servidores. La razón por la que existen las Tablas de Fusion de Google es hacer mucho trabajo pesado por el lado del servidor. La geocodificación y el almacenamiento en caché de teselas se realizan en sus servidores. Si no desea usar eso, entonces debe almacenarlos en caché en su servidor.

Si aún así, 2500 solicitudes por día son muy pocas, entonces debe mirar la licencia Premier (pagada) de Google Maps que le brinda 100,000 solicitudes de geocodificación por día para algo alrededor de 10k al año (eso es mucho, con el almacenamiento en caché del servidor debe no alcanzar este límite a menos que sea un sitio enorme o esté procesando datos pesados). Sin el almacenamiento en caché del lado del servidor y el uso de su enfoque actual, ¡solo podría hacer 800 páginas vistas por día!

Una vez que se dé cuenta de que otros proveedores cobran por código geográfico , comprenderá que debe almacenar en caché los resultados en la base de datos. ¡Con este enfoque le costaría unos 10 centavos de dólar por vista de página!

Su pregunta es, ¿puede evitar el límite de aceleración que Google le da? Seguro. Simplemente haga una solicitud desde diferentes direcciones IP. Demonios, podrías enviar las llamadas a través de ips elásticos de Amazon y siempre tendrías unas nuevas 2500 llamadas asignadas. Pero, por supuesto, además de ser ilegal (efectivamente está eludiendo la restricción que le dan los términos de servicio de Google Maps), estaría haciendo un truco para cubrir la falla de diseño inherente que tiene en su sistema.

Entonces, ¿cuál es la forma correcta para ese caso de uso? Antes de llamar a la API de geocodificación de Google, envíela a su servidor y pregunte si está en su caché. Si no es así, llame al geocódigo, guárdelo en su caché y devuelva el resultado.

Existen otros enfoques, pero esto debería ayudarlo a comenzar en la dirección correcta.

Actualización: De sus comentarios a continuación, dice que está usando PHP, así que aquí hay un ejemplo de código sobre cómo hacerlo correctamente (recomendación del propio equipo de Google) https://developers.google.com/maps/articles/phpsqlsearch_v3

Ragi Yaser Burhum
fuente
¿Tienes un ejemplo que podría seguir para enviarlo al servidor, etc.?
Rob
¿Cuál es su CMS de backend? (Supongo que puedes / saber cómo cambiarlo y solo quieres un ejemplo simple que muestre cómo hacerlo en el idioma que elijas. No necesitas un ejemplo de un js del lado del cliente, ¿o sí? ¿Estás usando algún js? marco como jquery?
Ragi Yaser Burhum
Además, deberá dar más contexto sobre cómo los datos del marcador
ingresan
1
OKAY. Php entonces. Este fragmento de la documentación de Google debe incluir el código de
Ragi Yaser Burhum
1
Consulte 10.1.3 (b) para obtener detalles sobre qué tipos de almacenamiento en caché están permitidos. developers.google.com/maps/terms#section_10_12
Paul Ramsey
14

Creo que Sasa tiene razón, en ambos sentidos.

En términos de enviar todas sus direcciones a la vez, una opción es enviar las solicitudes a intervalos. En el pasado, cuando usaba JavaScript, opté por retrasar las solicitudes en 0.25 segundos (¡parece que funciona!) Segundos usando el

setTimeout( [FUNCTION CALL] , 250 )

método.

En .NET he optado por:

System.Threading.Thread.Sleep(250);

Parece funcionar.

EDITAR: Realmente no puedo probarlo, ¡pero esto debería / podría funcionar!

Ejemplo de Javascript. AddressArray contiene cadenas que son direcciones ...

for (var i = 0; i < addressArray.length; i++0 
{

setTimeout('googleGeocodingFunction(' + addressArray[i] + ')' , 250);

}

EDITAR:

for (var i = 0; i < address.length; i++) {
    function(i) {
        setTimeout(geocoder.geocode({ 'address': address[i] }, function(results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                places[i] = results[0].geometry.location;

                var marker = new google.maps.Marker({ position: places[i], map: map });
                markers.push(marker);
                mc.addMarker(marker);
                google.maps.event.addListener(marker, 'click', function() {
                    if (!infowindow) {
                        infowindow = new google.maps.InfoWindow();
                    }

                    // Setting the content of the InfoWindow
                    infowindow.setContent(popup_content[i]);

                    // Tying the InfoWindow to the marker 
                    infowindow.open(map, marker);
                });

                // Extending the bounds object with all coordinates 
                bounds.extend(places[i]);

                // Adjusting the map to new bounding box 
                map.fitBounds(bounds)
            } else {
                alert("Geocode was not successful for the following reason: " + status);
            }
        }), 250);// End of setTimeOut Function - 250 being a quarter of a second. 
    } 
}
AtraparMono
fuente
Gracias por la respuesta. ¿Cómo puedo incluir eso en mi código? Todo esto es un poco nuevo, así que necesito algo de mano. Deberías poder ver mi código fuente.
Rob
Que bit Qué idioma estás usando?
CatchingMonkey
Estoy usando JavaScript, ¿cómo podría establecer un intervalo?
Rob
Edité mi respuesta.
CatchingMonkey
También me di cuenta que quería decir setTimeout () ... Gracias Casey.
CatchingMonkey
9

Parece que está alcanzando el límite de solicitud simultánea impuesto por Google (aunque no puedo encontrar una referencia a cuál es realmente el límite). Tendrá que espaciar sus solicitudes para que no envíe 125 solicitudes de una vez. Tenga en cuenta que también hay un límite de solicitud de código geográfico de 2500 por día.

Consulte el documento de Estrategias de codificación geográfica de Google para obtener más información.

Actualización: como una solución adicional inspirada gracias a una publicación de Mapperz, podría pensar en crear una nueva tabla de Google Fusion , almacenar su dirección y cualquier información relacionada en la tabla, y geocodificar la tabla a través de su interfaz web. Existe un límite para la cantidad de solicitudes de geocodificación que realizará una tabla Fusion, sin embargo, el límite es bastante grande. Una vez que llegue al límite, deberá volver a enviar la solicitud de geocodificación, y Fusion Tables continuará donde se quedó. La ventaja de este enfoque es una gran mejora de la velocidad, ya que solo necesitará geocodificar UNA VEZ, donde con su solución actual deberá geocodificar en cada carga, alcanzando rápidamente los límites diarios.

Sasa Ivetic
fuente
Supuse que estaría llegando al límite, soy tan nuevo en esto que creo que necesito un ejemplo de código para ayudar.
Rob
Estuve buscando en Google Fusion Tables y encontré algunos problemas. 1. Tiene que geocodificar manualmente las direcciones (a través de archivo-> geocode) en la tabla, ¿se puede hacer esto automáticamente? 2. Algunos marcadores solo aparecen en ciertos niveles de zoom, mientras que otros muestran cualquiera que sea el nivel de zoom. Este es el ejemplo: mediwales.com/mapping/example. Lo que eventualmente quiero hacer es exportar mis datos de Wordpress (es decir, todas las direcciones de la compañía) a la tabla de fusión, geocodificarlas automáticamente y luego tomar todas esas direcciones geocodificadas y trazar el mapa al instante.
Rob
7

Así es como estrangulo mis solicitudes de geocodificación en javascript, las direcciones son una matriz que contiene cada dirección para geocodificar:

for (i=0;i<=addresses.length;i++) {
    setTimeout( function () {
            geocoder.geocode( { 'address': addresses[i]}, function(results, status) {

                if (status == google.maps.GeocoderStatus.OK) { 

                    //create and add marker to map based off geocode result
                    var marker = new google.maps.Marker({  
                        map: map,
                        title: results[0].formatted_address,
                        position: results[0].geometry.location
                    });

                 } //EDIT, was missing the closing bracket here
            });

    }, i * 1500);
}

Esto esencialmente agrega un segundo y medio entre cada solicitud de geocodificación.

Casey
fuente
Gracias por la respuesta. Sigo recibiendo una página en blanco cuando intento integrarme en mi código - mediwales / mapping
Rob
¿Está utilizando alguna herramienta de depuración que pueda señalar el error? Si no lo está, intente usar el complemento FireFox firebug. Puede ser bastante útil en situaciones como esta.
Casey
No soy no No estoy seguro de haber puesto el código en el lugar correcto, actualizaré mi pregunta con mi intento.
Rob
Me faltaba un corchete de cierre en mi ejemplo de código. Edité mi respuesta y la agregué, con un comentario. Sin embargo, parece que esto no fue un problema en su código de muestra. ¿Estás obteniendo una página en blanco o un mapa en blanco? Una página en blanco indicaría que hay un error de sintaxis en el código JavaScript. Un mapa en blanco (sin marcadores) indicaría que el código de geocodificación tiene un problema.
Casey
1
Hola. Tuve otra oportunidad con tu respuesta. El retraso está funcionando ahora, pero no se pueden trazar los marcadores. De mi código, estos son los bits importantes que trazan los marcadores: (función (i) {y}) (i); sin ellos no trazará, incluso sin agregar el retraso.
Rob
5

He probado la página ahora y parece estar funcionando en este momento .

Si bien creo que el enfoque del temporizador que está utilizando actualmente es correcto y, hasta donde sé, el único que funcionará sin requerir algún soporte del lado del servidor, debería sugerir los siguientes cambios (me tomé la libertad de reescribir sus funciones de geocodificación) para aprovechar localStorage .

LocalStorage es una tecnología relativamente nueva integrada en la mayoría de los navegadores que permite que la página web almacene datos en el cliente. Es algo similar a las cookies, pero es mucho más potente y no siempre se reenvía al servidor (a diferencia de las cookies).

Mi objetivo es guardar la dirección geocodificada en el cliente para que si un usuario actualiza la página no haya necesidad de invocar nuevamente las funciones del geocodificador de Google. La implementación a continuación es cruda (deberíamos agregar código para verificar los registros obsoletos y probablemente necesitemos una mejor clave de almacenamiento en caché que el índice), pero debería ser suficiente para comenzar. Espero eso ayude.

(function() { 

window.onload = function() { 
 var mc;
// Creating an object literal containing the properties we want to pass to the map 
var options = { 
zoom: 0, maxZoom: 0, 
center: new google.maps.LatLng(52.40, -3.61), 
mapTypeId: google.maps.MapTypeId.ROADMAP 
}; 

// Creating the map 
var map = new google.maps.Map(document.getElementById('map'), options); 

// Creating a LatLngBounds object 
var bounds = new google.maps.LatLngBounds(); 

// Creating an array that will contain the addresses 
var places = []; 

// Creating a variable that will hold the InfoWindow object 
var infowindow; 
mc = new MarkerClusterer(map);
var popup_content = [..redacted..];

var geocoder = new google.maps.Geocoder(); 

var markers = [];

// Adding a LatLng object for each city 
function geocodeAddress(i) {
     // check if localStorage is available (it is now available on most modern browsers)
     // http://html5tutorial.net/tutorials/working-with-html5-localstorage.html
     // NB: this *must* be improved to handle quota limits, age/freshness, etc
     if(localStorage && localStorage['address_'+i]) {
        places[i]=JSON.parse(localStorage['address_'+i]);
        addPlace(i);
     } else {
      geocoder.geocode( {'address': address[i]}, function(results, status) {
        if (status == google.maps.GeocoderStatus.OK) {
            places[i] = results[0].geometry.location;
            if(localStorage) {
               // cache result locally on the browser, this will help reducing the number of requests
               // to the google geocoder in case the user refreshes the page
               // remember: the more he will refresh, the more he's likely to hit the limit
               // (this is one case where refreshing or closing the browser does not work)
               localStorage['address_'+i]=JSON.stringify(results[0].geometry.location);
            }

            addPlace(i);
        } else { 
            console.log("Geocoding of address "+address[i]+" failed");
        }
    })
}

function addPlace(i) {
    // Adding the markers 
    var marker = new google.maps.Marker({position: places[i], map: map});
    markers.push(marker);
    mc.addMarker(marker);

    // Creating the event listener. It now has access to the values of i and marker as they were during its creation
    google.maps.event.addListener(marker, 'click', function() {
        // Check to see if we already have an InfoWindow
        if (!infowindow) {
            infowindow = new google.maps.InfoWindow();
        }

        // Setting the content of the InfoWindow
        infowindow.setContent(popup_content[i]);

        // Tying the InfoWindow to the marker 
        infowindow.open(map, marker);
    });

    // Extending the bounds object with each LatLng 
    bounds.extend(places[i]); 

    // Adjusting the map to new bounding box 
    map.fitBounds(bounds);
}

function geocode() {
    if (geoIndex < address.length) {
        geocodeAddress(geoIndex);
        ++geoIndex;
    }
    else {
        clearInterval(geoTimer);
    }
}
var geoIndex = 0;
var geoTimer = setInterval(geocode, 600);  // 200 milliseconds (to try out)

var markerCluster = new MarkerClusterer(map, markers); 
} 
})
(); 
unicoletti
fuente
Muchas gracias, solo pruebo algo más, pero lo intentaré en un minuto. Suena como una buena idea.
Rob
Solo lo probé (ahora volví a la anterior), funcionó la primera vez, cuando lo actualicé, solo mostraba una página en blanco.
Rob
intente ahora, hubo un error, también tenga en cuenta que la variable popup_content ha sido redactada por brevedad.
unicoletti
3

utilizando geocodificadores geopy, puedo geocodificar una gran cantidad de direcciones sin problemas (no estoy seguro de la configuración de los carteles, o si puede incluir una dependencia de Python en su proyecto)

Aquí está mi prueba:

from geopy import geocoders

g = geocoders.GoogleV3()  #https://geopy.readthedocs.io/en/latest/#geopy.geocoders.GoogleV3

for x in xrange(1,10000):
    print x
    a = g.geocode("AV JOAO NAVES DE AVILA " + str(x) + " UBERLANDIA MG BRASIL")
    print a

fragmento de resultado

7595 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7595 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-288, Brasil ', (-18.9388154, -48.2220562))

7596 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7596 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-680, Brasil ', (-18.938814, -48.2217423))

7597 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7597 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-288, Brasil ', (-18.9388128, -48.2220381))

7598 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7598 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-680, Brasil ', (-18.9388114, -48.2217242))

7599 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7599 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-288, Brasil ', (-18.9388102, -48.2220201))

7600 (u'Av. Jo \ xe3o Naves de \ xc1vila, 7600 - Segismundo Pereira, Uberl \ xe2ndia - Minas Gerais, 38408-680, Brasil ', (-18.9388088, -48.2217062))

Esto todavía se está ejecutando y estoy con 7k resultados.

EDITAR: Después de un tiempo, llegué al final de la calle y Google comenzó a darme los mismos puntos, pero parece que todavía hace solicitudes y me da respuestas precisas.

George Silva
fuente
Geopy no es mágico, las restricciones de uso aún se aplican.
alphabetasoup
1

Esta función php (no sé en qué idioma estás trabajando, pero puedes distinguirla, estoy seguro) usa la API de geolocalizador de Google. Dada una dirección, devolverá la dirección normalizada y latlong. HTH.

// GEOLOCATEBYADDRESS
// @arg (string)address
// @return (array) ((int)flag,(array)address,array(rawresponse))

function geolocatebyaddress($lookupaddress){

    $lookupaddress=trim("$lookupaddress New Zealand");
    $lookupaddress=urlencode($lookupaddress);

    //send off google api lookup request
    $apiurl="http://maps.google.com/maps/api/geocode/json";
    $apiurl.="?address=$lookupaddress";
    $apiurl.="&region=NZ";
    $apiurl.="&sensor=false";

    if (function_exists("curl_init")) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $apiurl);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        $json = curl_exec($ch);
        curl_close($ch);
    }
    else     $json= file_get_contents($apiurl);

    //process response
    $response= json_decode($json,true);
    $approxflag=0;
    if ($response['status']=='OK' and count($response['results'])) {

        $aa= array();
        foreach($response['results'] as $cc=>$result) {
            //set keys
            foreach(array('street_number','road','suburb','city','postcode','region','lat','long') as $t){
                $aa[$cc][$t]='';
            }
            if ($result['geometry']){
                $aa[$cc]['lat']= $result['geometry']['location']['lat'];
                $aa[$cc]['long']=$result['geometry']['location']['lng'];
         }

            if (count($result['address_components'])){
                foreach ($result['address_components'] as $acs){
                    if ($acs['types'][0]=='street_number')               $aa[$cc]['street_number']= $acs['long_name']; 
                    if ($acs['types'][0]=='route')                       $aa[$cc]['road']=      $acs['long_name']; 
                    if ($acs['types'][0]=='sublocality')                 $aa[$cc]['suburb']=   $acs['long_name']; 
                    if ($acs['types'][0]=='locality')                    $aa[$cc]['city']=    $acs['long_name']; 
                    if ($acs['types'][0]=='postal_code')                 $aa[$cc]['postcode']= $acs['long_name']; 
                    if ($acs['types'][0]=='administrative_area_level_1') $aa[$cc]['region']=   $acs['long_name']; 
                }    
            }
            //successful?
            if ($result['geometry']['location_type']=='APPROXIMATE') $approxflag++;
            if (isset($result['partial_match']))  $approxflag++;
            if (!$aa[$cc]['street_number'])         $approxflag++;
        }
        if ($approxflag) return (array(1,$aa,$response));
        else return (array(2,$aa,$response));
    }
    else return (array(0,array(),$response));
}    
Peter
fuente
Gracias por la respuesta, ¿cómo incorporaría esto a mi código?
Rob el
Lo siento, supuse que estabas codificando el sitio. Esa función se usa como parte de las secuencias de comandos del lado del servidor que, por ejemplo, toma una dirección de entrada del usuario, usa la API de geocodificador de Google para obtener las coordenadas. A continuación, puede colocar esas coordenadas en su base de datos, y cuando necesite producir un mapa, simplemente consulte las coordenadas y produzca el mapa con marcadores. De esa manera no abusará del geocodificador para cada renderizado de página como se indica. (¿rebajaste mi comentario? Estoy tratando de ayudar, y penalizarme no va a alentarme en absoluto). También olvidé mencionar que la API requiere que la uses con un gmap.
Peter
1

Acabo de ver su consulta. Puedes probar el siguiente código. En la parte de comprobación del estado del geocodificación, llame de forma recursiva a la misma función con un intervalo de tiempo para las direcciones perdidas.

function spotPosition(address) {
        geocoder.geocode({ 'address': address }, function (results, status) {
            if (status == google.maps.GeocoderStatus.OK) {
                var lat = results[0].geometry.location.lat();
                var lang = results[0].geometry.location.lng();
                setMarker(lat, lang);
            }
            else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                setTimeout(function () {
                    //Recursively calling spotPosition method for lost addresses
                    spotPosition(address);
                }, 1000);
            }
        });
    }
jagath
fuente
0

Aquí está mi solución:

dependencias: Gmaps.js, jQuery

var Maps = function($) {
   var lost_addresses = [],
       geocode_count  = 0;

   var addMarker = function() { console.log('Marker Added!') };

   return {
     getGecodeFor: function(addresses) {
        var latlng;
        lost_addresses = [];
        for(i=0;i<addresses.length;i++) {
          GMaps.geocode({
            address: addresses[i],
            callback: function(response, status) {
              if(status == google.maps.GeocoderStatus.OK) {
                addMarker();
              } else if(status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
                lost_addresses.push(addresses[i]);
              }

               geocode_count++;
               // notify listeners when the geocode is done
               if(geocode_count == addresses.length) {
                 $.event.trigger({ type: 'done:geocoder' });
               }
            }
          });
        }
     },
     processLostAddresses: function() {
       if(lost_addresses.length > 0) {
         this.getGeocodeFor(lost_addresses);
       }
     }
   };
}(jQuery);

Maps.getGeocodeFor(address);

// listen to done:geocode event and process the lost addresses after 1.5s
$(document).on('done:geocode', function() {
  setTimeout(function() {
    Maps.processLostAddresses();
  }, 1500);
});
Julio Betta
fuente
0

No puede evitar el límite de geocodificación del mapa de Google: debe obtener y almacenar LatLng información de .

Si tiene varias ciudades y no desea obtener LatLng manualmente, puede usar un tiempo de espera para llamar progresivamente a geocoder.geocode y guardar información dentro de un objeto javascript y luego usar console.log(JSON.stringify(object, null, 4));para obtener en la consola un objeto bastante impreso, así, para ejemplo

            var locationsPosition = {
                    "Johannesburg - ZA": {
                        "lat": -26.2041028,
                        "lng": 28.047305100000017
                    },
                    "Chennai - IN": {
                        "lat": 13.0826802,
                        "lng": 80.27071840000008
                    }
             }

así que ahora puedes agregar marcador usando locationsPosition["Johannesburg - ZA"].laty.lng

Andrea Bisello
fuente
-1

Parece que necesitas hacer una de dos cosas:

  1. cambie su proceso a resultados de caché si no obtiene tantos que son únicos por día; o
  2. actualizar a un servicio que le permite procesar más por día

Como la gente ha mencionado muchas veces, pero no tengo experiencia personal, parece que una licencia de Google por 100k por día es de aproximadamente $ 10k USD por año.

Si desea el mismo nivel de precisión o mejor (y no tiene que pagar ese precio), puede probar nuestro servicio. Por mucho menos que Google (casi una décima parte del costo), podría obtener un límite mucho más alto que 2500 (nuestro límite más bajo es 25k / día).

Por supuesto, usar nuestra API de geocodificación de pago no es la solución que recomendaría para ser 100% honesto, aunque sea un mal sentido comercial admitirlo. En cambio, sugeriría ir con la opción 1, optimizar su servicio en caché. A menos que necesite más de 2500 códigos geográficos ÚNICOS por día.

Descargo de responsabilidad : trabajo para Geocode Farm (el servicio que recomiendo).

Geocode.Farm Staff
fuente
¿Por qué fue rechazado? ¿No veo dónde hay algo aquí incorrecto o incorrecto?
Geocode.Farm Staff