...

четверг, 26 января 2017 г.

OpenStreetMap, как получить координаты адреса, часть простая


Последнее время наблюдаю тенденцию, что всё больше и больше людей сталкиваются с проблемами в отсутствии геоданных. Вернее даже не так, в их закрытости. Если ещё вчера всех устраивали возможности картографических сервисов по расстановке маркеров, то теперь пользователь хочет большего: подсветить улицу, показать дома на ней, посчитать протяжённости рек и т.д. И тут их ожидает сюрприз, казалось бы на карте они всё это видят, но сделать ни чего не могут — это просто картинки. Развитие, что Google.Maps, что Яндекс.Карт остановилось на показе картинок, геокодинге, да навигации.


Шаг вправо, шаг влево и ты в тупике. Единственный путь — воссоздать необходимую геометрию самому. И если нарисовать дорогу и десяток домиков по улице вполне быстро и легко, то скажем сотня другая километров водного пути отбивает всё желание.
Именно в такие трудные моменты за спинами разрекламированных Google и Яндекс становится виден проект OpenStreetMap, и заявляет он: — Данные у меня есть, хочешь которые ты.


Да, возможно не такие полные местами, но именно геоданные, а не весёлые картинки. А это открывает большие возможности по их обработки и анализу. К тому же данные доступны по открытой лицензии ODbL и имеют два главных условия использования: обязательная ссылка на источник данных (участники OpenStreetMap) и в случае публичных производных данных они должны быть также опубликованы по лицензии ODbL.


Поехали


А теперь собственно окунёмся в эти данные. Сегодня наша цель извлечь из них адреса и получить их координаты. Причём будем делать это не поштучно, как это делают геокодеры — вводя адрес и получая координаты, а сразу все имеющиеся. Сохранять результат будем в CSV.


Особенность простого способа в том, что нам не нужны ни какие базы данных, знай себе копируй и вставляй. Но чтобы это было возможно, придётся идти на жертвы. А именно, наше упрощение в том, что адреса мы будем извлекать для заранее оговоренного одного населённого пункта. Мы просто первоначально ограничим наши поиски заданной территорией — нужный населённый пункт вырежем из общего набора данных.


Исходный материал


Итак, отправная точка — это данные OSM о всей планете. Но они очень большие, поэтому если нам не нужно покрытие всей планеты, то берут более локальные территории например на Geofabric разбито по континентам. Для российского сегмента наилучший вариант Gis-Lab, где удобно нарезаны файлы по регионам. Забираем необходимый файл региона в формате pbf.


Инструменты


Для дальнейшей работа нам понадобятся инструменты osmconvert и osmfilter. C помощью первого можно конвертировать данные из разных форматов и обрезать, оставляя только интересующие области, уменьшая тем самым объём и как следствие скорость обработки. Второй предназначен для фильтрации объектов по их свойствам.


Обрезание, хм… Вырезание области


Как и договаривались, нам необходимо локализовать данные только для нашего населённого пункта. С помощью osmconvert, это можно сделать топорно, задав ограничивающий прямоугольник двумя точками. За это отвечает параметр -b=<x1>,<y1>,<x2>,<y2> задаются южно-западная точка и северо-восточная. Если же у населённого пункта сложная форма и прямоугольная вырез не подходит можно создать полигон обрезки из ломанных линий. Параметр для задания такого файл будет -B=file.poly. Формат у него довольно прост: первая строка — название; затем «1» номер контура; далее перечисляем координаты точек, которые бы целиком охватывали наш НП и где последняя точка замыкается на первую; конец контура; конец файла. Больше информации о формате и как его можно получить.


А вот пример файла:


kursk
1
   36.035249   51.838105
   35.991534   51.562810
   36.125976   51.563141
   36.317305   51.681037
   36.333813   51.780274
   36.159021   51.837612
   36.035249   51.838105
END
END

Главное чтобы дома из соседних НП не попали к нам в вырезаемую область. Так же для упрощения превратим все дома в точки, для этого используем ключ --all-to-nodes. Выходной файл попросим сделать в формате o5m (достаточно указать расширение у файла), так как другая утилита умеет работать только с ним.
В итоге первая команда будет у нас такая:


osmconvert.exe -B=city.poly --all-to-nodes RU-Region.pbf -o=1_to-node.o5m

Теперь у нас есть точечные данные только из заданной области. Но там много того, что нам в итоге не нужно, например дороги, парки, заборы и т.д.


Фильтрация


Поэтому следующим шагом мы отфильтруем из всего многообразия только дома содержащие адреса. Дома в OSM обозначаются тегом builder, а адресная информация в тегах начинающихся на addr. Так же отбросим информацию об авторе и версии объекта, она нам просто не нужна.


osmfilter.exe 1_to-node.o5m --keep="building AND addr*" --drop-author --drop-version -o=2.building-addr.o5m

Ну вот файл ещё раз уменьшился в размерах и теперь настал момент посмотреть что же там внутри осталось. Самое время превратить его во что-то человеко-читаемое. Как и обещал это будет CSV.


Результат


Воспользуемся всё тем же osmconvert, в котором предусмотрен вывод в CSV. Из параметров стоит заострить внимание на колонки и из каких тегов вставляется в них информация.


osmconvert.exe 2.building-addr.o5m -o=3.addr.csv --csv-headline --csv-separator=; --csv="@id addr:street addr:housenumber @lat @lon"

@id addr:street addr:housenumber @lat @lon
1000000147959515 улица Масалова 25А 51.6522509 36.0337820
1000000147960436 Школьная улица 71 51.6546536 36.0139438
1000000147965426 улица Котова Гора 1 51.7337383 36.1837660

Ну вот, это уже какие-то да геоданные и их можно вставить в ГИС и как-то проанализировать, что и видно на представленной в начале картинке.


Но тема не ограничивается только адресами. На втором шаге можно оставить например остановки общественного транспорта и визуализировать транспортную доступность. Впрочем это уже совершенно из другой статьи...

Комментарии (0)

    Let's block ads! (Why?)

    Комментариев нет:

    Отправить комментарий