Anton Khorev's diary

Recent diary entries

Problems with level

Posted by Anton Khorev on 15 November 2018 in English (English).

There are problems with level=* tag stemming from the fact that not all mappers agree on what it means. This problem comes up more often in some geographic areas than in others where different floor numbering traditions exist. In this sense it is like name=* tag where certain parts of a name stop looking like parts of a name after being translated into a different language.

So what are exactly the problems with level=*? Some people think that the value of this tag should be whatever floor number that is used in place. You can usually but not always read it off some plaque, floor plan or elevator button. Other people think that the value should be a number such that the first floor at or above the ground level gets number 0, the floor above it gets 1 and so on. Those two different ways of assigning a value could be exactly the same, especially for English-speaking areas where they have a “ground floor” as level=0 and a “first floor” as level=1. If you are from those places, you may not even understand that there’s a problem. If you are from a place like Russia or the US, it’s evident for you that those ways are different. I’ll be using Russia as an example because it’s where I map.

But there should be no debate about the exact definition of level=* tag because we have a wiki where it’s perfectly documented, right? Not quite. First of all, we don’t have one wiki, we have multiple wikis in different languages. Those languages may correspond to areas with different floor numbering traditions, which in turn affects the wiki contents. Again, this is like name=*, where local wiki editors put their preferred spin on what should and what should not be part of a name.

Even if we stick to English wiki, we still won’t avoid the problems with its current contents. You may get different impression on what level=* actually means depending on where you start and where you end reading the page, and also whether you follow the links to certain other pages or not. In fact, since I mentioned other pages, how do you know which wiki page you have to read in the first place? You may think that it’s obviously Key:level, but that page disagrees with you, sending you elsewhere for further information. You may also remember building:min_level=* tag which also takes on level as a value. Or is it a different level? Is there a definition of level that exists independently of particular tags?

What can those disagreements lead to? We can look at this from the point of view of a data user and of a data editor. For a user, let’s say you want to get to a POI which is inside a building. You look it up in some app, for example OsmAnd, and the app would tell you which floor the POI is on. So you see among other things about the POI something like “Floor: 1”. Actually, OsmAnd will say “Level: 1”, but that’s going to happen if you have English interface. In Russian it’s going to be “Этаж” which is literally a floor. At this point we can remember what happens to the wikis in different languages and look at this as an attempt to bolster a particular interpretation of level=* through localization. I’m talking about level tag because the number you see in the app comes from this tag. As a user, you may not know anything about tags and possible differences in their interpretations. Your most likely interpretation of the number you see is going to be that it’s a floor number, a designation of a floor inside the building, which is either evident from local traditions or directly written somewhere. You are unlikely to attempt to determine level zero and then count the specified number of levels upwards. In fact, this counting operation may seem unnecessarily complicated and even nonsensical, which looks like a good argument to just use the self-evident floor number as a value of level tag. With this assumption you’ll only get the correct floor number if the last editor of level tag on the particular POI shares this opinion. If not, in Russia you’ll most likely end one level below the POI. Sometimes it’ll be two levels. It’s going to happen when “first floor” is slightly below the ground. In some cases the level will coincide with the floor number even under this “counting” interpretation, but you wouldn’t know that in advance.

What are the problems for editors? Obviously, different people may want different values for the same tag on the same object. This may lead to edit wars. You may then propose to keep whatever level numbering scheme already exists in a certain building and make everyone follow this scheme. Unfortunately this is not always possible. In order to know what scheme is in place you have to find stuff that is already mapped with level tag and figure out what scheme it corresponds to. There’s a chance that no single scheme would fit because different things were mapped by people with different opinions. This is likely to happen if there are many elements tagged with level. On the other hand there could be few and you wouldn’t notice them. All this scheme guessing has to be done because nobody indicates what scheme is to be followed at a particular place. Nobody indicates that because according to most mappers there’s only one right scheme and other schemes shouldn’t exist.

Even if you know the scheme, you can find yourself in a situation where you have to change already existing level values. For example, you may tag all of the POIs along a street in one manner and eventually you get to a place that was mapped differently. Do you stop and change your way starting with this place? Do you go back and retag everything you already have entered? If you have entered a lot and there’s only a few things mapped differently, it makes more sense to retag those few things.

Of course having two different interpretations of one tag is inconvenient. We are better off with just one that makes more sense and is easier to use. And we already know which one it is. Just write the local traditional floor number, you can always check it on place, you don’t need to figure out where’s level zero, you don’t need to count floors, you don’t need to follow the rules made up by foreigners who don’t know how things work in your country. That’s how people who prefer this particular scheme think, however there are reasons to think otherwise.

