¿Cómo geocodificar 300,000 direcciones sobre la marcha?

18

Tengo una base de datos que tiene 300,000 direcciones, que se mostrarán en el mapa. Sé que si geocodifico toda la dirección, será demasiado costosa para mí. Así que me preguntaba si es posible geocodificar la dirección sobre la marcha / en tiempo real, cuando un usuario selecciona una dirección (una dirección de propiedad) buscará a través de la base de datos y luego geocodifica la dirección y luego la asigna con Otros atributos.

Sería realmente bueno si pudieras compartir un código, concepto o cualquier cosa. Por cierto, mi backend está en mysql compatible con Joomla.

usuario1089553
fuente
Generalmente uso la capacidad de geocodificación ArcGIS para geocodificar un gran número de direcciones. Además, estoy realmente interesado en los procesos explicados aquí, especialmente, como probar el script de Python para geocodificar las direcciones usando Google, luego compararlas con lo que obtuve de ArcGIS. Desafortunadamente, me parece que no puedo encontrar todos los archivos y scripts relacionados que están en diferentes lugares. Le agradecería mucho que alguien me envíe todos los scripts en un archivo zip o cualquier instrucción paso a paso. Traté de usarlo y obtener algunos comentarios, pero no tuve éxito
Housh

Respuestas:

15

Mehul, solía trabajar en la industria de verificación de direcciones con una compañía llamada SmartyStreets. Existen muchos servicios de geocodificación, pero solo unos pocos admitirán el procesamiento por lotes con el volumen que necesita. (Google y otros no permiten el uso masivo de su API o el almacenamiento / almacenamiento en caché de resultados).

Si va a su base de datos MySQL y realiza una exportación de su tabla que contiene las direcciones, guárdela como un archivo CSV, por ejemplo. Luego puede procesarlo utilizando la herramienta web SmartyList o la herramienta de línea de comandos . Como dije, hay varios servicios disponibles, pero supongo que también querrá algo que verifique la existencia de direcciones (de ahí la razón de la geocodificación): si la dirección es incorrecta o está incompleta, también lo son los resultados de la geocodificación . Solo unos pocos servicios hacen esto.

LiveAddress es un servicio certificado por CASS por USPS. Hay algunos por ahí, así que investigue, pero quiere algo "sobre la marcha" / rápido y económico, así que nuevamente recomiendo LiveAddress. No solo verificará la dirección, sino que hará lo que necesite, que es proporcionar información de lat / lon y también la precisión de los resultados de geocodificación. Todo está basado en la web y procesará decenas de millones de registros en muy poco tiempo (vea esta pregunta como referencia ).

Si aún necesita geocodificar direcciones a medida que los usuarios interactúan, LiveAddress también tiene una versión API que se puede conectar a casi cualquier cosa y también admite el procesamiento por lotes sobre la marcha, pero se paga como una suscripción, no una sola vez. pago.

Mate
fuente
No está familiarizado con SmartyStreets, parece prometedor, gracias por el aviso.
Derek Swingley
La API LiveAddress hará 300,000 en aproximadamente 5-10 minutos. El servicio LiveAddress for Lists (cargar una lista para procesar) tarda entre 15 y 20 minutos. Ambos bastante rápidos. El servicio de Lista no requerirá que escriba ningún código.
Jeffrey
2
¿SmartyStreets solo geocodifica para los Estados Unidos?
Mapperz
Tengo datos que son para Singapur ¿funcionará? Si no hay alguna dirección que puedas darme ????
user1089553
Existen muchas reglas de copyright con Google Bing y otros proveedores. ¡No exportas datos!
11

Si le gusta Python, puede usar la API GeoPy , combinada con los enlaces de Python GDAL o Fiona , y crear un script muy básico como este para convertir las direcciones en un archivo de forma de puntos.

Esto geolocalizará un archivo llamado 'Address_to_geocode', creando un archivo de forma de salida llamado 'my_output.shp' en la carpeta 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')

Se supone que el archivo tiene solo una línea para una sola dirección, como por ejemplo:

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

Aquí estoy usando la API de Google, pero con GeoPy es muy básico para cambiar a diferentes API, como Yahoo !, GeoNames o MapPoint .

capooti
fuente
¡Esto es genial! ¡Gracias hombre! De todos modos, en la actualidad (01/2016), 'geocoders.Google ()' debería cambiarse a 'geocoders.GoogleV3 ()' como en geopy.readthedocs.org/en/1.11.0
umbe1987
1

