Jak geokodować 300 000 adresów w locie?

Posiadam bazę danych, która ma 300 000 adresów, które mają być pokazane na mapie. Wiem, że jeśli zakoduję wszystkie adresy, będzie to dla mnie za drogie. Zastanawiałem się więc, czy możliwe jest geokodowanie adresu w locie / w czasie rzeczywistym, kiedy użytkownik wybierałby adres (adres nieruchomości), przeszukiwałby bazę danych, a następnie geokodował adres, a następnie mapowałby go za pomocą inne atrybuty.

Byłoby naprawdę miło, gdybyś mógł udostępnić kod, koncepcję lub cokolwiek. Swoją drogą mój backend jest na mysql wspieranym przez Joomla.

Komentarze

  • Generalnie używam funkcji geokodowania ArcGIS do geokodowania dużej liczby adresów. Poza tym ' jestem bardzo zainteresowany opisanymi tutaj procesami, szczególnie lubię przetestować skrypt Pythona, aby geokodować adresy za pomocą Google, a następnie porównać je z tym, co ' został pobrany z ArcGIS. Niestety wydaje mi się, że ' nie mogę znaleźć wszystkich powiązanych plików i skryptów, które znajdują się w różnych miejscach. Byłoby bardzo wdzięczne, gdyby ktoś przesłał mi wszystkie skrypty w jednym pliku zip lub instrukcje krok po kroku. ' Próbowałem go użyć i uzyskać od Ciebie opinię, ale nie udało mi się

Odpowiedź

Mehul, pracowałem kiedyś w branży weryfikacji adresów w firmie o nazwie SmartyStreets. Istnieje wiele usług geokodowania, ale tylko kilka z nich obsługuje przetwarzanie wsadowe o wymaganej objętości. (Google i inne firmy nie zezwalają na masowe wykorzystanie ich interfejsu API ani na przechowywanie / buforowanie wyników).

Jeśli przejdziesz do bazy danych MySQL i wyeksportujesz tabelę zawierającą adresy, zapisz ją jako Na przykład plik CSV. Możesz go następnie przetworzyć za pomocą narzędzia do zbiorczej weryfikacji adresów dla list lub narzędzia wiersza poleceń . Jak powiedziałem, istnieje kilka usług, ale przypuszczam, że będziesz potrzebować czegoś, co również weryfikuje istnienie adresów (stąd powód geokodowania) – jeśli adres jest nieprawidłowy lub niekompletny, podobnie jak wyniki geokodowania. Robi to tylko kilka usług.

LiveAddress to usługa CASS-Certified przyznana przez USPS. Jest ich kilka, więc zrób swoje badania, ale chcesz czegoś „w locie” / szybkiego i niedrogiego, więc ponownie polecam LiveAddress. Nie tylko zweryfikuje adres, ale zrobi to, czego potrzebujesz, czyli poda informacje o długości i długości geograficznej, a także precyzję wyników geokodowania. Wszystko to jest oparte na sieci i błyskawicznie przetworzy dziesiątki milionów rekordów (patrz to pytanie jako odniesienie ).

Jeśli masz dalsze pytania muszą geokodować adresy podczas interakcji użytkowników, US Street Address ma również wersję API , która może być podłączona do prawie wszystkiego, a także obsługuje przetwarzanie wsadowe w trybie on-the- fly, ale jest opłacana jako abonament, a nie jednorazowa płatność.

Komentarze

  • Nie znam SmartyStreets, wygląda obiecująco, dziękuję za heads up.
  • LiveAddress API wykona 300 000 w około 5-10 minut. Usługa LiveAddress for Lists (przesłanie listy do przetworzenia) zajmuje 15-20 minut. Obie dość szybkie. Usługa List nie będzie wymagać od Ciebie pisania żadnego kodu.
  • SmartyStreets tylko geokody dla USA?
  • Mam dane, które są dla Singapuru, czy to będzie działać? Jeśli nie ma żadnych wskazówek, które mógłbyś mi dać ????
  • SmartyStreets oferuje teraz weryfikację adresu międzynarodowego. @ user1089553

Odpowiedź

Jeśli lubisz Pythona, możesz użyć GeoPy API w połączeniu z GDAL Python bindings lub Fiona i utwórz bardzo prosty skrypt, taki jak ten, do konwersji adresów na plik kształtu punktu.

To geolokalizuje plik o nazwie „adresy_to_geocode”, tworząc wyjściowy plik kształtu o nazwie „my_output.shp” w folderze my_output:

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

Plik powinien zawierać tylko wiersz dla pojedynczego adresu, na przykład:

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

Tutaj używam Google API, ale z GeoPy jest bardzo proste do przełączenia się na inne API, takie jak Yahoo !, GeoNames czy MapPoint .

Komentarze

  • To jest świetne! Dzięki! W każdym razie, obecnie (01/2016) ' geocoders.Google () ' należy zmienić na ' geocoders.GoogleV3 () ' jak w geopy.readthedocs.org/en/1.11.0

Odpowiedź

Inną opcją rozwiązania problemu byłoby zaimportowanie zbioru danych do fusion tabele i ustaw pole adresu jako lokalizację. Następnie automatycznie geokoduje punkty. Gdy to zrobisz, możesz wyeksportować dane jako KML.

Alternatywnie, możesz napisać skrypt php, aby korzystać z geokodera Yahoo, który ma limit 50 000 rekordów, więc wcześniej czy później będziesz mieć wszystkie swoje punkty geokodowane w swojej bazie danych.

Mam nadzieję, że to pomogło!

Komentarze

  • Dziękuję Tamas, ale nie chciałbym pobierać kml, a następnie pobierać informacje stamtąd, a następnie do m db. Lubię pomysł geokodowania Yahoo, ale nie jestem pewien jego dokładności, ponieważ nigdy nie korzystałem z Yahoo do mapowania. Daj mi znać, jeśli masz napisany jakiś scenariusz lub coś takiego. To jest bardzo pomocne.
  • Pamiętaj, że używanie geokodera Yahoo (lub Google, jeśli o to chodzi) z automatycznymi zapytaniami lub bez wyświetlania mapy, narusza Warunki korzystania z usługi …
  • Jak dotąd jak wiem, nie dzieje się tak, jeśli przedstawisz wynik na mapie. Popraw mnie, jeśli się mylę!
  • @Tamas Coś takiego. Zobacz to jednak: developers.google.com/maps/terms#section_10_1_3

Odpowiedź

Z powodzeniem używam geopy, która wykorzystuje usługę sieciową Google do geokodowania. Działa idealnie do 2k punktów na 24 godziny.

Odpowiedź

zdecydowanie najlepszy i najłatwiejszy geokoder, z jakiego korzystałem https://pypi.python.org/pypi/geocoder/1.8.0 mapy bing, mapy google, OSM itp.

Odpowiedź

Może nie jest to najlepsza odpowiedź na Twoje pytanie, ale możesz wypróbować BatchGeo. Bezpłatna wersja sprawiłaby, że bardzo cierpielibyście, ale nadal byłaby wystarczająco dobra do mojej pracy. Kupiliśmy wersję pro.

Sztuczka, aby uzyskać współrzędne z pliku KML, to zaimportować go do ArcGIS później.

Komentarze

  • Dzięki, czy możesz mi powiedzieć, jak mam zrobić BatchGeo. Czy znałbyś również nazwy darmowych wersji (Próbowałem dla Google Map api v3). Czy to również oznacza że muszę przechowywać wartości Lat / Long w mojej bazie danych, aby je zmapować. To właśnie zamierzałem zrobić w pierwszej kolejności.
  • Dzięki BatchGeo będziesz musiał zaimportować KML do swojej bazy danych, a następnie wyodrębnić współrzędne, nie znam innego sposobu, ponieważ Google zabrania podawania współrzędnych. Jeśli chodzi o Yahoo, moje doświadczenie z Turcją nie jest zbyt jasne. Większość krajów rozwijających się pozostaje poza zakresem Yahoo '. Anil.

Odpowiedz

Matej, To dlatego, że Google API pozwala pobierać do 2,5 tys. Dziennie.
Jeśli chodzi o rozwiązanie Geo, wsad nie jest jeszcze obsługiwany, ponieważ z mojego przeglądu kodu geo pythona wydaje się, że otwiera połączenie za każdym razem, gdy zażąda nowego połączenia, 300k prawdopodobnie utknie na zawsze (prawdopodobnie z błąd 400).
Gra z poligonami powinna załatwić sprawę, ale zależy to od obszaru „placu zabaw”, czy jest to 1 kraj czy n krajów.
W przypadku 1 kraju wielokąty powinny działać całkiem nieźle .
W przypadku n krajów rozwiązanie nie działa, ponieważ zbieranie danych będzie trwało dłużej za każdym razem, gdy dodasz inny kraj. Najlepszą metodą jest leniwe ładowanie.
=> zacznij od pomysłu na wielokąt, wszystko w innym kraju, utwórz dużą tabelę bazy danych do przechowywania danych. Przypuszczam, że ostatecznie będziesz przechowywać potrzebne dane.

Odpowiedź

Jeśli chcesz to zrobić z PHP – MySQL tutaj jest rozwiązanie, które wo rked for me:

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

Odpowiedź

Spróbuj tego interfejs API geokodujący . Jest darmowy przy niewielkim użyciu, ale jeśli chcesz więcej, to płacisz. Jest jednak tani i możesz go przetwarzać o wiele łatwo, przetwarzam za ich pośrednictwem miliony miesięcznie.

Odpowiedź

Użyj narzędzi do mapowania (wskazywanie na mapie | Batch Geocoding Tool ( http://www.mappointing.com/ )) W tym narzędziu możesz przetwarzać dane za pomocą bezpłatnego klucza API mapy Google. Ponadto narzędzie to zapewnia obliczanie odległości & Narzędzie wyszukiwania miejsc.

Komentarze

  • Dlaczego nie ' czy to nie osiągnęło tego samego limitu API wymienionego w OP?

Odpowiedź

Możesz zapisać swoje dane jako plik tekstowy (jeden rekord w wierszu), a następnie zbiorczo je geokodować za pomocą tej usługi: http://geocode.xyz/batch (działa w większości krajów europejskich)

lub możesz napisać własny kod dostępu do REST / JSON API: (jest bezpłatny do nieograniczonej liczby wyszukiwań)

Komentarze

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *