Однажды мне потребовалось получить из сырых ОСМ данных чистый сабсет города (потому что так удобно, компактно и просто красиво). К моему удивлению я не нашел готового рецепта, из-за чего для выполнения этой задачи потребовалось немного попотеть.

Ввиду вышеизложенного считаю своим долгом поделиться накопленным опытом.

Кишинев OSM

Допустим я хочу получить сабсет Кишинёва (почему? … там тепло, там мой дом, там моя мама)

Planet.osm нас, конечно, не интересует, зато есть geofabrik, но там планета нарезана на достаточно крупные шматки — http://download.geofabrik.de/europe/moldova.html

Значит, граница города есть в сырых данных.

Из отношения несложно получить полигон, делаем это либо руками, либо при помощи любой подходящей утилиты, например, этой.

Иии… теперь в игру вступает osmosis.

У нас есть осм всея Молдовы и ограничивающий полигон Кишинёва, этого вполне достаточно для получения сабсета города из сырого XML (OSM) файла:

osmosis --read-xml file="moldova.osm" --bounding-polygon file="kishinev.poly" --write-xml file="kishinev.osm"

Аналогично можно выковырять данные из PBF (Protocolbuffer Binary Format) файла:

osmosis --read-pbf file="moldova.osm.pbf" --bounding-polygon file="kishinev.poly" --write-xml file="kishinev.osm"

Немногим больше про osmosis можно почитать здесь.

Ну а готовый сабсет нужно срочно открывать в JOSM или импортировать в личный проект!

Кишинев JOSM

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


  1. Barbaresk
    11.08.2019 23:06

    Интересный твит


  1. kivsiak
    11.08.2019 23:30
    +2

    Зашёл в надежде обнаружить какую-то технику построения запросов а обнаружил вырезку по полигону.


    https://wiki.openstreetmap.org/wiki/Osmosis/Examples#Extract_administrative_Boundaries_from_a_PBF_Extract


  1. guleaevvlad
    12.08.2019 10:18

    лайк за Кишинев


    1. Vornic
      12.08.2019 10:20

      Да тут полно земляков )))
      А что за инструмент разрабатываете, для чего вам нужны границы города?


      1. sergpank Автор
        12.08.2019 13:30

        Да вот пилю в свободное время свой рендер для OSM — onemap.md


  1. Zverik
    12.08.2019 11:46

    Ох ужас какой. Osmosis старый, дико медленный и вообще не поддерживается автором.

    Современный и быстрый способ — использовать Osmium Tool. Аналог команды, которую привёл автор:

    osmium extract -p kishinev.poly moldova.osm.pbf -o kishinev.osm

    (Кстати, кто вообще в наше время использует несжатый текстовый формат osm xml? Есть же куча библиотек — тот же osmium — чтобы не мучаться.)

    Ну так вот, а теперь к задаче, которая определена в заголовке, но про которую в статье молчок. Как вырезать кусок из файла OSM, определённый отношением границы внутри этого файла? В случае с osmium tool, понадобятся две команды: получить границу из отношения Кишинёва и вырезать данные по ней.

    osmium getid -r moldova.osm.pbf r1748490 -o kishinev_boundary.osm
    osmium extract -p kishinev_boundary.osm moldova.osm.pbf -o kishinev.osm.pbf

    Всё по документации. Там ещё много интересного: преобразование форматов, фильтрация по тегам, получение данных на момент в прошлом, работа с файлами изменений и тому подобное. Osmosis нынче используют только и исключительно для автообновления базы osm2pgsql, да и то только потому, что альтернативу ещё не успели написать. Хотя для рендеринга уже есть скрипты на основе питоновского интерфейса к osmium.


    1. sergpank Автор
      12.08.2019 13:34

      Спасибо за ценный коментарий и годную альтернативу. Мне это очень пригодится.
      К сожалению, я варюсь в собственном соку и собираю нужную мне информацию по крупицам :)


      1. Zverik
        12.08.2019 14:09
        +1

        Основные преимущества — размер и бинарный формат. За их счёт чтение выполняется на порядок быстрее. Для кода разницы вообще никакой, особенно если используете библиотеку типа osmium или любую другую, умеющую в protobuf. Альтернативный вариант — xml, сжатый с помощью bzip2, но это тоже теперь считается медленно и вдвое больше pbf.


        Небольшие датасеты в процессе работы имеют тенденцию вырастать — например, «хорошо Кишинёв сделал, а можешь то же самое на всех остальных городах».


        Ковыряться в геоданных в текстовом редакторе просто не нужно. XML в саблайме — это совсем не легко и быстро. Это бороться с тонной визуального мусора и держать в голове всю структуру. Зачем, если можно открыть файл в JOSM (который умеет и pbf, если подключить одноимённый модуль) и пользоваться и визуальным отображением, и супер-мощным поиском-фильтрацией, и редактором, наконец.


        1. sergpank Автор
          12.08.2019 14:47

          Спасибо.
          Конечно работать с датасетами размера Planet.osm, или даже Moldova.osm уже довольно сложно и медленно, поэтому я и опустился до уровня небольшого города — 50..100 МБ

          Касательно нужно ли в принципе ковыряться в геоданных… т.к. я пишу свой велосипедный тайлгенератор (просто так 4fun), самостоятельно готовлю для него данные и далее по конвееру, для меня это важно. К тому же данные в OSM нерегулярные, часто содержат ошибки вроде дороги из одной точки, дома из двух, да и использование тегов тоже не всегда однозначное )

          Но в общем да, PBF + JOSM норм альтернатива для OSM + Sublime )


          1. Zverik
            12.08.2019 15:06

            А почему обрабатываете файлы osm с нуля, а не загружаете данные в базу с помощью osm2pgsql? Там все эти мелкие проблемы давно решены, плюс получите обновления в реальном времени и выборки данных по тайлам.


            1. sergpank Автор
              12.08.2019 23:59

              Изначально я разделял данные по таблицам, игрался с индексами чтобы ускорить выполнение запросов, сейчас структура моей базы близка к тому что генерирует osm2pgsql, наверное скоро перейду на этот вариант, хотя оно импортирует много ненужной для моих целей инфы, надо будет тестировать.

              А можно поподробнее на счет обновлений в реальном времени и выборки по тайлам? сейчас я обновляю все перезаписью базы, а тайлы выбираю самописным алгоритмом.


              1. freeExec
                13.08.2019 10:34

                хотя оно импортирует много ненужной для моих целей инфы

                Документацию не читай, в не доработках обвиняй — github.com/openstreetmap/osm2pgsql/blob/master/default.style
                А можно поподробнее на счет обновлений в реальном времени

                Режим --slim он будет хранить в базе сырые данные ОСМ, что позволит обновлять минутными изменениями. Но безупречно работает только для планеты целиком. На обрезках может случиться что будут задействованы объекты которых у вас нет в базе, но они засветились в изменениях.


  1. sergpank Автор
    12.08.2019 14:43

    удалено


  1. lemos
    12.08.2019 16:32

    А можно ли сразу как-то загрузить файл *.osm.pbf нужной области (без предварительной загрузки Planet.osm)?


    1. sergpank Автор
      12.08.2019 23:54

      Конечно, здесь вы можете скачать нужную область — http://download.geofabrik.de/
      И уже из нее вырезать сабсет по границе.


      1. lemos
        13.08.2019 11:20

        Я так и делаю обычно при создании карт для навигатора. Но если это две страны (например Россия и Норвегия), то приходится: 1) скачивать весь Северо-запад России, и всю Норвегию, 2) объединять карты, из-за чего при маршруторизации на границе возникают ошибки. Поэтому было бы проще и лучше загрузить только нужную область, не зависящую от административных границ.


        1. sergpank Автор
          13.08.2019 19:43

          Кэп подсказывает что вам было удобнее всего самостоятельно извлечь данные из planet.osm либо придумать как сшивать дороги разрезанные границей (когда-то в одном проекте мы так и поступали, потому что данные приходили по регионам, но «гейтвеи» нам поставляли в отдельной таблице, так что это были тривиально).

          Просто мысли вслух — Возможно удастся ускорить вырезку из planet.osm если проводить ее в 2 этапа — сначала вырезать участок прямоугольной формы (теоретически это должно быть быстро), а потом из него уже вырезать участок нужного вам региона — СЗ России+Норвегия…