300.000 adresi anında nasıl kodlayabilirsiniz?


18

Haritada gösterilecek 300.000 adrese sahip bir veritabanım var. Tüm adresi coğrafi olarak kodlarsam, benim için çok pahalı olacağını biliyorum. Bu yüzden bir adres (özellik adresi) bir kullanıcı seçtiğinde veritabanını aramak ve daha sonra adresi coğrafi kodlamak ve daha sonra eşlemek için adresi anında / gerçek zamanlı olarak coğrafi kodlamak mümkün olup olmadığını merak ediyordum diğer özellikler.

Bir kodu, konsepti veya herhangi bir şeyi paylaşabilmeniz gerçekten güzel olurdu. Bu arada arka ucum Joomla tarafından desteklenen mysql'de.


Genellikle çok sayıda adresi coğrafi olarak kodlamak için ArcGIS coğrafi kodlama özelliğini kullanıyorum. Ayrıca, burada açıklanan süreçlerle gerçekten ilgileniyorum, özellikle Google'ı kullanarak adresleri coğrafi olarak kodlamak için python komut dosyasını test etmek, ardından ArcGIS'ten aldığımlarla karşılaştırmak istiyorum. Ne yazık ki, farklı yerlerde bulunan ilgili tüm dosyaları ve komut dosyalarını bulamıyorum. Birisi bana tüm komut dosyalarını bir zip dosyasında veya adım adım talimatlarda gönderirse çok sevinirim.
Kullanmaya

Yanıtlar:


15

