Как известно, OSM - пространственная база данных, поэтому там широко используется связь на основе геометрической вложенности объектов. В основном это используется для адресов, но бывают и другие виды связей.
POI внутри здания наследуют адрес от этого здания, дороги внутри населённого пункта по умолчанию имеют maxspeed отличный от вне населённых пунктах и т.п. Однако далеко не везде эту проверку можно сделать легко и просто. Это легко при использовании БД с поддержкой пространственных данных (PostGIS и т.п.), что-то умеет распространённый конвертер osm2pl, однако во многих случаях готового инструментария нет, а программировать не все умеют. Поэтому и начинают плодиться теги addr:country/add:city на зданиях, addr:street/addr:housenumber на точечных POI, maxspeed=RU:urban на дорогах в населённых пунктах и т.п.
Вашему вниманию предлагается новый плагин под osmosis, который позволит решить данную проблему. С его помощью можно автоматически проставить необходимые теги на основе анализа геометрической вложенности объектов без программирования и использования пространственных БД.
Исходники лежат тут: https://github.com/sergeyastakhov/OSM/tree/master/osmareatag
Примеры: https://github.com/sergeyastakhov/OSM/tree/master/osmareatag/src/main/examples
Скомпилированная версия: https://cloud.mail.ru/public/4AyX/jQ85UbSAM
Для установки плагина надо распаковать zip-файл дистрибутива в подкаталог plugins того каталога где будете запускать osmosis (должен получиться каталог osmareatag-1.1.zip внутри каталога plugins).
Для простановки кодов стран нужны данные границ этих стран. На gislab, к сожалению, границы России битые и исправлять это они не очень то торопятся. Проще всего эту границу вытянуть отдельным запросом через API (link). В несжатом виде это будет 19 Мб, в формате pbf - 900 Кб. Если нужны другие страны - можно их так же вытянуть по одному и потом объединить, либо взять дамп нужного района на geofabric и отфильтровать из него.
Получив файл с границами стран - дальше нужно сформировать пространственный индекс. Пример (create_spatial_index.bat):
del national-boundary.idx
call osmosis --read-pbf russia-boundary.osm.pbf --lp --tag-area-content file=tag-index.xml prepareOnly=true --write-null
tag-index.xml
<?xml version="1.0" encoding="UTF-8"?>
<tag-processing>
<area id="national-boundary" cache-file="national-boundary.idx">
<match type="relation">
<tag k="boundary" v="administrative"/>
<tag k="admin_level" v="2"/>
</match>
</area>
</tag-processing>
Параметр file задаёт файл конфигурации, параметр prepareOnly=true задаёт что обработку выполнять не нужно, только создание индексов. В данном примере задаётся, что необходимо создать пространственный индекс для объектов типа relation с тегами boundary=administrative и admin_level=2 (границы стран). После создания индекс сохраняется в файле national-boundary.idx Если этот файл уже существует, то будет выполняться попытка загрузки из него, вместо использования данных из входного потока, что позволяет создать индекс один раз и затем им пользоваться многократно. Для России индекс занимает 2.7 Мб. При работе индекс держится в памяти, поэтому для больших индексов может потребоваться увеличить кол-во доступной памяти для osmosis
Дальше можно запускать обработку данных. Пример для простановки атрибутов дорог (highway_mark.bat):
call osmosis --read-pbf RU-LEN.osm.pbf --lp --bb clipIncompleteEntities=true --tag-area-content file=tag-highway.xml --write-xml RU-LEN.hwarea.osm.gz
tag-highway.xml
<?xml version="1.0" encoding="UTF-8"?>
<tag-processing>
<area id="national-boundary" cache-file="national-boundary.idx">
<match type="relation">
<tag k="boundary" v="administrative"/>
<tag k="admin_level" v="2"/>
</match>
</area>
<area id="boundary-administrative">
<match type="relation">
<tag k="boundary" v="administrative"/>
</match>
</area>
<area id="place">
<match>
<tag k="place" v="city|town|village|hamlet|isolated_dwelling|allotments"/>
</match>
</area>
<transform>
<name>Motorway speeds</name>
<match type="way">
<tag k="highway" v="motorway"/>
<inside area="national-boundary"/>
</match>
<output>
<add-tag k="maxspeed" v="${ISO3166-1}:motorway" context-area="national-boundary"/>
</output>
</transform>
<transform>
<name>Rural speeds</name>
<match type="way">
<tag k="highway" v="motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential"/>
<inside area="national-boundary"/>
<outside area="place"/>
</match>
<output>
<add-tag k="maxspeed" v="${ISO3166-1}:rural" context-area="national-boundary"/>
</output>
</transform>
<transform>
<name>Urban speeds</name>
<match type="way">
<tag k="highway" v="motorway_link|trunk|trunk_link|primary|primary_link|secondary|secondary_link|tertiary|tertiary_link|unclassified|residential"/>
<inside area="national-boundary"/>
<inside area="place"/>
</match>
<output>
<add-tag k="maxspeed" v="${ISO3166-1}:urban" context-area="national-boundary"/>
</output>
</transform>
<transform>
<name>Urban living street speeds</name>
<match type="way">
<tag k="highway" v="pedestrian|living_street|service"/>
<inside area="national-boundary"/>
<inside area="place"/>
</match>
<output>
<add-tag k="maxspeed" v="${ISO3166-1}:living_street" context-area="national-boundary"/>
</output>
</transform>
<transform>
<name>Administrative units</name>
<match type="way">
<tag k="highway" v=".*"/>
<inside area="boundary-administrative"/>
</match>
<output>
<add-tag k="administrative:${admin_level}" v="${name}" context-area="boundary-administrative"/>
</output>
</transform>
</tag-processing>
В данном примере проставляются атрибуты maxspeed на основе вхождения/невхождения в населённые пункты + добавляются атрибуты administrative:* для привязки к соответствующим административным границам. Инструкция add-tag добавляет тег при его отсутствии, если тег уже есть, он оставляется нетронутым.
Пример для простановки адресных данных на точечных POI (poi_addr.bat):
call osmosis --read-pbf RU-LEN.osm.pbf --lp --tag-area-content file=tag-poi-addr.xml --write-xml RU-LEN.poi.osm.gz
tag-poi-addr.xml
<?xml version="1.0" encoding="UTF-8"?>
<tag-processing>
<area id="national-boundary" cache-file="national-boundary.idx">
<match type="relation">
<tag k="boundary" v="administrative"/>
<tag k="admin_level" v="2"/>
</match>
</area>
<area id="region-boundary">
<match type="relation">
<tag k="boundary" v="administrative"/>
<tag k="admin_level" v="4"/>
</match>
</area>
<area id="place">
<match>
<tag k="place" v="city|town|village|hamlet|isolated_dwelling|allotments"/>
</match>
</area>
<area id="addr-building">
<match>
<tag k="building" v=".*"/>
<tag k="addr:housenumber" v=".*"/>
</match>
</area>
<transform>
<name>POI Addresses</name>
<match type="node">
<tag k="amenity|shop" v=".*"/>
<inside area="national-boundary"/>
<inside area="region-boundary"/>
<inside area="place"/>
<inside area="addr-building"/>
</match>
<output>
<add-tag k="addr:country" v="${ISO3166-1}" context-area="national-boundary"/>
<add-tag k="addr:region" v="${name}" context-area="region-boundary"/>
<add-tag k="addr:city" v="${name}" context-area="place"/>
<add-tag k="addr:street" v="${addr:street}" context-area="addr-building"/>
<add-tag k="addr:housenumber" v="${addr:housenumber}" context-area="addr-building"/>
</output>
</transform>
</tag-processing>
Надеюсь, наличие данного плагина уменьшит тенденцию простановки кучи избыточных тегов, которые вполне можно ставить автоматом.