OpenStreetMap

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

TL;DR

Основная задача: отметить POI так, чтобы её было как можно проще найти либо обнаружить её отсутствие или изменение при последующей проверке. В пределах проверяемых участков достигается заданием последовательности POI вдоль контуров зданий, которую удастся воспроизвести при проверке, либо в которой удастся заметить изменения. Последовательность создаётся заданием соответствия между POI как объектами, имеющими существенную площадь в масштабах зданий, и входами как точечными объектами на контурах зданий. Соответствие задаётся либо явно заданием entrance=* и его соединением с POI, либо неявно позиционированием POI рядом с местом расположения входа. В случае, если последовательность задать невозможно по причине отсутствия взаимно однозначного соответствия POI и входов, изображается структура проходов внутри здания, ведущих к POI. Также возможно использование дополнительных тегов для обозначения вертикального положения перечисленных объектов.

Куда ставить POI?

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

В Петербурге здания обычно уже нарисованы, и есть участники, которые оперативно дорисуют то, что будет построено. Иногда, правда, встречаются неточности у уже нарисованных зданий, которые могут помешать их использованию в качестве ориентиров для расположения POI. Одной из разновидностей неточностей является неправильное деление расположенных вплотную друг к другу зданий. Какое деление правильное – вопрос с не всегда однозначным ответом, но можно указать очевидно неправильные варианты, такие как диагональный разрез от угла, выходящего на перекрёсток. Также встречается различные смещения близко расположенных зданий и достаточно большие искажения их формы, которые имеет смысл устранить перед обозначением POI. Подобного рода неточности могут быть в данных изначально, например, в следствии обводки снимков с низким разрешением, или рисованием по принципу «лучше коряво, зато быстро нарисовать всё, чем качественно нарисовать часть, а остальное оставить пустым». Также эти неточности могут быть привнесены позже участниками, не вполне понимающими, что они делают, среди которых в данном случае преобладают пользователи iD.

Строительство нового здания на месте снесённого старого

Иногда здания меняются и в центре города

Если здания внутри квартала расположены более-менее правильно относительно друг друга, то их можно использовать в качестве ориентира для POI, даже не выясняя, смещён ли весь квартал. При уточнении положения квартала достаточно будет сдвинуть здания вместе с расположенными относительно них POI. Хотя POI я и обозначаю подобным образом, есть объекты, которые я рисую по-другому. Например, тротуары, проходящие вдоль зданий, я обозначаю относительно улицы с целью выравнивания вдоль оси, значит тротуары сдвигать вместе с кварталом не надо.

Допустим, что здания в приемлемом качестве уже есть, и при обозначении POI первоочередной задачей является выбор их расположения относительно зданий. Так как большинство POI, подходящих по моим критериям из прошлой записи, находятся внутри зданий, то и места для них надо выбрать внутри. Это даст точкам адреса, которые не понадобится задавать вручную, если только не понадобится адрес, не совпадающий с адресом здания. Кстати, существует мнение, которое я не разделяю, при котором (некоторые) POI обозначаются не внутри, а на границе здания. Про него будет написано ниже.

Геометрия точки

POI это «точка интереса», а какая геометрия и площадь могут быть у точки? Геометрическая точка, у которой нет площади, это абстракция, которая может подходить, а может и не подходить в различных ситуациях. Насколько POI уместно отмечать в виде геометрических точек, зависит от того, как плотно они расположены. Если в одном здании не больше одной POI, то точка вполне подойдёт для обозначения такой POI, причём не понадобится даже думать, куда именно внутри здания ставить точку. Но в тех местах, где я отмечаю POI, часто бывает не так, и если без обозначения площадными объектами обычно можно обойтись, то конкретное место внутри здания для точки выбирать уже приходится.

Если POI расположены достаточно близко, то понадобится отразить в данных их расположение друг относительно друга, а также относительно прочих деталей, отмеченных на здании. Этими деталями обычно являются въезды (barrier=gate, tunnel=building_passage), входы (entrance=*), части здания (building:part=*) и объекты расположенные на стенах типа почтовых ящиков, телефонов и часов. Делать это приходится как для упрощения проверок POI, чтобы не приходилось искать случайным образом разбросанные точки, так и для обозначения взаимодействий POI, таких как расположение одного заведения внутри другого или наличие общего входа в разные заведения.

POI в виде точек

Допустим пока, что POI обозначаются именно точками. Но обозначаемое заведение не является геометрической точкой, а значит придётся принимать решение, куда именно точку ставить. Можно посмотреть в вики, куда там советуют ставить точки всяких магазинов, amenity и прочего подобного. Иногда это рекомендация ставить точку внутри, иногда – по центру. По центру, конечно, звучит логично, это конкретное место в отличие от просто внутри, но на деле выясняется, что годится этот выбор опять же только для низкой плотности POI. Поскольку при низкой плотности выбор конкретного места практически не важен, то и толку от совета ставить по центру практически никакого нет.

Точки по центру заведений

Какие проблемы с установкой точки по центру заведения?

  • Несмотря на то, что центр – это, казалось бы, конкретное место, для его определения понадобятся конкретные границы заведения. Тут могут возникнуть различные мнения по поводу того, где они проходят. Например, будете ли вы включать в них служебные помещения или ограничитесь только местами, доступными клиентам? Я служебные помещения включаю, о чём будет написано ниже.

  • Даже если определиться с тем, что именно включать в границы заведения, сами эти границы могут быть неизвестны. Если включать служебные помещения, то точные границы сложно определить в связи с отсутствием к ним доступа, но даже если и не включать, то всё равно границы определить сложнее обычного. Помещения находятся внутри здания, значит их не видно на снимках, и gps в них не работает. Тут можно заметить, что в этих сложностях ничего страшного нет, для начала можно решить и примерно, а потом уточнить. Однако речь шла о преимуществах выбора центра как места для точки, и преимуществом было то, что это конкретное место. Теперь же выясняется, что конкретности заметно поубавилось.

  • Необходимость в принципе выяснять границы является недостатком в случае, если есть способ выбора точки, при котором их выяснять не надо. А он есть, и он как раз пригодится при том варианте проверок, который я обычно использую: идти вдоль улицы и отмечать все заведения подряд, не обязательно в них заходя, и, следовательно, не обязательно зная их границы.

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

  • «Ставьте точку по центру» звучит как уточнение рекомендации «ставьте точку внутри». Так будет, если заведение имеет форму выпуклого многоугольника. В других случаях центр может оказаться и снаружи. Так получится, например, если форма заведения П-образная. Точка POI, поставленная за пределами POI, выглядит довольно странно.

  • Центр – это не обязательно самое важное место, и пользователи при просмотре карты ищут, скорее всего, не его. Те, кто прочитал выше TL;DR, уже поняли, на какое искомое место и какой метод простановки точки без выяснения границ я намекаю.

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

Итого центр – не лучшее место точки как для пользователя, так и для редактирующего данные участника.

Точки рядом со входами

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

Почему имеет смысл ставить точку внутрь здания рядом со входом, а не на стену, прямо на вход?

  • Это гораздо ближе к приведенным выше рекомендациям ставить точку внутри или по центру заведения. Точка на стене, то есть границе здания окажется и на границе заведения, а не внутри его. Точка рядом со входом в центре не окажется, зато будет ближе к нему, чем точка на входе. Впрочем, бывает, что «рядом со входом» и «внутри» – это весьма разные места, но об этом потом.

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

  • Из редакторов типа MAPS.ME или OsmAnd по-другому и не выйдет. Точнее, промахнуться мимо здания, конечно же, выйдет, и нередко пользователям MAPS.ME это удаётся, но это не является желаемым результатом. А вот поставить точно на стену не получится, и не стоит даже и пытаться, особенно если вход уже отмечен. Можно сказать, что это проблемы пользователей этих не вполне пригодных редакторов, но какую-то часть данных они внесут, и если не настаивать на приклеивание точки к стене, то придётся опять же меньше переделывать.

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

Определённое расстояние

Причин ставить точку внутрь добавится, когда мы вспомним, что однозначного соответствия между входами и POI может и не быть. Но пока что ещё нужно точнее определить, что значит «ставить точку рядом со входом». Можно было бы этого и не определять, но тогда точки оказались бы разбросанными на разные расстояния от своих входов и порядка бы не было. Чтобы порядок был, можно задать определённое расстояние от входа и от стены, на котором должна находиться точка.

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

Расстояние от входа и границы здания до точки POI в моём случае равно двум метрам. Откуда эти два метра взялись?

  • Снова можно сказать, что традиционно так и делают. Конечно, ровно два метра традиционно не отмеряли, и ставить могли и на четыре метра, но не сильно больше. Чтобы ставили, например, на десять метров, я не помню.

  • Практически при любой ширине зданий точка, отстоящая на два метра от стены, будет ближе к этой стене, чем к противоположной. Редко попадаются здания у́же четырёх метров с POI внутри, причём такие, какие нельзя целиком отождествить с POI. Какие можно, а это, например, ларьки, либо сами пригодны для обозначения точками, либо позволяют поставить теги POI на свой полигон. Последний случай – это уже не обозначение POI точкой, так что его мы пока не рассматриваем.

  • Слишком близко к стене точку ставить не стоит, потому что тогда при корректировке геометрии здания она рискует оказаться за его пределами. Это произойдёт, если корректирующий не заметит POI, что бывает не так и редко. Типичный случай – когда сразу несколько зданий выравниваются вдоль улицы, например, потому что рядом с ними хочется провести линию тротуара, или потому что они вместе попали на снимок с коптера. Пара метров – расстояние, которое обычно и называется погрешностью рисования по снимкам, что позволяет надеяться на то, что корректировка произойдёт на меньшее расстояние и POI останутся внутри.

POI за пределами здания

Надежды оправдываются не всегда

  • Точке надо быть достаточно близко ко входу, чтобы в случае, когда рядом находятся несколько входов, можно было бы невооружённым взглядом определить, какой из них принадлежит POI. Для этого расстоянию от входа желательно быть меньше расстояний между входами, которое обычно больше двух метров, но бывает что не намного больше. Вариант с вооружением взгляда посредством рисования линий от входа до POI позже тоже будет рассмотрен.

  • Можно привести ещё одну причину, которая верна только на определённых широтах, в частности на той, на которой находится Петербург. В JOSM при десятиметровом масштабе, то есть когда рядом с линейкой в верхнем левом углу написано 10 м., ширина обводки площадных объектов, которые полностью не закрашиваются, примерно равна двум метрам. Такими объектами на данном масштабе являются, как правило, здания. Получается видимая граница закраски, на которую можно ставить точки POI, чтобы они были на одинаковом расстоянии от стены. Правда, двум метрам это расстояние будет равно при соблюдении некоторых дополнительных условий. Во-первых, должен быть добавлен какой-нибудь слой снимков, и включено масштабирование под их разрешение. Когда оно включено, слева от названия слоя появляется иконка в виде чёрных и белых квадратов в шахматном порядке. Включиться оно должно само при добавлении слоя, но можно случайно его выключить. Если его выключить, то не будет какого-то одного десятиметрового масштаба, так как масштаб можно будет устанавливать более свободно, а не только по шагам, подогнанным под разрешение снимков. Причина эта довольно специфическая, но ставить точки на два метра от стены я начал именно благодаря ей.

Обводка здания и POI на ней

Выравнивание под обводку здания: 1 – масштаб; 2 – линия, вдоль которой можно расставить POI; 3 – индикатор ограничения масштаба под снимок, ограничение работает даже когда снимок не отображается

Не лень ли выравнивать точки на два метра? Лень, поэтому я это делаю не вручную. Для подобного рода задач я пишу скрипты к плагину CommandLine для JOSM. В данном случае это скрипт PoiAlign из моего форка скриптов.

Проблемы определённого расстояния

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

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

С точки зрения рендеринга можно привести аргументы как против определённого расстояния, так и против слишком маленького, и два метра в этом смысле можно посчитать слишком маленьким. Рендерить POI тем легче, чем больше между ними расстояния. Если не пытаться выстроить их в одну линию, то расстояния можно увеличить, расставив POI так, чтобы некоторые были ближе к стенам, некоторые – дальше. Подобные действия, правда, лучше оставить для самих рендереров, но пока что известные рендереры делать этого не умеют.

Если POI стоят слишком близко к линии улицы, то их рендеринг будет сталкиваться с рендерингом названия улицы. На многих рендерах, включая стандартные тайлы, название POI может выводиться только под её значком. В этом случае наиболее пострадают POI на северной стороне улицы. Это опять же является проблемой рендереров, которым никто не мешает начать выводить названия сверху или сбоку. Можно повторить и традиционную рекомендацию «не рисуйте под рендер», хотя тут описаны проблемы любого рендерера, а не конкретного.

Можно сравнить метод расстановки POI с тем, как это делается на других картах. По какому принципу расставлены точки на картах Гугла и Яндекса? В общем, никакого принципа там не наблюдается. Точки стоят как попало, не обязательно даже внутри зданий. Это может объясняться тем, что они находятся в отдельном слое, и относительно зданий их ставить никто не пытается. Этим слоем могут быть их «народные» карты, где контуры зданий могут отличаться от «профессиональных». Ещё Гугл и Яндекс выводят далеко не все известные им POI, что позволяет уменьшить количество столкновений при рендеринге, но какого-либо принципа в их выборе тоже не наблюдается. На их рендерах можно увидеть точки, которых уже не существует, включая те, про которые им самим известно, что они не существуют. Яндекс с недавнего времени также показывает и входы в заведения. Ещё раньше это стал делать 2гис. 2гис при этом, как правило, не пытается представлять координаты POI и ограничивается их адресами, а значки точек выводит в горизонтальной плоскости там, где их входы, почему-то сдвигая их по вертикали на крышу.

Фрагмент Яндекс.Карт с выбранной POI

Яндекс показывает, где находится вход в ресторан Тан-Жен, и почему-то он отдельно от самого ресторана

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

Адаптация точек рядом со входами

Если отбросить рендер-проблемы и потенциальные войны правок из-за расстояний, то какие проблемы у метода обозначать POI точками, расположенными на расстоянии двух метров от входа останутся? Проблемы будут возникать в следующих ситуациях:

  1. POI значительно дальше двух метров. Тогда одной точкой не выразить информацию и о месте входа в здание, и о месте POI. По данному методу информация о месте POI выбрасывается, но это неправильно. Точка является обозначением именно POI, а не входа, значит лишней информацией у точки является место входа, и при необходимости что-то выбросить, следовало бы избавиться от него.
  2. За одним входом несколько POI. Если строго следовать методу, то несколько точек придётся ставить в одно и то же место. При этом внутри POI в лучшем случае окажется только одна из них, значит информации о месте POI опять нет.
  3. У одной POI может быть несколько входов. Одна точка не может передать информацию о двух входах, и по методу место для точки не определено.

Допустим, что несмотря на перечисленные выше проблемы мы всё равно хотим пользоваться описанным выше методом, то есть для обозначения POI ставить только одну точку, которая (как правило, от которого мы здесь отступим) ставится рядом со входом. Как можно его адаптировать к ситуациям 1, 2 и 3?

Ситуация 1: POI не рядом со входом. При внешней проверке, которую я обычно и делаю, когда иду смотреть участок первый раз, появляется дополнительная сложность: неизвестно, насколько далеко от входа находится POI, так как всё, что видно, это дверь с вывеской. Выше я писал, что не стоит стремиться выравнивать POI, находящиеся в глубине здания, но для этого нужно знать, что POI действительно в глубине. В итоге такие POI всё равно отмечаются рядом со входом. Если же их истинное расположение известно, то точки можно поставить куда-нибудь внутрь них. Дальше, поскольку при данном методе дополнительно ничего не рисуется, придётся добавить к ним примечание, например в теге note, как туда пройти. Понятно, что лучше было бы проход нарисовать, но, к сожалению, причины его не рисовать могут не ограничиваться незнанием его расположения. Рисованием проходов мы займёмся при последующих модификациях метода.

Ситуация 2: за одним входом несколько POI. Ровно в одно место их ставить, конечно же, никто не будет, значит их придётся каким-то способом раздвигать. Насколько результаты этого способа будут соответствовать настоящему расположению POI зависит от обстоятельств. Иногда можно хотя бы примерно оценить расположение POI, например, если за входной дверью сразу видны проходы в отдельные POI. Допустим, виден проход налево в один магазин, и направо в другой, тогда первый магазин можно отметить точкой чуть левее входа, другой – точкой чуть правее. Если оценить расположение POI нельзя, то вместе с ситуацией 2 может иметь место и ситуация 1. Собственно так и будет, если рассматриваемый вход – это вход в бизнес-центр или что-нибудь подобное. Тогда у самого входа будет написано про десяток организаций, но их расположение относительно здания и относительно друг друга останется неизвестным. В этом случае придётся городить скопление из точек рядом со входом, не имеющие никакого отношения к их истинному расположению.

Кое-какая информация о месте POI в случае с БЦ бывает. Обычно это номер этажа, но это расположить POI горизонтально не поможет. Если повезёт, то можно обнаружить окна каких-то из организаций. Всё это, казалось бы, повод не мапить подобные случаи без проведения внутренней разведки здания, после которой можно будет отметить POI другим способом, с рисованием внутренней геометрии. Однако куча POI может оказаться за любой дверью в любом здании, а не только в явно офисном, которое можно было бы заранее решить исключить из проверяемого участка.

Дверь с множеством табличек POI

За одним из входов в обычное жилое здание скрывается более десятка POI

Частный случай ситуации с несколькими POI – расположение одной POI внутри другой. Есть «большая» POI, а внутри неё – «маленькая», не имеющая собственного входа снаружи здания. Точку внутрь точки поставить не получится, поэтому если есть намерение по прежнему ставить только точки, то относительное расположение опять придётся передавать фиктивными координатами точек. В данном случае «большая» точка ставится как обычно, а «маленькая» – за ней вглубь здания, и её уже выравнивать на два метра от стены не надо.

Ситуация 3: у POI несколько входов. Ясно, что обычно не следует ставить по точке у каждого входа. Иногда бывают и менее ясные случаи, когда входы ведут в не соединённые между собой части заведения. Тут, строго говоря, одной точки не хватит не только для того, чтобы обозначить входы, но и для того, чтобы обозначить само заведение. Но если хочется обойтись одной точкой, придётся выбрать «главную часть», например, которая больше, и поставить точку у входа в неё. Подобным же образом можно поступить и в более простом случае, когда входы ведут в одно место, и заведение не состоит из нескольких частей. Тут можно выбрать «главный вход» и поставить точку рядом с ним. Главным может быть вход, который шире, который дольше открыт либо открыт в более доступное время, или который в более доступном месте, например на углу. Другой способ выбрать место для точки – поставить её посередине между входами, если входа два. Если входы расположены на разных сторонах здания, то точку можно опять же поставить на углу между ними.

Угол здания и два входа с разных сторон от него

Два входа в «Кондитерскую» с разных сторон относительно угла здания

Входы

Раз уж в большинстве случаев, описанных выше, точки ставились относительно входов в здания, почему бы не обозначить и сами входы? Тогда чаще всего для POI будет нужно поставить две точки: entrance=* на границу здания на место входа и точку POI в двух метрах от него. Если входов больше одного, то точек получится больше двух.

Недостатки

Первая причина этого не делать – лень ставить дополнительную точку. Для борьбы с ленью предназначен уже упомянутый скрипт PoiAlign, который вместе с выравниванием относительно границы здания может и поставить вход, и выровнять POI относительно существующего входа.

Также входы являются дополнительными данными, которые нужно поддерживать, при этом не настолько стабильные, насколько может показаться. Как уже было сказано в предыдущей записи, из окна на первом этаже могут сделать дверь, а из двери – окно. Двери, ведущие на лестницы жилых домов, гораздо более стабильны, поскольку саму лестницу переместить гораздо сложнее, но в связи с POI нас интересуют преимущественно не они.

Арка, в которой расположен вход в магазин

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

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

Возможны также сложности с определением наличия и количества входов, связанные с тем, что вход это не обязательно (одна) дверь. Вход может быть и без двери, хотя такое встречается редко. Если двери прямо на границе здания нет, то, скорее всего, она есть где-то дальше. Вход может состоять и из нескольких расположенных рядом и обычно одинаковых дверей. Почему их не обозначить отдельными входами? Они ведут в один и тот же коридор, фойе или что там за ними. Их могут открывать по очереди, например, сегодня открыта правая дверь, завтра левая, а послезавтра там важное мероприятие, и будет открыта центральная, а по окончании мероприятия на выход откроют все. Если отметить такие двери отдельными входами, то это усложнит данные и сразу даст одну из описанных выше ситуаций с несколькими входами для POI. Если отдельные входы в данном случае отмечать не хочется, то надо ещё определить, имеет ли место данный случай для каждой конкретной группы дверей. Если двери непрозрачные, то определить это может быть нереально без захода внутрь. Несмотря на только что сказанное, никто не мешает обозначить сами двери независимо от того, скольким входам они соответствуют. Для собственно двери есть отдельный тег door=*. Если принимать все эти решения и всё это делать, то можно потратить много времени, которое, возможно, лучше было бы потратить на ввод следующих POI.

Группа из двух дверей

Две двери, ведущие в одно место, открыта одна из них

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

Ещё одна неприятность – два входа, расположенные один ровно над другим. Поскольку это разные входы, то им нужны разные точки, но точки эти должны находиться в одном и том же месте, что неудобно. Лучше их чуть-чуть раздвинуть. Их POI, скорее всего, мы тоже захотим раздвинуть.

Лестницы, ведущие наверх и вниз к дверям, расположенным друг над другом

Один вход ровно над другим, добраться до них позволяют лестницы, приделанные снаружи к зданию

Преимущества

У обозначения входов вместе с POI есть и преимущества. Если не отметить вход, то его может позже отметить другой участник. Этот участник может не знать, что POI была отмечена рядом с местом входа и не станет пытаться сделать так, чтобы вход и точка POI оказались рядом. Поскольку место для входа выбрать сложнее, а при криво нарисованном здании вообще нельзя выбрать однозначно, велика вероятность того, что точка входа окажется не там, где точка POI. После этого одну из точек придётся двигать.

Если потратить достаточно времени на выбор места для входа, то не очень захочется тратить его ещё раз. Если при этом место входа в осмовских данных представлено только точкой POI, то его сохранность зависит от сохранности этой точки. Сохранность же точки зависит от того, насколько хорошо функционирует соответствующее ей заведение. Есть участники, которые готовы по любому подходящему поводу эту точку удалить. До этого мы доберёмся в следующей записи, когда будем рассматривать lifecycle prefix. Сейчас же отметим, что закрытый магазин они потрут, потому что он для них не магазин, зато закрытый вход они не потрут, потому что… В общем, если хотите, чтобы место входа осталось в данных, отметьте на нём entrance.

Обозначение

Вход обозначается точкой с тегом entrance=*, в который записывается тип входа. Чаще всего типом является просто entrance=yes, встречаются также значения main, staircase и service. Когда стоит ставить main, а когда хватит и обычного yes, не всегда очевидно. Иногда main используется для основного входа в любое место. Тогда единственный вход в магазин будет main, и main-входов будет даже больше, чем обычных. Противоположным вариантом будет считать main’ом только единственный главный вход в здание, если он есть, и у большинства зданий его нет.

Некоторые участники предлагают считать вход в магазин отдельным типом входа, и обозначать его entrance=shop. Объясняют они это тем, что без данного значения из осмовских данных непонятно, куда ведёт вход. Ниже будет показано, что нарисовав проходы внутри здания, можно сделать так, чтобы, куда он ведёт, понятно было. Это несколько убавляет причин использовать entrance=shop, хотя сам принцип задавать значение entrance по месту за входом уже используется в entrance=staircase.

За entrance=shop можно привести и другие аргументы: это тип использования входа или это конструктивная особенность входа. Подойдут оба аргумента. С точки зрения типа использования это вход для неограниченного множества посетителей, которые надолго в данном месте не задержатся, которые могут стать, а могут и не стать клиентами заведения, и могут использовать этот вход для выноса приобретённого товара. Вход может использоваться достаточно часто для прохода и туда, и обратно, значит он должен легко открываться, и через него должно быть удобно ходить встречным потокам людей. Может быть, на счёт «удобно» я преувеличиваю, но обычно сделано хотя бы что-то, чтобы облегчить встречный проход, например, есть возможность увидеть сквозь дверь, что кто-либо идёт навстречу. То есть дверь часто бывает прозрачная – это мы перешли к конструктивным особенностям. Ещё к ним можно отнести достаточно большую ручку двери, или даже автоматическое открывание. У такого входа не будет кнопок, переговорных устройств и прочих хитростей – за дверями со всем этим магазины тоже бывают, но на сам вход при этом не обязательно ставить entrance=shop. В общем, этот тег – не такая странная идея.

Дверь на лестницу и дверь в заведение

Два входа: staircase и shop; перед вторым входом ступеньки, у первого входа ступеньки внутри, на то он и staircase

Ещё встречается entrance=exit. «Вход=выход» некоторым так не нравится, что они предлагают использовать другой тег, а именно exit=*. Но на самом деле почти любой вход является также и выходом. По идее тогда следовало бы ставить почти всегда пару тегов entrance и exit, а это не слишком хочется делать. Можно вообще задуматься, почему обычно пишется именно «вход», а не «выход». Видимо, потому что в осме рисуется преимущественно то, что находится вне зданий, глядя на это из мест опять же вне зданий.

Если мы ограничимся только тегом entrance, то entrance=exit следует ставить на выход в чистом виде, через который нельзя войти. У POI и даже у мест скоплений POI, типа ТК, такие выходы попадаются редко. Чаще они встречаются на объектах с ещё большими потоками людей, например, на транспортных объектах вроде метро. Входы и, возможно, выходы метро считаются такими важными, что они удостоились своего собственного тега railway=subway_entrance. «Возможно» – потому что на выходы этот тег ставят менее охотно, предпочитая вместо него entrance=exit. Впрочем, и на вход в добавок к railway=subway_entrance иногда ставят entrance=main. Проблем было бы меньше, если бы тег railway для входов не использовался, но он был введён в употребление ещё в те времена, когда вход в здание обозначался как «здание», то есть building=entrance. Есть попытки ввести подобный тег и для железнодорожных станций.

Дверь с надписью «Exit only»

Здесь только выход из магазина матрёшек

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

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

Арка с двумя дверями под ней

Входы в здание под аркой

Ещё один вариант нахождения входа внутри площади здания – расположение входа под частью здания, не касающейся земли. Сам вход при этом будет на границе касающейся земли части, то есть на линии building:part, что вполне устраивает валидатор JOSM’а. В этих случаях, когда вход оказывается внутри площади здания, находящиеся за ним POI, конечно же, не нужно выравнивать относительно границы здания, хотя можно их выровнять относительно границы его части.

Входа, доступного для клиентов заведения, может и не существовать. Вместо него бывает окно для приёма и выдачи заказов. Тогда точку POI придётся ставить уже относительно окна. В другом случае окно присутствует не вместо входа, а дополнительно к нему. Тут уже POI лучше ставить относительно входа. И в том и в другом случае может возникнуть желание обозначить окно, и, следуя тому, что предлагается в ветке форума про МакАвто и МакЭкспресс, можно воспользоваться для этого тегом amenity=walk_up_window. Хотя по большей части в той ветке форума обсуждается, является ли подобное окно отдельной POI или нет, для нас это сейчас не важно, потому что само окно можно отметить в любом случае.

Три окна с шавермой и кофе

Окна обслуживания тоже могут идти плотно

Соответствие входов и POI без проходов

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

Совмещение

В разделе Точка рядом со входом описывалось, почему точку POI лучше ставить внутрь здания, а не на стену. Но если мы взялись ставить и точку входа, которая окажется уже на стене, может быть можно ей и ограничиться, поставив на неё все теги заведения вдобавок к entrance=*? Помимо того, что это самый экономичный по отношению к рисованию способ, он ещё и наиболее явно задаёт соответствие входа и POI. К сожалению у этого способа есть серьёзные недостатки:

  • Все вышеописанные причины ставить точку POI внутрь никуда не исчезают от того, что на ней будет ещё и тег entrance. Допустим, мы считаем, что это хорошие причины и ожидаем, что они тем более являются хорошими для тех, кого не интересует обозначение входов, а это большинство мапящих POI. Тогда нас должно беспокоить, что метод объединения POI и входа в одной точке несовместим с методом обозначения POI внутри здания, по которому основная часть POI и обозначена, на что есть хорошие причины. Эти «объединённые» POI будут выделяться среди остальных.

  • Вход и POI это разные сущности, так что нежелательно представлять их одним осмовским элементом. Проблемы, которые могут возникнуть, связаны с использованием тегов, которые сами по себе не задают чего-то физически существующего, и ставятся в дополнение к тем тегам, которые задают. То есть это такие теги, которые уточняют тип сущности или описывают её свойства. А если на элементе два тега, которые задают две разные физические сущности, то к какой из них станет относиться добавленный на тот же элемент дополняющий тег? Самым распространённым дополняющим тегом является name. На POI, подобные рассматриваемым в этих записях, name стараются поставить всегда, когда название удаётся определить. Тогда name окажется и на «объединённой» точке, и его значение сможет считаться названием входа, а это не то, чего обычно хотят, хотя некоторые в ряде случаев предлагают делать исключения. Можно, конечно, возразить, что у входов редко бывают названия, следовательно ясно, что name относится не ко входу, однако name – не единственный подобный тег. Такая ситуация возникает не только со входами. Ниже будет рассмотрена ситуация, когда POI будет совмещена со зданием, и нужно будет задать и название здания, и название POI. Там же будет рассмотрен и другой взгляд на эту проблему, при котором мы утверждаем, что отмечаем мы в первую очередь не заведение, здание или вход в него, а географическое место. Если мы посмотрим таким образом на точку с тегами и входа, и POI, то name относится не ко входу и не к POI, а к месту, а, значит, неопределённости, к чему относится name, нет. Однако в данной ситуации нам это не поможет, потому что вход и POI это разные места, а то, что осмовских данных они представлены одной точкой – результат экономности при добавлении точек для рассматриваемого метода. Становится видно, что экономность эта проявлена зря.

  • Обозначить вход и POI одной точкой не выйдет, если нет взаимно однозначного соответствия вход-POI. У метода поставить POI рядом со входом в этом случае тоже возникнут проблемы, но их легче исправить. Здесь же, если входов у одной POI несколько, то придётся выбирать «главный» вход, к которому будут добавлены теги POI. Если же за одним входом несколько POI, то поставить их теги на одну точку не получится, и придётся выбирать уже «главную» POI, а остальные со входом не совмещать. При этом ни «главного» входа, ни «главной» POI может на самом деле не быть.

  • Раз уж все POI со входами совместить не получится, можно предложить это делать только в случае однозначного соответствия, а в других случаях ставить точки POI внутри зданий. Тогда пока за входом одно заведение, оно совмещается со входом. Если там открывается ещё одно, то, помимо его добавления, старое заведение отделяется от входа. Если какое-то из них закрывается, то оставшееся, видимо, снова приклеивается ко входу, хотя, скорее всего, этого уже делать никто не будет. Так что лучше просто всегда ставить POI внутри зданий.

Отношение

Допустим, что вход и POI обозначены разными элементами. Как обозначить то, что вход относится к POI? Может быть, осмовским отношением?

Отношения в осме – довольно неудобные элементы, например, потому что нет самого объекта отношения, который выводился бы редактором, и на который можно было бы ткнуть, чтобы его выбрать. Ткнуть можно только член отношения, и только через член можно выбрать само отношение. Без помощи членов до отношения можно добраться через список, существующий отдельно от карты, что менее наглядно. Сказанное про список относится к JOSM, в других редакторах чего-либо подобного может и не быть. Неудивительно, что использования отношений стараются избегать, и хотя для целей соответствия входа и POI было придумано несколько разновидностей отношений, ни один из них широко не используется.

  • Отношение building. Отношение позволяет задать здание и связать с ним его входы и POI. Непонятно, зачем это делать, ведь входы и POI и так находятся на контуре здания или внутри него. Ещё более непонятно, как это позволит нам задать соответствие между отдельными входами и POI. Предлагается же задать его таким довольно странным способом: создать отдельное отношение здания для каждой POI, про которую известна дополнительная информация типа отдельного входа. Вход при этом надо записать в него с ролью entrance, а саму POI – не совсем ясно, с какой, видимо с outline, что будет означать, что POI надо обозначить полигоном. Почему отдельная POI превращается в здание – непонятно. Короче, получается что-то страшное, что делать не стоит. Для того, чтобы сделать что-то менее страшное, были придуманы два следующих типа отношений.

  • Отношение site. Это отношение ещё неоднократно нам встретится, но, к сожалению, нам ни разу не удастся заключить, что оно-то и является решением очередной проблемы. Если посмотреть на текущую редакцию его описания, то вообще не понятно, как оно может нам помочь со входами. В этой редакции – действительно никак. Однако ранее это отношение, предназначенное для сбора нескольких элементов в единое целое, могло включать в себя и член с ролью entrance. Позже его, видимо, посчитали излишним, так как отношение позволяет задать периметр объекта, а на периметре можно искать уже сам вход, да и чем является периметр решили переопределить. Впрочем, возможно и в прежней интерпретации использовать его для задания соответствия входа и POI не получилось бы, потому что нужный нам вход является, строго говоря, входом в здание, и не всегда является входом непосредственно в заведение, и, следовательно, не всегда является частью заведения, которую можно было бы собрать в одно отношение с ним. Некоторым участникам могло казаться, что site подходит для решения данной задачи, другим могло казаться иначе. В данный момент вообще не наблюдается согласия, для чего это отношение предназначено. Например, в Петербурге его используют для коллекций типа «Сеть АЗС Лукойл», то есть для того, что текущая редакция вики делать не рекомендует. В итоге это отношение для решения нашей задачи не подходит.

  • Отношение associated_entrance. Популярностью это отношение не пользуется, зато оно наиболее близко по смыслу к поставленной задаче. Оно достаточно простое и логичное, так что если бы вы про него не знали, то придумали бы что-нибудь очень похожее. Если того, что описано в следующем разделе, сделать не удастся, а соответствие вход-POI как-то обозначить захочется, то лучше всего использовать именно этот тип отношения. Как нам объясняет страница-пропозал, все POI здания неявно связаны со всеми входами. Однако мы знаем, что в реальности чаще всего это не так, и связи между каждым входом и каждой POI нет. Зато всё множество входов и POI можно поделить на непересекающиеся подмножества, внутри которых связи уже есть. Тогда для каждого из таких подмножеств можно создать отношение associated_entrance. Каждое подмножество будет состоять из одного или нескольких входов и из одной или нескольких POI, при этом через любой из входов можно пройти в любую из этих POI. Все входы подмножества надо добавить в отношение с ролью entrance, а все POI подмножества – с пустой ролью.

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

Проходы к POI

Если не объединять вход и POI в один элемент, которым может быть точка или отношение, то соответствие между ними придётся задать геометрически, то есть что-то дополнительно нарисовать. Самый логичный способ это сделать – нарисовать проход, ведущий от входа к POI, а также, если нужно, от одной POI к другим. Нарисованный проход задаст соответствие как с точки зрения машиночитаемых данных, так и с точки зрения участников, и избавит от необходимости писать примечания типа «вход через арку/другой магазин». Также, поскольку проход может соединять несколько входов и POI, он избавит от проблем, связанных с отсутствием их взаимно однозначного соответствия. Проход этот в реальности может состоять из коридоров, лестниц, направлений движения через залы или как бы вообще не существовать, когда заходишь в дверь и сразу оказываешься в заведении.

Если принять этот способ, то отмечание POI превращается в разновидность indoor mapping, только в отличие от распространённого Simple Indoor Tagging, когда рисуются препятствия типа стен, здесь наоборот рисуются проходы. Препятствия, конечно, тоже можно отметить, но это не решит поставленной задачи соединить вход с POI. Вычисление соответствия входов и POI по данным о препятствиях будет заключаться в составлении поэтажных планов и дальнейшей маршрутизации по площадям этих планов, свободным от препятствий. Маршрутизацию по площадям пока никто не делает, и ещё непонятно, однозначно ли определены соединения между планами в виде лестниц и прочих не лежащих в плоскости проходов. Если же рисовать вместо этого линии проходов, то подойдут обычные средства маршрутизации. Точнее, поскольку маршрутизация нужна только в пределах одного здания, подойдут даже и тупые средства типа поиска в ширину и даже в глубину.

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

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

Перейдём ко второй подзадаче. Она заключается в том, чтобы соединить одной или несколькими линиями один или несколько входов с одной или несколькими точками POI. Какие осмовские элементы нам для этого подойдут? Подойдут в первую очередь линии с пешеходными тегами highway=*, а именно:

  • highway=footway – тег, используемый для пешеходного чего угодно, когда не подходит ничего другое; как следствие, используется слишком широко, зато у него есть уточняющий тег footway=*;
  • highway=steps – тег для обозначения лестниц; чаще всего используется для ступенек вне зданий, хотя большинство лестниц находятся внутри;
  • highway=corridor – гораздо менее поддерживаемый тег для коридоров, зато предназначенный для использования именно внутри зданий.

Насколько в принципе уместно соединять POI с highway? Например, валидатору JOSM’а не нравится, когда точки amenity, office, shop соединены с highway. Но тут валидатор проявляет непоследовательность, ведь если POI отмечена полигоном, то никаких возражений с его стороны не поступает.

Раз уж даже редактор возражает против рисования проходов внутри зданий, может быть без них можно обойтись? И обойтись на самом деле можно в большинстве случаев обозначения видимых с улицы POI. Эти POI мы выстраивали в последовательность, ставя их на определённое расстояние от границы здания, чтобы за ними было легче следить. При имеющихся данных о последовательности мы знаем, что, допустим, сначала идёт магазин А, потом Б, потом В. Если в реальности мы увидим магазин Г между А и В, то мы будем знать, что Б надо поменять на Г. Но бывают случаи, когда в последовательность магазины не выстроить, например, если между А и В идёт Б, но в глубине Б есть коридор налево с Б1 и направо с Б2. Если мы начнём подозревать, что Б2 закрылся, нам надо знать, куда идти внутри здания, чтобы найти место на котором он находился, и решить, что с ним делать. Типичными примерами таких Б1 и Б2 являются точки продажи кофе с собой и точки ремонта электроники, часто безымянные. Такие точки придётся ставить вглубь здания вне последовательности, и если они не соединены проходами с другими POI и/или входами, то будет сложно доказать, на месте ли они до сих пор. Дело осложняется ещё и тем, что они могут идти группами по несколько штук в одном здании с близко расположенными входами одновременно на нескольких этажах.

Место с несколькими POI, соединёнными пересекающимися проходами

Несколько дверей, за которыми по несколько POI на нескольких этажах; рядом ещё и метро

Новый вход в подвал

С того момента, как я в прошлом месяце сфотографировал это место, в подвале появилось ещё три POI – это под бывшим Макдоналдсом на Сенной, на месте которого теперь тоже три POI, и это я ещё не говорю, что на 2, 3, 4 и 5 этажах

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

Теперь рассмотрим составляющие проходов.

Лестницы

Для лестницы ничего лучше highway=steps не подходит. К лестнице внутри здания придётся добавить как минимум indoor=yes. Это пригодится для рендереров, делающих различие между тем, что внутри, и тем, что снаружи, таким как OsmAnd.

Хорошо, когда лестница на пути к POI специально сделана для этого пути, и ни в какое другое место не ведёт. Если же путь к POI проходит через такую лестницу, какие обычно находятся в лестничных клетках многоэтажных зданий, и сама точка находится на одном из верхних этажей, то придётся рисовать несколько витков лестницы со всеми сопутствующими неприятностями типа необходимости поставить две разные точки в одно и то же место так, чтобы они были в разных местах. Это точки, которые находятся одна ровно над другой, так как марши и площадки лестницы находятся один над другим. Они должны быть представлены разными осмовскими точками, чтобы не создавать связности там, где её нет. Если разные точки создать ровно на одном месте, то неудобно будет редактировать, да и валидатор JOSM’а по этому поводу выскажется. Отсюда следует одна из причин не рисовать проход, даже когда он известен: рисовать может оказаться слишком сложно.

Эскалатор – обозначается как лестница с дополнительным тегом conveying=*. Вместо этого довольно часто попадается тег escalator=*, но это хуже, потому что тогда для движущихся не-лестниц, то есть траволаторов, придётся изобретать ещё один тег, например travolator=*. Траволатор можно обозначить тем же conveying=*, добавленным уже к highway=footway.

Коридоры

Для коридоров имеется непосредственно подходящий тег highway=corridor. У этого тега меньшая поддержка среди рендереров, что и хорошо, и плохо. Хорошо это тем, что рендерер не будет пытаться выводить плотно расположенные проходы внутри зданий на бо́льших зумах, когда выводить их не нужно. Плохо это примерно тем же, только на меньших зумах. Хуже всего результат выглядит, когда вместе с коридорами надо нарисовать и лестницы – тогда будут видны ни с чем не связанные ступеньки. Во многих простых случаях, когда за входом либо сразу POI, либо сразу короткие проходы в разные стороны, результат с использованием тега highway=corridor получается вполне приемлемым. Тогда, возможно, конечному пользователю карты рендер коридоров и не нужен.

С точки зрения редактирующих данные участников, у тега highway=corridor тоже есть и преимущества, и недостатки. К преимуществам можно отнести то, что про него сразу ясно, что он внутри здания. Это значит, что дополнительно не надо ставить indoor=yes, а раз ставить не надо, то нельзя и забыть поставить. Лично мне удаётся забыть поставить какой-нибудь indoor-тег довольно часто, так как для них никаких предупреждений валидаторы, встроенные в редакторы, не дают. Зато для упомянутых выше простых случаев достаточно линии с одним тегом highway=corridor. Именно такой способ, как самый простой, и используется в скрипте PoiAlign, когда создаётся соединение входа и POI.

Недостатки highway=corridor заключаются в том, что ни JOSM ни Vespucci его не понимают, во всяком случае без дополнительной настройки. JOSM понимает только то, что это highway, чего ему достаточно, чтобы ругаться на соединения с POI. Зато чтобы рендерить как-либо отлично от линии без тегов, этого не достаточно. В итоге нельзя забыть поставить indoor=yes, зато можно забыть сам highway=corridor. Но JOSM теперь предупреждает и о линиях без тегов, значит забыть всё-таки не выйдет? Выйдет, если добавить ещё какой-нибудь тег, обычно level. Линия, на которой стоит только level, вполне устраивает валидатор JOSM’а. Лучше настроить JOSM, чтобы и highway=corridor, и indoor=yes как-либо отображались, что сделать довольно просто с помощью ​MapCSS. Добавить свой файл со стилем можно через меню View > Map Paint Styles > Map paint preferences, дальше в появившемся диалоге нажать на + рядом с правым верхним углом.

Если хочется, чтобы corridor выглядел как footway, можно добавить файл, содержащий такой стиль:

way[highway=corridor] {
	width: 1;
	color: foot#00ff00;
}

При желании можно отображать и indoor подобно тому, как рисуются тоннели:

way[highway=corridor],
way[highway=steps][indoor=yes],
way[highway=footway][indoor=yes] {
	casing-width: 1;
	casing-color: indoor#888888;
	casing-dashes: list(10, 2);
}

Из Vespucci использовать corridor ещё более неудобно. Помимо того, что он не рендерится как дорожка, он ещё и не попадает в автозаполнение значения тега, даже после того, как он был введён. А именно Vespucci приходится использовать на месте для отрисовки сложного indoor’а, когда нет желания ни бороться с редактором, ни смотреть правильные значения тегов в интернете. В этом случае легче использовать для обозначения коридоров highway=footway.

Почему бы тогда всегда не использовать footway? Сам проход мы по-прежнему можем обозначить, причём более распространённым тегом. Теряется информация о том, что это именно коридор? У нас есть уточняющий тег footway=*. Правда сейчас все его распространённые значения относятся к проходам вдоль и поперёк улиц, то есть к тротуарам и переходам, но возможно стоит добавить footway=corridor и прочие значения для того, что будет описано ниже.

Однозначно ответить, что лучше – corridor или footway – не получается. Теоретически есть выбор между: * меньше перегружать значениями highway=footway, использовав вместо него другое значение для тега highway, то есть highway=corridor, и * не вводить в употребление ещё одно значение более высокого уровня, то есть highway=corridor, когда можно использовать второстепенный уточняющий тег, в данном случае – footway=*.

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

Прочие проходы через помещения

Коридор – это проход, ограниченный по бокам стенами. Но не всякий проход ими ограничен. В качестве ограничителей могут выступать полки с товарами в магазинах, перила во многоэтажных залах или столики в фудкортах. Ограничителей может не быть вообще, если цель прохода находится на противоположной стороне зала. У зала, конечно, стены есть, но весь целиком он проходом не является. Линия прохода в этом случае займёт наиболее удобную траекторию движения по залу.

Как подобные проходы обозначать? steps не подходит, значит придётся использовать либо footway либо corridor. Выше мы уже начали рассматривать тег highway=corridor в принципе, а не только применительно к собственно коридорам. Если мы посчитаем его уместным для коридоров, то можем ли мы также посчитать его уместным и для прочих проходов? Наименее подходящим случаем для corridor выглядит проход без ограничителей. Но можно сказать, что он и для footway не подходит, ведь никакой выделенной дорожки нет. А раз не подходит и тот, и другой тег, то можно использовать более простой corridor… или более распространённый footway. Короче, опять однозначно не ответить, что лучше. В итоге обычно получается, что если начали в данном здании использовать один из тегов, то и продолжаем его использовать в случаях, подобных описанным здесь.

Проходы поперёк других проходов

Допустим, что есть коридор, и он уже нарисован одной линией. Её нам хватит, чтобы соединить начало и конец коридора. Но между началом и концом коридора может быть дверь, за которой нужная нам POI. Точка этой POI окажется сбоку от линии коридора, значит линию и точку придётся соединить ещё одной линией. Эта линия будет соответствовать проходу от линии коридора до двери. Следует ли её обозначать как коридор? Находится она в коридоре, но сам коридор уже обозначен. Или мы можем сказать, что линия соответствует проходу через дверной проём, просто её пришлось продлить до пересечения с линией коридора. Этот проход можно посчитать за отдельный короткий коридор.

Если представить себе длинный коридор через бизнес-центр с кучей офисов, то возникнет желание отметить подобные линии до каждого из офисов именно как highway=corridor для того, чтобы они не рендерились, иначе результат будет похож на бахрому. Может также возникнуть желание придумать свой тег, причём даже не footway=*, а highway=*. Стандартные маршрутизаторы его не поймут, но нам этого и не надо, так как линия с этим тегом будет короткая, значит маршрут и так подойдёт достаточно близко к цели, да и занимаемся мы рисованием проходов в первую очередь для организации процесса обновления POI, а не для маршрутизации.

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

  • Вместо коридора у нас тротуар.
  • Вместо двери в помещение с POI у нас входная дверь в здание. Сами двери мы в обязательном порядке не обозначаем в обеих ситуациях, но вход в здание, который обычно совпадает с дверью, мы обозначаем.
  • Вместо POI сбоку от коридора у нас POI сразу за входом в здание.
  • Коридор нужно было соединить с POI, на что хватало одной линии, которая целиком находилась внутри здания. Соединение же с тротуаром состоит из двух частей: от тротуара до входа вне здания и от входа до POI внутри здания. Мы пока ещё не решили, нужно ли нам рисовать первую часть, но вторую часть рисовать нужно. Далее в этом разделе мы будем рассматривать только вторую часть.
  • В случае с коридором мы рассматривали, стоит ли обозначать соединение как коридор, потому что оно находится в коридоре. В случае с тротуаром соединение входа с POI находится не на тротуаре, значит обозначать его как тротуар не имеет смысла.
  • В случае с коридором мы рассматривали соединение и по-другому – как дверной проём, продлённый до линии коридора. На самом деле продлевался он и в другую сторону, до точки POI, но это было незаметно, если мы не обозначали саму дверь. В случае с тротуаром точка, от которой продлевается проём, всегда обозначена как вход, и интересующая нас часть соединения является продлением от неё до точки POI.

Из всего этого следует, что footway=sidewalk на соединение входа с POI ставить не стоит. Значит набор подходящих тегов для этой линии такой же, как и в случае с коридором, ведь там sidewalk мы бы тоже не поставили, а всё остальное вроде как подходит.

Точечные объекты

Линия соединения может проходить через объекты, которые не являются линейными. Поскольку эти объекты для обозначения соединения не нужны, то их не обязательно вводить с точки зрения следования нашему методу обозначения POI. Некоторые из этих объектов, тем не менее, могут являться полезными ориентирами для нахождения POI, и их имеет смысл ввести. Сделать это можно, как правило, поставив точку с нужными тегами на линию пути.

Распространённым видом объектов является двери внутри здания. Если дверь открыта во время, доступное для посещения интересующего нас места, то на неё можно даже не обратить внимания. Если и входные двери обычно не обозначают как двери, то и без внутренних можно обойтись. Несколько больше толку от обозначения дверей, которые надо самостоятельно открывать, хотя и тут, если дверь сразу ведёт к цели, например, если это дверь офиса, можно полениться её вводить. Обозначить дверь можно тегом door=* со значением, соответствующим её типу. Например, обычная дверь на петлях это door=hinged.

Объектами на пути, которые сложно не заметить, являются турникеты. Встречаются они на станциях метро, железнодорожных станциях и местах с пропускным режимом. К последним из интересных в смысле POI мест относятся некоторые бизнес-центры. Обозначить его можно точкой с тегом barrier=turnstile. Турникет может пропускать только в одну сторону, тогда на часть пути можно поставить oneway=yes.

Входная дверь, за которой виден турникет

Хитрый вход в БЦ с переговорными устройствами и турникетом за дверью

Нелинейным объектом, который можно назвать обязательным для обозначения, является лифт. Обозначается он с помощью тега highway=elevator, что является примером растяжения тега highway дальше казалось бы предназначенного смысла. Впрочем, это растяжение не настолько бессмысленное, как обозначение фонарей с помощью highway=street_lamp, ведь точкой лифта можно соединить другие, уже линейные highway, то есть проходы на разных этажах.

Выше уже был упомянут тег level, который можно поставить на линию прохода для обозначения его вертикального уровня. Почему я не написал «для обозначения этажа» станет ясно из раздела про теги вертикального положения, где оно рассматривается преимущественно для точек POI. Здесь мы предположим, что level уже поставлен на части проходов, которые соединяются точкой лифта. В случае линейных объектов, level нужен на самой линии, а на точках, входящих в линию, этого тега может и не быть. Лифт является одной из таких точек, значит не обязательно ставить тег level и на него. Но, допустим, что поставить level всё-таки захотелось, например, чтобы показать, что лифт идёт и на этажи, которые пока не нарисованы. В этом случае на его точке в тег level надо записать через точку с запятой список значений уровней, как тех проходов, которые уже нарисованы и соединены с лифтом, так и тех, которых пока нет.

Чем соединить окно?

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

Проходы с улицы ко входам

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

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

Дорожка ко входу

Дорожка, ведущая в заведение; если она будет нарисована, то наверняка дойдёт до входа

Менее понятные случаи – это когда рядом со входом дорожка есть, но ведёт она не ко входу. Соответственно через точку входа она не проходит и вставлять вход в линию как промежуточную точку нелогично. Типичным случаем такой дорожки является тротуар, который рисуется вдоль границы здания не глядя на то, есть ли на ней входы или их нет. Линия тротуара в этом случае проходит рядом со входами, то есть мимо них. При этом в сами входы можно пройти непосредственно с тротуара, то есть никакой выделенной дорожки к ним нет, и вроде как нечего к ним рисовать. Тогда откуда может возникнуть желание их чем-то соединить с тротуаром?

  • Можно захотеть соединить вход с тротуаром из соображений связности графа маршрутизации. Снаружи здания находится глобальный граф маршрутизации, если всё введено правильно и его никто не разорвал. Но при рисовании проходов внутри здания тоже образуется граф, который будет изолирован, если его не связать посредством соединения входа с тротуаром. После этого можно будет строить маршрут до POI, включающий указания, куда идти внутри здания.

  • Можно обнаружить, что на пути ко входу есть что-то существенное, что хотелось бы нарисовать. Например, при входной двери могут быть ступеньки, что важно с точки зрения accessibility. Если пририсовать ко входу ступеньки, то они вовсе не обязательно достанут до линии тротуара, и может захотеться чем-то соединить уже их, чтобы не образовывался тупиковый highway.

Идущие выше соображения про менее понятные случаи были изложены из расчёта, что тротуар уже нарисован. Если тротуар ещё не нарисован, но в реальности существует, то полезнее будет сначала нарисовать его. Если в реальности его нет, а есть какой-либо другой highway, идущий рядом со стеной здания, то далее в этом разделе, под «тротуаром» подразумевается именно этот highway. Подобную роль может играть, например, highway=pedestrian или highway=service, если вход находится во дворе.

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

Из аналогий с коридором осталась интерпретация «раз соединение проходит по тротуару, то отмечать его надо как тротуар». Но это корявый вариант, так как тротуар уже отмечен, и никакого дополнительного тротуара, ведущего ко входной двери, не существует. Из этого следует, что если мы хотим оставаться в рамках широко используемых тегов, то проход ко входу либо к тому, что к нему пририсовано типа лестницы, надо обозначать как highway=footway без footway=sidewalk.

На тротуаре помимо тегов highway=footway, который мы решили воспроизвести на рассматриваемом проходе, и footway=sidewalk, который мы решили не воспроизводить, могут быть и другие теги:

  • surface=* – материал поверхности тротуара. Поверхность рассматриваемого прохода от тротуара, а точнее по тротуару до входа, как правило, совпадает с поверхностью всего тротуара, значит можно её тег и не повторять на линии прохода. С другой стороны, поверхность эта объективно есть и на протяжении прохода, значит можно и повторить, особенно если для полноты мы захотим surface на всех highway. Похожий выбор приходится делать при рисовании пешеходных переходов, которые, как правило, тоже не имеют своей выделенной поверхности, и их тоже можно рассматривать как соединения с тротуаром. Есть и другие свойства поверхности, например, smoothness, про которые можно сказать то же самое.

  • lit=* – освещённость. Подобная ситуация и с этим тегом: если освещение есть на тротуаре, то есть и на проходе. Если постараться, то удастся найти или изобрести и другие теги, соответствующие свойствам, которые повторяются у тротуара и у прохода. Такие свойства можно назвать интенсивными, как в физике. Значит, можно найти и экстенсивные свойства, которые совпадать не будут.

  • width=* – ширина. У прохода она наверняка будет отличаться от ширины тротуара. Это как раз пример экстенсивного свойства, теги которого копировать точно не нужно. В случае именно с шириной, её вообще может не существовать, если у прохода нет ограничителей по бокам, тогда ставить этот тег даже с другим значением не следует.

В принципе, при нарисованном area:highway можно было бы наследовать значения таких тегов, как surface и lit от него. Если у нас есть highway, который полностью помещается в area:highway, то и интенсивные свойства у него те же. В подобном наследовании ничего принципиально нового не будет, например, оно уже широко используется для адресов. Конечно, сейчас никто не будет на основании этого убирать теги с линий тротуаров, но как причина не ставить теги со свойствами на второстепенные проходы это вполне подойдёт.

Что можно пририсовать ко входу с внешней стороны здания помимо прохода по тротуару? Мы уже называли лестницы, которые можно обозначить с помощью линии highway=steps. Ещё бывают пандусы, с которыми связаны всякие accessibility-теги типа ramp или wheelchair. Насколько агрессивно эти теги следует ставить, неясно. Например, массовая расстановка wheelchair=yes на все достаточно широкие и не слишком наклонные дорожки пока не наблюдается. Если же не обращать внимания на то, для каких целей пандусы установлены, то на них можно поставить тег incline=*. Некоторые предпочитают на подобные конструкции ставить ещё и bridge=yes, даже если под ними можно пробраться только ползком. Упомянутые средства подъёма не обязательно вплотную подходят к двери, например, если есть крыльцо. Тогда понадобится соединять их и с дверью тоже с помощью highway=footway.

Основная проблема с рисованием всего этого заключается в том, что в результате получается много второстепенных по сравнению с тротуаром линий. Лет семь назад так могли бы сказать и про сами тротуары – они второстепенные по сравнению с highway=primary, highway=secondary и прочим. Но у тротуаров есть свой набор тегов, и если, например, вы не хотите, чтобы они рендерились, вам надо игнорировать всё, на чём стоит footway=sidewalk. А у всех этих соединений со входами своих тегов нет, значит непонятно как их отфильтровать. Фильтровать же их захочется, потому что их может быть реально много. Есть места, магазины в которых попадаются через каждые пять шагов.

Итого получается следующие теоретические вопросы: 1. Можем ли мы определить, что значимость проходов ниже на основании какого-нибудь объективного критерия? 2. Как обозначить значимость в данных?

Критерий второстепенности

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

Рассмотрим пешеходные переходы. Без них тротуары рисовать бесполезно, так как тротуары не будут соединены друг с другом. Значит, переходы надо рисовать вместе с тротуарами, и в этом смысле у них значимость не ниже. Можно заметить, что при обычном способе их рисования они не полностью находятся внутри площади другого highway. Начало линии у них лежит в площади тротуара, середина – в площади проезжей части, конец – в площади противоположного тротуара. Но в принципе мы могли бы сделать и по-другому и провести переход только по проезжей части, а в пределах тротуаров соединить его опять же некими highway. Теперь и сам переход, и его соединители полностью находятся в площадях других highway и получаются менее значимыми. Нам же нужно, чтобы их значимость была такая же, как у тротуаров, для чего критерий придётся уточнить. Уточним мы его, руководствуясь тем, что, как было сказано выше, тротуары должны быть чем-то соединены: значимость highway не ниже, если он нужен для связности графа маршрутизации. Или так не выйдет, ведь мы соединяем менее значимым проходом компоненту графа внутри здания – все коридоры и прочее, которые мы вели до POI. Тут можно выкрутиться, сказав, что вся компонента менее значимая, и связность остального глобального графа не нарушится, если её вырезать, то есть для нашего критерия связность должна обеспечиваться для частей графа одинаковой значимости.

Ещё может быть непонятно, находится ли highway в площади другого highway. В основном, это касается лестниц. Лестницы при дверях относятся ко всей этой мишуре, которую хочется объявить второстепенной. Но находятся ли они в площади тротуара? Если они пристроены к дверям, то вроде как да, но они могут быть и более внушительными и входить в так сказать архитектурный облик здания, тогда, скорее, тротуар проложен так, чтобы их обойти. Можно было бы попробовать определить второстепенность по наличию поверхности тротуара под ступеньками, но тогда второстепенными не будут ведущие вниз лестницы при входах в подвалы. Да и при ведущих вверх ступеньках поверхности может быть не видно, а исключать непроходимые места из поверхности тоже странно, ведь тогда придётся вырезать и места занятые урнами, столбами и прочим.

Ступеньки на разных сторонах улицы

Вид с серьёзных ступенек на менее серьёзные

Поэтому уточним критерий нахождения в площади по-другому: площадью будем считать то место, которое мы бы посчитали за таковую, если бы не обратили внимания на тот highway (или последовательность highway), второстепенность которого определяем. Например, есть лестница, ведущая в подвал. Как бы мы нарисовали area:highway тротуара, если бы не заметили лестницу? Скорее всего, то место, где находится лестница, вошло бы в area:highway, значит лестница второстепенна. Оговорка про последовательность highway сделана на случай, если сама лестница подходит не в упор к двери и соединяется со входом с помощью ещё какого-то highway. Если мы не заметим лестницы, то мы не заметим и её соединения с дверью. Теперь у нас есть приемлемый критерий второстепенности.

Обозначение второстепенности

Как обозначить второстепенный проход в осмовских данных? Понятно, что линией с какими-то тегами. Варианта тут два – либо какое-то новое значение highway, либо highway=footway с новым значением тега footway, а в случае со ступеньками, видимо с тегом steps. С улицами целиком либо с их проезжими частями пошли по первому пути, и есть набор значений для highway: primary, secondary и т.д. Есть также значения специально для соединений: primary_link, secondary_link и т.д. Наша второстепенность подобна второстепенности соединений, и в этом случае нам нужны теги highway=footway_link и highway=steps_link без дополнительных тегов footway=*. Можно, правда, придраться к тому, что link’ами соединяют и highway одинаковой значимости, и если мы хотим действовать аналогично, то связность из критерия второстепенности надо убрать, а переходы надо тоже объявить линками. Я этого пока не предлагаю, потому что у переходов свой тег уже есть, а менять им значение highway можно начать и потом, когда и если это значение получит достаточную поддержку. Тогда же можно будет расширить критерий второстепенности, чтобы под него подходили и переходы.

Второй вариант выглядел бы так: highway=footway + footway=sidewalk_link и аналог для steps. Первый вариант лучше, если хочется, чтобы мишура перестала рендериться прямо сейчас, даже в ущерб маршрутизации. При втором варианте маршрутизация будет, но придётся дожидаться, пока рендереры научатся понимать новые теги, если они вообще согласятся их понимать. Правда и в первом случае, мы хотим мишуру видеть на больших зумах, так что лучше, чтобы рендереры научились понимать описываемые здесь теги, и, заодно и описанные ранее indoor-теги, и не рендерили на небольших зумах и их.

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

Вертикальная геометрия

Вспомним, что мы пытаемся отмечать на данный момент. Мы ставим точку POI где-то внутри соответствующего заведения, скорее всего на расстоянии двух метров от входа, возможно обозначаем сам вход, возможно соединяем вход и точку POI. В этом разделе мы будем делать вид, что мы только ставим точку POI, так как именно это является нашей основной целью. Поскольку теги с информацией о POI мы пока не рассматриваем, то нашей задачей на данный момент является выбор места для точки. Место мы выбираем в пространстве, которое на самом деле трёхмерное, но точку мы ставим на плоскости, потому что поверхность земли плоская, по крайней мере, локально в центре Петербурга, где нет гор. POI, тем не менее, могут располагаться на разной высоте над этой поверхностью и даже под ней. Высоту можно было бы измерить непосредственно, и записать её в теге ele, но это, как правило, не делается. Интересна обычно не высота относительно уровня моря, а высота относительно того, что находится рядом, причём выраженная не в единицах измерения длины, а качественно, типа «это выше того» или «это на одной высоте с тем». Для этого имеются теги level, addr:floor, level:ref, location, layer. Теги POI в этой записи мы рассматривать не собирались, но упомянутые здесь теги относятся не к сути заведений, а к их месту, так что их мы рассмотрим.

Слегка наклонный тротуар

Если постараться, то в некоторых местах в центре Петербурга у улиц можно заметить наклон

level

Чаще всего приходится иметь дело с тегом level. Он обозначает уровень внутри здания. Высота уровня обычно равна высоте этажа. За точку отсчёта уровней, то есть за то место, где уровень равен нулю, принимается самый низкий уровень пола какого-либо этажа, находящийся над землёй. У здания получается вертикальная шкала уровней, значения которой идут от building:min_level на полу нижнего этажа, до building:levels на крыше, если крыша плоская, или на чердаке в случае типичной для центра Петербурга двускатной крыши. building:min_level обычно не ставят, потому что, глядя на здание снаружи, сложно определить, сколько у него этажей под землёй, но это не помешает использовать отрицательные значения на отмечаемых нами объектах.

POI имеет площадь, но мы пока что сжимали её до точки. Точно также POI имеет и протяжённость в высоту, которую мы тоже сожмём. Чаще всего заведение занимает только один этаж. В этом случае оно всё равно не плоское, и может занимать даже всё пространство от пола до потолка. Вместо диапазона уровней для разных точек внутри площади заведения мы получим одно или несколько значений уровня с помощью округления вниз до целого числа. Строго эта операция выглядит так: берём (несчётное) множество всех точек пространства внутри заведения, отображаем их все по функции точкаеё округлённый до целого вниз уровень, получаем (конечное) множество округлённых уровней. Элементы этого множества пишем через точку с запятой в тег level. У заведения на одном этаже в теге level будет одно целое число, у многоэтажных заведений будет список из нескольких целых чисел.

То, что было выше сказано про level является одной из интерпретаций, не противоречащих его общепринятому использованию, а возможны и другие:

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

  • Не использовать непрерывную шкалу уровней, использовать дискретную. Тогда всему этажу будет соответствовать какое-то одно значение уровня. Это выглядит проще, да и зачем нам непрерывная шкала, если мы используем только целые значения? Только целые значения мы используем для интересующих нас POI, а в общем случае нам могут пригодиться и дробные. Главная причина не использовать дробные значения на данный момент – это их интерпретация редакторами и приложениями. JOSM и Vespucci сейчас в своих автофильтрах их игнорируют, то есть не показывают их ни вместе с целым уровнем выше, ни вместе с целым уровнем ниже. В JOSM всё плохо и без этого, он не поддерживает даже перечисления уровней через точку с запятой.

  • Не требовать округления и разрешить, в частности, «полууровни». В типичном здании они могут соответствовать лестничным площадкам между этажами, на которых интересующие нас POI бывают редко, но, в принципе, ничто, кроме размера площадок им там быть не мешает. Тогда вместо округления уровня надо брать его нижнюю границу, но не совсем понятно, что делать с многоэтажными POI. Можно, например, считать, что перекрытия между этажами делят их на отдельные части, и в level пишется список нижних границ этих частей.

  • Разрешить дробные значения при дискретной шкале – комбинация двух предыдущих вариантов. Дискретная шкала это не обязательно целые значения. Дробное же значение теперь будет соответствовать промежуточному этажу, что обычно не нужно, или площадке между этажами.

Въезд на подземную парковку с указателем «уровень»

Термин «уровень» на местности; неизвестно, соответствуют ли эти уровни нашему определению

Есть также весьма распространённые противоречащие общепринятому использованию интерпретации тега level. Можно заметить, что по крайней мере при обозначении POI уровень соответствует, хотя и не обязательно равен, определённому этажу. Почему тогда не отказаться от термина уровень и использовать этаж, и именно этаж и писать в level? У этажа обычно есть обозначение или номер, являющийся чаще всего, но не всегда числом, которое даётся по принципу, соответствующему традициям для данной местности, данного типа зданий и назначению данного этажа. Однако, традиции эти бывают разные, и в общем случае, глядя на эти обозначения, нельзя сказать ни как расположены этажи относительно земли, ни как относительно друг друга. Вам может казаться, что первый этаж над уровнем земли в этой стране и её ближайших окрестностях всегда имеет номер 1. Чаще всего так и есть, но, например, в торговых центрах номер 1 иногда бывает у этажа над первым. В этом разделе термин уровень используется для того, чтобы не перепутать его значение с номером этажа.

Лестница перед выходом из ТК

Вид с лестницы соединяющий этаж 1 на уровне 0 и этаж опять же 1 на уровне 1

Из общепринятой интерпретации level следует, что уровни нам надо отсчитывать так, как считают все нормальные люди, то есть те, кто программируют на си-подобных языках: начиная от нуля с условием завершения по строгому неравенству (level < building:levels). Если серьёзно, то считать от нуля следует, скорее всего, потому что так решили те, кто придумал тег level, а в их местах этот метод подсчёта даст те же значения уровней, что и номера этажей, если ограничиться теми этажами, которые обозначаются числами и находятся ниже 13-го уровня. В общем случае значения уровней и номера этажей совпадать уже не будут, но зато из самих уровней всегда будет ясно их относительное положение, которое в общем случае неясно из номеров этажей.

В наших местах уровень и этаж будут обычно отличаться на единицу, что может быть неудобно, если надо ориентироваться именно по номерам этажей. Соответственно, у нас есть участники, которые либо хотят считать уровни от единицы, либо не хотят считать вообще. Нежелающие считать хотят использовать исключительно номера этажей. Несмотря на то, что номера или какие-либо другие обозначения этажей существуют не всегда, данные участники говорят, что номера «есть, видны прям на этаже и эффективно могут (быть) на месте проверены», уровни же верифицируемыми они не считают. Процесс вычисления значения level по их мнению является «игрой в считалочки», а сама схема значений level, построенная по этому принципу «неработоспособна». Всё это не было бы проблемой, если бы они не хотели при этом результат своего подсчёта либо неподсчёта писать в тот же тег level. Более подходящие теги для записи этого результата описываются в следующем подразделе, но их упомянутые участники предпочитают не замечать.

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

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

Надпись «1-2 floor»

Обозначение этажей по-русски по-английски

Всё написанное выше в данном подразделе являлось теоретическими рассуждениями. Теперь вернёмся к тому, с чем приходится сталкиваться на практике. Допустим, что мы отмечаем POI, видимые с улицы – это по прежнему большая часть отмечаемых мной POI. Раз они видны с улицы, то ясно, что они не на десятом этаже. Собственно отмечаем мы их рядом с их входом, вход доступен с земли, а за входом идёт проход, в котором сложно заблудиться, значит по большому счёту не важно на каком уровне POI находится. Основная информация для обнаружения заведения уже есть в его координатах на плоскости и без тега level можно обойтись. Так оно и есть в большинстве мест. Но попадаются места, где POI идут плотно, располагаясь на разных этажах, обычно от подвального до второго. Входы в них расположены близко друг к другу, а иногда и совсем один над другим. В этом случае, чтобы не запутаться, можно поставить на POI тег level, у которого значением обычно будет −1, 0 или 1, где 0 это обычный первый этаж.

Лестницы вверх и вниз, ведущие от тротуара ко входам в магазины

Типичное расположение магазинов на двух этажах

Немного другая ситуация возникает, когда заведение надо обозначить не рядом со входом, и при этом мы захотим соединить вход и точку POI линией прохода. Но этого будет недостаточно, чтобы не запутаться, если проход ведёт в место под или над другой POI. Обычно это выглядит так: есть нормальный первый этаж, на котором входы в магазины на нормальном расстоянии. В добавок к нему есть подвальный этаж со своими входами, и за каждым входом расположен целый «куст» из мелких POI, иногда с довольно длинными проходами до них. «Нормальные» магазины получаются расположенными над сетью подвальных POI, и это «над» надо отразить в данных. В данном случае подвальные магазины получат level=-1, а нормальные – level=0.

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

Непитерские проблемы это когда поверхность, на которой находится здание, не является горизонтальной. Земля в некоторых местах всё-таки не плоская, и при движении по горизонтали можно попасть из места над поверхностью в место под. Местом над может быть точка на полу какого-то этажа, раз она над, то её уровень неотрицательный. Но в этой же горизонтальной плоскости можно оказаться и под, а это уже отрицательный уровень. Поскольку до этого землю мы считали плоской, не приходилось даже требовать того, чтобы горизонтальная плоскость соответствовала одному уровню, это получалось само собой. Теперь нам надо это потребовать. Требовать мы будем это в пределах того, на чём стоит building:levels, то есть либо на всём здании, либо на его части, обозначаемой с помощью building:part. Если внутри этих пределов наблюдается описанная ситуация с переходом из над в под, то level там однозначно не определён. Чтобы его определить, есть два варианта действий: 1. Отпилить часть здания, в которой перехода не будет, а, значит, не будет и проблем с определением level. Обозначить эту часть как building:part со своей этажностью, которая может отличаться от этажности остального здания. 2. Выбрать какую-то вертикальную линию, например, проходящую через главный вход, и присвоить горизонтальным плоскостям уровни точек на этой линии.

Тут у нас наблюдается свобода выбора, главное, чтобы значения уровней в результате выбора не противоречили тегам building:levels на здании или части.

Понижение уровня земли перед дворцом

Непитерские проблемы в Питере

К питерским проблемам относятся те проблемы определения уровня, которые возникнут несмотря на то, что земля плоская. Когда нужно обнаружить первый этаж над уровнем земли, вы, скорее всего, признаете за него и тот, который на пару сантиметров ниже. Эту пару сантиметров вы и не заметите. А если это пять сантиметров? Десять? Двадцать? Для какого-то значения вы решите, что это уже level=-1. Другой же участник может считать, что это всё ещё level=0. Чтобы устранить эту неоднозначность, можно предложить считать уровень отрицательным, если, чтобы на него попасть, надо пройти вниз по хотя бы одной ступеньке, то есть сделать вниз хотя бы два шага.

Дверь, за которой уровень пола чуть ниже

Один шаг вниз при входе в магазин, из-за которого не стоит считать его уровень отрицательным

Дверь, за которой несколько ступенек вниз

Более существенное количество ступенек вниз

Задача осложняется тем, что уровень пола мог быть изменён отдельно для рассматриваемого заведения. При входе в другое заведение на том же этаже может быть другое количество ступенек, в частности потому, что могут быть причины это количество уменьшить ради accessibility. level хотелось бы иметь одинаковый для всего этажа. Для этого можно попробовать использовать критерий для выбора между level=-1 и level=0, не связанный с тем, насколько глубоко приходится спускаться. Связать вместо этого его можно с размером окон на рассматриваемом этаже. Если на этаже, который расположен ниже уровня земли, окна по высоте меньше, чем окна на этажах, находящихся явно над землёй, то данный этаж достаточно низок, чтобы считать его уровень отрицательным.

Окна разной высоты на разных этажах

Снизу окна ниже, сверху – выше

По последнему критерию level=0 будет получаться чаще. Получается, что у нас есть некоторая свобода выбора, подобная свободе выбора нулевого уровня при наклонной поверхности. Конечно, в случае неопределённости можно было бы выяснить, как называется интересующий нас этаж, и если он «первый», то сделать выбор в пользу level=0. Однако выяснить это в случае с входами с улицы в заведения может и не получиться, потому что обозначения этажа у них нет.

Неопределённость несколько уменьшается за счёт того, что выбранное значение уровня должно сочетаться со значением building:levels. Например, если над интересующим нас этажом есть ещё три и building:levels равно четырём, то это level=0. Если же building:levels равно трём, то это level=-1. Это решило бы наши проблемы, если бы мы могли рассчитывать на то, что правильно определённое значение building:levels уже стоит или его легко определить самостоятельно, а также на то, что мы можем без проблем сосчитать этажи над POI. Рассчитывать на всё это можно было бы, если бы здания имели простую форму, однако проблемы я назвал питерскими потому что тут так не бывает.

Глядя на здание только с одной стороны, в частности с той, где находится POI, для которой надо определить level, вовсе не обязательно удастся определить этажность. Также не обязательно будет иметься возможность посмотреть на здание с другой стороны, с которой не обязательно будет видно то же самое количество этажей. Количество этажей может быть другим за счёт асимметрии крыши, пристроек, надстроек и просто того, что, находясь близко к зданию, может быть не видно того, что у него наверху, а при осмотре POI приходится находиться близко. Помимо того, что всё это может быть сложно определить, это может быть сложно и записать. Чтобы этажность была правильной в произвольном месте, которое может нас заинтересовать, может понадобиться делить здание на части с различными значениями building:levels. Велика вероятность того, что до нас деление сделано не было, и building:levels был поставлен целиком на всё здание по неизвестному принципу. Неизвестно даже, знал ли ставивший этот тег, что части с различной этажностью в данном случае существуют, ведь он мог ограничился просмотром здания только с одного ракурса, возможно даже с яндекс-панорам. В общем случае приходится предполагать, что любой объект в осме отмечен самым простым способом, потому что так быстрее, а значит у отмечавшего была возможность совершить больше подобных правок. В итоге часто легче определять уровень отдельно взятой точки не глядя на building:levels.

Другого рода неприятности связаны с взаимодействием с теми участниками, у которых альтернативный взгляд на значения тега level. Для них обычный первый этаж это level=1, а подвал это level=0. Если ранее в POI-плотном месте, где хотелось бы обозначить уровни, чтобы не запутаться, один из таких участников расставил теги level по-своему, то их придётся менять, иначе вместо достижения цели «не запутаться» будет достигнуто нечто противоположное. Не исключено и ведение войны правок, ведь мнение оппонента теперь как бы подкреплено текстом русской вики. В итоге может понадобиться сослаться на изложенные здесь соображения, не зря же я их писал. Если оппонент использует для редактирования OsmAnd, то у него есть дополнительные причины понимать level именно как обозначение этажа. OsmAnd при нажатии на точку показывает информацию о ней, куда входит и «этаж». «Этаж» на самом деле равен level’у, хотя пользователь наверняка хотел бы увидеть вместо этого номер этажа. В результате совместных усилий стандартно и альтернативно видящих level участников, а также того, что однозначного соответствия между уровнем и этажом в общем случае нет, османдовский «этаж» следует воспринимать как номер этажа с точностью ±1, а то и ±2.

Ещё я был уверен, что какое-то приложение называло layer «уровнем», но сейчас не могу обнаружить, какое именно. Интересно, что от одного из альтернативных участников поступило предложение layer именно как уровень и использовать. Почему для этого понадобится альтернативный взгляд ещё и на этот тег, станет ясно из подраздела, идущего за следующим. В следующем же подразделе мы рассмотрим, куда всё-таки писать номер этажа.

addr:floor, level:ref и им подобные

Многоэтажные здания, то есть ТК или БЦ, будут основным видом мест, где использования обозначения положения по вертикали не избежать. Вертикальное положение POI придётся задать как для пользователей, так и для самого процесса поддержки POI в актуальном состоянии. Чтобы проверить, существует ли заведение, надо иметь возможность его найти, и желательно, чтобы процесс поиска не включал в себя обход всех этажей торгового комплекса. Если для записи вертикального положения точек, доступных изнутри здания, мы по прежнему будем использовать level, нас ждут новые проблемы. Когда мы отмечаем POI, видимые с улицы, мы можем вообще не думать, как называется их этаж. «Первый» он или «цокольный» нам не важно, мы просто посмотрим на расположение относительно земли и из этого выведем значение уровня. Находясь же внутри здания мы не станем смотреть на землю снаружи. Ориентироваться мы будем по обозначениям этажей, которые написаны у лестниц, в лифтах и на схемах. Получается, что нужно будет проделывать следующие операции:

  1. Снаружи определить этаж, соответствующий нулевому уровню;
  2. Изнутри обнаружить обозначение этого этажа и таким образом установить соответствие этаж-уровень;
  3. При записи информации о POI преобразовать обозначение этажа в уровень и записать его;
  4. При поиске записанной POI преобразовать уровень в обозначение этажа, по которому точку и искать.

Получается многовато шагов и, соответственно, многовато возможностей ошибиться. Если бы просто записывать обозначение этажа, то всех этих соответствий-преобразований проделывать не надо было бы. Тут-то сторонники писать это обозначение в level могли бы заявить о своей правоте, но мы обратим их внимание на то, что никто не мешает записывать обозначение и в другой тег, ведь у этого обозначения другой смысл. Одним из вариантов другого тега является addr:floor, про который в английской вики говорится, что он редко используется, но теперь мы ему нашли применение.

Если вы при обозначении точек в ТК боитесь запутаться в level – не ставьте его, по крайней мере при первом обходе здания. Ставьте на точки addr:floor, который потом можно будет заменить на level или даже и не заменить, а поставить level дополнительно. level будет играть роль указателя положения в пространстве, существующего независимо от обозначений мест, а addr:floor будет частью адреса, которая пригодна для использования даже без геометрии. Кроме addr:floor в этом смысле может пригодиться и addr:door, обозначающий номер помещения. Это относится, в основном, к БЦ с номерами офисов, но номера помещений встречаются и в некоторых ТК.

Двери в номерами 39, 41, 43

Двери с номерами в ТК

Addr:floor подходит как замена для level не во всех случаях. Например, если рисовать коридоры и прочие проходы, на которые можно и нужно ставить level, то addr:floor для них подойдёт только если вас не смущает такое понятие как адрес коридора. В данном случае имеет смысл ограничиться указанием addr:floor для точек, рядом с которыми есть обозначение этажа на месте, таких как двери у лестничной клетки. Ещё лучше использовать вместо addr:floor тег level:ref, рассматриваемый ниже.

Есть применение для addr:floor и при обозначении POI с улицы. Это относится к тем POI, которые непосредственно не видны, зато видны таблички, указывающие, что они где-то в данном здании. Именно о них шла речь в прошлой записи там, где рассказывалось про дополнительную верификацию. На табличках могут быть указаны номера этажей, которые можно записать в тег addr:floor соответствующей точки. Использовать вместо этого level опять же может быть неудобно, так как для этого придётся определять, какой level соответствует какому этажу, чем при внешнем осмотре здания – том самом, при котором и приходится читать таблички – заниматься не хочется. Помимо адресации смысл записи этажа в данном случае заключается в том, чтобы показать, что это одна из точек, которая не видна снаружи, и её не надо искать с улицы и выравнивать относительно границы здания, если речь идёт не о первом этаже.

Можно возразить против использования для обозначения этажа именно тега addr:floor. Есть мнение, что в тегах addr: должны быть только части почтового адреса, а этаж частью почтового адреса не является. Например, этого мнения придерживаются разработчики Nominatim. Впрочем, то, что ищет Nominatim, и то, что рассматривается в указанном докладе полным адресом не является, там ограничиваются адресами зданий, а чтобы послать письмо, потребуется ещё и номер квартиры или помещения. На это не обращают внимания, потому что помещения в осме обычно не мапят, но это «обычно» – не наш случай, мы как раз офисы обозначать собираемся. Может быть, про этажи можно сказать нечто подобное, то есть, что их обычно не обозначают, но мы собираемся обозначать и их. Хотя обозначение этажа и не является частью почтового адреса, оно является частью адреса в более широком смысле как указания места, понятного человеку и состоящего из частей, постепенно это место уточняющих.

Ещё против этажа как адреса можно сказать, что он избыточен при указанном номере помещения и поэтому не нужен. Однако избыточных тегов адреса хватает и без этажа, начиная с почтового индекса. Также избыточной может быть литера, которую либо пишут в addr:letter, либо приписывают к номеру дома, либо делают и то и то.

Если мы всё-таки не хотим использовать тег addr:floor, несмотря даже на то, что это принятый пропозал, то придётся взять другой тег. Раз записывать мы хотим номер этажа, то это может быть что-то типа ref, но сам ref не годится, так как ставить мы его будем не на элемент, обозначающий весь этаж. Если мы захотим сказать, что это обозначение level’а, то его можно назвать level:ref, как сейчас предлагается в Simple Indoor Tagging. Правда, с таким названием он выглядит как дополнение к уже обозначенному level’у, а нам он может быть нужен также как альтернатива. Мы можем захотеть использовать тег для обозначения этажа только у отдельной точки, когда сам этаж ни как геометрию составляющих его помещений или проходов, ни как набор находящихся на нём POI мы рисовать не собираемся, и в этих случаях level:ref подходит не вполне. Зато он вполне годится быть поставленным на саму геометрию, хотя неизвестно, в каких количествах стоит его ставить. Нужен ли он на всём, на чём стоит level? Видимо, нет, его можно поставить временно, а после простановки level убрать, оставив только там, где есть сами обозначения этажей. Более точный ответ на этот вопрос зависит от того, как собираются вести себя приложения, показывающие планы этажей: им нужно откуда-то номер этажа взять.

Если нас не устраивает ни addr:floor, ни level:ref, что ещё можно использовать для подобных целей? Я встречал тег floor, хотя в вики он не задокументирован. Для временного использования, чтобы не запутаться в этажах, подойдёт и он. Ещё встречаются предложения записать все соответствия между уровнями и обозначениями этажей в один-два тега на здании. Этот вариант для временного использования уже не подойдёт, потому что на POI придётся ставить именно level.

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

  • POI не привязана никак, то есть стоит в произвольном месте внутри здания, её истинное положение неизвестно, но известен этаж. В этом случае использовать level не имеет смысла, level:ref тоже не очень подходит, и лучшим вариантом оказывается addr:floor.

  • POI стоит на своём месте, но не соединена с какими-либо внутренностями здания, которые и не нарисованы. Так бывает, если POI видна снаружи и поставлена на основании внешнего осмотра. В этом случае наоборот больше подходит level, хотя, если известно обозначение этажа и нет несогласия с тем, что он является частью адреса, можно добавить addr:floor.

  • POI привязана к внутренней геометрии здания. По сравнению с предыдущим пунктом здесь становится нужнее обозначение этажа и больший смысл обретает тег level:ref. Level поставить тоже придётся, хотя можно сразу этого и не делать. Про addr:floor можно сказать то же, что и в предыдущем пункте.

Как видно из данного списка ситуаций, обозначения этажей появляются в осме на стыке ввода отдельных точек и детального indoor mapping. Первое предлагается делать даже новичкам из редакторов типа MAPS.ME, а вторым занимается мало кто. Этим, возможно, и объясняются разногласия в использовании тега level и неопределённость того, что надо или не надо к нему добавлять. Тут бы мне хотелось сказать, что тема этажей в этой записи закрыта, но к сожалению к ней ещё придется вернуться в ситуации с ещё более неопределённым набором действий.

location и layer

Разнообразие вертикального положения POI не ограничивается этажами зданий. POI могут быть и вне зданий, но всё равно над или под чем-то. «Под» это обычно в подземном переходе или в метро. Если проход под землёй, в котором расположена POI, ещё не нарисован, его надо нарисовать, иначе не будет никаких ориентиров для расположения точки. Когда проход нарисован, он обычно обозначен с помощью линии с тегами highway=footway, tunnel=yes, layer=(отрицательное значение). На нахождение прохода под землёй указывает, скорее, tunnel, чем layer.

Тег layer предназначен для указания относительного вертикального положения объектов, но его зона действия – только точки пересечения элементов, а не область, определённая другим элементом, таким как здание или его часть в случае тега level. Горизонтальный уровень тег layer не задаёт и, соответственно, используется для задания вертикального порядка таких объектов, которые могут быть весьма негоризонтальны. К подобным объектам относятся мосты и части развязок, а желание некоторых участников использовать этот тег для горизонтальных этажей выглядит довольно странно. Есть соглашение ставить отрицательные значения layer на объекты, находящиеся под землёй, но, строго говоря, само по себе это не является обозначением нахождения под землёй. Является же это обозначением нахождения под объектами со значением layer выше, в основном с layer=0, подразумевающимся по умолчанию для всех объектов, на которых тег layer не поставлен.

Если POI находится, допустим, в подземном переходе, то возникает желание обозначить её нахождение там копированием каких-либо тегов с самого перехода. Какие теги имеет смысл скопировать? Ясно, что не highway=footway. tunnel тоже не подходит, ведь сама POI туннелем не является. Остаётся layer, но он сам по себе не означает нахождение под землёй. В случае с подземным переходом для точки этот тег в большинстве случаев не означает ничего. Относительное положение он показывает только в точках пересечения объектов, а поскольку мы рассматриваем его установку на точку, пересечься она может только с площадным объектом, а его, скорее всего, не будет. Это не значит, что layer ставить на POI не надо, он покажет, что POI как-то относится к подземному проходу, находящемуся рядом, но это отношение может быть понятно только для редактирующих данные участников. Им, возможно, пригодится найти/выделить/отфильтровать подземный ход со всем его содержимым по значению layer.

Подземность придётся показывать другими средствами, в частности, тегом location. У него могут быть разные значения, но нас интересует преимущественно location=underground. Собственно его и можно поставить на POI, чтобы указать, что она находится под землёй. На сам подземный ход этот тег ставить не надо, так как там уже стоит tunnel. Среди прочих значений этого тега можно отметить overground и overhead, предназначенные для того, чтобы показать приподнят ли над землёй объект типа трубопровода или нет, для POI это вряд ли пригодится. Зато пригодиться может location=roof для POI, находящихся на крыше, что иногда бывает. Ещё есть location=indoor, при том, что мы уже встречались с тегом indoor=yes. Хотя большинство наших POI находятся внутри зданий, на них не ставят ни тот, ни другой тег. location=indoor на самом деле является одним из значений, предназначенных для подстанций.

Если точка находится в подземном ходу, и хочется однозначно показать, в каком именно, то ни layer, ни location этого сделать не могут. Точку POI придётся соединять с проходом подобно тому, как вход в здание соединяются с тротуаром, с теми же соображениями, описанными выше в соответствующем разделе, включающими использование нестандартных тегов. Ну то есть никто этого не делает.

Иногда для подземных сооружений включая метро вместо location и layer пользуются тегом level. Не так странно поставить level=-1 на подземный переход или что-нибудь подобное на метро, если оно неглубоко. Не вполне понятно, какой level ставить на платформу, до которой надо спускаться на эскалаторе две минуты, как в центре Петербурга.

POI полигонами

Преимущества

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

  • POI просто достаточно большая. Поскольку в основном мы отмечаем заведения внутри зданий, то «достаточно большая» означает «сопоставимая по размеру (длине, площади) с размером здания». Обозначать одной точкой то, что по величине похоже на практически всегда рисуемый полигоном объект – это какая-то дискриминация. Другое дело, что мы можем не знать, что POI на самом деле большая, и обозначить её точкой по этой причине.

  • POI занимает всё здание. Выше мы описывали способы, по которым можно выбрать место для точки POI. Здесь же нам предоставляется возможность этот выбор не делать, так как место уже отмечено. Остаётся только поставить теги POI на уже существующий полигон, что ещё проще, чем обозначить POI точкой. Правда, новые теги на полигоне могут пересечься с уже присутствующими тегами здания, тогда возникнут проблемы, которые рассматриваются в одном из следующих подразделов.

  • Надо что-то обозначить внутри POI. Внутри точки ничего нарисовать нельзя, значит нам понадобится элемент, имеющий площадь.

  • У POI несколько входов. Мы, конечно, можем обозначить эти входы и соединить их проходами с точкой POI, но тут опять надо совершать выбор места для точки. Вместо набора способов типа «напротив главного входа», «посередине между входами», «на углу» мы обозначим POI там, где она на самом деле, не сжимая её до точки. Также в случае, если за входами сразу находится заведение, просматривающему карту будет сразу понятно, что не надо идти по каким-то коридорам, чтобы в это заведение попасть.

  • У POI может быть окно заказа/выдачи. Мы так и не определились, чем его привязать к точке POI, а в контур полигона POI мы можем его спокойно включить.

  • POI может быть несвязна. Конечно, её всё равно можно обозначить точкой, но что если одна часть по одну сторону от чего-то, а другая – по другую? Тогда ставить точку где-то посередине будет странно, ведь эта середина как раз придётся на место, разделяющее части заведения. В роли таких разделителей могут быть арки или лестничные клетки. Зато при рисовании POI полигоном можно воспользоваться одним из самых популярных средств усложнения данных – отношением мультиполигона. То, что следует сделать в данном случае, а именно нарисовать отдельными полигонами несвязные части и объединить их в мультиполигон, усложнением, конечно же, не будет, так как по-другому подобного результата не добиться.

Два входа в магазин, между которыми арка

Две части магазина, разделённые аркой

Недостатки

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

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

  • Не видно границы POI на снимках, как на аэрофотосъёмке, так и на уличных панорамах, и трек внутри здания не записать. Эти проблемы уже упоминались в качестве недостатков при установки точки в центр заведения, теперь же они становятся более явными.

  • Такие данные сложнее поддерживать. Помимо того, что сами данные сложнее, они содержат в себе претензию на большую точность и, соответственно, причину эту точность повышать. Если граница POI нарисована весьма примерно – а нередко её так и приходится рисовать – то может потребоваться её изменить. Измениться может и сама граница в реальности, например, на месте одного магазина могут открыться два. Если бы POI была обозначена точкой, то в этом случае понадобилось бы подвинуть эту точку и добавить ещё одну. Если же был использован полигон, то его придётся делить на две части, для чего придётся выяснять и проводить линию раздела.

  • От этого может быть мало толку. Если заведение не было отмечено, а мы взяли и отметили его самым простым способом, то есть точкой, это будет серьёзным улучшением данных с точки зрения пользователя. Если мы точку перерисовали в полигон, то улучшение от этого действия гораздо менее существенное. Существенным оно будет, если внутри заведения можно заблудиться, правда в этом случае одного лишь полигона по контуру не хватит.

  • Есть редакторы POI, которые не имеют возможностей добавления POI каким-либо другим способом, кроме точки. В качестве примера можно привести MAPS.ME. Другой подобный редактор – OsmAnd – до недавнего времени не давал даже менять теги на уже отмеченных полигоном POI.

Помещения

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

Для начала надо определиться с тем, что находится внутри границы заведения, а что снаружи. Основной выбор тут такой: есть площадь, в которую могут попасть посетители и в которой оказываются услуги или демонстрируются и продаются товары. Она, конечно же, находится внутри границы. Но есть и площадь, в которую посетители попасть не могут, зато могут попасть работники, и работают они и на этой площади. Находится ли эта площадь внутри границы заведения, которую мы хотим провести? Тут можно рассуждать по-разному.

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

Можно ли сказать, что включать в границу POI только доступные места однозначно легче? Сразу отметим, что даже если ответ и окажется положительным, то это не будет означать, что так и надо поступать. Допустим, в магазине есть отдел без самообслуживания, то есть имеется прилавок, за которым продавец. Посетитель попасть за прилавок не может, значит это место надо было бы исключить из территории POI. Можно возразить, что место это не слишком большое, практически сразу за продавцом будет стена, вот примерно по этой стене мы и обозначим доступную территорию, а то, что в неё попала область между прилавком и стеной – это допустимая погрешность. Стены, однако может и не быть. Подобная ситуация наблюдается в фаст-фудах. Тут, конечно, всё равно можно возразить, что понятно, где начинается другое помещение, которым в случае фаст-фудов будет кухня, и что это не помешает отметить только доступные помещения. Может быть, так и есть, пока я только хочу показать, что случаи, когда служебные помещения включить легче, чем не включить, возможны.

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

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

Раз уж мы обратили внимание на банкоматы, можно рассмотреть часто встречающийся случай, когда перед входом в банк находится холл с банкоматами так, чтобы ими можно было воспользоваться даже тогда, когда банк закрыт. Или он на самом деле не перед входом, а является как бы отделом внутри банка? Нужно его включать в границы банка или нет? В данном случае меньше споров вызовет рисование банка точкой. Банкоматы внутрь точки всё равно не поставить, они рисуются там, где находятся. Мимо них рисуется проход в собственно отделение банка, заканчивающийся точкой amenity=bank. Проход на самом деле есть, точка на самом деле внутри банка, значит всё правильно. Здесь же мы хотим сделать ещё более правильно.

Нам было бы легче, если холл с банкоматами не входил бы в границы банка. Какая причина ставить банкоматы в отдельное помещение? Свой режим работы. А у собственно банка другой режим. На самом деле, у банка может быть несколько разных режимов, например для физических и юридических лиц, так что сложностей может быть ещё больше, но пока допустим, что режим один. Если банкоматы окажутся внутри полигона с этим режимом, то своего режима у них не будет. Точнее, поставить opening_hours на них можно, но в результате получатся работающие банкоматы в закрытом банке. Режимы работы – тема для другой записи, здесь мы только отмечаем, что легче помещение с банкоматами не включать, а рисование банка точкой является одной из разновидностей этого невключения.

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

Окно, через которое виден вход в банк и банкомат

Банкомат перед первой дверью, на которой написано про банк

Аргумент с режимом работы как причиной рисовать границы в том или ином месте можно попробовать применить и к служебным помещениям. Какой у них режим? Он нам может быть неизвестен, и он может отличаться от того режима, который сообщается посетителям и становится известен осмерам. Это, скорее, говорит о том, что надо какими-то другими средствами отмечать режим, то есть обозначать внутри POI отделы и ставить opening_hours на них, или ставить access со временем, а в качестве критерия границы POI режим работы не годится.

Вернёмся к служебным помещениям. Допустим, что мы ещё не убеждены, что их надо включать в границы POI. Если отмечать не только обычные магазины, то выяснится, что существуют места, в которые никаким способом, кроме предварительной договорённости, не попасть. Ими будут, например, большинство офисов. Если служебные помещения в границы POI не включать, то у таких мест внутри границ не будет ничего, следовательно, их никак не отметить. Мы могли бы применять разные критерии для границ магазинов и офисов, но зачем? К тому же, нам придётся тогда отличать офисы от магазинов, а это может быть не всегда легко сделать. Например, турагентства в осме относятся к shop’ам, хотя часто выглядят как офисы.

Впрочем, в вики в ряде случаев наблюдаются рекомендации не включать в POI то, что не относится к прямому назначению заведения. Допустим, есть театр, и есть его дирекция. Следует ли всегда включать дирекцию в amenity=theatre? Она может находиться как в здании театра, так и отдельно, иногда достаточно далеко. Скорее всего, никто не захочет вырезать её из здания, но если она находится отдельно, то и объединять её с театром никто не будет. Подобным образом можно посмотреть и на университет, из которого никто не возьмётся вырезать офис приёмной комиссии на основании того, что там ничему не учат, зато если этот офис будет находиться отдельно, его никто не отметит как университет. То есть, можно действовать по принципу не включать в заведение то, что не относится к его основной деятельности, если оно географически достаточно обособлено.

Ещё мы можем отмечать входы, в том числе служебные, то есть entrance=service. Тогда мы захотим, чтобы каждый вход был по крайней мере рядом с тем заведением, в которое он ведёт. Служебные входы могут вести в служебные помещения, и чтобы не отрывать входы от POI, эти помещения удобнее сделать частью её полигона.

Стены

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

  • Рисуя границу POI прямо по контуру здания, не нужно придумывать, где провести ещё одну линию. В противном случае пришлось бы рассуждать так: контур здания проведён по внешней стороне его внешней стены, стена имеет и внутреннюю сторону, контур POI надо провести именно по внутренней, для этого его нужно отодвинуть на ширину стены, которую придётся измерить. Стена обычно не такая широкая, чтобы пришлось отодвигать контур на существенное расстояние, а само расстояние будет меньше типичной погрешности рисования, так что с этой точки зрения проводить линию по внутренней стороне стены не имеет смысла.

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

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

  • В контур здания, в том месте, где находится POI, может быть включено то, что к POI не относится. Это могут быть телефоны, почтовые ящики и, что самое главное, входы, которые в POI не ведут. Если мы хотим правильного соответствия входов и POI, эти входы включать в контур POI нельзя. Если при этом контур POI ведётся по контуру здания, то их точки следует пропустить. Так получится линия, проходящая практически по упомянутым точкам, но не включающая их в себя, что неудобно. Ещё хуже, если объекты, которые в реальности существуют и могут быть отмечены на контуре здания, ещё не отмечены. Когда придёт время их ввести, то просто ткнув в редакторе на желаемое место, можно добавить точку в оба контура одновременно, а если нужно добавить только в один, то потребуются более хитрые операции. Их надо и самому не забыть произвести, и чтобы другие участники тоже не забывали и вообще понимали, что именно нужно делать. В случае если точки на контуре и POI находятся на разных этажах, нам могло бы помочь наличие на них тега level. Редактор мог бы выдавать предупреждения о проведении контура POI через точки с несовпадающим уровнем. К сожалению, этим не всегда удастся пользоваться для входов, так как вход может не быть на одном уровне со своим заведением, например, если за входной дверью находится лестница. Если по лестнице надо подняться достаточно высоко, и POI находится далеко от уровня земли, то в контур не должно входить практически ничего из того, что может быть обозначено на стене здания. Тогда гораздо проще и безопаснее контур POI по стене не проводить.

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

Несвязные части

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

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

Некоторые, кстати, считают возможным включать в мультиполигон и те элементы, из которых площадной объект не собрать, в частности, точки. Руководит ими желание собрать в один элемент что угодно, чтобы повесить на всё это один набор тегов, и таким образом реализовать принцип один объект – один элемент. Если точки в мультиполигоне смысла не имеют, то существует отношение, в которое их включить уже можно. Это уже известное нам отношение site. Однако его поддержка в приложениях неизвестна и даже сама возможность поддержки вызывает вопросы.

С объединением несвязных частей можно и перестараться. Например, бывает, что объединяют в один мультиполигон части университетов, находящихся в разных местах, иногда довольно далеко друг от друга. Вместо этого лучше отметить каждую из частей своими тегами. Выше мы уже рассматривали случай, когда часть университета можно не считать собственно университетом, и как amenity=university не обозначать. Если части не признавать за университет нельзя, например, если это разные факультеты, у них могут быть свои собственные названия, которые можно добавить в name, или найдутся какие-нибудь другие теги, специфичные для отдельных частей. Однако нередко на части университет поделен неизвестным образом, по крайней мере для внешнего наблюдателя, и никаких специфичных для частей тегов задать не выходит. Когда теги на частях получаются одинаковыми, возникает желание объединить их в мультиполигон, а в противном случае смысл и даже возможность такого объединения пропадёт. Приведённый здесь пример является частным случаем проблемы определения того, одна это POI или несколько. Данная проблема уже упоминалась в разделе про входы в связи с окнами выдачи, но в этой записи подробно рассматриваться не будет.

Всё здание

Одним из преимуществ обозначения POI полигонами является отсутствие необходимости совершать произвольный, не в полной мере зависящий от реального положения объектов выбор места для точки POI. Остаётся сделать только зависящий от реальности выбор места для границы полигона, но бывают ситуации, когда не надо делать и его. Самая распространённая из них – совпадение POI со зданием, которое, как мы предполагаем, уже нарисовано. Значит остаётся поставить на него теги POI и дело сделано.

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

Совет из вики относится к той ситуации, когда проблем от совмещения возникать не должно. Она возникает, если здание построено или предназначено специально для POI, и их можно как бы отождествить. Например, это здание театра, построенное для театра. Называют здание так же, как и театр, появилось оно тогда же, когда и театр и так далее. Таким зданием может быть и ларёк, даже если он появился раньше, чем туда пришли его текущие обитатели. Можно сказать, что у него самого по себе названия не было бы, и появляется оно только благодаря находящейся в нём POI, а значит конфликта названий ларька и POI нет.

Если же здание появилось задолго до обосновавшегося в нём заведения, то отождествить их не получится. Здание может обладать никак не относящимися к заведению свойствами, которые мы захотим записать в тегах, и наоборот. Одним из вариантов выйти из этого положения является разграничение объектов воздействия тегов: мы объявляем, что определённое множество тегов относится к зданию, а другое множество – к POI. Например, понятно, что building:levels относится к зданию. Но с таким распространённым тегом как name это не пройдёт, именно по причине его распространённости: название может быть и у здания, и у заведения. Чтобы устранить эту проблему, например, утверждается следующее: название здания – оно не название, а «историческое название». Раньше это был Дом Мятлевых, а теперь это прокуратура. Почему именно «был» – не совсем понятно, видимо, имеется в виду, что раз Мятлевы больше не являются владельцами здания, то здание больше не следует по ним именовать. «Историческое название» помещается не в тег name, а в тег historic_name, чтобы освободить name для прокуратуры. После этого возникает то же положение, которое производились попытки разрешить, только добавился ещё один тег. Почему именно name относится к прокуратуре, а historic_name ко зданию? Почему не наоборот?

Неподалёку от рассмотренного примера с прокуратурой находится здание Синода, в котором библиотека имени Ельцина. Если, опять же, хочется определить название, то можно посмотреть, что написано на месте, и обнаружить, что написано там и про библиотеку, и про Синод. И название – не единственный конфликтный тег. Есть ещё, например, start_date, в который можно записать дату постройки здания, в данном случае – 1834 год. Но, поскольку, этот тег попадёт и на библиотеку, не станет ли он означать также дату открытия библиотеки?

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

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

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

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

Возможна и такая ситуация, когда заведение занимает всё здание, и к этому ничего не прибавить, но на само здание теги POI ставить не следует. Тогда никто не мешает отметить место, занятое зданием ещё раз, что можно сделать несколькими способами:

  • если здание отмечено одной замкнутой линией, можно провести ещё одну такую же линию и проставить на неё теги POI;
  • можно создать мультиполигон с единственным членом – линией здания в роли outer, и поставить на этот мультиполигон теги POI;
  • можно создать новый мультиполигон, на которой перенести теги здания, а теги POI поставить на то, что было до того, но это лишняя правка исходной линии, и так делать не стоит.

Вертикальность

Может показаться, что полигон – хоть и более трудоёмкий способ представить POI, зато позволяющий отразить её истинную геометрию. На самом деле, поскольку полигон – фигура двумерная, то верно это только для геометрии на плоскости. С точки зрения вертикальной геометрии нас интересует возможность показать, на каком этаже располагается POI. В общем случае, POI может располагаться и на нескольких этажах. Что с этим делать мы уже подумали, в этом случае мы перечислим в теге level соответствующие уровни. Никаких проблем поставить этот тег на точку, в случае если POI обозначена таким способом, нет. В общем-то их нет и в случае с полигоном, однако на разных этажах заведение может занимать разную площадь. Когда мы обозначали POI точкой, на это можно было внимания не обращать, так как площадь обозначать мы не пытались. В случае обозначения полигоном площадь есть, но перечисленные уровни заведение занимает не на всей своей площади.

Магазин, под вторым этажом которого другие магазины

«Теремок» (справа) под вторым этажом «Фабрики» (вход слева)

Какая площадь должна входить в полигон POI? Как и для других объектов, например, зданий, это должна быть площадь проекции на горизонтальную плоскость. Её можно поделить на части, для которых заведение занимает разные множества этажей. Например, будет часть площади, где оно только на первом этаже, часть – на первом и втором, часть – только на втором. Видно, что это подобно зданиям, внутри которых могут быть части, обозначаемые с помощью building:part, у которых указывается этажность. Кажется, что и для POI должно быть подобное решение, но такого способа обозначения частей заведений, который был бы широко распространён, нет. Если мы захотим его сейчас придумать, как он должен выглядеть?

Допустим, мы отмечаем shop=*. По аналогии с building=* мы обозначили полигоном или мультиполигоном площадь его проекции. Внутри этой площади мы рисуем части магазина, занимающие разные этажи. Здание делить на части можно как по горизонтали, так и по вертикали. Для магазина мы тоже можем разрешить оба способа. Хотя в случае деления горизонтальными плоскостями получатся перекрывающиеся части, для POI это будет, как правило, более естественный вариант, так как перекрытия между этажами обычно есть, а стен в местах альтернативного вертикального деления может и не быть. Обозначим внутри площади магазина эти части полигонами с тегами, допустим, shop:part=yes. Плохо тут, конечно, то, что если бы мы обозначали не shop, а amenity, office и т.п., то для их частей понадобились бы другие теги: amenity:part, office:part и т.п. Если нам это кажется проблемой, мы можем обозначать части и другим тегом, например poi:part. В этом случае мы, возможно, добавим соответствующий тег и на всё заведение, в данном случае poi=yes.

Дальше надо указать этажи, а точнее уровни, соответствующие частям POI. У частей здания для этого используются теги building:levels и building:min_level. Очень редко встречается тег building:max_level. Здесь мы можем поступить либо так же, либо вспомнить, что мы уже используем для этой цели тег level. Если мы пойдём первым путём, то есть указанием диапазона уровней разными тегами, то имеет смысл использовать пару shop:min_level, shop:max_level (или amenity:min_level, или poi:min_level).

Если мы отмечаем части чего-либо, то должна быть возможность однозначно определить, чему эти части принадлежат. В случае со зданиями, часть, обозначенная с помощью building:part, относится к тому зданию, внутри которого она находится. Этого достаточно, так как проекции зданий на горизонтальную плоскость почти никогда не пересекаются. Бывают и исключения, такие как одно здание внутри другого, но тогда здание, находящееся внутри, обычно достаточно небольшое, например, это ларёк, и его на части делить не нужно. В случае же с POI возможны и довольно часто наблюдаются пересечения их проекций. Это особенно верно для многоэтажных POI, занимающих разную площадь на разных этажах, так как причиной не занимать одинаковую может являться то, что необходимое для этого место на другом этаже уже занято другим заведением. Следовательно, просто включения одной площади в другую может оказаться недостаточно для определения принадлежности части целому.

Когда другие способы не срабатывают, в ход идут отношения. Первое, что можно попробовать – использовать уже широко используемый вид отношения. Для объединения частей в единое целое широко используется мультиполигон, даже тогда, когда это неправильно. В данном случае, когда у одной POI могут быть перекрывающиеся части, он совсем не подходит. Мы можем запретить деление горизонтальными плоскостями и оставить деление вертикальными гранями. Тогда части POI не будут пересекаться, но будут соприкасаться. Для внешних границ мультиполигона это тоже не совсем правильно, но уже поддаётся осмысленной интерпретации. «Не совсем правильно» означает, что это будет расхождением со стандартом, которому спецификация мультиполигонов пытается следовать, но при этом разрешается от стандарта отойти для соприкасающихся границ, правда почему-то только для внутренних. Если идти таким путём, то полигона-проекции всего заведения рисовать не нужно, нужны только непересекающиеся части с установленными списками уровней, а прочие теги POI следует поставить на мультиполигон.

Это было, конечно, использование мультиполигона не по назначению, так что имеет смысл поискать что-то другое. При рассмотрении предыдущего использования отношений не по назначению, в разделе про несвязные POI упоминалось отношение site. Наш случай обсуждался как пример применения этого отношения. В этом случае можно оставить деление горизонтальными плоскостями, поставить на части теги level, а прочие теги POI поставить на отношение.

Если ни мультиполигон, ни site нас не устраивают, то можно придумать свой тип отношения. Назвать его можно чем-то вроде poi_parts. Для его членов нужно две роли – одна для проекции всего заведения целиком, другая – для его частей. Проекция целиком была бы не нужна, если бы мы были уверены, что всех сразу удастся заставить его использовать. Но, поскольку такое вряд ли произойдёт, проекция, на которой будут теги POI, будет существовать для обратной совместимости.

Все способы задать геометрию, которые используют отношения, будут менее популярны, чем те, которые отношения не используют. В осме есть один тип «естественного» отношения для этих целей – это мультиполигон. Его все понимают, и никто не стесняется использовать, даже слишком не стесняется. В случае с частями магазинов мы хотели бы без отношения обойтись, но нам нужно как-то обозначить отношение в широком смысле между частями и целым, то есть задать отношение, не используя элемент отношения. В осме есть средства и для этого, например тег is_in. Идут они из тех далёких времён, когда элементов отношений в осме не было, а теперь они как бы не нужны. Отношения они задают менее явно, но мы можем здесь захотеть пойти на их использование, так как для нас пока не так важно, чтобы результат был на 100% машиночитаемым, важнее, чтобы мы сами могли его прочитать. Если мы решимся пойти этим путём, то в is_in или ему подобный тег, например, is_in:poi, мы запишем название заведения, то есть то, что у заведения записано в теге name. Очевидный риск тут заключается в том, что name может измениться, но в принципе за этим можно автоматически следить.

Помимо вариантов с рисованием частей, можно предложить отметить помещения заведения по схеме Simple Indoor Tagging, поставить точку POI в какое-то одно из них, и оставить пользователям задачу догадаться, что они связаны. Ещё можно отметить POI отдельно на разных этажах. Тут уже можно использовать полигоны. Может быть, удастся даже придумать для этих разных экземпляров POI разные теги, не считая level.

Глядя на все эти теоретические рассуждения, можно усомниться в необходимости отмечания частей POI. Действительно, зачем они нужны? Если вы не собираетесь одновременно использовать и полигоны и level, то они и не нужны. Но если вы полигоны и level используете, то зачем вы это делаете? В контексте данной записи они нужны для того, чтобы не запутаться, где какая POI находится, когда POI расположены достаточно плотно. Двух- и более этажные POI как раз находятся в таких местах и как раз занимают разную площадь на разных этажах и по-всякому пересекаются в проекции с прочими POI. Если не рисовать части и просто поставить список этажей на проекцию, то из-за пересечений получится, что, согласно осмовским данным, в одном месте находятся несколько POI. Это совсем не то, что хочется получить.

Рисование неизвестного

Нарисовать полигон сложнее, чем поставить одну точку. Сложности при этом связаны не только с тем, что надо больше рисовать, но и с тем, что может понадобиться рисовать то, чего не видно. Если мы хотим нарисовать заведение, находящееся в здании и выходящее на улицу, то не так сложно получить его протяжённость вдоль здания. Это можно сделать подсчётом окон как изнутри, так и снаружи. Сложнее определить, насколько заведение уходит в глубину здания. Если нам повезёт, то мы увидим окна, выходящие на противоположную сторону здания, но чаще всего их не видно. Производить измерения без внешних ориентиров, насколько глубоко внутрь здания уходит не всегда полностью видимая площадь заведения, мы можем и не захотеть. Зато мы можем не захотеть и выбрасывать из вводимых данных известную нам протяжённость POI вдоль внешней стены здания.

Почему нам может быть важна эта протяжённость? Она нам важна применительно к сбору информации о POI, так как в первую очередь мы производим их внешнюю разведку. «В первую очередь» потому что даже если мы и зайдём внутрь интересующего нас места, то не раньше, чем увидим его снаружи. Если POI достаточно длинная, и, тем более, если по её длине располагаются несколько входов, то может быть важно эту длину как-то обозначить.

Точку мы ставить не хотим, а помимо точек для обозначения POI мы умеем использовать только полигоны. Но как мы нарисуем полигон, если у нас есть информация только о его «длине», и нет информации о «ширине»? Я рассматривал даже вариант обозначения POI незамкнутой линией, проходящей вдоль стены, но решил, что это будет выглядеть слишком странно. Скорее всего, сторонний наблюдатель подумает, что это ошибка, и линию просто забыли замкнуть.

Если нам повезло, то снаружи будет видна и «длина» и «ширина». Это произойдёт, если заведение находится на обозреваемом углу здания, на углу квартала. Это хорошо, так как именно угловые POI неудобнее всего обозначать точками, если пользоваться делением на области проверки, как это делаю я. Небольшое перемещение точки могло бы перебросить её из области одной улицы в область другой, а с полигоном такого не произойдёт.

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

Полигон POI, уходящий вглубь здания до середины

Нарисованное по методу *до середины отделение почты, рисовал не я*

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

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

POI вне зданий

Отчасти то, что касается обозначения POI, находящихся вне зданий, мы уже рассматривали в разделе про вертикальную геометрию. Там упоминался тег location и то, что он для обозначения расположения POI внутри здания не используется. Большинство наших POI находятся внутри, так что нужнее был бы тег для точек снаружи, но location=outdoor для последних не используется по тем же причинам. Из всех значений location для POI вне зданий подойдут underground и roof, а для обычного положения за пределами здания подходящего широко использующегося значения нет. Есть, правда, нерекомендуемое значение kiosk, показывающее попытки обозначить положение, промежуточное между indoor и outdoor.

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

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

Если ларёк не нарисован, то есть два варианта действий: рисовать его как любое другое здание или не рисовать и сразу отмечать POI. Рисовать его как здание, то есть полигоном, бывает лень по уже упомянутым причинам размера и стабильности. Ларёк мелкий и его контур плохо виден на снимках, да и переместиться или исчезнуть он может с куда большей вероятностью, чем обычное здание, так что очень скоро может выясниться, что рисовали мы его зря. Полигон приходится рисовать, когда нужно внутрь поместить несколько объектов, в случае с ларьком же внутри него обычно что-то одно. Ещё нас может остановить то, что ларёк может находиться внутри другого здания, а вложенные здания мы рисовать не хотим. Если всё это нас или наших предшественников не остановило, и здание ларька нарисовано, то мы оказываемся в ситуации с POI, занимающей всё здание, рассмотренной в одном из предыдущих разделов.

Несколько ларьков под крышей

Ларьки в здании вокзала

Если же рисовать ларёк мы не решились, а POI мы обозначаем точкой, то к этой точке имеет смысл добавить тег building=kiosk. Это поможет показать, что точка POI не оказалась случайно за пределами здания. Эти случайности возникают либо когда саму точку ставят мимо, либо когда меняют геометрию здания не обращая внимания на то, что у него внутри.

Как я маплю

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

Рассмотренные способы

Перечислим рассмотренные способы обозначения POI.

  1. Отметить POI точкой.

    1.1. Поставить точку на границу POI, где вход, совместив её со входом. Можно сделать, если вход только один, и он принадлежит только данной POI.

    1.2. Поставить точку внутрь POI.

    1.2.1. Поставить точку посередине POI, для такого определения середины, при котором она будет внутри POI. Дополнительно может понадобиться решить, входят или не входят в пределы POI определённые помещения.

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

  2. Отметить POI площадным объектом – полигоном или мультиполигоном, а возможно и более экзотическим отношением. Дополнительно понадобиться решить, входят или не входят в пределы POI определённые помещения.

Независимо от вышеперечисленного, можно:

  1. Не отметить входы.

  2. Отметить входы.

    2.1. Не соединять вход ни с POI, ни с глобальным графом маршрутизации.

    2.2. Соединить вход с POI. Может получиться само собой, если POI нарисована площадным объектом.

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

    2.4. Соединить вход и с POI, и с глобальным графом.

Независимо от вышеперечисленного и друг от друга, можно поставить или не поставить вертикальные теги level, level:ref, addr:floor, location, layer.

Используемые мной способы

Из всего перечисленного выше, когда я где-либо обозначаю POI в первый раз, я обычно использую самый простой из методов, который позволит не запутаться в данном месте. Для большинства мест это обозначение POI точкой на расстоянии двух метров от входа без обозначения самого входа и без вертикальных тегов. Большинство мест – это те места, где (входы в) POI идут достаточно редко, допустим, они расположены не ближе 10 метров друг к другу. Поступать иначе, то есть мапить их более сложным методом, означало бы тратить время, которое лучше было бы потратить на ввод POI в другом месте. Кроме того, при первой проверке я не пытаюсь получить информацию, необходимую для рисования контуров POI и проходов к ним. Первую проверку я, как правило, делаю с записью трека, а если при этом заходить внутрь зданий, что понадобится для получения необходимой информации, то трек будет сбиваться.

Если входы в POI расположены близко, одной из причин этого является то, что ведут они на разные этажи. В этом случае я в первую очередь добавляю тег level. Так я могу обойтись без дополнительной геометрии, то есть без рисования входов, которое, как я писал в соответствующем разделе, будет подразумевать большую точность. Уровень этажа POI будет видно практически на любой фотографии, в том числе на той, на которой не виден вход. Цокольный или подвальный этаж (здесь имеется ввиду расположение этажа, а не его название в конкретном здании) нередко можно определить даже по фотографиям интерьера, которые часто бывают опубликованы на сайтах заведений. Это всё может пригодиться, если фотография со входом не получилась, и если нужно определить, какое заведение открылось вместо какого.

Выяснением номера этажа, который можно было бы записать в level:ref или addr:floor я специально не занимаюсь, и, соответственно, писать в эти теги мне обычно нечего. Каждый раз их использовать вместо или в дополнение к level и не получилось бы, потому что сам номер может не существовать. Случаи, когда номера нет, или, по крайней мере, когда он нигде не написан, встречаются довольно часто как раз тогда, когда я решаю использовать level. Речь идёт в первую очередь о цокольных или подвальных этажах, в которых могут находиться POI рядом с другими POI на первых этажах, и для которых никакого обозначения на месте, что это, например, этажи номер ноль я пока не встречал. Даже существующие обозначения этажей вряд ли будут написаны рядом с POI. Обозначения эти в центре Петербурга встречаются у входов на лестницы, и эти входы могут быть с другой стороны здания за закрытыми воротами.

Указатель с номерами этажей 0, 1, 2, 3, 4, 5

Этажи номер ноль, конечно, существуют, но в обычном здании подвал так никто не называет

Указатель с номерами этажей для лестницы жилого дома

У обычного здания этажи обозначаются так

Где обозначения этажей у POI можно встретить, так это на табличках в местах, где эти таблички служат единственным свидетельством существования POI, видимым с улицы. Тут я эти обозначения записываю в теги addr:floor на точках POI. А куда в этом случае, когда расположение самих POI остаётся неизвестным, я ставлю их точки? Я их ставлю рядом со входом, у которого про них написано. Если этажи точек известны, то ближе ко входу я ставлю те точки, у которых номер этажа меньше. Так может получиться несколько рядов точек, например, сначала точки второго этажа, потом третьего и так далее. У POI на первом этаже больше шансов быть видимыми снаружи, и их по описываемому принципу приходится ставить гораздо реже. Иногда этажи на табличках не написаны, но написаны номера офисов, и можно попытаться угадать этажи из них. Если это не получается, то я ставлю точки примерно в том порядке, в каком расположены их таблички.

POI, расставленные внутри здания в негеографическом порядке

«Матрица» из точек у БЦ

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

  • Если я поставил точку внутри здания, не соединив её проходом, и она стоит рядом со входом в здание, и это не единственная точка рядом со входом, то у неё скорее всего фиктивное положение.

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

  • Точки с фиктивным положением вы можете смело двигать, куда надо, только надо будет ещё что-то сделать, чтобы я их не подвинул обратно.

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

  • Другой способ – обозначить POI не точкой, а полигоном. Полигон я двигать никуда не буду, если только мне не понадобится сдвинуть всё здание. Этот способ особенно подойдёт, если в положении POI вы уверены не потому что знаете, как туда пройти, а потому что можете снаружи найти соответствующие окна. Тогда вы знаете протяжённость POI вдоль внешней стены и можете действовать по принципу, описанному в разделе Рисование неизвестного.

  • Если оба описанных выше варианта не подходят, то можно написать примечание, как пройти с улицы в POI.

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

Родственный тегу addr:floor тег level:ref я пока не использовал, но, возможно, буду использовать при indoor-маппинге. Его я намерен ставить туда, где в реальности есть обозначения этажей, обычно это выходы с лестниц внутри зданий. Пока за indoor я серьёзно не брался и только в одном здании подобным образом записал обозначения этажей, причём записал в тег addr:floor, и, видимо, зря, потому что по смыслу тут больше подходит именно level:ref. Мне кажется, что софту, который выводит планы этажей, стоило бы на всём level’е внутри здания или части здания с заданным количеством уровней искать эти обозначения, и если попадётся хотя бы одно, использовать его для всего этажа. Разработчики схемы Simple Indoor Tagging хотят, чтобы оно было именно на бесполезной с моей точки зрения обводке всего этажа, что является частным случаем того, чего хочу я.

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

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

Пять входов в магазины на одинаковом расстоянии друг от друга

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

Входы в здания могут быть уже обозначены другими участниками, но обычно это ещё не сделано. В первую очередь появляются входы на лестницы, но за ними редко бывают интересующие меня POI. Прочие входы, включая входы в магазины, обозначены бывают редко, если только их не совмещают с самим магазином. Такие совмещения я разделяю на две точки, соединённые проходом: вход на контуре здания и POI внутри. Проход тут нужен, чтобы не снести информацию о соответствии входа и POI. Историю редактирования точки я оставляю на POI, а не на входе, то есть операция разделения состоит из вырезания совмещённой точки из контура здания, её перемещения, удаления с неё тегов входа и создания новой точки входа на исходном месте. Делать приходится именно так, потому что часто сама POI существовала ещё до своего совмещения со входом. Если вход обозначен без POI, то я просто ставлю POI рядом с ним или перемещаю к нему уже обозначенную POI, а проход обычно не рисую, так как обычно его геометрия мне неизвестна.

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

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

На сам вход я чаще всего ставлю тег entrance=yes. entrance=main я использую либо для очевидного главного входа в здание, который определяется независимо от находящихся в здании POI, либо для основного входа в крупное заведение, например, занимающее всё здание, или содержащее внутри себя множество POI, например ТК или БЦ. Если таких входов несколько, то я могу поставить несколько main. entrance=shop я пока не использую.

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

Несколько легче выяснить границы угловой POI, что для меня хорошо, в связи с используемым мной методом записи информации о произведённых проверках POI. Проверки я делаю по участкам, в которые обычно входят стороны кварталов. В прошлой записи в разделе Где? я обращал внимание на то, что вход POI должен быть внутри участка, а угловой вход или даже место, где вход может появиться, – внутри обоих участков. Это нужно было в том числе для того, чтобы точка, поставленная либо рядом с таким входом, либо по какой-нибудь другой причине на углу, тоже оказалась внутри участков. Другой причиной может являться установка точки на углу, когда входы в POI есть по обе стороны от угла. Сами входы находятся как в одном участке, так и в другом, POI я ищу по входам, значит хочу обозначить и её в обоих участках. Пока я обозначаю POI точкой, в оба участка её можно добавить, только поставив на углу. Однако подобный способ обозначения POI вынуждает принимать решения о расположении точки, которые ещё более произвольны, чем «два метра». Соответственно, я стараюсь места с несколькими входами обозначать не одной точкой, а полигоном, который естественным образом пересечётся со всеми необходимыми участками.

Полигон POI на углу здания

«Кондитерская» на углу с фотографии перед разделом про входы; перед ней и описываются решения об расположении точки

С проходами вне зданий входы я пока не соединяю, потому что для записи расположения POI они не нужны, и я не определился, какие теги на них ставить. Если я всё-таки решаюсь соединяющий проход нарисовать, то с тротуара необязательных тегов типа surface на него я не копирую. Здесь я поступаю так же, как и с пешеходными переходами через улицы – поверхность и прочие свойства улицы я на них не ставлю.

Какие теги ставить на внутренние проходы, я тоже не вполне определился. В простых случаях, когда не надо рисовать лестницы, я использую highway=corridor. В случаях посложнее – иногда использую его же, иногда highway=footway. Пока я не знаю, на чём остановлюсь, удобнее использовать corridor, так как если я решу от него отказаться, то его легко массово заменить на footway. Обратную замену сделать сложнее, так как footway используется гораздо шире и для других вещей.

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

Немного истории

Способы, которыми я обозначал POI, менялись на протяжении того периода времени, как я стал отдельно этим заниматься, то есть с сентября 2016 года. Когда я начинал обозначать POI, я вообще не хотел делать геометрические правки, то есть рисовать какие-либо линии. После долгого перерыва мне было лень настраивать JOSM и вспоминать, как им пользоваться. Чтобы более-менее приемлемо в нём рисовать, нужно установить десяток плагинов. К тому же ещё выяснилось, что два нужных мне плагина – AlignWays и CommandLine – несовместимы с на тот момент текущей версией JOSM. В результате я три-четыре месяца ограничивался добавлением, редактированием, удалением точек и изменением тегов на уже существующей геометрии. Это значит, что POI я обозначал либо точками, либо тегами на всём здании целиком, входы и проходы не рисовал.

Когда другие участники стали изменять геометрию под редактируемыми мной точками, мне пришлось десяток плагинов всё-таки установить, но из геометрических правок я стал делать только минимально необходимые. Некоторые полигональные объекты я рисовать начал – в основном это было то, что полигонами обозначается традиционно, то есть детские сады, школы, бизнес-центры, но не обычные магазины. Таким образом я обошёл Адмиралтейский район и приступил к Центральному в апреле 2017 года.

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

Касательно заметок можно сказать, что на любую точку может прилететь что-нибудь типа что её не видно, а дальше те, кто считают своим долгом заметки закрывать, её потрут. Но точку на самом деле может быть не видно, потому что она глубоко внутри здания. Это «глубоко» лучше выразить через осмовские данные, то есть нарисовать до точки проход, что мне и пришлось начать делать в сложных случаях, когда за одной дверью находятся несколько POI. Для этого приходится заходить внутрь, чего я ни разу не делал при обходе Адмиралтейского района, и пока я не знаю, как это лучше совмещать с регулярными проверками, упомянутыми в предыдущей записи.

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

Заключение

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

  • Следует ли использовать entrance=shop и другие нетрадиционные типы входов?
  • Стоит ли использовать разные ключи для входов и выходов?
  • Обозначать ли окна заказа/выдачи, и если да, то каким тегом? Подойдёт ли для этого amenity=walk_up_window или они сами по себе не являются amenity, аналогично входам?
  • Ограничиваться ли традиционными тегами highway=footway и highway=steps при рисовании проходов внутри здания, использовать дополнительно highway=corridor или вводить ещё значения для highway=*? А, может быть, вводить их для footway=*?
  • Если использовать highway=corridor, то как широко? Для любого прохода насквозь помещения или только для основного? Для любого ли помещения или только для собственно коридора, если нам удастся однозначно определить, что такое коридор?
  • Как часто следует рисовать проходы с улицы ко входам в здания? К любым входам, только к тем, за которыми обозначены проходы, только к тем, за которыми сквозные проходы?
  • Какие теги использовать для проходов снаружи ко входам? Обычные highway=footway и highway=steps или другие, введённые специально для данной задачи?
  • Как обозначить заведение с разными по площади частями на разных этажах здания?

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

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

Discussion

Comment from luiswoo on 24 October 2018 at 14:12

Гы-гы, «Как я провёл лето на 90 листах» https://yadi.sk/d/oBqLJgYTbBlXAg — в fb2 ради шутки. Не могёт браузер фф в документ без оглавления — заголовки есть, но оглавления нет, не MOffice, что на лету его делать.

Comment from Anton Khorev on 27 October 2018 at 03:02

Не могёт браузер фф в документ без оглавления

https://addons.mozilla.org/ru/firefox/addon/overview/

Log in to leave a comment