That other way of thinking goes as follows. We had the definition of level that has 0 assigned to the first level above the ground level for at least seven years. This definition is used in Simple 3D buildings (S3DB) for about as long. All of the software that uses S3DB data relies on this definition. It would be inconvenient to come up with another “indoor” level numbering scheme. It may not even be a numbering because floors can be designated by letters and then you wouldn’t know the vertical order of levels without extra data. Even some of software that mainly concerned with indoor visualizations like OpenLevelUp assumes 0-based numbering. So there is only one scheme that works, it’s been around for a long time, and it’s how it defined in the wiki. That last statement about the wiki is a bit of a wishful thinking done by the proponents of this scheme.

Those were the ideas behind the two major level numbering schemes: locally-defined labeling (it’s may not be strictly numbering) and 0-based numbering. As you can see, the proponents of these schemes can be pretty convinced that their scheme is the correct one and they want the level tag for themselves. In addition you can come up with many more schemes. For example, you may want 1-based numbering where you say that those who think that ground floor and first floor are two different floors got their traditions wrong and have to adapt to 1-based counting because all normal people count from one.

One noteworthy scheme lies between the two major ones. A scheme that we’ll call locally-based numbering attempts to fix some issues with locally-defined labeling. It uses only numbers that make the vertical level sequence well-defined. For this scheme you replace all non-numeric level labels with numbers. For example, if a building had level K below level 0, like described in this comment, you replace K with -1. Usually it’s the same as matching the number sequence …, -2, -1, 0, 1, 2, … as close as possible with all numeric labels. In this case the result is usually going to be the same as picking either 0-based or 1-based numbering, whatever fits best.

There’s one extra quirk that is skipped levels. Imagine a 100-storey building without 13th floor. The best match with the sequence would involve setting level=2 for 1st floor, level=3 for 2nd and so on until 12th floor. This is not what people typically want to do so it’s fixed by extra hack. This hack can be added to any of the numbering schemes mentioned above. It consists of declaring some of levels as non existent and their numbers are thrown out of the sequence before it’s matched with numeric labels. It also makes level numbers incompatible with S3DB levels, in case you use it with 0-based numbering.

For places like Russia, no matter what scheme you pick, you lose either compatibility with existing tools or traditional floor numbers, maybe both. Losing traditional numbers is particularly annoying because you have to use numbers that are almost always one off and it’s easy to make mistakes because of that. I think that compatibility with tools is the main divide here. Those who use S3DB want to see the visualizations with tools that assume 0-based numbering. After a while they get somewhat comfortable with that scheme and are more likely to stick with it for other things. Those who don’t use S3DB see 0-based numbering as something alien.

How prevalent are the problems described here, are they worth your attention? In the place I map, Saint Petersburg, Russia, both main schemes are in use. That means you can’t rely on levels displayed by apps like OsmAnd. I’ve seen levels changed from one scheme to another when next user comes to edit elements with existing level tags. I had to do it myself too, in the situations I described above. Now I mostly avoid the buildings such as malls that are mapped using the other scheme, but eventually I’ll have to do something about them. I haven’t yet seen full-blown edit wars over level values, however currently there’s nothing that would stop one from happening.

What’s to be done about it? You can do something about the editing apps, the end-user apps and the tagging conventions with their documentation. That last thing is going to be the subject of another post, but I can tell right away what can be done with the editors even if we don’t agree on the exact meaning of level tag. This is for editors with indoor mode such as Vespucci. In this mode you don’t have to enter the level values directly, the editor sets them for you. You only have to select the level to be displayed. The level selector can be modified to display some other number instead of the actual level value, or display both actual and altered values alongside each other. The simplest way to specify how to alter the value is to have the level offset option that takes numeric values. For example, with the +1 offset, level=0 would be displayed as 1. A more elaborate options would be required to skip (or insert) certain numbers and replace numbers with letters (or letters with numbers), but the simple offset would solve a lot of problems.

I tried to write this post from neutral point of view without preferring any particular scheme. You can read about my opinion on which scheme is better and which one do I use in my previous post (in Russian). It’s quite long, but you only need sections Вертикальная геометрия and Как я маплю. The next thing to be discussed about levels is what exactly the wiki says. I’m going to leave it for another post.

Как я отмечаю POI – Геометрия

Posted by Anton Khorev on 23 October 2018 in Russian (Русский).

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


Основная задача: отметить 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=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. Он обозначает уровень внутри здания. Высота уровня обычно равна высоте этажа. За точку отсчёта уровней, то есть за то место, где уровень равен нулю, принимается самый низкий уровень пола какого-либо этажа, находящийся над землёй. У здания получается вертикальная шкала уровней, значения которой идут от 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 или другие, введённые специально для данной задачи?
  • Как обозначить заведение с разными по площади частями на разных этажах здания?

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

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

Как я отмечаю POI – Что? Где? Когда?

Posted by Anton Khorev on 13 July 2018 in Russian (Русский).

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


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

Где: в данный момент – на территории Адмиралтейского и Центрального районов Санкт-Петербурга в первую очередь вдоль официальных улиц (согласно rgis), далее во дворах и ТК.

Когда: в какой-либо момент со вторника по пятницу с 11:00 по 18:00, при необходимости в другое время.


Целевые теги

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

  • amenity – некоторым. Этот ключ соответствует разнородным объектам, как урнам, так и университетам. Университеты при данных проверках мне нужны, а урны – нет. Урны у меня относятся к особому виду проверок – урново-скамеечной картографии, для которых более-менее годится как редактор, но сейчас речь не о них.

  • club – всем. Это редко используемый тег, про который часто непонятно, стоит ли использовать именно его.

  • craft – всем, какие заметны в городской среде, а это те, которые предоставляют услуги населению, например, ателье.

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

  • landuse – так сложилось, что некоторые крупные объекты, которые удовлетворяют критериям, например заводы, обозначаются этим тегом. Если я их могу обнаружить, то я их обозначаю, но в результаты проверки не включаю.

  • leisure – некоторым, например leisure=playground не подходит. Детские площадки я обозначаю при детальной отрисовке дворов, так что если я пойду искать во дворе POI, то чтобы отдельно туда не ходить за всем остальным, я отмечу и детские площадки.

  • office – всем, но большинство из них никак о себе не сообщают, и я такие не обозначаю.

  • shop – всем. Самый очевидный ключ для данных проверок.

  • tourism – некоторым. Музеи нужны, а viewpoint’ы – нет.

Видно, что невозможно придумать фильтр для типов точек, которые меня интересуют, так как в любой момент может войти в употребление новый тег из семейства amenity, leisure или tourism, и будет неизвестно, интересует ли он меня. То же самое с другой стороны выглядит как невозможность сформулировать определение интересующего меня множества объектов на местности на основе тегов осм.

Требования к POI

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

Кофе с собой

Не подходит, так как на колёсах

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

Продажа симок

Поставите ли вы здесь office=telecommunication?

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

Закрытый ларёк

Этот ларёк не работает только сейчас или в принципе?

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

Платёжный терминал

Типичный платёжный терминал в типичном магазине

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

Что ещё обычно заметно только в виде таблички:

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

  • мелкие услуги типа изготовления ключей и ремонта всякой всячины.

  • всё, что находится в бизнес-центрах, а это не обязательно офисы. Не в каждый БЦ можно свободно войти.

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

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

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

Этим «где-то в интернете» обычно является сайт заведения или его страница в какой-либо соцсети, когда их нет, могут помочь всякие официальные документы. Понятно, что из «где-то» приходится исключить чужие базы данных типа 2ГИС, а также то, что поисковики любят показывать справа от результатов. Несколько раз я добавлял офисы компаний потому что про них сообщалось в СМИ, что бывает в связи с имущественными спорами с различной степенью криминальной составляющей.

Возможные офисы

Есть ли за этой дверью офисы, с учётом того, что на сайте соответствующих организаций про них не написано?

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

Предпочтения одних видов POI другим

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

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

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

Автобусная остановка

Остановка не подходит, так как нет персонала

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

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

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


Географическое где

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

Адмиралтейский район

Западный край Адмиралтейского района

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

Граница Адмиралтейского района

Железные дороги – ещё один вариант естественных границ районов

Прочие места Адмиралтейского района, где есть POI, я обхожу параллельно с улицами Центрального района. Эти прочие места, то есть дворы и всяческий indoor, уже нельзя мапить без предварительной подготовки, которая может заключаться в выяснении доступности для посещения самого места и скачивании данных в Vespucci. Этот процесс более растянут по времени, чем обход улиц, соответственно ждать, пока я обойду все дворы с POI в одном районе, прежде чем приступать к другому, непродуктивно.

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

Геометрическое где

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

Прямой и срезанный угол в JOSM

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

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

Окно на первом этаже

Бывает, что дверь превращается обратно в окно

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

Прямой и срезанный угол в JOSM

Граница участков проходит через более острый угол здания

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

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

Цель этих правил – чтобы было понятно, где границы участка, не глядя на их изображение.


Регулярные проверки

Теперь можно рассмотреть регулярные проверки, до которых я обещал добраться ещё в прошлой записи. Это те проверки на местности, при которых я выясняю, присутствуют ли и работают ли POI на всём участке целиком, и которые я делаю в те дни недели и то время суток, когда ожидаю, что большинство из POI работают. Дни недели это будние кроме понедельника, так как есть достаточно много POI, не работающих по выходным, а из будних дней самый популярный, чтобы не работать, это понедельник. По понедельникам любят не работать специализированные магазины для узкого круга покупателей, например shop=hifi. Время суток для проверки – между 11:00, когда уже открылись все, кто открывается до обеда, и 18:00, когда работающие в обычное рабочее время уже начинают закрываться. Зимой приходится заканчивать ещё раньше, потому что быстро темнеет и фотографии становится делать сложнее.

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

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


Это заведение раньше пяти вечера вы не заметите

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

Нерегулярные проверки

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

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

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

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

Как я отмечаю POI – Метаданные

Posted by Anton Khorev on 19 June 2018 in Russian (Русский).

Почему пришлось взяться за POI

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

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

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

Другое дело – магазины, кафе и т.п. По весьма примерным подсчётам их «время полураспада» составляет 5 лет. То есть если вы их все отметите и подождёте 5 лет, половина из них уже не будет существовать. И если их много, то найдётся какой-нибудь магазин, который закроется или откроется практически сразу после вашей проверки. А их очень даже может быть много – так много, что они на рендер не поместятся. Значит, просто один раз сходить и отметить подобного рода точки, а затем считать, что дело сделано, не выйдет.

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

Время проверок

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

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

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

Места проверок

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

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

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

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

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

Метаданные проверок

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

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

Что касается третьего элемента в записи – номера пакета правок, то как мы уже знаем, его может и не быть. Соответственно, уже с самого начала его указывать было необязательно. Тут можно поинтересоваться, зачем в принципе записывать пакет, ведь дата проверки берётся не из него. В данный момент это просто средство для меня, чтобы искать пакеты правок, относящиеся к определённому месту. По обычной истории правок это делать неудобно. В идеале хотелось бы иметь способ получить всю информацию по POI, признанную мной правильной на момент проверки, и она содержалась бы в пакете, если бы правки в обязательном порядке затрагивали все точки и, желательно, ничего кроме точек. Но это не так, хотя отчасти я пользуюсь записанными пакетами в качестве временного средства сделать snapshot данных. (примечание на июнь 2018: кое-что поменялось между написанием и публикацией; собственно snapshot уже делается, и полей в соответствующем csv-файле уже не три)

Далее обнаружилось, что не всегда реально сделать правки для всего участка за один заход. Соответственно, пришлось разрешить указывать множество пакетов правок для одной проверки. Связано это с тем, что попадаются участки, на которых может быть хоть пятьдесят POI, например, Лиговский проспект между площадью Восстания и Транспортным переулком (1, 2), и это если исключить из него Московский вокзал и «Галерею». Придумывать особенный способ деления на участки поменьше для «POI-плотных» мест мне не хочется, так как при текущем способе деления границы участков очевидны даже без разглядывания картинок, где они нарисованы, тем более, что изначально они не были нарисованы.

Метаданные участков

Сначала данные об участках содержались в первую очередь в их названиях. Названия эти состоят из названий улиц и диапазонов номеров домов. Названия улиц не уникальны во всём субъекте федерации, но уникальны внутри центральных районов. В районах, включающих разные населённые пункты, типа Пушкинского, подобной уникальности может уже не быть, но ими я пока систематически не занимаюсь. Если к названию улицы добавить номера домов, то так можно задать сторону квартала, выходящую на определённую улицу – тот тип участков, которые я проверяю в первую очередь. Проблема тут в том, что номеров по нужной улице может не существовать. Улицами здесь я называю всё, что в Петербурге официально ими считается, и отображается зелёными линиями в rgis. Это включает и площади, а по ним часто не бывает номеров, тогда в название участка приходится вместо них писать, какая это сторона, например, юго-западная. Даже если номера и есть, то они не всегда очевидны, их может не быть в осме и так далее. Дополнительно к номерам я решил давать текстовое описание, которое позволит в сочетании с именем участка найти его, даже если я ошибусь с номерами. Сначала это привело к появлению ещё одного csv-файла с записями (название участка, описание).

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

Недостатки у работы со слоем-файлом такие:

  • А вдруг его случайно закачаешь, тем более, что josm будет предлагать это сделать, если вносить изменения. К счастью, вскоре после того, как я перешёл к использованию слоя, в josm была добавлена возможность запретить закачивать слой, если в его файле есть xml-атрибут upload='never', поставленный на корневой элемент. Достаточно один раз его вручную поставить, и этот недостаток исчезает.

  • А вдруг в него случайно скачаешь данные осма, ведь их в нём быть не должно. Операцию скачивания ещё и нельзя отменить, так что приходится следить, какой слой выбран, и хранить версии файла, например, в git, чтобы в случае скачивания и сохранения лишних данных можно было бы откатиться к «чистой» версии. Впрочем, недавно был добавлен и атрибут download='never'.

  • josm всё-таки предназначен для редактирования данных осма, и у всех объектов должен быть осмовский идентификатор. А какие идентификаторы у объектов, которых в осме нет и не будет, то есть у наших участков? Всему, что не закачано, josm даёт временные идентификаторы – отрицательные числа - но нет гарантий, что они постоянны. А если мы начали пользоваться системой контроля версий, то изменения идентификаторов для нас нежелательны. Можно попробовать переустановить идентификаторы перед записью в git так, чтобы изменений было поменьше, но пока я этим не занимаюсь.

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

Как я отмечаю POI – Пролог

Posted by Anton Khorev on 26 April 2018 in Russian (Русский).

Имея на руках софт с данными osm, становится сложно заблудиться, по крайней мере в здешних местах, то есть в Санкт-Петербурге и окрестностях. Можно выяснить, например, не только как пройти к Эрмитажу, но и как пройти от Тарховки до Сестрорецка вдоль залива, а потом найти там на карте «Пятёрочку». И можно с удивлением обнаружить, что эта «Пятёрочка» существует в реальности. Удивительно это потому, что зная количество магазинов и прочих заведений в городе и скорость, с которой они меняются, можно усомниться в возможностях осмеров поддерживать данные обо всех этих точках в актуальном состоянии.

Действительно, далеко не всегда присутствие точки на карте соответствует её существованию на месте. Вот случай, произошедший со мной в период моей неактивности в osm в середине 2010-х. Иду я в Сбербанк, а там выясняется, что не работает устройство, печатающее талончики, и надо вставать «в порядке живой очереди». А зачем мне это, если я могу дойти до другого отделения, которое рядом. То, что оно рядом, я знаю, ведь у меня в телефоне OsmAnd, и само это отделение, вроде бы, я лично ранее ввёл. Однако по прибытии на место выясняется, что этого отделения нет. Тогда я иду ко второму ближайшему согласно данным osm отделению. Его тоже нет. Обнаружилось только третье отделение, в котором выяснилось, что мне нужно идти именно в то, в которое я пришёл сначала, а не в любое, но это уже не проблемы osm. Проблемы osm заключались в устаревших данных poi, и эти проблемы я пытался начать исправлять как за несколько лет до случая со Сбербанком, так и после, но дело дальше планирования и сбора небольшого количества данных не уходило.

Первые свои poi я вносил вместе с данными о кварталах Адмиралтейского района СПб в 2011-2012 году. Это были данные обо всём подряд внутри квартала целиком. Контуры зданий, этажность, арки, проезды, проходы, газоны, деревья; позже – входы в здания с номерами лестниц и квартир. Большинство подобных объектов меняются редко, в отличие от магазинов и прочих poi, следовательно потом нужно будет заниматься отдельно обновлением исключительно poi. Делать это будет несколько легче, чем мапить всё подряд, в том числе и потому, что большинство магазинов видны с улицы, и не нужно пытаться пролезть в не всегда открытые дворы.

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

Если сейчас данные о внутренностях кварталов, парков и зданий я ввожу на месте в Vespucci, то в те времена приходилось рисовать на бумажке. И с poi было особенно неудобно разбираться, потому что для того, чтобы не загромождать схему местности на бумаге записями о точках, их лучше фотографировать. Для этого надо было взять в руку телефон, но обе руки были заняты ручкой и бумажкой. В итоге ввод poi не был тогда для меня приоритетной задачей, и я не пытался вводить их контактные данные, режимы работы и прочие подробности.

Осенью 2011 у меня появилась ещё одна задача: маршруты общественного транспорта. В Яндексе данные по остановкам были неточные, транспортного портала ещё не существовало, и получалось, что надёжного источника данных вообще не было. Что я по этому поводу делал – отдельная история, к poi прямого отношения не имеющая, так как здесь речь идёт о poi «магазинно-кафейного» типа, а не об остановках. На одном из этапов сбора данных о маршрутах я шёл как можно дальше вдоль основных улиц и смотрел, какие на них находятся остановки, и транспорт каких маршрутов по ним проезжает. Расстояние между остановками большое относительно расстояния между упомянутым выше всем подряд, следовательно, существенную часть времени я просто шёл. Ясно, что более полезно было бы заодно собирать какие-нибудь данные, и в некоторых случаях я так и стал делать.

Для сбора данных об общественном транспорте ручка и бумажка уже не нужны, достаточно делать фотографии и записывать их с помощью OsmTracker’а. На gps можно рассчитывать в большей степени, чем во дворах, кроме того, нужное место на фотографии можно сравнить с Яндекс-Панорамами. То же самое можно сказать и о сборе данных о poi, которые я и стал собирать, пока ходил от остановки к остановке. Но все эти данные о poi так и не попали в osm, потому что недостаточно их собрать, надо ещё их ввести, а вводить их дольше, чем собирать.

Помимо того, что на это нужно время, ещё одной причиной неввода стало то, что я представлял себе, какие мне нужны инструменты для решения определённых задач, связанных с редактированием poi. Вот одна из таких задач. Как это отчасти видно из приведённого выше второго поста fserges’а, обычной ситуацией является нежелание мапить уже отмапленное, несмотря на то, что, как видно из первого поста, ясно, что poi на местах меняются. Это можно объяснить так. Допустим, что poi в каком-то месте вообще не отмечены. Тогда никакой рендерер не рендерит их значков, и видно, что это место пустое. Теперь мы пошли и их отметили, и место стало непустым, на нём появились значки. Результат наших действий ясно виден, причём виден даже тем, кто не знаком с данным местом. Прошло какое-то время, и данные устарели, их надо вводить по-новой. Но значки с рендера от этого не исчезли, и незнакомый с местностью разглядывающий карту участник по прежнему будет видеть, что вроде как тут всё отмаплено. Если мы перемапим данное место, то подобный участник не заметит разницы: была куча значков и стала куча значков. То, что это куча значков новая – на ней не написано. Значит надо сделать так, чтобы было видно, где куча значков новая, а где старая.

Инструменты, конечно же, сами не напишутся (и всё, что я хотел, до сих пор не написано), а обновление данных я откладывал до написания инструментов. В 2013-2015 годах я несколько раз предпринимал попытки собирать данные, но в итоге за это время я не сделал вообще ни одной правки. Наконец мне просто надоело, что всё, что я тогда делал, было связано с сидением на стуле за компом, а osm – это, по крайней мере, не постоянное сидение на стуле, и я решил взяться-таки за ввод poi без предварительного написания инструментов. Тогда я думал, что дело будет выглядеть так: раз в неделю я буду где-то в течение часа в качестве «обеденного перерыва» ходить и собирать данные о точках внутри определённого муниципального образования, делать это я смогу по дороге в какое-либо место в промежутке между другими делами; таким образом я смогу поддерживать данные в состоянии полугодичной-годичной свежести. В итоге всё получилось, конечно, не так, особенно «в течение часа», да и область действия пришлось сразу поменять из-за того, что по дороге куда-либо я довольно быстро пересекал границы МО.

28 сентября 2016 года я отправился собирать данные, которые, наконец, попадут в osm. Ну а сейчас я собрался начать об этом писать, и в одной, а скорее всего более, чем в одной, из следующих записей я расскажу о том что, где, когда и каким образом я маплю в плане обновления данных о poi. для тех, кто не пользуется

Posted by Anton Khorev on 31 January 2018 in Russian (Русский).

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

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

Допустим, что мы решили, что две темы про на форуме – это нормально. В этом случае всё равно можно возразить, что одна из них имеет негативный характер, так как у неё в названии содержится слово «ошибки». А что, собственно, заслуживает обсуждения – правильные правки? В осме, например, есть обсуждения пакетов правок. Для чего им пользуются? Ну иногда для того, чтобы сказать автору правки, что он занимается вандализмом, ведением войны правок и всё ломает (это были примеры комментариев к некоторым моим правкам), но обычно это обсуждение реальных или потенциальных ошибок. Так что ошибки в осме обсуждаются, а если кто-то захочет перейти к замечаниям про вандализм и т.п. в форме, неприемлемой для форума, то на этот случай есть модераторы, которых помимо Zverik’а ещё два. Если вам кажется, что форум – не место для обсуждения ошибок, потому что существует упомянутое выше обсуждение пакетов правок, то вы должны быть и против темы «откаты правок». Вы можете сказать, что «откаты правок» - для тех случаев, когда обсуждение пакета не помогло. Ну так и в случае с правками из оно не поможет.

Ошибки в правках как особенности редакторов

Многие ошибки в редакторах, ориентированных на новичков, объясняются особенностями самих редакторов. – это редактор не просто для новичков, а даже для тех, кто не понимает, где именно он редактирует данные, и даже что действия из редактора являются именно редактированием общих данных. Но ведь используют не только новички, но и опытные участники. Можно же им редактировать и не делать всего того, про что написано ниже? При определённых условиях можно, и я об этом писал (например, про перекрывание доступа в интернет для с целью последующей проверки пакета в josm), но нередко и опытные участники делают всё то.

Чтобы показать, что я не придираюсь именно к, рассмотрим для начала другой редактор – iD. Вы, возможно, видели, как в правках из этого редактора некоторые точки, например, точки дорог оказываются перетащенными на существенное расстояние. В результате получается ломаная линия, проходящая сквозь препятствия в виде зданий, пересекающая другие дороги без общей точки пересечения и т.п. Ясно, что это не имеет смысла, и у вас может возникнуть мысль про выполнившего данную правку типа «он что, идиот что ли?» Но он, скорее всего, не идиот, и здесь имеет место особенность редактора. Возьмём хорошо известный вам josm. Какой кнопкой мыши вы перетаскиваете точки? Левой. Какой вы перемещаете область редактирования? Правой. А что в iD? Точки перетаскиваются левой, область прокручивается тоже левой. Если вы предпочитаете josm и никогда не пользовались iD, то попробуйте, и вы заметите, что у вас тоже получатся случайно перетащенные точки. Ну а редактор iD на сайте предлагается тем, кто не пользовался до него вообще ничем, и кто перетаскивания не заметит.

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

Особенности редактирования из

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

Создание дубликатов уже существующих точек

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

В осме есть места, не редактирующиеся годами, для которых месячный возраст данных не будет иметь значения, но есть и активно редактирующиеся места. Если открылся новый магазин в заметном месте, то существует высокая вероятность того, что он будет отмечен несколькими пользователями. Одним из этих пользователей может быть представитель данного магазина. Иногда и оба пользователя могут быть представителями. Мне известен подобный случай, когда точка была добавлена через iD. Это, конечно же, не привело к её немедленному появлению в, которого, возможно, пришлось бы ждать полтора месяца, и точка была добавлена ещё и через Так что если вы создаёте только что открывшийся магазин, вам может понадобиться следить за отредактированным местом, чтобы отлавливать дубли. Лично у меня случалось, что в добавок ко своей точке, я получал ещё две в течении нескольких дней. Одна из них в данном случае была создана из osmand, видимо, по подобным причинам.

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

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

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

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

Создание заметок про отсутствие уже удалённых или заменённых точек

Встречаются заметки с просьбой удалить или просто с утверждением об отсустсвии того, чего рядом с этими заметками не обнаружить. Они могли быть поставлены на объект, существовавший в данных пользователя по первой причине создания дубликатов. Можно обратить внимание на то, что добавляет к тексту заметки, если он был введён пользователем, название точки, послужившей поводом к созданию заметки, её тип и дату-версию данных у пользователя. При этом пользователь не знает, что он создаёт именно заметку. Для пользователя эта операция может выглядеть как собственно удаление, так как она влияет на отображение точки. Кстати, отменить создание заметки-удаления невозможно, даже если пакет правок ещё не отправлен, в отличие, например, от создания новых точек. Ну и конечно же ни про какие пакеты правок и про то когда именно происходит загрузка данных, пользователь понятия не имеет. В датах-версиях можно заметить, что некоторые пользователи не обновляют свои данные год и больше. Имя и тип точки старые версии не писали, и заметки, относящиеся непонятно к чему со стандартным текстом «amenity doesn’t exist» всё еще могут существовать.

Создание заметки при создании точки, при том, что в заметке не содержится никакой информации, которой бы уже не было в точке

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

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

Задание несоответствующих друг другу тегов на одной точке

Иногда это явление происходит в очевидно бессмысленном виде: компьютерный магазин «Столовая». Можно догадаться, что на этом месте раньше был магазин, а потом открылась столовая. Пользователь поменял name, но почему он не поменял amenity/shop? Потому что редактор этого сделать не даёт. Бывают и менее очевидные случаи, например, когда ресторан помечен как ночной клуб. Ведь вполне возможно, что на самом деле это также ночной клуб. Но нет – это пользователь обновил name у точки на месте бывшего клуба.

Помимо типа точки, который пользователь видит, но не может поменять, есть и такие теги, которые пользователь даже и не видит. Это все теги, которые не вписались в шаблон для редактирования, то есть большинство использующихся тегов. Их пользователь обновлять не будет. Не прочитает он и заметки для редактирующего в note. Все редакторы можно поделить на те, которые не скрывают теги, на те, которые сначала скрывают, но могут показать, и на те, которые не могут. josm относится к первым, iD – ко вторым («все теги» обычно свёрнуто), к последним. Последние проще для неподготовленного пользователя при добавлении новых данных, зато совсем не годятся для редактирования существующих. Можно подумать, что никаких проблем быть не может, если надо всего лишь поменять значение website или opening_hours. Но представьте себе, что на точке также стоит fixme, в котором сказано, что текущее значение неправильное. После редактирования без учёта fixme, неправильным становится уже сам fixme.

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

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

Создание новых точек вместо редактирования существующих либо без удаления старых

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

Создание точек с неподходящим типом

Бывает, что в городе вдруг появляются водопады и прочие объекты, которых не может там быть. Это пользователь захотел обозначить что-то, для чего доступного для выбора типа в не нашлось. Список доступных типов ограничен, а один из них выбрать обязательно нужно. Можно было бы догадаться поставить заметку, но на пустом месте это сделать не получится, так что, если заметка и появится, то только вместе с водопадом. Скорее всего, однако, заметка не появится, и вам придётся либо угадывать, что имел в виду пользователь, либо откатывать.


К сожалению, спам не ограничивается известным случаем с тегом banner_url. Рассмотрим историю редактирования одного уже удалённого здания. Как видно, в версии #10 помимо этажности я задал название и сайт. Как мне это удалось, если не даёт редактировать названия у зданий? Конечно же я ничего, кроме этажности править не собирался, но у свои соображения на этот счёт. Есть агентство недвижимости на букву Ц, рекламу которого можно увидеть в приложении в общем и на некоторых зданиях в отдельности, во всяком случае в Санкт-Петербурге. Редактирование этих зданий может привести к попаданию в правку рекламы Ц. Если вы видите подозрительные name и website на здании, то надо опять же проверить историю редактирования на предмет наличия в ней правок из Если они есть, то возможно следует их откатить.

Ввод данных с точностью плюс-минус дом

Пользователи ставят точки мимо нужного здания несколько чаще, чем пользователи других редакторов. Объясняется тем, что им приходится рассчитывать на gps, находясь рядом со зданиями, отсутствием спутника/аэрофотосъёмки в качестве подложки и невозможность подвинуть свои точки после добавления. Например, один пользователь, входящий в топ-10 редактирующих из, идёт вдоль улицы и вносит все POI подряд, не зная, что вместо дома n их надо было ставить в n+2, вместо n+2 – в n+4 и т.д. Дойдя до конца квартала, он, конечно, поймёт, что ошибся, но исправить ошибку уже не сможет. Это не очень хороший повод для доверия к точности координат точек менее топовых пользователей. Мимо точки ставят и без, да и магазины, бывает, в действительности перемещаются в соседний дом, но если вы видите точку не на том здании, на каком считаете, что она должна быть, её создание правкой из – аргумент в вашу пользу. Ну и некоторые вообще в здание попасть не могут, и ставят на проезжую часть. Может быть они ожидают, что в интерфейсе добавления в нужное место надо ткнуть, а не тащить его под «прицел».

Нелогичное объединение правок в пакеты

Пакеты правок, создаваемые пользователями могут быть как «атомарными», содержащими одну точку, так и «планетарного масштаба», с правками в разных частях света. И зачем пользователи так разбивают свои правки на пакеты? А они их и не разбивают, это за них делает приложение. Правки с одной точкой будут у тех, у кого с интернетом всё в порядке, «планетарные» будут у туристов, экономящих мобильный трафик. Я видел пакет, в котором помимо создания дублей в СПб, было создание дублей во Франции (и коллегам оттуда приходилось делать suppression d’un restaurant en doublon) и, может быть, не-дублей на Шри-Ланке. Пакеты могут быть и пустыми – это если соединение оборвётся.


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

Насколько это плохо и что с этим делать

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

"Mapping Well With Mapsme"

Posted by Anton Khorev on 1 October 2017 in Russian (Русский).

После прочтения этого топика на форуме возникает желание прокомментировать упомянутый там доклад Mapping Well With Mapsme.

“Вместо того, чтобы собственно редактировать данные, можно добавлять метки”

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

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

“При добавлении места выдаётся длинный список типов, но мы типа об этом подумали и у нас есть поиск”

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

“ отсылает данные, когда приложение закрывается”

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

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

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

“Обычное имя, которое без языка, защищается, чтобы его не грохнули туристы”

Сам рассказ про редактирование названий сопровождается скриншотом, где поле “English” заполнено по-японски - имеет обыкновение самостоятельно его заполнять. Докладчика это не смущает, хотя для пользователя наверняка важно, запишется это всё в name:en или нет. Когда я подобное заполнение поля “English” русским названием удалял, в результате не создавалось и name:ru. Я до сих пор не уверен, что именно произойдёт при редактировании имени, и логика там, похоже, менялась в недавних версиях.

Защиту “настоящего” name можно охарактеризовать и по-другому: не даём пользователю ожидаемого способа полностью переименовать точку. В результате этого в разных name будут разные названия. Тогда зачем вообще давать редактировать название, ведь можно было бы давать только добавлять новые языковые варианты. Например, можно было бы показать “настоящее” нередактируемое название, а рядом поставить кнопочку “добавить перевод”. У некоторых объектов название менять и не дают, например у зданий и, следовательно, у poi, совпадающих со зданиями. В этом случае под редактирование подставляется номер дома, хорошо, что там валидатор.

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

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

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

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

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