Vermeiden Sie das Google Maps-Geocode-Limit?

32

Ich erstelle eine benutzerdefinierte Google-Karte mit 125 Markierungen, die über ein cms gezeichnet werden. Beim Laden der Karte erhalte ich folgende Meldung:

Geocode war aus folgendem Grund nicht erfolgreich: OVER_QUERY_LIMIT

Ich bin mir ziemlich sicher, dass ich die Marker auf diese Weise geokodiert habe.

Wie kann ich diese Warnungen vermeiden und gibt es eine effizientere Möglichkeit, die Ergebnisse zu geokodieren?

UPDATE: Dies ist mein Versuch, Caseys Antwort zu geben. Ich bekomme im Moment nur eine leere Seite.

<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> 

Es spielt keine Rolle, wie die Lösung lautet, solange die Markierungen sofort geladen werden und keine allgemeinen Geschäftsbedingungen verletzt werden.

rauben
quelle
Sie sagen nicht, warum oder wie oft Sie diese Suchvorgänge durchführen. Sie versuchen nicht, auf jeder gerenderten Seite die gleichen Punkte zu geocodieren, oder? In diesem Fall sollten Sie die Verwendung der API in Betracht ziehen, um diese Suchvorgänge serverseitig nur einmal auszuführen, wenn der Speicherort zum ersten Mal zur Datenbank hinzugefügt wird.
Peter
Wenn Sie @Peters Rat versuchen möchten, gibt es hier ein einfaches Tool , mit dem Sie die Punkte in einer Google-Tabelle geokodieren können. Auf diese Weise können Sie die Lat / Long-Werte für die Städte in das CMS schreiben, sodass Sie den Geocoder zur Laufzeit nicht verwenden müssen.
Stephen Lead
@ Peter Eigentlich klingt das nach einer großartigen Idee. Ich bin ein wenig hin und her gerissen, da dies die Benutzerfreundlichkeit meines CMS beeinträchtigen wird. Wenn der Kunde die Länge pro Firma herausfinden muss, anstatt nur die Adresse einzugeben, ist dies nicht sehr benutzerfreundlich. Verstehe ich das richtig?
Rob
Siehe meine neue Antwort weiter unten für eine PHP-Funktion.
Peter
2
@rob FWIW Ich denke Ragi hat den richtigen Ansatz. Für die Antwort von Casey ist es weiterhin erforderlich, dass Sie bei jedem Zeichnen der Karte jeden Punkt geocodieren, was für Ihren statischen Datensatz anscheinend nicht erforderlich ist
Stephen Lead,

Antworten:

57

Wie alle anderen könnte ich Ihnen eine Antwort mit Code geben, aber ich glaube nicht, dass Ihnen jemand erklärt hat, dass Sie etwas tun, das grundlegend falsch ist .

Warum schlagen Sie diesen Fehler? Weil Sie jedes Mal Geocode aufrufen, wenn jemand Ihre Seite aufruft und Sie Ihre Ergebnisse nirgendwo in der Datenbank zwischenspeichern!

Die Beschränkung besteht darin, Missbrauch von Google-Ressourcen zu verhindern (ob willentlich oder unfreiwillig) - genau das tun Sie :)

Obwohl Googles Geocode schnell ist, würde er, wenn jeder ihn so benutzt, seine Server ausschalten. Der Grund, warum es Google Fusion Tables gibt, besteht darin, dass Sie einen Großteil des schweren Server-Side-Liftings für Sie durchführen müssen. Die Geokodierung und das Zwischenspeichern der Kacheln erfolgt auf ihren Servern. Wenn Sie das nicht verwenden möchten, sollten Sie sie auf Ihrem Server zwischenspeichern.

