Hur geokodar du 300 000 adresser i farten?

Jag har en databas som har 300 000 adresser som ska visas på kartan. Jag vet att om jag geokodar hela adressen blir det för dyrt för mig. Så jag undrade om det är möjligt att geokoda adressen i farten / realtid, när en användare skulle välja en adress (en fastighetsadress) skulle den söka igenom databasen och sedan geokodera adressen och sedan mappa den med andra attribut.

Det skulle vara riktigt trevligt om du kunde dela en kod, ett koncept eller något annat. Förresten är min backend på mysql som stöds av Joomla.

Kommentarer

  • Jag använder i allmänhet ArcGIS-geokodningsfunktionen för att geokodera ett stort antal adresser. Jag ’ är verkligen intresserad av de processer som förklaras här, speciellt som att testa python-skriptet för att geokoda adresserna med hjälp av Google och sedan jämföra dem med vad jag ’ har fått från ArcGIS. Tyvärr verkar det som om jag ’ inte kan hitta alla relaterade filer och skript som finns på olika platser. Det skulle vara så uppskattat om någon skulle skicka mig alla skript i en zip-fil eller någon steg-för-steg-instruktion. Jag ’ har försökt använda den och få lite feedback till dig, men jag lyckades inte

Svar

Mehul, jag arbetade tidigare i adressverifieringsbranschen med ett företag som heter SmartyStreets. Det finns många geokodningstjänster där ute, men endast få stöder batchbearbetning med den volym du behöver. (Google och andra tillåter inte massanvändning av deras API eller lagring / caching-resultat.)

Om du går till din MySQL-databas och utför en export av din tabell som innehåller adresserna, spara den som en CSV-fil till exempel. Du kan sedan bearbeta den med Valideringsverktyg för massadress för listor eller Kommandoradsverktyg . Som sagt, det finns flera tjänster där ute, men du vill ha något, antar jag, som verifierar att det finns adresser också (därav anledningen till geokodning) – om adressen är fel eller ofullständig, så är geokodningsresultaten. Det är bara ett fåtal tjänster som gör det.

LiveAddress är en tjänst som är CASS-certifierad av USPS. Det finns några där ute så gör din forskning, men du vill ha något ”on-the-fly” / snabbt och billigt så igen rekommenderar jag LiveAddress. Det kommer inte bara att verifiera adressen utan gör sedan som du behöver, vilket är leverans av lat / lon-information och även precisionen i geokodningsresultaten. Det är allt webbaserat och kommer att bearbeta tiotals miljoner poster på nolltid (se den här frågan som referens ).

Om du har ytterligare behöver geokoda adresser när användare interagerar, US Street Address har också en API version som kan anslutas till nästan vad som helst och den stöder också batchbehandling på-the- flyga, men betalas som en prenumeration, inte en engångsbetalning.

Kommentarer

  • Känner inte till SmartyStreets, ser lovande ut, tack för head up.
  • LiveAddress API kommer att göra 300 000 på cirka 5-10 minuter. Tjänsten LiveAddress for Lists (ladda upp en lista för bearbetning) tar 15-20 minuter. Båda är ganska snabba. Listtjänsten kräver inte att du skriver någon kod.
  • SmartyStreets endast geokoder för USA?
  • Jag har data som är för Singapore kommer det att fungera? Om inte några anvisningar du kan ge mig ????
  • SmartyStreets erbjuder internationell adressverifiering nu. @ user1089553

Svar

Om du gillar Python kan du använda GeoPy API , kombinerat med GDAL Python-bindningar eller Fiona och skapa ett mycket grundläggande skript som detta för att konvertera adresserna till en punktformfil.

Detta kommer att geolokalisera en fil med namnet ”adresser_till_geokod” och skapa en utmatningsformfil med namnet ”min_output.shp” i mappen min_utdata:

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

Filen ska ha en rad för en enda adress, till exempel:

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

Här använder jag Google API, men med GeoPy är väldigt grundläggande för att byta till olika API, som Yahoo!, GeoNames eller MapPoint .

Kommentarer

  • Det här är fantastiskt! Tack mannen! Hur som helst, för närvarande (01/2016) bör ’ geokodrar.Google () ’ ändras till ’ geocoders.GoogleV3 () ’ som i geopy.readthedocs.org/en/1.11.0

Svar

