Последнее время наблюдаю тенденцию, что всё больше и больше людей сталкиваются с проблемами в отсутствии геоданных. Вернее даже не так, в их закрытости. Если ещё вчера всех устраивали возможности картографических сервисов по расстановке маркеров, то теперь пользователь хочет большего: подсветить улицу, показать дома на ней, посчитать протяжённости рек и т.д. И тут их ожидает сюрприз, казалось бы на карте они всё это видят, но сделать ни чего не могут — это просто картинки. Развитие, что 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 |
Ну вот, это уже какие-то да геоданные и их можно вставить в ГИС и как-то проанализировать, что и видно на представленной в начале картинке.
Но тема не ограничивается только адресами. На втором шаге можно оставить например остановки общественного транспорта и визуализировать транспортную доступность. Впрочем это уже совершенно из другой статьи...
Автор: freeExec