Wenn 2500 Anfragen pro Tag immer noch zu wenig sind, müssen Sie sich die (kostenpflichtige) Lizenz von Google Maps Premier ansehen, mit der Sie 100.000 Geokodierungsanfragen pro Tag für etwa 10.000 pro Jahr erhalten (das ist eine Menge - bei serverseitigem Caching sollten Sie dies tun diese Grenze nicht erreichen, es sei denn, Sie sind eine riesige Site oder führen eine umfangreiche Datenverarbeitung durch. Ohne serverseitiges Caching und unter Verwendung Ihres aktuellen Ansatzes wären Sie nur in der Lage, 800 Seitenaufrufe pro Tag durchzuführen!

Sobald Sie feststellen, dass andere Anbieter eine Gebühr pro Geocode erheben , werden Sie verstehen, dass Sie die Ergebnisse in der Datenbank zwischenspeichern sollten. Mit diesem Ansatz würden Sie ungefähr 10 US-Cent pro Seitenaufruf kosten!

Ihre Frage ist, können Sie das von Google vorgegebene Gaslimit umgehen? Sicher. Stellen Sie einfach eine Anfrage von verschiedenen IP-Adressen. Heck, Sie könnten die Anrufe durch amazon elastische IPS vertreten und würden immer neue 2500 zugeteilte Anrufe haben. Abgesehen davon, dass Sie illegal sind (Sie umgehen effektiv die Einschränkungen, die Ihnen durch die Nutzungsbedingungen von Google Maps auferlegt wurden), würden Sie natürlich auch einen Hack durchführen, um den inhärenten Konstruktionsfehler zu beheben, den Sie in Ihrem System haben.

Was ist der richtige Weg für diesen Anwendungsfall? Bevor Sie die Google Geocode-API aufrufen, senden Sie sie an Ihren Server und fragen Sie, ob sie sich in Ihrem Cache befindet. Ist dies nicht der Fall, rufen Sie den Geocode auf, speichern Sie ihn in Ihrem Cache und geben Sie das Ergebnis zurück.

Es gibt andere Ansätze, aber dies sollte Ihnen den Einstieg in die richtige Richtung erleichtern.

Update: Ihren Kommentaren zufolge wurde angegeben, dass Sie PHP verwenden. Hier finden Sie ein Codebeispiel für die korrekte Vorgehensweise (Empfehlung des Google-Teams selbst): https://developers.google.com/maps/articles/phpsqlsearch_v3

Ragi Yaser Burhum
quelle
Haben Sie ein Beispiel, wie ich es an den Server usw. senden könnte?
Rob
Was ist Ihr Backend-CMS? (Ich nehme an, Sie können / wissen, wie Sie es ändern können, und möchten nur ein einfaches Beispiel, das zeigt, wie Sie dies in der Sprache Ihrer Wahl tun. Sie benötigen kein Beispiel für ein clientseitiges js, oder? Verwenden Sie ein js? Framework wie jquery?
Ragi Yaser Burhum
Außerdem müssen Sie mehr Kontext darüber
angeben,
1
OKAY. Php dann. Dieses Bit aus der Google-Dokumentation sollte den mysql- und den php-Teil code.google.com/apis/maps/articles/phpsqlgeocode.html
Ragi Yaser Burhum
1
Siehe 10.1.3 (b) für Einzelheiten darüber, welche Arten von Caching zulässig sind. developers.google.com/maps/terms#section_10_12
Paul Ramsey
14

Ich denke, Sasa hat in beiden Punkten Recht.

Wenn Sie alle Ihre Adressen gleichzeitig senden möchten, besteht eine Möglichkeit darin, die Anforderungen in Intervallen zu senden. In der Vergangenheit habe ich mich bei der Verwendung von JavaScript dafür entschieden, Anfragen mit dem um 0,25 (scheint zu funktionieren!) Sekunden zu verzögern

setTimeout( [FUNCTION CALL] , 250 )

Methode.

In .NET habe ich mich entschieden für:

System.Threading.Thread.Sleep(250);

Scheint zu funktionieren.

EDIT: Kann es nicht wirklich testen, aber das sollte / könnte funktionieren!

Javascript Beispiel. Das addressArray enthält Zeichenfolgen, die Adressen sind ...

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

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

}

BEARBEITEN:

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. 
    } 
}
CatchingMonkey
quelle
Danke für die Antwort. Wie kann ich das in meinen Code integrieren? Dies ist alles ein bisschen neu, also brauchen Sie etwas Handhaltung. Sie sollten in der Lage sein, meinen Quellcode anzuzeigen.
Rob
Welches Stück? Welche sprache sprichst du
CatchingMonkey
Ich benutze Javascript, wie kann ich ein Intervall einstellen?
Rob
Bearbeitet meine Antwort.
CatchingMonkey
Auch realsed meinte ich setTimeout () ... Danke Casey.
CatchingMonkey
9

Es hört sich so an, als ob Sie das von Google festgelegte Limit für gleichzeitige Anfragen erreichen (obwohl ich keinen Verweis auf das tatsächliche Limit finde). Sie müssen Ihre Anforderungen so platzieren, dass nicht 125 Anforderungen gleichzeitig gesendet werden. Beachten Sie, dass es auch eine maximale Anzahl von 2500 Geocodierungen pro Tag gibt.

Wenden Sie sich an Google Geocodierungsstrategien Dokument für weitere Informationen.

Update: Als zusätzliche Lösung, die durch einen Beitrag von Mapperz inspiriert wurde, könnten Sie darüber nachdenken, eine neue Google Fusion-Tabelle zu erstellen , Ihre Adresse und alle zugehörigen Daten in der Tabelle zu speichern und die Tabelle über die Weboberfläche zu geokodieren. Es gibt eine Begrenzung für die Anzahl der Geocodierungsanforderungen, die eine Fusionstabelle stellt, die Begrenzung ist jedoch ziemlich groß. Sobald Sie das Limit erreicht haben, müssen Sie die Geocodierungsanforderung erneut senden, und Fusion Tables wird dort weitermachen, wo sie aufgehört hat. Der Vorteil dieses Ansatzes ist eine enorme Geschwindigkeitsverbesserung, da Sie nur EINMAL geokodieren müssen, wobei Sie mit Ihrer aktuellen Lösung jede Last geokodieren müssen, um schnell die täglichen Grenzen zu erreichen.

