Como geocodificar 300.000 endereços em tempo real?

18

Eu tenho um banco de dados com 300.000 endereços, que devem ser mostrados no mapa. Eu sei que se eu codificar geograficamente todo o endereço, será muito caro para mim. Então, eu queria saber se é possível codificar geograficamente o endereço on-line / em tempo real, quando um usuário seleciona um endereço (um endereço de propriedade), ele pesquisa no banco de dados e depois codifica geograficamente o endereço e mapeia-o com outros atributos.

Seria muito bom se você pudesse compartilhar um código, conceito ou qualquer coisa. A propósito, meu back-end está no mysql suportado pelo Joomla.

user1089553
fonte
Geralmente, uso o recurso de geocodificação do ArcGIS para geocodificar um grande número de endereços. Além disso, estou realmente interessado nos processos explicados aqui, especialmente, como testar o script python para geocodificar os endereços usando o Google e compará-los com o que obtive do ArcGIS. Infelizmente, parece-me que não consigo encontrar todos os arquivos e scripts relacionados que estão em lugares diferentes. Seria muito apreciado se alguém por favor me envie todos os scripts em um arquivo zip ou qualquer instrução passo a passo. Eu tentei usá-lo e obter algum feedback a você, mas eu não estava successfu
Housh

Respostas:

15

Mehul, eu costumava trabalhar no setor de verificação de endereços com uma empresa chamada SmartyStreets. Existem muitos serviços de geocodificação por aí, mas poucos suportam o processamento em lote com o volume necessário. (O Google e outros não permitem o uso em massa de suas APIs ou resultados de armazenamento / armazenamento em cache.)

Se você for ao seu banco de dados MySQL e fizer uma exportação da sua tabela que contém os endereços, salve-a como um arquivo CSV, por exemplo. Você pode processá-lo usando a ferramenta da web SmartyList ou a ferramenta de linha de comando . Como eu disse, existem vários serviços por aí, mas presumo que deseje algo que verifique a existência de endereços também (daí o motivo da geocodificação) - se o endereço estiver errado ou incompleto, os resultados da geocodificação também serão . Apenas alguns serviços fazem isso.

O LiveAddress é um serviço certificado pelo CASS pelo USPS. Existem alguns por aí, assim como sua pesquisa, mas você deseja algo "on-the-fly" / rápido e barato, então recomendo o LiveAddress. Ele não apenas verifica o endereço, mas também faz o que você precisa, que fornece informações de lat / lon e também a precisão dos resultados de geocodificação. É tudo baseado na Web e processará dezenas de milhões de registros rapidamente (veja esta pergunta como referência ).

Se você precisar mais geocodificar endereços à medida que os usuários estiverem interagindo, o LiveAddress também possui uma versão da API que pode ser conectada a praticamente qualquer coisa e também suporta processamento em lote on-the-fly, mas é pago como uma assinatura, não apenas uma vez. Forma de pagamento.

Matt
fonte
Não familiarizado com o SmartyStreets, parece promissor, obrigado pelo alerta.
Derek Swingley
A API do LiveAddress fará 300.000 em aproximadamente 5 a 10 minutos. O serviço LiveAddress for Lists (faça upload de uma lista para processamento) leva de 15 a 20 minutos. Ambos bem rápidos. O serviço de lista não exigirá que você escreva nenhum código.
21412 Jeffrey
2
SmartyStreets apenas geocódigos para os EUA?
Mapperz
Eu tenho dados que são de Cingapura, vai funcionar? Se não houver instruções, você poderia me dar ????
user1089553
Existem muitas regras de direitos autorais no Google Bing e em outros provedores. Você não exporta dados!
11

Se você gosta de Python, pode usar a API GeoPy , combinada com as ligações GDAL Python ou Fiona , e criar um script muito básico como esse para converter os endereços em um shapefile de ponto.

Isso irá geolocalizar um arquivo chamado 'address_to_geocode', criando um shapefile de saída chamado 'my_output.shp' na pasta 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')

O arquivo deve ter apenas uma linha para um único endereço, como por exemplo:

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

Aqui estou usando a API do Google, mas com o GeoPy é muito básico mudar para API diferente, como Yahoo !, GeoNames ou MapPoint .

capooti
fonte
Isso é ótimo! Valeu cara! De qualquer forma, no momento (01/2016), 'geocoders.Google ()' deve ser alterado para 'geocoders.GoogleV3 ()' como em geopy.readthedocs.org/en/1.11.0
umbe1987
1

Outra opção para resolver seu problema seria importar seu conjunto de dados para tabelas de fusão e definir o campo de endereço como local. Em seguida, ele codificará os pontos automaticamente. Depois de concluído, você pode exportar os dados como KML.

Ou ... como alternativa, você pode escrever um script php para usar o geocoder do yahoo, que tem um limite de 50.000 registros; assim, mais cedo ou mais tarde, todos os seus pontos serão geocodificados no banco de dados.

Espero que isso tenha ajudado!

EZMapdesign
fonte
tamas obrigado, mas eu não gostaria de obter o kml e, em seguida, buscar as informações de lá para m db. Eu gosto da ideia de geocodificação do yahoo, mas não tenho muita certeza da precisão, pois nunca usei o yahoo para mapeamento. Entre em contato se você tiver algum script escrito ou algo assim. Esta é uma grande ajuda
user1089553 22/03
Tenha em mente que o uso de Yahoo (ou Google, para que o assunto) geocoder com consultas automáticas ou sem mostrar um mapa irá violar TOS ...
Matt
Tanto quanto eu sei, não é se você apresentar a saída em um mapa. Corrija-me se eu estiver errada!
EZMapdesign
@Tamas Kind of. Veja isso, no entanto: developers.google.com/maps/terms#section_10_1_3
Matt
0

Talvez não seja a melhor resposta para sua pergunta, mas você pode tentar o BatchGeo. A versão gratuita faria você sofrer muito, mas ainda era bom o suficiente para o meu trabalho. No entanto, nós compramos a versão pro.

O truque para obter coordenadas do arquivo KML é importá-lo para o ArcGIS posteriormente.

Anıl Çelik
fonte
Obrigado, você pode me dizer como eu faço um BatchGeo, também você saberia os nomes da versão gratuita (eu estava tentando pelo Google Map api v3). Isso também significa que eu tenho que armazenar os valores Lat / Long no meu banco de dados para mapeá-lo. Isto é o que eu pretendia fazer em primeiro lugar.
user1089553
Com o BatchGeo, você terá que importar o KML para o seu banco de dados e extrair as coordenadas. Não conheço outra maneira, pois o Google proíbe fornecer coordenadas. Sobre o Yahoo, minha experiência com a Turquia não é realmente brilhante. A maioria dos países em desenvolvimento fica de fora do escopo do Yahoo. Anil.
22612 Anıl Çelik
0

Eu tenho usado com êxito a geopy que usa o serviço da web de geocodificação do Google. Funciona perfeitamente para até 2k pontos por 24 horas.

Matej
fonte
0

Matej, isso porque a API do Google permite gerar até 2,5 mil por dia.
Sobre a solução Geo, o lote ainda não é suportado, porque, a partir da minha análise do código geo python, parece que ele abre uma conexão toda vez que ele solicita um novo cordinate, 300k provavelmente ficará para sempre (provavelmente com o erro 400).
Jogar com Poligons deve funcionar, mas depende de qual é a sua área 'Play ground', se é 1 país ou n países.
Para um país, os polígonos devem funcionar muito bem.
Para n países, a solução não funcionará, pois a coleta levará mais tempo sempre que você adicionar outro país. O melhor aproch para fazê-lo é carga preguiçosa.
=> comece com a idéia do polígono, tudo em outro país, crie uma grande tabela de banco de dados para armazenar os dados; eventualmente, você manterá os dados que você precisa, suponho.

Benjaminel
fonte
0

Se você quiser fazer isso com PHP - MySQL, aqui está uma solução que funcionou para mim:

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

Experimente esta API de geocodificação . É gratuito para uso pequeno, mas se você quiser mais, eles pagam. No entanto, é barato e você pode processar com muita facilidade, eu processo milhões por mês através deles.

John M.
fonte
0

Você pode salvar seus dados como um arquivo de texto (um registro por linha) e depois codificá-lo em lote usando este serviço: http://geocode.xyz/batch (funciona na maioria dos países europeus)

ou, você pode escrever seu próprio código para acessar a API REST / JSON: http://geocode.xyz/api (é gratuito para pesquisas ilimitadas)

Ervin Ruci
fonte
0

Use as ferramentas Mappointing (Apontar mapa | Ferramenta de geocodificação em lote ( http://www.mappointing.com/ )) Nesta ferramenta, você pode processar os dados usando a chave de API gratuita do mapa do Google. E também esta ferramenta está fornecendo Cálculo de distância e ferramenta de busca de local.

Debasis Sahu
fonte
Por que isso não atingiu o mesmo OP de limite de API mencionado?
Lynxlynxlynx