Как геокодировать 300 000 адресов на лету?

18

У меня есть база данных, которая имеет 300 000 адресов, которые должны быть показаны на карте. Я знаю, если я геокодирую все адреса, это будет слишком дорого для меня. Поэтому мне было интересно, можно ли геокодировать адрес на лету / в реальном времени, когда пользователь выбирает адрес (адрес свойства), он выполняет поиск в базе данных, а затем геокодирует адрес и затем сопоставляет его с другие атрибуты.

Было бы очень хорошо, если бы вы могли поделиться кодом, концепцией или чем-то еще. Кстати мой бэкэнд на mysql поддерживается Joomla.

user1089553
источник
Я обычно использую возможность геокодирования ArcGIS для геокодирования большого количества адресов. Кроме того, мне очень интересны процессы, описанные здесь, в частности, такие как тестирование сценария python для геокодирования адресов с помощью Google, а затем сравнение их с тем, что я получил от ArcGIS. К сожалению, мне кажется, что я не могу найти все связанные файлы и сценарии, которые находятся в разных местах. Буду очень признателен, если кто-нибудь отправит мне все сценарии в одном zip-файле или пошаговую инструкцию. Я пытался использовать его и получить некоторую обратную связь с вами, но мне это не удалось
Housh

Ответы:

15

Мехул, я работал в индустрии верификации адресов с компанией SmartyStreets. Существует множество сервисов геокодирования, но лишь немногие будут поддерживать пакетную обработку с требуемым объемом. (Google и другие не разрешают массовое использование их API или сохранение / кэширование результатов.)

Если вы зайдете в базу данных MySQL и выполните экспорт таблицы, содержащей адреса, сохраните ее, например, в виде CSV-файла. Затем вы можете обработать его с помощью веб-инструмента SmartyList или инструмента командной строки . Как я уже сказал, есть несколько сервисов, но вы, я полагаю, захотите что-то, что также проверяет наличие адресов (отсюда и причина геокодирования) - если адрес неправильный или неполный, то же самое можно сказать и о результатах геокодирования. , Только несколько служб делают это.

LiveAddress - это сервис, сертифицированный CASS USPS. Есть некоторые из них, так что сделайте свое исследование, но вы хотите что-то "на лету" / быстро и недорого, поэтому я снова рекомендую LiveAddress. Он будет не только проверять адрес, но и делать то, что вам нужно, что дает информацию о широте и продолжительности, а также точность результатов геокодирования. Все это основано на веб-технологиях и будет обрабатывать десятки миллионов записей в кратчайшие сроки (см. Этот вопрос в качестве справочного материала ).

Если в дальнейшем вам необходимо геокодировать адреса при взаимодействии пользователей, LiveAddress также имеет версию API, которая может подключаться практически ко всему, а также поддерживает пакетную обработку на лету, но оплачивается как подписка, а не единовременно. оплата.

Matt
источник
Не знаком с SmartyStreets, выглядит многообещающе, спасибо за внимание.
Дерек Суингли
API LiveAddress сделает 300 000 примерно за 5-10 минут. Служба LiveAddress for Lists (загрузить список для обработки) занимает 15-20 минут. Оба довольно быстрые. Служба списка не потребует от вас написания какого-либо кода.
Джеффри
2
SmartyStreets только геокоды для США?
Mapperz
У меня есть данные, которые для Сингапура это будет работать? Если бы не какие-либо направления вы могли бы дать мне ????
user1089553
С Google Bing и другими поставщиками существует множество правил авторского права. Вы не экспортируете данные!
11

Если вам нравится Python, вы можете использовать GeoPy API в сочетании с привязками GDAL Python или Fiona и создать очень простой скрипт, подобный этому, для преобразования адресов в точечный шейп-файл.

Это позволит определить местоположение файла с именем «address_to_geocode», создавая выходной шейп-файл с именем «my_output.shp» в папке 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')

Файл должен содержать строку для одного адреса, например:

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

Здесь я использую Google API, но с GeoPy очень просто переключаться на разные API, такие как Yahoo !, GeoNames или MapPoint .

capooti
источник
Это круто! Спасибо чувак! В любом случае, в настоящее время (01/2016), geocoders.Google () следует изменить на geocoders.GoogleV3 (), как в geopy.readthedocs.org/en/1.11.0
umbe1987
1

Другой вариант решения вашей проблемы - импортировать ваш набор данных в таблицы слияния и установить поле адреса в качестве местоположения. Затем он будет геокодировать точки автоматически. После этого вы можете экспортировать данные в формате KML.

Или ... в качестве альтернативы, вы можете написать php-скрипт для использования геокодера Yahoo, который имеет ограничение в 50 000 записей, поэтому рано или поздно у вас будут все геокодированные точки в вашей базе данных.

Я надеюсь, что это помогло!

EZMapdesign
источник
спасибо Тамас, но я не хотел бы получить кмл, а затем получить информацию оттуда, а затем в дБ. Мне действительно нравится идея геокодирования Yahoo, но я не слишком уверен в точности, которую он имеет, так как я никогда не использовал Yahoo для картографирования. Пожалуйста, дайте мне знать, если у вас есть сценарий или что-то еще. Это отличная помощь
user1089553
Имейте в виду, что использование геокодера Yahoo (или Google, в этом отношении) с автоматическими запросами или без отображения карты нарушит TOS ...
Matt
Насколько я знаю, это не так, если вы представляете результаты на карте. Поправь меня, если я ошибаюсь!
EZMapdesign
@ Тамас Вид. Посмотрите это, однако: developers.google.com/maps/terms#section_10_1_3
Мэтт
0

Возможно, не самый лучший ответ на ваш вопрос, но вы можете попробовать BatchGeo. Бесплатная версия заставила бы вас сильно страдать, но все же была достаточно хороша для моей работы. Хотя мы купили про версию.

Хитрость для получения координат из файла KML состоит в том, чтобы импортировать его в ArcGIS позже.

Анил Челик
источник
Спасибо, можете ли вы сказать мне, как мне сделать BatchGeo, также вы бы знали названия бесплатной версии (я пытался для Google Map api v3). Также это означает, что мне нужно хранить значения широты / долготы в моей базе данных, чтобы отобразить их. Это то, что я собирался сделать в первую очередь.
user1089553
С BatchGeo вам придется импортировать KML в вашу базу данных, а затем извлекать координаты, другого пути я не знаю, так как Google запрещает указывать координаты. Что касается Yahoo, мой опыт с Турцией не очень яркий. Большинство развивающихся стран остаются вне сферы действия Yahoo. Анил.
Анил Челик
0

Я успешно использую Geopy, который использует веб-сервис геокодирования Google. Он отлично работает до 2 тыс. Баллов в сутки.

Матей
источник
0

Матей, это потому, что Google API позволяет тянуть до 2,5к в день.
Что касается решения Geo, пакет пока не поддерживается. Это связано с тем, что из моего обзора кода geo python кажется, что он открывает соединение каждый раз, когда запрашивает новый кординат, 300k, вероятно, зависнет навсегда (возможно, с ошибкой 400).
Игра с Полигонами должна помочь, но это зависит от того, какая у вас игровая площадка, если это 1 страна или n стран.
Для 1 страны полигоны должны работать довольно хорошо.
Для n стран решение не будет работать, так как сбор будет занимать больше времени, когда вы добавляете другую страну. Лучший способ сделать это - ленивая нагрузка.
=> начните с идеи многоугольника, каждая вещь в другой стране, создайте большую таблицу базы данных для хранения данных, в конечном итоге вы будете хранить те данные, которые вам нужны, я полагаю.

Benjaminel
источник
0

Если вы хотите сделать это с PHP - MySQL, вот решение, которое сработало для меня:

<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
источник
0

Попробуйте это геокодирование API . Это бесплатно для небольшого использования, но если вы хотите больше, они заставляют вас платить. Однако это дешево, и вы можете легко это обработать, я через них обрабатываю миллионы в месяц.

Джон М.
источник
0

Вы можете сохранить свои данные в виде текстового файла (одна запись на строку), а затем выполнить геокодирование пакета с помощью этого сервиса: http://geocode.xyz/batch (работает для большинства европейских стран)

или вы можете написать свой собственный код для доступа к API REST / JSON: http://geocode.xyz/api (это бесплатно для неограниченного поиска)

Эрвин Ручи
источник
0

Используйте инструменты картирования (наведение карты | инструмент пакетного геокодирования ( http://www.mappointing.com/ )). В этом инструменте вы можете обрабатывать данные с помощью бесплатного API-ключа карты Google. А также этот инструмент обеспечивает расчет расстояния и поиск места.

Дебасис Саху
источник
Почему это не достигнет того же упомянутого предела ОП API?
lynxlynxlynx