Wie können 300.000 Adressen im laufenden Betrieb geocodiert werden?

18

Ich habe eine Datenbank mit 300.000 Adressen, die auf der Karte angezeigt werden sollen. Ich weiß, wenn ich die gesamte Adresse geocodiere, ist das für mich zu teuer. Ich habe mich also gefragt, ob es möglich ist, die Adresse im laufenden Betrieb / in Echtzeit geocodiert zu speichern. Wenn ein Benutzer eine Adresse (eine Eigenschaftsadresse) auswählt, durchsucht er die Datenbank und codiert die Adresse geocodiert und ordnet sie dann zu andere Attribute.

Es wäre wirklich schön, wenn Sie einen Code, ein Konzept oder etwas anderes teilen könnten. Übrigens ist mein Backend auf MySQL, das von Joomla unterstützt wird.

user1089553
quelle
Im Allgemeinen verwende ich die ArcGIS-Geokodierungsfunktion, um eine große Anzahl von Adressen zu geokodieren. Ich bin auch sehr an den hier erläuterten Prozessen interessiert, insbesondere daran, das Python-Skript zu testen, um die Adressen mit Google zu geocodieren, und sie dann mit den von ArcGIS erhaltenen zu vergleichen. Leider scheint es mir nicht möglich zu sein, alle zugehörigen Dateien und Skripte zu finden, die sich an verschiedenen Orten befinden. Es wäre sehr dankbar, wenn mir jemand alle Skripte in einer ZIP-Datei oder einer Schritt-für-Schritt-Anleitung zusenden würde. Ich habe versucht, es zu verwenden und ein Feedback an Sie zu bekommen, aber ich war nicht erfolgreich
Housh

Antworten:

15

Mehul, ich habe in der Adressprüfungsbranche mit einer Firma namens SmartyStreets gearbeitet. Es gibt viele Geokodierungsdienste, aber nur wenige unterstützen die Stapelverarbeitung mit dem von Ihnen benötigten Volumen. (Google und andere erlauben keine Massenverwendung ihrer API oder das Speichern / Zwischenspeichern von Ergebnissen.)

Wenn Sie zu Ihrer MySQL-Datenbank gehen und einen Export Ihrer Tabelle ausführen, die die Adressen enthält, speichern Sie diese beispielsweise als CSV-Datei. Sie können es dann mit dem SmartyList- Web-Tool oder dem Befehlszeilen-Tool verarbeiten . Wie ich bereits sagte, gibt es mehrere Dienste, aber Sie möchten vermutlich auch etwas, das die Existenz von Adressen überprüft (daher der Grund für die Geokodierung) - wenn die Adresse falsch oder unvollständig ist, sind es auch die Geokodierungsergebnisse . Dies tun nur wenige Dienste.

LiveAddress ist ein Dienst, der vom USPS CASS-zertifiziert ist . Es gibt einige, die Ihre Recherchen durchführen, aber Sie möchten etwas "on-the-fly" / schnell und kostengünstig, also empfehle ich LiveAddress erneut. Es überprüft nicht nur die Adresse, sondern erledigt auch alles, was Sie benötigen. Dies beinhaltet die Angabe von Lat / Lon-Informationen und auch die Genauigkeit der Geokodierungsergebnisse. Es ist alles webbasiert und wird in kürzester Zeit Dutzende Millionen Datensätze verarbeiten (siehe diese Frage als Referenz ).

Wenn Sie während der Benutzerinteraktion weitere Adressen geocodieren müssen, verfügt LiveAddress auch über eine API- Version, die praktisch alle Funktionen unterstützt und die Stapelverarbeitung im laufenden Betrieb unterstützt, jedoch als Abonnement und nicht als einmaliges Abonnement bezahlt wird Zahlung.

Matt
quelle
Nicht vertraut mit SmartyStreets, sieht vielversprechend aus, danke für die Hinweise.
Derek Swingley
Die LiveAddress-API erledigt 300.000 in ungefähr 5-10 Minuten. Der LiveAddress for Lists-Dienst (Hochladen einer Liste zur Verarbeitung) dauert 15 bis 20 Minuten. Beides ziemlich flott. Für den Listendienst müssen Sie keinen Code schreiben.
Jeffrey
2
SmartyStreets nur Geocodes für die USA?
Mapperz
Ich habe Daten für Singapur. Funktioniert das? Wenn nicht irgendwelche Anweisungen könnten Sie mir geben ????
user1089553
Es gibt viele Copyright-Regeln bei Google Bing und anderen Anbietern. Sie exportieren keine Daten!
11

Wenn Sie Python mögen, können Sie die GeoPy-API in Kombination mit den GDAL-Python-Bindungen oder Fiona verwenden und ein sehr einfaches Skript wie dieses erstellen, um die Adressen in ein Punkt-Shapefile zu konvertieren.

Dadurch wird eine Datei mit dem Namen "address_to_geocode" geografisch lokalisiert und ein Ausgabe-Shapefile mit dem Namen "my_output.shp" im Ordner "my_output" erstellt:

import os
from geopy import geocoders
from osgeo import ogr, osr

def geocode(address):
    g = geocoders.GoogleV3()
    place, (lat, lng) = g.geocode(address)
    print '%s: %.5f, %.5f' % (place, lat, lng)
    return place, lat, lng

def parse_file(filepath, output_shape):
    # create the shapefile
    drv = ogr.GetDriverByName("ESRI Shapefile")
    if os.path.exists(output_shape):
        drv.DeleteDataSource(output_shape)
    ds = drv.CreateDataSource(output_shape)
    # spatial reference
    sr = osr.SpatialReference()
    sr.ImportFromProj4('+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs')
    lyr = ds.CreateLayer(output_shape, sr, ogr.wkbPoint)
    # fields
    featDefn = lyr.GetLayerDefn()
    fld_id = ogr.FieldDefn('id', ogr.OFTInteger)
    fld_address = ogr.FieldDefn('ADDRESS', ogr.OFTString)
    fld_address.SetWidth(255)
    lyr.CreateField(fld_id)
    lyr.CreateField(fld_address)
    print 'Shapefile %s created...' % ds.name
    # read text addresses file
    i = 0
    f = open(filepath, 'r')
    for address in f:
        try:
            print 'Geocoding %s' % address
            place, lat, lng = geocode(address)
            point = ogr.Geometry(ogr.wkbPoint)
            point.SetPoint(0, lng, lat)
            feat = ogr.Feature(lyr.GetLayerDefn())
            feat.SetGeometry(point)
            feat.SetField('id', i)
            feat.SetField('ADDRESS', address)
            lyr.CreateFeature(feat)
            feat.Destroy()
            i = i + 1
        except:
            print 'Error, skipping address...'

parse_file('addresses_to_geocode', 'my_output')

Die Datei soll nur eine Zeile für eine einzelne Adresse enthalten, wie zum Beispiel:

Via Benedetto Croce 112, Rome, Italy
Via Aristide Leonori 46, Rome, Italy
Viale Marconi 197, Rome, Italy

Hier verwende ich die Google-API, aber mit GeoPy ist es sehr einfach, auf andere APIs wie Yahoo! GeoNames oder MapPoint umzusteigen .

capooti
quelle
Das ist toll! Danke, Mann! Derzeit (01/2016) sollte "geocoders.Google ()" in "geocoders.GoogleV3 ()" geändert werden, wie in geopy.readthedocs.org/de/1.11.0
umbe1987 12.01.16
1

Eine andere Möglichkeit, um Ihr Problem zu lösen, besteht darin, Ihren Datensatz in Fusionstabellen zu importieren und das Adressfeld als Speicherort festzulegen. Dann werden die Punkte automatisch geocodiert. Danach können Sie die Daten als KML exportieren.

Oder ... Sie können alternativ ein PHP-Skript schreiben, um den Yahoo-Geocoder zu verwenden, der ein Limit von 50.000 Datensätzen hat. Früher oder später haben Sie alle Ihre Punkte in Ihrer Datenbank geocodiert.

Ich hoffe das hat geholfen!

EZMapdesign
quelle
danke tamas aber ich möchte nicht die kml bekommen und dann die informationen von dort holen und dann zu m db. Ich mag die Idee der Yahoo-Geokodierung, aber ich bin mir nicht sicher, welche Genauigkeit sie hat, da ich Yahoo noch nie für die Kartierung verwendet habe. Bitte lassen Sie mich wissen, ob Sie ein Skript geschrieben haben oder etwas. Dies ist eine große Hilfe
user1089553
Beachten Sie, dass die Verwendung von Yahoo (oder Google) Geocodern mit automatisierten Abfragen oder ohne Anzeige einer Karte gegen die Nutzungsbedingungen verstößt ...
Matt
Soweit ich weiß, geht es nicht, wenn Sie die Ausgabe auf einer Karte präsentieren. Korrigiere mich, wenn ich falsch liege!
EZMapdesign
@ Tamas Art von. Siehe hierzu jedoch: developers.google.com/maps/terms#section_10_1_3
Matt
0

Vielleicht nicht die beste Antwort auf Ihre Frage, aber Sie können BatchGeo ausprobieren. Die kostenlose Version würde dich sehr leiden lassen, war aber trotzdem gut genug für meine Arbeit. Wir haben jedoch die Pro-Version gekauft.

Wenn Sie Koordinaten aus einer KML-Datei abrufen möchten, müssen Sie diese später in ArcGIS importieren.

Anıl Çelik
quelle
Danke, können Sie mir sagen, wie ich einen BatchGeo mache, und wissen Sie auch, wie die kostenlose Version heißt (ich habe versucht, Google Map api v3 zu verwenden)? Bedeutet dies auch, dass ich die Lat / Long-Werte in meiner Datenbank speichern muss, um sie abzubilden. Dies ist, was ich in erster Linie tun wollte.
user1089553
Mit BatchGeo müssen Sie KML in Ihre Datenbank importieren und dann die Koordinaten extrahieren. Ich kenne keine andere Möglichkeit, da Google die Angabe von Koordinaten verbietet. Über Yahoo ist meine Erfahrung mit der Türkei nicht wirklich hell. Die meisten Entwicklungsländer sind von Yahoo ausgeschlossen. Anil.
Anıl Çelik
0

Ich habe erfolgreich Geopy verwendet, das den Google Geocoding-Webdienst verwendet. Es funktioniert perfekt für bis zu 2.000 Punkte pro 24 Stunden.

Matej
quelle
0

Matej, das ist, weil Google API erlauben, bis zu 2.5k pro Tag zu ziehen.
In Bezug auf die Geo-Lösung wurde Batch noch nicht als unterstützt befunden, da es nach meiner Überprüfung des Geo-Python-Codes jedes Mal, wenn er eine neue Koordinate anfordert, eine offene Verbindung zu haben scheint. 300 KB bleiben wahrscheinlich für immer hängen (wahrscheinlich mit Fehler 400).
Das Spiel mit Poligons sollte den Trick machen, aber es hängt davon ab, was Ihr "Spielplatz" ist, ob es sich um 1 Land oder n Länder handelt.
Für 1 Land sollten die Polygone ziemlich gut funktionieren.
In n Ländern funktioniert die Lösung nicht, da die Erfassung jedes Mal länger dauert, wenn Sie ein anderes Land hinzufügen. Das beste Aproch, um es zu tun, ist faul Last.
=> beginne mit der Polygon-Idee, alles in einem anderen Land, erstelle eine große Datenbanktabelle, um die Daten zu speichern, schließlich wirst du die Daten speichern, die du brauchst, nehme ich an.

Benjaminel
quelle
0

Wenn Sie es mit PHP machen wollen - MySQL ist hier eine Lösung, die für mich funktioniert hat:

<script type="text/javascript" charset="utf-8">

    var customIcons = {
      restaurant: {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_blue.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
      },
      bar: {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_red.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png'
      },
      club:
      {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_yellow.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png' 
      },
      church:
      {
        icon: 'http://labs.google.com/ridefinder/images/mm_20_green.png',
        shadow: 'http://labs.google.com/ridefinder/images/mm_20_shadow.png' 
      }
    };

      function initialize() 
      {
        var mapOptions = {
          center: new google.maps.LatLng(37.976178, 23.735881),
          zoom: 7,
          mapTypeId: google.maps.MapTypeId.roadmap
        };
        var map = new google.maps.Map(document.getElementById("map-canvas"),
            mapOptions);
        <?php header("content-type: text/html;charset=utf-8");
        $getpoints = "SELECT lat, lng, name, address, type FROM markers";
        $getpoints .= $filter;

        if(!$result = $con->query($getpoints)){
        die('There was an error running the query 
        [' . $con->error . ']');
        }

        else 
        {
            while ($row = $result->fetch_assoc()) 
            {
                $thematic = "'$row[type]'";
                $name = "'$row[name]'";
                $map_address = "$row[address]";

                $url = "http://maps.googleapis.com/maps/api/geocode/json?sensor=false&address=".urlencode($map_address);
                $lat_long = get_object_vars(json_decode(file_get_contents($url)));

                // pick out what we need (lat,lng)
                $lat_long = $lat_long['results'][0]->geometry->location->lat . "," . $lat_long['results'][0]->geometry->location->lng;

                echo "var myLatlng1 = new google.maps.LatLng($lat_long); 
                var icon = customIcons[$thematic] || {};
                var marker1 = new google.maps.Marker({ 
                position: myLatlng1, 
                map: map,
                icon: icon.icon,
                title: '$map_address'
                });";           
            }
        }       

        ?>    
      }

      google.maps.event.addDomListener(window, 'load', initialize);
    </script>
pancy1
quelle
0

Probieren Sie diese Geokodierungs-API aus . Es ist kostenlos für den kleinen Gebrauch, aber wenn Sie mehr wollen, werden Sie dafür bezahlt. Es ist jedoch billig und Sie können es sehr leicht verarbeiten, ich verarbeite Millionen pro Monat durch sie.

John M.
quelle
0

Sie können Ihre Daten als Textdatei speichern (ein Datensatz pro Zeile) und sie dann mithilfe dieses Dienstes stapelweise geocodieren: http://geocode.xyz/batch (funktioniert in den meisten europäischen Ländern)

Sie können auch Ihren eigenen Code schreiben, um auf die REST / JSON-API zuzugreifen: http://geocode.xyz/api (kostenlos für unbegrenzte Suchvorgänge).

Ervin Ruci
quelle
0

Mappointing-Tools verwenden (Kartenzeigetool | Batch-Geocoding-Tool ( http://www.mappointing.com/ )) In diesem Tool können Sie die Daten mit dem kostenlosen API-Schlüssel von Google Map verarbeiten. Und auch dieses Tool bietet Entfernungsberechnung und Ortssuche.

Debasis Sahu
quelle
Warum wurde nicht dasselbe API-Limit erreicht, von dem OP erwähnt wurde?
Lynxlynxlynx