Mehul, adres doğrulama sektöründe SmartyStreets adlı bir şirketle çalışıyordum. Orada çok sayıda coğrafi kodlama hizmeti var, ancak sadece birkaç tanesi ihtiyacınız olan hacimde toplu işlemeyi destekleyecek. (Google ve diğerleri, API'lerinin toplu olarak kullanılmasına veya sonuçların depolanmasına / önbelleğe alınmasına izin vermez.)

MySQL veritabanınıza gidip adresleri içeren tablonuzun dışa aktarımını gerçekleştirirseniz, bunu örneğin bir CSV dosyası olarak kaydedin. Daha sonra SmartyList web aracını veya komut satırı aracını kullanarak işleyebilirsiniz . Dediğim gibi, orada birkaç hizmet var, ama sanırım adreslerin varlığını da doğrulayan bir şey isteyeceksiniz (bu nedenle coğrafi kodlamanın nedeni) - adres yanlış veya eksikse, coğrafi kodlama sonuçları da . Bunu sadece birkaç servis yapıyor.

LiveAddress, USPS tarafından CASS Sertifikalı bir hizmettir . Orada birkaç araştırma kadar yapmak, ama bir şey istiyorum "anında" / hızlı ve ucuz bu yüzden tekrar LiveAddress öneririz. Sadece adresi doğrulamakla kalmayacak, daha sonra istediğiniz enlem / boylam bilgisini ve coğrafi kodlama sonuçlarının kesinliğini de sağlayacaktır. Her şey web tabanlıdır ve hiçbir zaman on milyonlarca kaydı işleyecektir ( bu soruyu referans olarak bakın ).

Kullanıcılar etkileşimde bulunurken adresleri coğrafi olarak kodlamanız gerekiyorsa, LiveAddress'in hemen hemen her şeye ekleyebileceği bir API sürümü de vardır ve aynı zamanda anında toplu işlemeyi destekler, ancak bir kerelik değil bir abonelik olarak ödenir ödeme.


SmartyStreets'e aşina olmayan, umut verici görünüyor, kafalar için teşekkürler.
Derek Swingley

LiveAddress API'si yaklaşık 5-10 dakikada 300.000 gerçekleştirecektir. Listeler için LiveAddress hizmeti (işlenmek üzere bir liste yükleyin) 15-20 dakika sürer. Her ikisi de oldukça hızlı. Liste servisi herhangi bir kod yazmanızı gerektirmez.
Jeffrey

2
SmartyStreets sadece ABD için coğrafi kodlar mı?
Mapperz

Singapur için çalışacak verilerim var mı? Herhangi bir yön değilse bana verebilir ????
user1089553

Google Bing ve diğer sağlayıcılarla birçok telif hakkı kuralı vardır. Verileri dışa aktarmazsınız!

11

Python'u beğendiyseniz , GDAL Python bağları veya Fiona ile birlikte GeoPy API'sini kullanabilir ve adresleri bir nokta şekil dosyasına dönüştürmek için böyle çok basit bir komut dosyası oluşturabilirsiniz.

Bu, 'address_to_geocode' adlı bir dosyayı coğrafi olarak konumlandırarak my_output klasöründe 'my_output.shp' adlı bir çıktı şekli dosyası oluşturur:

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

Dosyanın, örneğin tek bir adres için yalnızca bir satırı olması gerekir:

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

Burada Google API kullanıyorum, ancak GeoPy ile Yahoo !, GeoNames veya MapPoint gibi farklı API'lara geçmek çok basit .


Bu harika! Teşekkürler dostum! Her neyse, şu anda (01/2016), 'geocoders.Google ()', geopy.readthedocs.org/en/1.11.0
umbe1987

1

Sorununuzu çözmek için başka bir seçenek, veri kümenizi füzyon tablolarına aktarmak ve adres alanını konum olarak ayarlamak olacaktır. Ardından noktaları otomatik olarak kodlar. Tamamlandığında, verileri KML olarak dışa aktarabilirsiniz.

Ya da alternatif olarak, 50.000 kayıt sınırına sahip yahoo geocoder'ı kullanmak için bir php betiği yazabilirsiniz, bu yüzden er ya da geç tüm noktalarınız veritabanınızda coğrafi kodlanmış olacaktır.

Umarım bu yardımcı olmuştur!


teşekkürler tamas ama ben kml almak ve sonra oradan ve sonra m db bilgi almak istemiyorum. Yahoo geocoding fikrini seviyorum ama eşleme için yahoo hiç kullanmadım gibi, doğruluk çok emin değilim. Yazılı bir senaryo veya başka bir şey varsa lütfen bana bildirin. Bu çok yardımcı
user1089553 22:12

Otomatik sorgularla veya bir harita göstermeden Yahoo (veya Google için) coğrafi kodlayıcı kullanmanın TOS'u ihlal edeceğini unutmayın ...
Matt

Bildiğim kadarıyla, çıktıyı bir harita üzerinde sunuyorsanız değil. Eğer Yanlışsam beni düzelt!
EZMapdesign

@Tamas Tür. Ancak şunu görün: developers.google.com/maps/terms#section_10_1_3
Matt


0

Sorunuza en iyi cevap olmayabilir, ancak BatchGeo'yu deneyebilirsiniz. Ücretsiz sürüm, çok fazla acı çekmenizi sağlar, ancak yine de işim için yeterince iyiydi. Yine de, pro sürümünü satın aldık.

KML dosyasından koordinat almanın hilesi daha sonra ArcGIS'e aktarmaktır.


Teşekkürler, nasıl bir BatchGeo yapacağımı söyleyebilir misiniz, ayrıca ücretsiz sürümün isimlerini de biliyor musunuz (Google Map api v3 için çalışıyordum). Ayrıca bu harita için Lat / Long değerleri veritabanımda saklamak zorunda olduğu anlamına mı geliyor. İlk etapta bunu yapmayı amaçladım.
user1089553

BatchGeo ile, veritabanınıza KML almak ve koordinatları çıkarmak zorunda kalacaksınız, Google'ın koordinat sağlamayı yasakladığı gibi başka bir yol bilmiyorum. Yahoo hakkında, Türkiye ile yaşadığım deneyim gerçekten parlak değil. Gelişmekte olan ülkelerin çoğu Yahoo'nun kapsamı dışında kalıyor. Anıl.
Anıl Çelik

0

Google coğrafi kodlama web hizmetini kullanan geopy'yi başarıyla kullanıyorum. 24 saatte 2k noktaya kadar mükemmel çalışır.


0

Matej, Thats çünkü Google API günde 2.5k çekmeye izin veriyor.
Geo çözümü hakkında, toplu iş henüz desteklenmediği için, coğrafi python kodunu incelememden, her yeni bir kordinat istediğinde bağlantıyı açtığı görülüyor, 300k muhtemelen sonsuza kadar sıkışacak (muhtemelen hata 400 ile).
Poligonlar ile oynamak hile yapmalıdır, ancak 1 ülke veya n ülke ise 'Oyun alanı' alanınıza bağlıdır.
1 ülke için çokgenler oldukça iyi çalışmalıdır.
N ülke için çözüm işe yaramaz, çünkü başka bir ülke eklediğinizde koleksiyon daha uzun sürer. Bunu yapmak için en iyi yaklaşım tembel yüktür.
=> çokgen fikriyle başlayın, başka bir ülkedeki her şey, verileri tutmak için büyük bir veritabanı tablosu oluşturun, sonunda ihtiyacınız olan verileri tutacağınızı varsayalım.


0

PHP - MySQL ile yapmak istiyorsanız işte benim için çalışan bir çözüm:

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

0

Bu coğrafi kodlama API'sını deneyin . Küçük kullanım için ücretsizdir ancak daha fazlasını isterseniz ödeme yaparsınız. Ancak ucuz ve bu kadar kolay işleyebilir, ben ayda milyonlarca iş.


0

Verilerinizi bir metin dosyası (her satıra bir kayıt) olarak kaydedebilir ve bu hizmeti kullanarak coğrafi olarak toplu olarak kodlayabilirsiniz: http://geocode.xyz/batch (çoğu avrupa ülkesi için çalışır)

veya REST / JSON API'sına erişmek için kendi kodunuzu yazabilirsiniz: http://geocode.xyz/api (sınırsız arama için ücretsizdir)


0

Harita İşaretleme araçlarını kullanma (Harita işaretleme | Toplu Coğrafi Kodlama Aracı ( http://www.mappointing.com/ )) Bu araçta Google harita ücretsiz API anahtarını kullanarak verileri işleyebilirsiniz. Ve ayrıca bu araç Mesafe hesaplama ve Yer arama aracı sağlar.


Bu OP'nin bahsettiği API sınırını neden düşürmedi?
lynxlynxlynx
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.