Otra opción para resolver su problema sería importar su conjunto de datos a tablas de fusión y establecer el campo de dirección como ubicación. Luego geocodificará los puntos automáticamente. Una vez que se haya completado, puede exportar los datos como KML.

O, alternativamente, puede escribir un script php para utilizar el geocodificador de yahoo que tiene un límite de 50 000 registros, por lo que tarde o temprano tendrá todos sus puntos geocodificados en su base de datos.

¡Espero que esto haya ayudado!

EZMapdesign
fuente
gracias tamas pero no me gustaría obtener el kml y luego buscar la información desde allí y luego a m db. Me gusta la idea de la geocodificación de Yahoo, pero no estoy muy seguro de la precisión que tiene, ya que nunca he usado Yahoo para el mapeo. Por favor, avíseme si tiene algún guión escrito o algo. Esta es una gran ayuda
user1089553
Tenga en cuenta que usar Yahoo (o Google, para el caso) geocodificador con consultas automáticas o sin mostrar un mapa violará los TOS ...
Matt
Que yo sepa, no lo es si presentas el resultado en un mapa. ¡Corrígeme si estoy equivocado!
EZMapdesign
@Tamas Tipo de. Sin embargo, vea esto: developers.google.com/maps/terms#section_10_1_3
Matt
0

Tal vez no sea la mejor respuesta a su pregunta, pero puede probar BatchGeo. La versión gratuita te haría sufrir mucho, pero aún así fue lo suficientemente bueno para mi trabajo. Sin embargo, hemos comprado la versión pro.

El truco para obtener coordenadas del archivo KML es importarlo a ArcGIS más adelante.

Anıl Çelik
fuente
Gracias, ¿pueden decirme cómo hago un BatchGeo, también sabrían los nombres de la versión gratuita (estaba intentando la API v3 de Google Map). Esto también significa que tengo que almacenar los valores Lat / Long en mi base de datos para poder mapearlo. Esto es lo que pretendía hacer en primer lugar.
user1089553
Con BatchGeo, tendrá que importar KML a su base de datos y luego extraer las coordenadas, no sé de otra manera, ya que Google prohíbe proporcionar coordenadas. Acerca de Yahoo, mi experiencia con Turquía no es realmente brillante. La mayoría de los países en desarrollo quedan fuera del alcance de Yahoo. Añil.
Anıl Çelik
0

He estado usando con éxito geopy que usa el servicio web de geocodificación de Google. Funciona perfectamente por hasta 2k puntos por 24 horas.

Matej
fuente
0

Matej, eso es porque la API de Google permite obtener hasta 2.5k por día.
Acerca de la solución Geo, todavía no se admite que el lote sea compatible, porque, según mi revisión del código geo python, parece abrir la conexión cada vez que solicita un nuevo cordinado, 300k probablemente se quedará para siempre (probablemente con el error 400).
Jugar con Poligons debería ser el truco, pero depende de cuál sea su área de 'Play ground', si es 1 país o n países.
Para 1 país, los polígonos deberían funcionar bastante bien.
Para n países, la solución no funcionará, ya que la recopilación llevará más tiempo cada vez que agregue otro país. La mejor manera de hacerlo es la carga perezosa.
=> Comience con la idea del polígono, cada cosa en otro país, cree una gran tabla de base de datos para guardar los datos, eventualmente tendrá los datos que necesita, supongo.

Benjaminel
fuente
0

Si quieres hacerlo con PHP, MySQL aquí es una solución que funcionó para 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>
pancy1
fuente
0

Prueba esta api de geocodificación . Es gratis para uso pequeño pero si quieres más te hacen pagar. Sin embargo, es barato y podría procesarlo con mucha facilidad, yo proceso millones al mes a través de ellos.

John M.
fuente
0

Puede guardar sus datos como un archivo de texto (un registro por línea) y luego geocodificarlos por lotes utilizando este servicio: http://geocode.xyz/batch (funciona para la mayoría de los países europeos)

o puede escribir su propio código para acceder a la API REST / JSON: http://geocode.xyz/api (es gratis para búsquedas ilimitadas)

Ervin Ruci
fuente
0

Utilice las herramientas de Mappointing (Map puninting | Batch Geocoding Tool ( http://www.mappointing.com/ )) En esta herramienta puede procesar los datos utilizando la clave API gratuita del mapa de Google. Y también esta herramienta proporciona herramienta de cálculo de distancia y búsqueda de lugar.

Debasis Sahu
fuente
¿Por qué esto no alcanzaría el mismo límite API mencionado por OP?
lynxlynxlynx