RU:Catalog/Zverik
Это переработка схемы ErshKUS. Скопирую сюда список основных целей:
- Полный перевод тегов, для понимания обычного человека
- Конвертация в пресеты JOSM
- Создания иерархии элементов для различных каталогов/списков и её однородность
- Организации списка "правильных" тегов, для пользователей и валидаторов
Сделаем несколько дополнительных утверждений:
- Одна запись описывает один объект, определяемый одним или несколькими тегами. При этом если какой-то тег используется в паре и отдельно, это должны быть различные объекты, иначе второй тег -- дополнительный.
- Дополнительные теги модифицируют свойства объекта, не изменяя его принципиально. Например, fee=*. Эти теги не группируются, их значения могут быть произвольны.
- Дополнительные теги могут объединяться в общие группы. Например, name, opening_hours, operator, brand, phone, fax, website -- общая группа "poi".
- Основные теги фиксированы, значения дополнительных тегов могут варьироваться.
- Все теги и дополнительные теги имеют идентификаторы, на которые ссылается перевод, и могут ссылаться внешние базы данных.
Большей частью схема основана на формате пресетов Potlatch 2 (см. раздел ссылок). Автор этого редактора неоднократно указывал на применимость формата для создания общего каталога тегов.
Каталог создаётся в формате JSON, как наиболее актуальном для современных приложений. Он состоит из единственного файла схемы и нескольких файлов перевода. Также см. /Форматы и /SQL.
Схема
Каталог -- это массив из объектов, тип которых определяется по ключу type. Каждый объект должен иметь идентификатор в ключе name, уникальный в пределах файла. Он может состоять только из латинских букв, цифр и знака подчёркивания, и должен начинаться с буквы.
Любые объекты или группы объектов могут быть объединены в группу. При этом связь может быть не древовидной, но сетевой, "многие ко многим". Так, shop=car_parts может одновременно входить в группу магазинов и POI для автомобилистов. Однако большинство инструментов требует древовидную структуру групп, поэтому первая группа из списка "родителей" считается главной, остальные могут быть отброшены.
Метаинформация
Первым элементом всегда идёт запись метаинформации. Все описанные ключи обязательны. Этот документ описывает версию формата 0.2 (описание не окончательное, формат может значительно меняться). Также см. #История изменений.
Ключ | Значения | Описание |
---|---|---|
type | meta | Обозначает запись метаинформации. |
name | Catalog | Строка с названием формата. |
version | число с плавающей точкой | Номер версии вида N.M (например, 1.2). Мажорная версия увеличивается при несовместимости нового формата со старым (например, когда type для дополнительного тега стал массивом, а не строкой), минорная -- когда изменения незначительны и не ломают совместимость (например, новый ключ в словаре). |
timestamp | время в формате ISO 8601 | Время создания файла каталога. |
Версии
У каждого объекта верхнего уровня (т.е. объекта с ключом type, не вложенного структурно в другие) присутствует хэш version со следующими обязательными полями:
Ключ | Значения | Описание |
---|---|---|
id | целое положительное число | Номер версии, начинается с 1 и увеличивается при каждом изменении данных. |
author | строка | Имя пользователя в OpenStreetMap, изменившего данные. |
uid | целое положительное число | Идентификатор пользователя в OSM. Может быть равен нулю: это означает автоматический импорт. |
timestamp | время в формате ISO 8601 | Время последнего изменения записи. |
Группа объектов
Группы служат двум целям. Во-первых, это теги для объектов и классов дополнительных тегов со связью "многие ко многим". Так, объект может входить в группы магазинов и автомобильных магазинов, которые вложены одна в другую. Во-вторых, из них можно построить древовидную структуру, какая встречается в пресетах и каталогах POI. Поэтому желательно, чтобы между группами не было связей A->B->A, хотя циклы из четырёх и более групп допустимы.
Ключ | Значения | Обязателен? | Описание |
---|---|---|---|
type | group | да | Обозначает группу объектов. |
name | идентификатор | да | Идентификатор группы. |
group | массив идентификаторов групп | нет | Если это подгруппа, нужно указать одну или несколько родительских групп. |
Объект
Если какой-то объект по тегам подпадает под несколько описаний, берётся самое точное: так, если есть объекты для highway=service и highway=service + service=parking_aisle, то когда указаны оба тега, должен использоваться последний.
Ключ | Значения | Обязателен? | Описание |
---|---|---|---|
type | feature | да | Обозначает объект. |
name | идентификатор | да | Идентификатор объекта. |
group | массив идентификаторов групп | нет | Можно указать одну или несколько родительских групп. |
applies | массив из node/way/area/relation/changeset | да | Указывает типы объектов, к которым применимо это определение. |
tags | хэш { "тег" : "значение", ... } | да | Теги, определяющие этот объект (обычно одна или две пары). Если у объекта нет общего значения, то указать вместо него пустую строку (см. поле values). Второй тег становится основным, если его нельзя считать поясняющим основной. Т.е. сущность, выраженная основным тегом, качественно отличается от основного+дополнительного тега. |
values | массив значений | нет | Если объект определяется одним и только одним тегом, можно задать список значений, которые он может принимать. Например, для building=yes могут быть альтернативы building=apartments, building=garage и т.д. |
deprecated | true/false | нет | Если true, способ обозначения объекта устарел и не рекомендуется к использованию. Современные способы нужно указать в sameas и в словаре. |
attributes | массив дополнительных тегов | нет | Дополнительные теги для этого объекта. Теги из этого списка имеют приоритет перед определёнными в классах. |
members | массив членов отношения | нет | Для отношений -- описание членов. |
classes | массив идентификаторов классов | нет | Классы дополнительных тегов для этого объекта. Если теги в классах пересекаются, приоритет имеет класс, указанный в списке первым. |
related | массив идентификаторов | нет | Идентификаторы связанных с этим определением объектов, групп и классов. |
sameas | массив идентификаторов и ссылок на доп. теги | нет | Чаще всего -- ссылки на дополнительные теги (вида name.key, где name -- идентификатор содержащего доп. тег объекта или класса), наличие которых обозначает присутствие описываемого здесь объекта. Пример: amenity=atm и atm=yes. Также ссылки на объекты, эквивалентные этому: shop=insurance и office=insurance. |
Член отношения
В схеме могут указываться теги для отношений. Состав члены отношений тоже можно регламентировать, через массив members. Элементы этого массива имеют следующий формат:
Ключ | Значения | Обязателен? | Описание |
---|---|---|---|
role | строка | да | Роль объекта в отношении. |
name | идентификатор | нет | Идентификатор записи для словаря. Ему достаточно быть уникальным в пределах массива членов отношения. По умолчанию равен полю role, для пустой роли -- "empty". |
applies | массив из node/way/area/relation | да | Типы объектов, которые могут содержаться в этой роли. |
features | массив идентификаторов | нет | Если в этой роли могут быть только определённые объекты (например, больницы) или группы (например, дороги), они перечисляются в списке. |
required | true/false | нет | Если true, требуется хотя бы один член в этой роли. |
count | число | нет | Ограничение на количество членов в этой роли. |
Дополнительный тег
Дополнительные теги могут указываться только как элементы массива attributes объекта или класса. Поэтому поле type у них означает нечто совсем иное. В словарях на дополнительные теги ссылаются с упоминанием родительского элемента, поэтому можно, хотя и не рекомендуется, делать одинаковые идентификаторы в разных объектах или классах.
Ключ | Значения | Обязателен? | Описание |
---|---|---|---|
key | ключ тега | да | Ключ тега. |
synonym | другой ключ | нет | У некоторых ключей есть синоним: например, phone и contact:phone. В качестве синонима нужно указывать менее популярный вариант. |
name | идентификатор | нет | Идентификатор поля. По умолчанию равен key с вырезанными символами, не подходящими для идентификатора. |
important | true/false | нет | Если true, дополнительный тег очень желателен для простановки. Например, ref на highway=trunk. |
suffixes | массив суффиксов | нет | Список допустимых суффиксов для ключа. |
type | массив из free/text/ boolean/variant/number/speed/period |
да | Допустимые типы значений тега (см. ниже). |
range | [ min, max, step ] | нет | Для типа number можно указать границы значений: например, [-5,5,1] для ключа level. |
values | массив значений | нет | Для типа variant здесь перечисляются возможные значения. |
default | значение | нет | Значение, когда тег не задан. Для типа boolean это "yes" или "no". |
Возможные типы:
Тип | Описание |
---|---|
text | Строка в свободной форме. |
boolean | Значение да/нет. Может принимать разнообразные значения: yes/no/true/false/1/0 и т.п. |
variant | Один из заданного списка вариантов. Считается, что пустая строка -- тоже всегда вариант (но ей не нужно присутствовать в списке). |
number | Число. |
speed | Скорость: число плюс суффикс единиц измерения: "40" или "30 mph". |
period | Значение opening_hours=*. |
У тега может быть не только несколько значений (тип variant), но несколько типов значений: например, для lit=* типы будут ["boolean", "period", "variant"].
Класс дополнительных тегов
Ключ | Значения | Обязателен? | Описание |
---|---|---|---|
type | class | да | Обозначает объект. |
name | идентификатор | да | Идентификатор класса. |
group | массив идентификаторов групп | нет | Можно указать одну или несколько групп, к которым относится класс. |
attributes | массив дополнительных тегов | да | Дополнительные теги, характерные для этого класса объектов. |
suffixes | массив суффиксов | нет | Список допустимых суффиксов для всех тегов этого класса. |
classes | массив идентификаторов классов | нет | Классы могут содержать другие классы. Так, класс "poi" может включать классы "address" и "contact". |
Суффикс
Ключи дополнительных тегов иногда уточняются суффиксами: name:en=*, maxspeed:forward=*. Суффиксы делятся на категории: направление, язык, валюта и т.п. Для особых значений суффикса могут быть категории только из одного элемента. Также см. /Суффиксы.
Ключ | Значения | Обязателен? | Описание |
---|---|---|---|
type | suffix | да | Обозначает категорию суффиксов. |
name | идентификатор | да | Идентификатор категории суффиксов. |
values | массив строк | да | Список суффиксов этой категории. |
Пример
[
{
"type": "meta",
"name": "Catalog",
"version": "0.1",
"timestamp": "2012-11-05T08:58:00Z"
},
{
"type": "group",
"name": "trade"
},
{
"type": "feature",
"name": "shop_supermarket",
"group": ["trade"],
"tags": {"shop": "supermarket"},
"attributes": [
{
"key": "toilets",
"type": ["boolean"]
}
],
"class": ["poi"],
"applies": ["node", "area"]
},
{
"type": "group",
"name": "services"
},
{
"type": "feature",
"name": "amenity_bank",
"group": ["services"],
"tags": {"amenity": "bank"},
"attributes": [
{
"key": "atm",
"type": ["boolean"]
},
{
"key": "atm2",
"type": ["boolean"]
}
],
"class": ["poi"],
"applies": ["node", "area"]
},
{
"type": "feature",
"name": "amenity_toilets",
"group": ["services"],
"tags": {"amenity": "toilets"},
"class": ["poi"],
"applies": ["node", "area"]
},
{
"type": "class",
"name": "poi",
"attributes": [
{
"key": "name",
"type": ["text"],
"suffixes": ["language"],
"important": "true"
},
{
"key": "operator",
"type": ["text"]
},
{
"key": "opening_hours",
"type": ["period"]
}
]
},
{
"type": "suffix",
"name": "language",
"values": ["en", "ru", "de", "fr", "uk", "be", "fi", "se", "es", "it"]
},
{
"type": "feature",
"name": "restriction",
"applies": ["relation"],
"tags": {"type": "restriction"},
"attributes": [
{
"key": "restriction",
"type": ["variant"],
"values": ["no_right_turn", "no_left_turn", "no_u_turn", "no_straight_on",
"only_right_turn", "only_left_turn", "only_straight_on"],
"important": "true"
},
{
"key": "except",
"type": ["variant"],
"values": ["psv", "bicycle", "hgv", "motorcar"]
}
],
"members": [
{
"role": "from",
"applies": ["way"],
"required": "true",
"count": 1
},
{
"role": "to",
"applies": ["way"],
"required": "true",
"count": 1
},
{
"role": "via",
"applies": ["node", "way"],
"required": "true"
},
{
"role": " location_hint",
"applies": ["node"],
"count": 1
}
]
},
{
"type": "class",
"name": "lit",
"attributes": [
{
"key": "lit",
"type": ["variant", "boolean", "period"],
"values": ["automatic"]
}
]
}
]
Словарь
Словари требуются для визуального представления каталога. По сути, это перевод всех тегов на человеческий язык. Также указываются ссылки на описания тегов и, возможно, длинные описания.
Общая структура
Все ключи объединяются в группы по типам, все ключи обязательны (но могут быть пустыми):
Ключ | Значение | Описание |
---|---|---|
language | [ "код языка IETF", "название" ] | Код языка, указывает, для какого языка это перевод, вместе с названием языка (на самом языке). |
features | хэш записей | Строки для объектов и групп. |
attributes | хэш записей | Строки для дополнительных тегов. |
members | хэш записей | Строки для членов отношений. |
suffixes | хэш записей | Строки для категорий суффиксов. |
values | хэш переводов | Переводы общих значений, вроде yes и no. |
Идентификаторы
Хэши -- ключи с привязанным хэшем свойств. В качестве ключей используются:
- для features и suffixes -- поле name;
- для attributes -- составной ключ "name.key", где name -- идентификатор содержащего атрибут feature или class. Если в описании атрибута присутствует поле name, то используется "name.attribute_name". Можно использовать для атрибута ключ в виде просто key, тогда он будет использован при отсутствии более специфичного перевода. Работает наследование: сначала проверяется название объекта, затем -- название класса. Например, можно перевести "bank.operator" независимо от перевода атрибута класса "poi.operator" и общего перевода "operator".
- для members -- тоже составной ключ "name.role" ("name.empty" для пустой роли) или "name.member_name", когда указано поле name. В отличие от атрибутов, общие переводы указывать нельзя, роли всегда зависимы от отношений.
Запись
Единственным обязательным ключом в записи является name, но очень желательно указать максимальное количество ключей.
Ключ | Значение | Описание |
---|---|---|
name | строка | Название объекта или группы на человеческом языке. |
description | строка | Расширенное описание объекта или группы. |
values | хэш хэшей записей | При наличии поля values у объекта; для дополнительного атрибута типа variant; для суффиксов указывается хэш вида { "значение1": {name: "перевод1", ...}, "значение2": {name: "перевод2", ...} }. Структура переводов такая же, как для записей. В случае объектов нужно указывать только поля, замещающие основные. Для суффиксов ключами в этом хэше хэшей являются названия суффиксов. |
link | url | Ссылка на описание объекта или группы в интернете. |
wiki | название статьи | Название статьи в вики OpenStreetMap, например, "RU:Link (highway)". Для преобразования в ссылку все пробелы заменяются на знаки подчёркивания, в начало добавляется "http://wiki.openstreetmap.org/wiki/". |
image | url картинки | Ссылка на фотографию или иное изображение объекта. |
keywords | массив строк | Набор ключевых слов, по которым можно найти этот объект или группу. |
boolean | [ "перевод для yes", "перевод для no" ] | Только для дополнительного тега типа boolean: Две строки: перевод для положительного и отрицательного значения. Должно содержать тип. например, для fee: [ "Бесплатно", "Платно" ]. Если не указано, используется обычный формат "Название: перевод значения". |
absent | строка | Только для дополнительного тега: Строка, используемая при отсутствии тега на объекте. Например, для name -- "Без названия". При наличии флага important это поле обязательно. |
version | хэш версии | Информация о последнем изменении записи, смотрите описание хэша в разделе "Схема". |
Перевод
Раздел переводов обычных значений имеет однообразную структуру, так как таких значений немного. Для простоты сразу напишем её в JSON:
"values": {
"absent": "не указано",
"boolean": {
"yes": "есть",
"no": "нет"
},
"speed": {
"mph": "м/ч",
"kph": "км/ч",
"default": "км/ч"
},
"period": {
"Mo": "пн",
...
"Su": "вс",
"Jan": "янв",
...
"Dec": "дек",
"24/7": "круглосуточно",
"off": "закрыто"
},
"version" {
...
}
}
Значение absent используется только для дополнительных тегов с флагом important. Описание хэша "version" смотрите в разделе "Схема".
Пример
{
"language": ["ru", "Русский"],
"features": {
"trade": {"name": "Торговля"},
"services": {"name": "Услуги"},
"shop_supermarket": {"name": "Супермаркет", "description": "Торговая точка больше обычного магазина",
"wiki": "RU:Tag:shop=supermarket", "keywords": ["магазин", "супермаркет"]},
"amenity_bank": {"name": "Банк", "description": "Отделение банка", "wiki": "RU:Tag:amenity=bank", "keywords": ["банк", "деньги"]},
"amenity_toilets": {"name": "Туалет"},
"restriction": {"name": "Запрет поворота", "description": "Отношение устанавливает ограничения направлений движения на перекрёстках",
"wiki": "RU:Relation:restriction", "keywords": ["поворот", "перекрёсток", "запрет", "знак", "ограничение"]}
},
"attributes": {
"atm": {"name": "Банкомат", "description": "Присутствует ли рядом или внутри банкомат"},
"amenity_bank.atm2": {"name": "Дополнительный банкомат"},
"toilets": {"name": "Туалет", "description": "Наличие туалета", "boolean": ["Есть туалет", "Туалета нет"]},
"poi.name": {"name": "Название", "absent": "Без названия"},
"poi.operator": {"name": "Владелец"},
"poi.opening_hours": {"name": "Время работы"},
"restriction.restriction": {"name": "Разрешённые направления движения", "values": {
"no_right_turn": {"name": "прямо и налево"}, "no_left_turn": {"name": "прямо и направо"}, "no_u_turn": {"name": "запрещён разворот"},
"no_straight_on": {"name": "налево и направо"}, "only_right_turn": {"name": "только направо"},
"only_left_turn": {"name": "только налево"}, "only_straight_on": {"name": "только прямо"}
}}
},
"members": {
"restriction.from": {"name": "Откуда", "description": "Отрезок дороги, откуда едет транспортное средство"},
"restriction.to": {"name": "Куда"},
"restriction.via": {"name": "Через", "description": "Точка перекрёстка или набор промежуточных линий"},
"restriction.location_hint": {"name": "Знак", "description": "Место для рисования значка запрета на карте"}
},
"suffixes": {
"language": {"name": "Язык", "description": "Перевод значения тега на другие языки", "values": {
"en": {"name": "английский", "description": "Значение на английском языке"},
"de": {"name": "немецкий"}, "ru": {"name": "русский"}, "fr": {"name": "французский"}
}}
},
"values": {
"absent": "неизвестно",
"boolean": {
"yes": "есть",
"no": "нет"
}
}
}
История изменений
Версия | Что изменилось |
---|---|
0.1 | Первая версия. |
0.2 |
|