Sasa Ivetic
quelle
Ich schätze, ich würde das Limit erreichen. Ich bin so neu darin, dass ich denke, ich brauche ein Codebeispiel, um zu helfen.
Rob
Ich habe mir Google Fusion Tables angesehen und bin auf ein paar Probleme gestoßen. 1. Sie müssen Adressen manuell (über Datei-> Geocode) in der Tabelle geocodieren. Kann dies automatisch erfolgen? 2. Einige Marker werden nur in bestimmten Zoomstufen angezeigt, während andere unabhängig von der Zoomstufe angezeigt werden. Dies ist das Beispiel - mediwales.com/mapping/example. Schließlich möchte ich meine Wordpress-Daten (dh alle Unternehmensadressen) in die Fusionstabelle exportieren, diese automatisch geocodieren und dann alle geocodierten Adressen abrufen und die Karte sofort plotten.
Rob
7

So drossele ich meine Geocodierungsanforderungen in Javascript, wobei Adressen ein Array sind, das jede Adresse für die Geocodierung enthält:

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);
}

Dies fügt im Wesentlichen eineinhalb Sekunden zwischen jeder Geokodierungsanforderung hinzu.

Casey
quelle
Danke für die Antwort. Ich bekomme
Rob
Verwenden Sie Debugging-Tools, die auf den Fehler hinweisen könnten? Wenn dies nicht der Fall ist, versuchen Sie es mit dem FireFox-Plugin Firebug. In solchen Situationen kann es sehr praktisch sein.
Casey
Ich bin nicht nein Ich bin nicht sicher, ob ich den Code richtig eingegeben habe. Ich werde meine Frage bei meinem Versuch aktualisieren.
Rob
In meinem Codebeispiel fehlte eine schließende Klammer. Ich habe meine Antwort bearbeitet und mit einem Kommentar hinzugefügt. Es sieht jedoch so aus, als wäre dies kein Problem in Ihrem Beispielcode. Erhalten Sie eine leere Seite oder eine leere Karte? Eine leere Seite zeigt an, dass der Javascript-Code einen Syntaxfehler enthält. Eine leere Karte (keine Markierungen) weist darauf hin, dass der Geokodierungscode ein Problem aufweist.
Casey
1
Hallo. Ich habe Ihre Antwort noch einmal durchgesehen. Die Verzögerung funktioniert jetzt, aber die Marker können nicht geplottet werden. Aus meinem Code sind dies die wichtigen Bits, die die Marker darstellen - (Funktion (i) {und}) (i); ohne diese wird es nicht zeichnen, auch ohne die Verzögerung hinzuzufügen.
Rob
5

Ich habe die Seite nun versucht , und es scheint zu funktionieren jetzt .

Obwohl ich denke, dass der Timer-Ansatz, den Sie derzeit verwenden, korrekt ist und meines Wissens der einzige ist, der ohne serverseitige Unterstützung funktioniert, sollte ich die folgenden Änderungen vorschlagen (ich habe mir erlaubt, Ihre Geocodierungsfunktionen umzuschreiben). um localStorage zu nutzen .

LocalStorage ist eine relativ neue Technologie, die in den meisten Browsern integriert ist und es der Webseite ermöglicht, Daten auf dem Client zu speichern. Es ähnelt etwas Cookies, ist jedoch viel leistungsfähiger und wird nicht immer erneut an den Server gesendet (im Gegensatz zu Cookies).

Mein Ziel ist es, die geocodierte Adresse auf dem Client zu speichern, sodass beim Aktualisieren der Seite die Geocoder-Funktionen von Google nicht erneut aufgerufen werden müssen. Die unten stehende Implementierung ist grob (wir sollten Code hinzufügen, um nach veralteten Datensätzen zu suchen, und wahrscheinlich einen besseren Caching-Schlüssel als den Index benötigen), aber sie sollte ausreichen, um Ihnen den Einstieg zu erleichtern. Ich hoffe es hilft.