Ett annat alternativ för att lösa ditt problem skulle vara att importera din dataset till fusion och ange adressfältet som plats. Då geokodar punkterna automatiskt. När det är klart kan du exportera data som KML.

Eller … alternativt kan du skriva ett php-skript för att använda yahoo geocoder som har en gräns på 50 000 poster, så förr eller senare du kommer att ha alla dina poäng geokodade i din databas.

Jag hoppas att det hjälpte!

Kommentarer

  • tack tamas men Jag skulle inte vilja hämta kml och sedan hämta informationen därifrån och sedan till m db. Jag gillar att tänka på yahoo geokodning men jag är inte så säker på den noggrannhet den har, eftersom jag aldrig har använt yahoo för kartläggning. Vänligen meddela mig om du har skrivit något manus eller något. Detta är en stor hjälp
  • Tänk på att användning av Yahoo (eller Google, för den delen) geokodare med automatiserade frågor eller utan att visa en karta bryter mot TOS …
  • Så långt som jag vet är det inte om du presenterar utdata på en karta. Korrigera mig om jag har fel!
  • @Tamas Typ av. Se dock detta: developers.google.com/maps/terms#section_10_1_3

Svar

Jag har framgångsrikt använt geopy som använder Googles geokodning webbtjänst. Det fungerar perfekt i upp till 2k poäng per 24 timmar.

Svara

den överlägset bästa och enklaste geokodaren jag har använt https://pypi.python.org/pypi/geocoder/1.8.0 bing maps, google maps, OSM etc ..

Answer

Kanske inte det bästa svaret på din fråga men du kan prova BatchGeo. Gratisversionen skulle få dig att lida mycket, men var ändå bra nog för mitt arbete. Men vi har köpt proversionen.

Knep för att få koordinater från KML-filen är att importera till ArcGIS senare.

Kommentarer

  • Tack, kan du berätta för mig hur gör jag en BatchGeo, skulle du också veta namnen på gratisversionen (Jag försökte Google Map api v3). Det betyder också att jag måste lagra Lat / Long-värdena i min databas för att kunna mappa det. Det här är vad jag tänkte göra i första hand.
  • Med BatchGeo måste du importera KML till din databas och sedan extrahera koordinaterna, jag vet inget annat eftersom Google förbjuder att tillhandahålla koordinater. Om yahoo, min erfarenhet av Turkiet är inte riktigt ljus. De flesta utvecklingsländer utesluts från Yahoo ’ s räckvidd. Anil.

Svar

Matej, det beror på att Google API tillåter att dra upp till 2,5 000 per dag.
Om Geo-lösningen har batch ännu inte visat sig stödjas eftersom ”s eftersom från min recension av geo-pythonkoden verkar det öppna anslutning varje gång han begär en ny kardinal, kommer 300k antagligen att fastna för alltid (förmodligen med fel 400).
Spela med poligoner bör göra tricket men det beror på vad som är ditt ”lekplats” -område, om det är 1 land eller n länder.
För 1 land ska polygonerna fungera ganska snyggt .
För n länder fungerar lösningen inte eftersom samlingen tar längre tid när du lägger till ett annat land. Det bästa sättet att göra det är lat belastning.
=> börja med polygonidén, allt i ett annat land, skapa en stor databastabell för att hålla data, så småningom kommer du att behålla de data du behöver antar jag.

Svar

Om du vill göra det med PHP – MySQL här är en lösning som är okej rked för mig:

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

Svar

Prova det här geokodning API . Det är gratis för liten användning men om du vill ha mer får de dig att betala. Det är dock billigt och du kan bearbeta så mycket enkelt, jag bearbetar miljoner per månad genom dem.

Svar

Använd Mappointing-verktyg (Map pointing | Batch Geocoding Tool ( http://www.mappointing.com/ )) I det här verktyget kan du bearbeta data med hjälp av Google map gratis API-nyckel. Och det här verktyget ger avståndsberäkning & Plats sökverktyg.

Kommentarer

  • Varför skulle ’ inte detta träffa samma API-gräns som OP nämnts?

Svar

Du kan spara dina data som en textfil (en post per rad) och sedan geo-koda batchen med den här tjänsten: http://geocode.xyz/batch (fungerar för de flesta europeiska länder)

eller, du kan skriva din egen kod för att komma åt REST / JSON API: (det är gratis för obegränsade sökningar)

Kommentarer

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *