Здравствуй, дорогой читатель.

Спешу поделиться тем, как на самом деле найти геоданные без регистрации и СМС. По чесноку. Без всяких-яких. И даже “подписывайтесь на телеграмм канал” - не будет, у меня его и нет…

И речь пойдёт про инструмент Osmosis.


Побудительный мотив

Сидел я тут намедни, и наткнулся на интереснейшую вещь: почти часовой подкаст на YouTube канале Хабра: Хабр Про. В чём магия геоданных и как их найти без регистрации и СМС. И тема то небезынтересна.

Но в подкасте было всё кроме ответа на главный вопрос: “как же их найти?”. И вот сижу я, обманутый, и думаю как восстановить справедливость. Вопрос поставлен, а ответа нет. И решил взять дело в свои руки - написать эту статью. Прошу любить и жаловать.

Зачем?

Не публикация, конечно, "зачем", а: "зачем получать геоданные".

Для исследований:

Кто сказал "урбанистика"?

Если создаёте свое приложение с блэкджеком... с картами:

А иногда просто по фану:

Да много всякого...

Так где?

Вопрос то поставлен ребром: без регистрации и СМС, а значит безвозмездно, то есть даром! Это ограничение оставляет нас, по большому счёту, с единственным известным мне вариантом: OSM.

В OSM прекрасно всё: он сбалансированный как инь и янь. Масштабный, открытый, универсальный, обо всём что может быть на карте, с бардаком, бесконечными спорами как надо и не надо картографировать и перманентно нестабильной документацией (посмотрите для интереса блок тегирование в новостях из мира OpenStreetMap), - всё как мы любим. Т.е. польза и энтропия зашкаливают.

Т.е. в нём есть всё, если нет - значит скоро будет, если ждать невозможно: занесите сами. Но в правилах чёрт ногу сломит. А раз правила гибкие, то и инструменты для работы с этими данными должны быть под стать: либо есть линия партии и “шаг влево, шаг вправо - расстрел”, либо “что хочу, то и ворочу”. А раз буква O в OSM это Open, то придерживаться будем “что хочу, то и ворочу”.

Инструмент подходящий есть - osmosis, и его-то я опишу, но будьте готовы: придётся вникать не только в команды инструмента, но и в правила OSM, примеры приведу, ссылки приложу, но прогулка не будет лёгкой, на блюдечке с голубой каёмочкой вам эти данные не получить: без СМС всё-таки, а значит придётся поработать.

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

Ну и не осмосисом единым, конечно же, есть, например, ещё osmium и д.р. см. Alternatives to osmosis.

Приготовления

Установка osmosis

Инструкции по установке доступны на OpenStreetMap Wiki.

Опишу таки как поставить на Windows:

  1. Для начала нужна Java.

  2. ...

  3. Качаем zip архив Osmosis c GitHub.

  4. Извлекаем архив.

По сути вся установка. Запустите командную строку. Перейдите в директорию, куда извлечён архив, найдите папку bin, например, D:\osmosis-0.49.2\bin, и выполните команду osmosis для проверки.

И так, ложка есть - инструмент установлен. Теперь пойдём добывать варенье.

Сырые данные

Данные нам нужны в формате PBF. Я их всегда качаю с geofabrik. Находим нужный регион - качаем. Есть и другие источники подробнее смотрите страницу Planet.osm на OpenStreetMap Wiki.

Данные получены. Осталось разобраться как это есть.

Работа с данными

Инструкцию по всем командам (версия 0.48) можно посмотреть всё там же: на Openstreetmap Wiki.

Важно понимать несколько вещей при работе в командной строке с Osmosis.

Термины

Задачи (Tasks)

В командной строке вы пишите последовательность задач (Tasks). Каждая задача начинается с символов --, например:

osmosis --read-pbf file=myfile.osm.pbf --write-null

Здесь две задачи --read-pbf и --write-null.

У задач есть сокращённая запись:

osmosis --rd file=myfile.osm.pbf --wn

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

Аргументы (Arguments)

Аргументы относятся к задачам, после которых они следуют, и являются парой ключ-значение.

Некоторые задачи могут принимать безымянные аргументы - аргументы «по умолчанию» - ключ не обязательно указывать. Если не указан ключ, то osmosis будет подставлять тот ключ, который соответствует аргументу «по умолчанию», вот это, одно и то же:

osmosis --read-pbf file=myfile.osm.pbf --write-null
osmosis --read-pbf myfile.osm.pbf --write-null

file - аргумент по-умолчанию для задачи --read-xml.

Потоки (Pipeline)

Задачи воспринимают данные как поток. Визуально это можно представить в виде пазлов:

  • команды которые создают поток из внешнего источника данных;

В документации к osmosis описан такой таблицей:

Pipe

Description

outPipe.0

Produces an entity stream.

  • команды которые принимают поток на вход, обрабатывают его, и возвращают результат в виде потока, в другие команды;

В документации к osmosis таблица будет выглядеть так:

Pipe

Description

inPipe.0

Consumes an entity stream.

outPipe.0

Produces an entity stream.

  • команды которые принимаю поток, и “сливают” его.

В документации к osmosis:

Pipe

Description

inPipe.0

Consumes an entity stream.

Я вместо таблиц буду иллюстрировать пазлами, очень уж они мне нравятся.

Таким образом у вас должны быть задачи создания потоков, возможно обработки потоков, возможно манипуляции потоками, и завершения потоков. И они должны выстраиваться в некую цепочку, как конвейер.
Задачи в последовательности можно ставить как угодно, - ошибки не будет, главное чтобы входящие потоки “следующей” задачи соотносились с исходящими потоками “предыдущей”.

Однако это “как угодно” будет, давать разные результаты. Последовательность задач имеет значение.

Это особенности работы с инструментом, - его философия. Понимание этих простых вещей сделает вашу работу с инструментом более осмысленной.

А теперь к задачам.

Задачи чтения

Начнём, конечно же с задач чтения, полагаем что дамп данных мы скачали таки в формате pbf.

--read-pbf (--rb)

Всё прозаично, - ничего не делает кроме как создаёт поток для чтения данных из файла, вся работа по обработке: правила выборки, сохранение - потом.

Имеет один параметр file, в котором указывается путь к файлу.

Ну и пример мы уже видели, посмотрим ещё раз:

osmosis --read-pbf file=myfile.osm.pbf --write-null

--read-xml (--rx)

Читает данные из файла структуры OSM XML.

Задачи записи

--write-xml (--wx)
--write-pbf (--wb)

Записывает поток, соответственно либо в OSM XML либо в PBF. В качестве аргумента принимает как минимум имя файла.

XML хотя бы человекочитаема, в большинстве примеров будем её использовать, чтобы можно было открыть и глазками посмотреть что там происходит.

Но погодите что-то куда-то записывать. Мало ли что за pbf файл вы добыли, просто прочитать его и сохранить - задача сомнительной полезности. Попробуем его сначала как-то урезать. С файлом поменьше и работать будет попроще.

Задачи фильтрации по области

--bounding-box (--bb)

Извлекает данные в пределах определённой ограничивающей рамки, задаваемой координатами широты и долготы.

И так, я скачал pbf со всем Уральским Федеральным Округом, а поскольку всё подряд мне не надо, - выберу один город, и сохраню его в отдельный pbf-файл.

osmosis \
    --read-pbf file=myfile.osm.pbf \
    --bounding-box top=57.2456 left=65.4316 bottom=57.0719 right=65.6945 \
    --write-pbf file=tyumen.osm.pbf

Координаты ставил на глаз, по гугл картам, всё что попало в этот прямоугольник, должно попасть и в итоговый pbf.

--bounding-polygon (--bp)

А эта для тех кто хочет заморочиться. Если прямоугольник по каким-то причинам не устраивает, то можно задать полигон произвольной формы. Задаётся прямоугольник серией координат широта/долгота, в отдельном файле, подробнее смотреть: Polygon Filter File Format.

Есть в интернетах уже готовые полигоны смотрите http://download.openstreetmap.fr/polygons/ например.

В целом с пространственными ограничениями - всё.

И про это уже писали на Хабре: Как вырезать сабсет города (любого отношения) из OSM данных.

Задачи фильтрации данных по атрибутам

По сути самый важный раздел - для него всё и затевалось, остальные задачи, - это так, вспомогательные.

Для этого раздела уже понадобится понимание структуры и правил OSM.

Важно знать что элементы в OSM трёх типов:

  • узлы (node), они же точки

  • пути (way), они же линии

  • отношения (relation), они же отношения (sic!)

Все задачи фильтрации оперируют этими тремя категориями.

Помимо этого у элементов OSM есть ещё такое понятие как теги. Теги описывают конкретные особенности элементов карты, это единственный способ как-то обозначить к чему относятся данные, см. Скованные одним слоем. Т.е. данные в OSM бесконечно расширяемые и неделимы (на слои) - собственно по этой причине и написана данная статья, было бы всё по слоям - писать было бы не о чем.

Ну а чтобы ответить на вопрос, какие теги бывают, можете заглянуть на страницу Category:Keys и оценить насколько глубока кроличья нора. И важно понимать что список не окончательный, - модель же бесконечно расширяема.

Ладно, переходим к задачам.

--node-key (--nk)
--way-key (--wk)

Фильтры по OSM тегам.

Учитывая список ключевых тегов (теги указываются в параметре keyList, через запятую), эти фильтры пропускают только те узлы или линии, соответственно, у которых установлен хотя бы один из этих тегов.

EBNF грамматика
EBNF грамматика

Например попробуем получить все линии дорог. Для обозначения дорог в OSM используется тег highway:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --way-key keyList=highway \
    --write-xml roads-way.osm.xml

Обратите внимание, что эти фильтры --node-key работает только с узлами, и ВЫБРАСЫВАЕТ все пути и отношения, а фильтр --way-key фильтрует только линии, но ОСТАВЛЯЕТ в потоке и узлы и отношения - никак их не фильтруя.

Можете попробовать сделать ещё аналогичный фильтр по узлам и сравнить результаты:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --node-key keyList=highway \
    --write-xml roads-node.osm.xml

В итоге файл roads-way.osm.xml - распух от несвязанных с дорожной инфраструктурой данных, а roads-node.osm.xml,... ну он получился предсказуемым.

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

--node-key-value (--nkv)
--way-key-value (--wkv)

Работают аналогично предыдущим, но помимо тегов, которые являются ключами можно добавить ещё и значения ключей, которые вас интересуют, в формате key.value. Всё что не соответствует: либо нет тегов, либо есть теги, но значения не те - будет отброшено.

В качестве аргумента keyValueList в котором и указывается список желаемых комбинаций key.value.

Давайте для примера запросим все точки, которыми отмечены камеры контроля скорости:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --node-key-value keyValueList=highway.speed_camera \
    --write-xml radar.osm.xml

При необходимости в keyValueList можно передавать несколько пар key.value, через запятую, тогда они будут восприниматься как логическое ИЛИ, т.е. в итоговый поток попадут те элементы которые соответствуют или одному фильтру, или другому, или третьему и т.д. сколько бы фильтров ни было.

EBNF грамматика
EBNF грамматика

Для примера можем получить камеры и лежачие полицейские:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --node-key-value keyValueList=highway.speed_camera,traffic_calming.bump \
    --write-xml road.osm 

Ну а если мы хотим получить логическое И, скажем не просто получить камеры контроля скорости, а с ограничением скорости на 40 км/ч, (это в отдельном теге хранится), то нужно применить две задачи последовательно:

osmosis \ 
    --read-pbf tyumen.osm.pbf \
    --node-key-value keyValueList=highway.speed_camera \
    --node-key-value keyValueList=maxspeed.40 \
    --write-xml radar.osm.xml 

Вот и результат:

<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="Osmosis 0.49.2">
  <bounds minlon="65.43160" minlat="57.07190" maxlon="65.69450" maxlat="57.24560" origin="0.49.2"/>
  <node id="7893291158" version="1" timestamp="2020-09-10T11:41:59Z" uid="0" user="" lat="57.2022677" lon="65.6050515">
	<tag k="direction" v="55"/>
	<tag k="highway" v="speed_camera"/>
	<tag k="maxspeed" v="40"/>
  </node>
</osm>

Собственно немного в Тюмени таких камер (но надо иметь в виду что OSM не гарантирует полноту и корректность данных), находится на пересечении улиц Щербакова и Мелиораторов, пользуясь случаем передаю всем привет - предупреждён, значит вооружён.

Можно комбинировать задачи разных типов, например если хотим просто получить камеры для которых в OSM указано хоть какое-то ограничение на скорость:

osmosis \ 
    --read-pbf tyumen.osm.pbf \
    --node-key-value keyValueList=highway.speed_camera \
    --node-key keyList=maxspeed \
    --write-xml radar.osm.xml 

В качестве примера для линий получим все автомагистрали:

osmosis \
    --read-pbf tyumen.osm.pbf  \
    --way-key-value keyValueList=highway.motorway \
    --write-xml road.osm.xml

--tag-filter (--tf)

Самая полезная задача для выбора данных.

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

Принять/отклонить

В качестве параметра принимает строку, которая определяет поведение “принятия/отклонения” объекта, с которым будет работает фильтр:

  • accept-nodes,

  • accept-ways,

  • accept-relations,

  • reject-nodes,

  • reject-ways,

  • reject-relations.

Здесь accept - принять, reject - отклонить.

Каждая задача фильтрует только указанный тип объекта, пропуская все остальные типы объектов. Т.е. если мы указываем accept-ways, то он отфильтрует все линии, оставив только те, что соответствуют фильтру, а узлы и отношения пройдут дальше попав на выходной поток, о них нужно будет позаботиться отдельно.

Фильтр по тегам

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

Шаблоны тегов не обязательны, если их не указать, то фильтр соответствует всем объектам данного типа.

osmosis \
    --read-pbf tyumen.osm.pbf \
    --tag-filter accept-ways highway=* \
    --tag-filter reject-node \
    --tag-filter reject-relations \
    --write-xml output.osm.xml

В этом примере мы выбираем все линии дорог, отбрасываем все точки и отношения: accept-ways разрешительная задача, которая разрешает все линии которые соответствуют условию, reject-node и reject-relations - запретительные задачи, у которых нет условия, а значит они отбрасывают всё.

Множество значений

В рамках определенного шаблона тегов для одного ключа можно указать несколько значений, используя список, разделённый запятыми (работает опять же через логическое ИЛИ).

Модифицируем пример:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --tag-filter accept-ways highway=* \
    --tag-filter reject-ways highway=motorway,motorway_link \
    --tag-filter reject-node \
    --tag-filter reject-relations \
    --write-xml output.osm.xml

Здесь мы выберем все линии дорог, а потом исключаем из них (в reject-ways) автомагистрали и съезды с автомагистралей.

Подстановочное значение * (одна звездочка) соответствует любому значению.

Обратите внимание, что каждая задача фильтрации тегов может принимать более одного шаблона тегов и примет (accept) или отклонит (reject) объект, если он соответствует любому из этих шаблонов. Иными словами, пар ключ=значение в одной задаче может быть несколько.

EBNF грамматика
EBNF грамматика

Например мы захотим получить все места для спорта, отдыха и туризма:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --tag-filter accept-nodes sport=* tourism=* leisure=* \
    --tag-filter accept-ways sport=* tourism=* leisure=* \
    --tag-filter reject-relations \
    --write-xml rest-poi.osm.xml

Тут могла быть реклама VisitTyumen, но нет.

--used-node (--un)
--used-way (--uw)

Ранее мы писали что каждая задача фильтрует только указанный тип объекта, пропуская все остальные типы объектов, а об остальных придётся побеспокоиться отдельно.

Например фильтруем мы линии, что делать с узлами? Отбросить? Можно и отбросить конечно, а что если мы хотим оставить те, что используется в линиях, которые мы ранее отфильтровали, а остальные отбросить?!

Вот для этого и существует --used-node - ограничивает поток узлов теми, которые используются в линиях и/или отношениях которые присутствуют во входном потоке.

Модифицируем уже рассмотренный ранее пример:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --tag-filter accept-ways highway=* \ 
    --tag-filter reject-ways highway=motorway,motorway_link \
    --tag-filter reject-relations \
    --used-node \
    --write-xml output.osm.xml

Вещь полезная, ибо way - не совсем линии, координаты точек они не хранят, только ссылки на них (ref):

<way id="1010891689" version="1" timestamp="2021-12-10T07:49:28Z" uid="0" user="">
	<nd ref="6045517422"/>
	<nd ref="9326407121"/>
	<tag k="highway" v="service"/>
	<tag k="service" v="parking_aisle"/>
</way>

Координаты хранятся отдельно в узлах:

<node id="6045517422" version="3" timestamp="2021-12-10T07:49:28Z" uid="0" user="" lat="57.1364932" lon="65.4755765"/>

Поэтому если важна геометрия линии (way), то мало выбрать линии, надо ещё и выбрать узлы, а --used-node - единственный способ получить только используемые точки - отбросив остальные.

Задача --used-way аналогична, ограничивает поток линий (way) теми, которые используются в отношениях (relation) которые присутствуют во входном потоке.

Задачи по управлению потоком

Эти задачи позволяют манипулировать структурой потока. Манипуляций с данными, не проводят.

--write-null (--wn)

Отбрасывает все входные данные. По сути прерывает поток. Это полезно для проверки целостности входных файлов или тестирования каких-то задач на корректность написания.

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

--merge (--m)

Объединяет два потока в один. Только два. Если вам нужно объединить три источника данных, придётся указывать эту задачу дважды. И так далее.

Если бы такой пазл существовал он бы выглядел вот так (головоломка выходит на новый уровень):

Для примера откроем три потока из разных файлов:

osmosis \
    --read-pbf tyumen.osm.pbf \
    --read-pbf tobolsk.osm.pbf \
    --read-pbf ishim.osm.pbf \
    --merge \
    --merge \
    --write-pbf merged.osm.pbf

Первый merge объединяет tyumen.osm.pbf и tobolsk.osm.pbf, создаёт поток, второй merge объединяет этот поток и поток из ishim.osm.pbf, создаёт поток, и затем мы сохраняем его в отдельный pbf файл, который содержит все три города.

Следующая команда создаст выходной файл, содержащий кафе, а также все пешеходные дороги и точки, на которые они ссылаются.

osmosis \
    --read-pbf tyumen.osm.pbf \
    --tag-filter reject-relations \
    --tag-filter accept-nodes amenity=cafe  \
    --tag-filter reject-ways \
    \
    --read-pbf tyumen.osm.pbf \
    --tag-filter reject-relations \
    --tag-filter accept-ways highway=footway \
    --used-node \
    \
    --merge \
    --write-xml amenity-and-motorway.osm

В общем merge задача полезная - позволяет одной командой получить разношерстные данные, написав несколько последовательных блоков команд, и не мучаться со всякими reject и accept пытаясь всё впихнуть в один tag-filter.


По сути из задач, полезных для добычи данных - всё. Если конечно не копать в сторону взаимодействия с БД, но это уже совсем другая история. Про эту историю уже тоже есть очерк на Хабре: Импорт OpenStreetMap. От бинарного исходника к таблице в БД в несколько шагов.

Заключение

Что ж, надеюсь я помог Вам разобраться в теме добычи геоданных из выгрузки OSM. Это не все возможности osmosis но для получения данных в виде XML (почти человеческом) - достаточные.

Если Вам хочется глубже погрузится в мир OSM со всеми его преимуществами и недостатками, то вот несколько ссылок

И небольшой совет по поиску тегов OSM: не надо вычитывать всю документацию в поисках нужного тега - сначала смотрите как картографируют другие. Т.е. находите на карте (https://www.openstreetmap.org) один из интересующих Вас объктов, на правой панели инструментов выбираете "Что здесь?", кликаете на карту на интересующий Вас объект, и смотрите как он закартографирован.

Просмотр тегов на карте
Просмотр тегов на карте

Это поможет понять в каком направлении копать документацию.

Удачи!

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


  1. sshikov
    10.01.2024 16:23

    Не уловил, как можно при описании исследования данных в OSM вообще не упомянуть https://overpass-turbo.eu/? Как по мне, сначала идем туда, изучаем разметку, пишем запросы. И потом уже осмозис (или другая утилита, например паркетизер).


  1. velon Автор
    10.01.2024 16:23
    +2

    В публикации есть несколько примеров где используются геоданные, понятное дело что osmosis тут и не причём - это могло быть реализовано и с помощью других инструментов, да и явно не одного... но всё же, главное задача, а инструмент это уже дело наживное, поэтому пишите о других примерах где и как геоданные используются.

    Думаю много можно найти примеров необычного приложения.


    1. igor_suhorukov
      10.01.2024 16:23
      +1

      Спасибо за подробный разбор osmosis

      это действительно "швейцарский нож" для OSM дампов, только его больше не развивают.

      Из примеров задач - поиск лучшего места для жилья, по моему мнению, отличное применение для геоданных из OpenStreetMap


      1. velon Автор
        10.01.2024 16:23
        +1

        Почему не развивают? Зашёл на GitHub в историю коммитов: https://github.com/openstreetmap/osmosis/commits/main/ , - пациент скорее жив, чем мёртв.

        Текущая версия 0.48 появилась в 2020 году, если я не ошибаюсь, - да не самая большая динамика (раньше релизы были чаще), но и не так чтобы древность.

        Но если Вы имеете в виду что новые команды вряд ли появятся, то соглашусь, я этого тоже не жду.


        1. igor_suhorukov
          10.01.2024 16:23
          +1

          Почему не развивают?

          К сожалению, только поддержка проекта. В 2020-2022 я провел много времени разбирая исходники этого проекта, чтобы написать запись PBF в PostGIS шустрее и с разбиением данных в таблицы по H3 index.


          1. velon Автор
            10.01.2024 16:23

            Надеюсь они приняли Pull Request.


            1. igor_suhorukov
              10.01.2024 16:23

              Я не делал PR в osmosis. Не думаю что мой код с учетом статуса проекта приняли бы, там и внешние утилиты вызываются к тому же. Просто выложил openstreetmap_h3 на GitHub.


      1. velon Автор
        10.01.2024 16:23
        +1

        С жильём согласен, можно много примеров привести где OSM пригодится, вижу у Вас много публикаций на эту тему - тут добавить нечего.

        Мне ещё вот эта публикация нравится: 1 000 000 жилых домов России. Но она не совсем про OSM.


        1. igor_suhorukov
          10.01.2024 16:23

          Мне ещё вот эта публикация нравится

          Данные о годах постройки домов и типовых проектов зданий, как оказалось, есть в OSM. Для спальных районов Москвы данных прилично, а в остальных зданиях start_date и design:ref редкость.

          А так в других городах по РФ действительно для аналитики парсят ГИС ЖКХ. Так делали в параллельном проекте на одной из моих предыдущих работ.


  1. NickyX3
    10.01.2024 16:23
    +2

    Пример бы как выгрузить полигоны райнов города, было бы удобно


    1. velon Автор
      10.01.2024 16:23
      +1

      osmosis \
        --rb file.osm.pbf \
        --wkv boundary.administrative \
        --tf reject-relation \
        --un \
        --wx boundary.xml

      Так попробуйте: берём файл --rb, делаем фильтр по административным границам boundary.administrative, отбрасываем все отношения reject-relation, оставляем точки из которых состоят линии границ --un.

      Для более детальной настройки используйте фильтр по admin_level см. boundary.

      Получим что-то в духе:

      ...
        <node id="3467344978" version="1" timestamp="2015-04-20T08:40:51Z" uid="0" user="" lat="57.080591" lon="65.4632397"/>
        <node id="3802047459" version="2" timestamp="2019-06-25T10:08:28Z" uid="0" user="" lat="57.0924709" lon="65.5657055"/>
        <node id="4324760740" version="2" timestamp="2016-07-29T04:43:09Z" uid="0" user="" lat="57.1731187" lon="65.6030412"/>
        <way id="550959671" version="2" timestamp="2022-05-02T16:22:26Z" uid="0" user="">
          <nd ref="716821476"/>
          <nd ref="716821344"/>
          <nd ref="716823830"/>
          <nd ref="5321016260"/>
          <nd ref="716823006"/>
          <nd ref="716822613"/>
          <nd ref="716822092"/>
          <nd ref="716820906"/>
          <nd ref="5321016177"/>
          <tag k="admin_level" v="6"/>
          <tag k="boundary" v="administrative"/>
        </way>
      ...

      Но это не полигоны, к сожалению. Полигоны ещё собрать надо из точек, которые придётся найти по ref. Osmosis это не сделает, придётся что-то своё писать.

      UPD лучше relation выбрать, ниже другой вариант.


      1. NickyX3
        10.01.2024 16:23

        А в чем сложность создать из точек полигоны? Порядок?


        1. velon Автор
          10.01.2024 16:23

          У osmosis? Не знаю, он так просто не умеет - авторы видимо не для этого его задумывали.

          Порядок не является проблемой, все теги <nd> идут в нужном порядке.

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

          В целом и порядок линий и порядок точек в выгрузке сохраняется - написать кастомное решение которое возьмёт отношения, для каждого отношения переберёт линии, потом переберёт точки и создаст полигон - выполнимая задача.

          Но это уже не osmosis. И придётся что-то писать - уже не из коробки. Умеют ли так аналоги osmosis - я не знаю.


          1. freeExec
            10.01.2024 16:23

            Всё же вопрос стоял про районы города. То что вы решили не выбрасывать отношения, это правильно. Потому что границы это всегда отношения. Но тут другая проблема, выбираются все границы, а не уровня районов городского округа. А во вторых, районы это не всегда административные единицы, могут быть и просто именованные части города. В общем-то задача не такая и простая, как может показаться.


            1. velon Автор
              10.01.2024 16:23

              Про admin_level я писал. Про именованные районы города, подскажите что это за тег, если нужно объединять, то тут без merge будет не обойтись.


              1. freeExec
                10.01.2024 16:23

                В коде просто админ-уровень не отразился. А именованные районы, это значения тега place


                1. velon Автор
                  10.01.2024 16:23

                  Это потому что в код я его не включил, описав в тексте что "соль перец по вкусу". Но вот пример с admin_level и place:

                  osmosis \
                    --rb file.osm.pbf \
                    --tf accept-relations boundary=administrative \
                    --tf accept-relations admin_level=9 \
                    \
                    --rb file.osm.pbf \
                    --tf accept-relations place=suburb,quarter,neighbourhood \  
                    \
                    --merge
                    \
                    --uw \
                    --un \
                    --wx boundary.xml

                  Здесь два потока: Один по отношениям boundary, у которого admin_level=9, второй по отношениям с place=suburb,quarter,neighbourhood. Потом Мы их объединяем с --merge и выбираем way и node --uw --un.

                  admin_level=9 и place=suburb,quarter,neighbourhood нужно в зависимостри от потребностей настраивать.


      1. NickyX3
        10.01.2024 16:23
        +1

        Хм... Данные OSM всеж немного не очень пока структурированы.

        Возьмем к примеру Екатеринбург, в нем есть Академический район, но он не является участником города. Похоже единственный путь реально выгребать boundary administrative из квадрата


    1. velon Автор
      10.01.2024 16:23

      osmosis \
        --rb file.osm.pbf \
        --tf accept-relations boundary=administrative \
        --uw \
        --un \
        --wx boundary.xml

      Поправка, сейчас подумал что лучше от relation плясать а не от way


  1. sshikov
    10.01.2024 16:23

    Не уловил, как можно при описании исследования данных в OSM вообще не упомянуть https://overpass-turbo.eu/? Как по мне, сначала идем туда, изучаем разметку, пишем запросы. И потом уже осмозис (или другая утилита, например паркетизер).


    1. velon Автор
      10.01.2024 16:23

      Мне он не кажется удобным для изучения разметки - потому и не пишу. Уловили? Возможно я не умею его готовить... но пусть об этом пишут те кто умеет.


      1. sshikov
        10.01.2024 16:23

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

        Возможно я не умею его готовить... 

        Легко верю. Он сложный. Но ведь и разметка достаточно сложная, и тут интерактивный режим работы решает. Я подумывал про него написать, но ушел с того проекта, где я его активно применял на ежедневной основе. По-моему тут была про него статья, поищу.

        https://habr.com/ru/articles/520524/ ну вот скажем статья в том числе и про него.


        1. velon Автор
          10.01.2024 16:23
          +1

          Я не совсем про сложность, я просто не представляю как его использовать для исследования разметки, в моём представлении он для поиска "белых пятен" на карте.

          Например: я хочу что-то закартографировать, в соседней ветке мы уже вспомнили про даты постройки домов, давай в качестве примера и возьмём.

          Мне нужно найти те дома у которых дата постройки не указана, например есть квартал, почти везде всё заполнено но может быть пара домов без даты, мне либо тыкаться по каждому в поисках пустоты, либо зайти на turbo и ввести что-то типа:

          nw[building][!start_date]({{bbox}});
          (._;>;);
          out;

          и он мне подсветит building где отсутствует start_date - profit.

          Но мне уже надо знать и про тег building и проstart_date.

          Про "не умею готовить" - я имел в виду именно это - не могу представить соответствующий сценарий, в моём представлении это инструмент другого назначения.

          Но я плохой осмер - редко картографирую, поэтому и с overpass-turbo не взаимодействую, - не могу его из-за этого полноценно оценить.

          На счёт сложности - да, для многих порог входа будет очень велик, жаль что Вы отказались от идеи описать его, думаю многим бы это пригодилось. В целом вот хорошая публикация для начинающих: Overpass API: следующий уровень владения OpenStreetMap.

          "Кому на Руси жить хорошо?" - это прям хардкор, для начального уровня наверно слишком.


          1. sshikov
            10.01.2024 16:23
            +1

            Ну да, я согласен - это другие кейсы, тут я пожалуй тоже не скажу, что оверпасс был бы удобен. Тэги надо либо знать априори, либо хотя бы понимать, где у нас правильно размеченные объекты на карте - и тогда зайти с их стороны. Если ни то ни другое нам не известно - то наверное инструмент для работы с текстовым представлением (либо xml, либо может быть - база) будет лучше.

            Для меня оверпасс - это инструмент для задач типа "открыть карту, найти объект какого-то известного типа (станцию метро), изучить, как она размечена, какими тэгами отмечены выходы, и т.п. А потом уже идем в базу, или запускаем осмозис. И выгружаем все станции и все выходы к себе, и мучаем по всякому.

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