(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
quelle
Vielen Dank, versuchen Sie es gleich noch einmal. Klingt wie eine gute Idee.
Rob
Habe es gerade ausprobiert (habe jetzt wieder auf das vorherige zurückgegriffen), es hat dann das erste Mal funktioniert, als ich es aktualisiert habe, zeigte es nur eine leere Seite.
Rob
Wenn Sie es jetzt versuchen, ist ein Fehler aufgetreten. Beachten Sie auch, dass die Variable popup_content der Kürze halber überarbeitet wurde.
unicoletti
3

mit geopy geocodern kann ich eine große anzahl von adressen problemlos geocodieren

hier ist mein test:

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

Ergebnis-Snippet

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

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

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

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

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

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

Dies läuft immer noch und ich bin mit 7k Ergebnissen.

BEARBEITEN: Nach einer Weile habe ich das Ende der Straße erreicht und Google hat angefangen, mir die gleichen Punkte zu geben, aber es sieht so aus, als ob es noch Anfragen macht und mir genaue Antworten gibt.

George Silva
quelle
Geopy ist keine Zauberei, die Nutzungsbeschränkungen gelten weiterhin.
Buchstabensuppe
1

Diese PHP-Funktion (ich weiß nicht, in welcher Sprache Sie arbeiten, aber Sie können sie auseinander nehmen, im sicher) verwendet Google Geolocator API. Bei einer gegebenen Adresse wird die normalisierte Adresse und latlong zurückgegeben. 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
quelle
Danke für die Antwort, wie würde ich das in meinen Code einbauen?
Rob
Es tut mir leid, ich habe angenommen, dass Sie die Website codiert haben. Diese Funktion wird als Teil des serverseitigen Skripts verwendet, das beispielsweise eine Benutzereingabeadresse verwendet und die Koordinaten mit dem Google Geocoder-API ermittelt. Sie können diese Koordinaten dann in Ihre Datenbank einfügen. Wenn Sie eine Karte erstellen müssen, fragen Sie einfach die Koordinaten ab und erstellen Sie die Karte mit Markierungen. Auf diese Weise missbrauchen Sie den Geocoder nicht für jedes Seiten-Rendering, das als Diskussion angezeigt wird. (Haben Sie meinen Kommentar niedergeschrieben? Ich versuche zu helfen, und mich zu bestrafen, wird mich überhaupt nicht ermutigen). Auch ich habe vergessen zu erwähnen, dass die API es erfordert, dass Sie es mit einer gmap verwenden.
Peter
1

Ich habe gerade Ihre Anfrage gesehen. Sie können versuchen, folgenden Code. Rufen Sie im Teil "else" der Geocode-Statusprüfung dieselbe Funktion mit einer Zeitlücke für die verlorenen Adressen rekursiv auf.

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
quelle
0

Hier ist meine Lösung:

Abhängigkeiten: 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
quelle
0

Sie können das Google Map-Geocode-Limit nicht umgehen: Sie müssen LatLng- Informationen abrufen und speichern .

Wenn Sie mehrere Städte haben und LatLng nicht manuell beziehen möchten, können Sie mithilfe einer Zeitüberschreitung geocoder.geocode aufrufen, Informationen in einem Javascript-Objekt speichern und dann console.log(JSON.stringify(object, null, 4));in der Konsole ein hübsches gedrucktes Objekt abrufen , z Beispiel

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

Jetzt können Sie mit locationsPosition["Johannesburg - ZA"].latund einen Marker hinzufügen.lng

Andrea Bisello
quelle
-1

Es hört sich so an, als müssten Sie eines von zwei Dingen tun:

  1. Ändern Sie Ihren Prozess so, dass die Ergebnisse zwischengespeichert werden, wenn Sie nicht so viele eindeutige Ergebnisse pro Tag erhalten. oder
  2. Upgrade auf einen Service, mit dem Sie mehr pro Tag verarbeiten können

Wie schon oft erwähnt, aber ich habe keine persönlichen Erfahrungen damit, scheint eine Google-Lizenz für 100.000 USD pro Tag ungefähr 10.000 USD pro Jahr zu sein.

Wenn Sie die gleiche oder eine bessere Genauigkeit wünschen (und diesen Preis nicht zahlen müssen), können Sie unseren Service ausprobieren. Für viel weniger als Google (fast ein Zehntel der Kosten) könnten Sie ein viel höheres Limit als 2500 erhalten (unser niedrigstes Limit ist 25.000 / Tag).

Natürlich ist die Verwendung unserer Paid-Geocoding-API nicht die Lösung, die ich empfehlen würde, um 100% ehrlich zu sein, auch wenn es geschäftlich schlecht ist, dies zuzugeben. Ich würde stattdessen vorschlagen, Option 1 zu wählen und Ihren Dienst für den Cache zu optimieren. Es sei denn, Sie benötigen mehr als 2500 UNIQUE-Geocodes pro Tag.

Haftungsausschluss : Ich arbeite für Geocode Farm (den Dienst, den ich empfehle).

Geocode.Farm Staff
quelle
Warum wurde das herabgestimmt? Ich sehe nicht, wo irgendetwas hier falsch oder falsch ist?
Geocode.Farm Staff