Обсуждаем новые структуры данных API, избавляемся от строка=строка

вопрос такой: главный тэг (#sport в данном случае) предполагается только один? или допускаем несколько?

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

Но как можно избавиться от именованных атрибутов?

Например, есть дорога, она асфальтирована, она односторонняя, на ней две полосы, ограничение скорости 40 км/ч, и есть название – улица Космонавтов.

Что и как нужно распарсить, чтобы узнать ограничение скорости и название?

Допускаем, конечо.
#sport” это по сути “#sport: yes”

В “моём” синтаксисе - не надо избавляться :slight_smile:


#highway: primary
#name: {улица Космонавтов}
#max,speed: 40  /знак
#surface: asphalt
#oneway
#lanes: 2

Такое не предлагается. Это основа онтологии и вменяемых информационных систем, кто бы и что про неё не думал.

Мы прячем старые говорливые теги в иерархии меток. Метки могут быть иерархичны (метка ##shop:tea зависит от #shop), а могут быть полностью независимы (более адекватный подход, позволяет несколько таксономий, которые если очень хочется можно потом объединить новой более общей меткой или зависимостью от другой метки)

В недоработанной онтологии OSM пользователи путают атрибут (key=value) и понятия (##метка у семантической коробки). Класса объекта в OSM нет. Нет машинно-читаемого архетипа, если вам будет проще.

Проблема в том что главная ##метка меняется:

  • пишете ли вы рендер (для всего мира, только для одной страны)
  • пишете ли вы геокодер (самая сложная задача для всего мира вообще, ответы на вопрос “как назвать этот объект?”)
  • что является для вас “спортом” (бокс - нет, шахматы - да, фигурное плавание - нет, компьютерные игры - нет)
  • интересны ли для вас только группы спортов (только бильярды)

Вопрос сложный, зависит от цели для которой вы хотите распарить объект. На понятийном уровне нужно учитывать семантические коробки (фигурные скобки у синтаксиса OverQuantum:


##highway
{
    #surface: asphalt
    #oneway: true
    #lanes: 2
    #maxspeed: 40
    #name: улица Космонавтов
}

Т.е. чтобы распарсить такую структуру (я специально сделал #highway похожим на данные из OSM) для графа дорог логика будет очень похожа на предыдущую:

  1. Если встречаешь у коробки #highway, то тебе эта группа тегов (коробка) как минимум интересна (валидация)
  2. Если противоречивых тегов нет у коробки #highway ##nothighway, то можно собственно приступать к извлечению данных
    2.1 можно останавливаться если встречаются метки, отличные от вашего белого списка
    2.2 можно продолжать извлекать данные, на свой страх и риск (те метки могут значить “это не дорога”, а могут не значит ничего ##ufo или вам не мешать ##namedobject)
  3. Извлекаем только те атрибуты которые нам интересны (не нужно имя для графа дорог) и умываем руки

тот же самый объект реального мира могут замапить как


##namedobject
{
     #name: улица Космонавтов
     #name:ru: улица Космонавтов
     #name:en: Kosmonavtov street
     #description: угадываю название на Английском
}
##highway
{
    #surface: asphalt
    #oneway: true
    #lanes: 2
    #maxspeed: 40
    #name: улица Космонавтов
}

Геокодер может обрабатывать только коробку с ##namedobject если хочет работать быстро или “смотреть атрибуты только для него”. Тегирование под роутинг, геокодинг и рендеринг (#hex-значения, которых в реальном мире-то нет) это вообще-то, нормально. Просто делать нужно в отдельных для этого местах, чтобы людей не смущать.

“Постойте-ка в реальном мире только одно имя, мы тут сущности плодим”.

В этом вся соль и есть. Онтологии не строятся из абстрактных побуждений ##объектмира, ##боженькасотворил.
Вместо этого абсолютно все пользователи будут использовать самые-самые практичные для них онтологии:

  • #shop // не самая лучшая идея, я бы сразу использовал ##sells:goods и ##sells:services
  • #highway
  • #poi // плохая категория, я бы такую не стал использовать

Что делать если на вашу очень осмысленную коробку покушаются какой-то непонятной меткой? Завелось тут ##ufo понимаешь, что с ними делать теперь. Ну во-первых, спросить у автора метки ##ufo (до этого дооооооолгий и мучительный процесс принятия тегов) что он хочет с ней делать или посмотреть что он написал в её описании на вики, может быть она вам не навредит с её атрибутами.

Если не походит чья-то метка, делайте копию старой вашей коробки. Например: у вас было #highway {}, кто-то пришел и указал #highway #poi {}

Эту схему poi вы считаете непримиримой к данному объекту реального мира, у вас пасинг ломается от её специфических атрибутов схемы #poi. Эту ситуацию мы всегда видим у приверженцев тега type=. **У одних одно, у других он значит **другое.

Поэтому вы копируете старую коробку только с #highway и не мешаете людям экспериментировать с #poi. Может он у них заработает и вы к них присоединитесь. Может нет, у вас будет своя коробка (и ваш любимый хеш-тег на ней).

(собирая мысли в кучу)

итак, имеем контору, которая:

  • продаёт б/у мотоциклы (японские):
  • торгует экипировкой для мото, квадроциклистов и велосипедистов;
  • предоставляет услуги ремонта мотоциклов;
  • предоставляет услуги зимнего хранения мотоциклов, скутеров и шин;
  • предоставляет услуги гос. тех. осмотра мотоциклов;

как я понимаю, можно будет её описать так:



#shop
{
  #motorcycles: japan            / как тэг б/у поставить не придумал
  #equip: motorcycles
  #equip: atv
  #equip: bicycles
}

#motorcycles
{
  #sale: yes                        / value yes можно в принципе опустить
  #type: enduro
  #type: sport
  #type: chopper
  #made: suzuki
  #made: honda
  #equip                            / подразумевается yes
  #winter_store
  #safety_inspection
}

#equip
{
  #motorcycles              / подразумевается yes
  #motorcycles: cross    / особо отметим продажу кроссовой экипировки
  #atv: winter                 / вот тут вопрос, только ли зимнюю экипировку продаёт магазин? нужно ли добавить просто тэг #atv, если не только?
  #bicycles
  #bicycles: contact_shoes
}

#safety_inspection
{
  #motorcycles
}

#winter_store
{
  #motorcycles
  #scooters
  #tires
  #temperature: 17C
}


это на первый взгляд избыточно, но при составлении карты пунктов техосмотра нам достаточно запросить только глав-тэг #safety_inspection и разобрать его нутро, а не копаться в под-тэгах тэгов вида shop=motorcycles, как ныне.
при карте пунктов зимнего хранения - то же самое, достаточно глав-тэга #winter_store
карта магазинов экипировки (вело, мото, квадро, горнолыжной, снегоходной, каякерской) - опять же: #equip и не будем отвлекаться на магазины, продающие мотоциклы и пункты мото тех. осмотров.
карта “магазинов вообще” получит достаточную инфу из тэга #shop

на мой взгляд - очень приятная схема для создания софта, использующего ОСМ получается.

p.s. конечно, подобную контору необязательно описывать столь уж подробно. но, если такая возможность будет - весьма удобно.

В синтаксе OverQuantum предлагаю различать #атрибуты=значния (обычно внутри скобок) и ##понятия (главные теги в старой схеме OSM, poi-теги).

Найдутся конечно люди которые будут настаивать что #motorcycles это подсвойство магазина, но мне тоже нравятся разные понятия.

  1. я бы назвал не одной меткой #motorcycles, а #sells:goods + #sells:goods:motorcycles
  2. #equip #winter_store #safety_inspection я бы убрал из старого #motorcycles
  3. #equip переименовал в #sells:goods + #sells:goods:motorcyclesequip + #sells:goods:equip
  4. вместо #safety_inspection бы добавил ##sells:service:safety_inspection у магазина или другого объекта, я сам не пойму о какой инспекции идёт речь, для чего
  5. #winter_store добавил бы теги #sells:goods:motorcycles + #sells:goods:scooters + #sells:goods:tires

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

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

речь идёт о гос. тех. осмотре транспортных средств. и тут возможны варианты:

  • контора профильно занимается тех. осмотром только легковушек

##safety_inspection
{
  #cars
}

  • тоже самое для легковых, грузовых и мотоциклов:

##safety_inspection
{
  #cars
  #motorcycles
  #tracks
}

  • контора продаёт мотоциклы, экипировку и предоставляет услугу тех. осмотра мотоциклов:

##motorcycles
{
  #sells
  #equip
  #safety_inspection
}

её же можно описать более подробно:


##motorcycles
{
  #sells
  #equip
  #safety_inspection
}

##safety_inspection
{
   #motorcycles
}

##shop
{
  #motorcycles
  #equip:motorcycles
}

вполне себе описание пересекающимися множествами :slight_smile:

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

Совсем упоролись. Json же! Несколько значений в квадратных скобках. Дикты и списки. Парсится на всех языках программирования. Определен ескейпинг. Стандартен чуть более чем полностью. Бросайте свои велосипеды. Джсон онли. Ну yaml в крайнем случае. Он лучше, но труднее валидируется и сложнее сам по себе.

А еще в постгресе знатная оптимизация и индексация джсона по полям плюс компактное хранение. Смекаете? Если внутри хранить именно так - Мегапрофит. Количество записей в бд резко сократится за счет денормализации.

Праивльно предложил товарищ в посте номер 3.

Согласен. Зачем изобретать что-то еще, если тут очень хорошо подходит JSON? Он не перегружен форматированием, всё по минимуму.

Автор JSON истеричка и его мирок ограничен только языком JS. На JSON свет не сошёлся. Основной формат будет XML, как и всегда. Прежде чем вспоминать модные словечки (JSON, YAML, ОБОЖЕМОЙЯИЗОБРЁЛКАКРАБОТАЛИСПИСКИВЛИСПЕЩЕ45ЛЕТНАЗАД) зачем вы это говорите вообще?

Где DOM парсеры для JSON? Где стримящие парсеры для JSON?
Где в вашем JSON: CSS, XPATH? Как вы в вашем JSON делаете проверки элементов на что-то? Кто-то решил изобрести велосипед и решил что каждый разработчик должен писать код выборки на каждом языке?
Где в вашем JSON XSD? Вы хоть раз типизировали ваши структуры? Или парсить строки каждый день это мода на stackoverflow?
Предложите хоть одну вменяемую библиотеку для JSON. Хоть для одного языка. Вы libxml хоть раз видели?

Потому что в нём ничего и нет больше.

  • Ни опциональной типизации XSD
  • Ни гибких языков запросов XSLT, XPATH, CSS
  • Ни расширяемости в другие языки-стандарты (ответ на вопрос “да кому он нужен?”)
  • Ни нормальных библиотек для работы с ним (json.org не предлагать)

В JavaScript он более приятный чем в других языках. Меня тошнит от него в любом языке с нормальной типизацией (не JS).

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

Ы? Really?

JSON:

Моё (если условиться, что всё - рабочие маркеры, а комментарии должны предваряться “/”):

  building
  type: public
  levels: 2
  height: 15m
  material: brick
  {
    roof
    shape: flat
    material: rubber
  }

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

ИМХО, не надо умножать сущности.
Есть маркер, он может иметь значение, а может не иметь.
oneway - не главный тэг

Раз уж пошло активное обсуждение синтаксиса - публикую описание на оригинальный синтаксис для адресной книжки. Есть RFC-образная спецификация.
Поскольку адресная книжка ориентирована на то, что записать информацию важнее, чем её разметить, то там допустим простой текст, без разметки, а # служит разметкой.
Иерархии через { } там вообще нет, т.к. я посчитал, что строго группировать адресную информацию - дело глубоко безнадёжное.

Т.е. в таком упрощённом синтаксисе нужно понимать как 5 тегов-понятий и 3 атрибута у каждого из этих понятий?

В этом примере немного путаницы на мой взгляд, так стоит обозначить:

Если же скобки убрать то будет неоднозначность: являются ли нижеследующие атрибутами свойствами понятия (building) или самостоятельными понятиями (type, levels, height). Одно другого не исключает, но в рамках свойств building и старой схемы я придерживаюсь мнения что “этажность” это таки свойство здания (building) и его нужно обрамлять скобочками.

Нет.
Всё, что находится внутри одной пары { } является описанием одной сущности. Аналогично с тем, что сейчас все тэги объекта в ОСМ являются описанием одной сущности.
Нет разницы между маркерами внутри одной пары { }, “ключевой” маркер может стоять первым, может последним.
Пара { } внутри другой является описанием подчинённой сущности, которая принадлежит внешней.
Глобальная пара { } подразумевается.

Вот это:

  building
  type: public
  levels: 2
  height: 15m
  material: brick
  {
    roof
    shape: flat
    material: rubber
  }

означает 2 сущности:
Основная: здание, публичное, 2 этажа, высотой 15 метров, из кирпича
Подчинённая сущность: крыша, плоская, из резины

Если идентификатор хранить точно там где простые свойства=значения, мы повторяем опыт OSM:

  1. если маркер стоит “последним”, то нужно обработать все свойства=значения.
  2. требуется знать какие из свойств=значений главные, а какие - нет

В нормальных онтологиях специально выделяют “понятие” и специальный синтаксис для него (хештег/двойной хештег) чтобы можно было

  1. быстрее отличить его от свойства=значения
  2. отличить его без знания предметной области

Т.е. это только вы знаете что building - основной, если у вас по тексту (обозначению) это не ясно, то значит этой информации недостаточно чтобы извлечь знания.
Напротив, если условится обозначать основые теги как #building то будет сразу ясно что это “понятие”, а не “атрибут”.

понял, тогда с учётом этого, нужно сделать хотя бы так:

  #building
  type: public
  levels: 2
  height: 15m
  material: brick
  {
    #roof
    shape: flat
    material: rubber
  }

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


#building
#building:with:roof
/...

В принципе, метки building:with:roof не обязательны. И такие понятия можно добавить в базу в неявном виде или при обработке запроса.

PS. Давно не писал CSS, предок с прямым потомком:

object#building > #roof

можно было бы его ускорить до

object#building:with:roof

Мне лично сомнительно преимущество выделения основных тэгов. Самоописательными они от этого не становятся.
Если вы получили объект с описанием

#вигвам
height=10

и не знаете, что такое “вигвам”, вам # не поможет. А высоту 10 метров можно бы и распарсить.

Чё-та мне кажется не надо опитимизировать синтаксис ради быстроты парсинга. Попахивает premature optimization, которая root of all evil.
Рекомендовать их ставить первыми - можно.

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

речь не об этом. Знаний нет, зато вам не нужно угадывать что главное:

  • height=
  • вигвам=

Прямо сейчас можно наблюдать это в type=.
Вы точно также не знаете что такое height, вигвам - но можете на основе #вигвам отфильтровывать. непонятные хештеги могут сломать вашу программу

Как тогда быть с этим допущением в синтаксе:
Глобальная пара { } подразумевается.

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

А если не требовать, а просто рекомендовать, то парсинг усложняется, причём настолько что этот формат будет не надстройкой на xml, а самостоятельным. В xml атрибуты всегда вначале не просто так:

Если все свойства одинаковые у двух сущностей, смешанных в один объект, нет смысла их разделять, дублируя все свойства.
Например, магазин + мастерская, с одним временем работы и т.д.

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

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

Прямо сейчас в osm можно продублировать информацию об объекте мира, этим не злоупотребляют без надобности.

Технически это запретить в любом случае не получится без знания всех доменов в OSM, это займёт много лет такая задача.

Ну я собственно про это и спрашиваю - зачем корень один требовать:
Глобальная пара { } подразумевается.

<описание элемента в osm>
<суть class=“building”></суть>
<суть class=“#leisure”></суть>
</описание элемента в osm>