|Definition:||Creating and interconnecting stacked levels, core part of multi-storey builings, vertical elevators (lifts) and ladders|
- 1 Proposal
- 2 Rationale
- 3 Concept
- 4 Tags
- 5 Roles
- 6 Examples
- 7 Rendering
- 8 Features/Pages affected
- 9 Comments
When mapping outdoor lifts and ladders, highways going through buildings and other things where identical or almost identical features are stacked exactly on top of each other, the currently used definitions are not sufficient for easy mapping.
This proposal suggests an easy way of mapping these features. Its aim is to encode the data easily with existing editors (Potlatch, JOSM, etc.) 'good enough' for routing software to find routes through these structures and to generate clear and complete navigation instructions.
Although the concept technically supports extensive indoor mapping, it does not encourage mappers to do it. It is sufficient to map indoor structures needed to find ways through the structure and points of (general) interest inside it. All junctions where turns are needed should be mapped. The first part of ways that are of no general interest should be mapped as well, in order to generate proper instructions.
The level map concept in conjunction with the existing multipolygon concept automatically made it possible to create 3D multipolygons. However, to make full use of it and to keep compatibility with existing renderers, two small extensions to the multipolgyon are proposed here.
A concept for mapping vertical ways (for truly vertical lifts and ladders) completes the proposal.
While the detailed explanations are quite long in order to provide good defaults and to fulfil all possible (exotic) needs, the concept works out to be very easy to use.
If you are a developer and wonder what level maps mean to you, it depends on the kind of software you have in mind. If your software doesn't care about 3D or routing, you can probably ignore level maps safely. If it is about 3D or routing, you might want to read the level map software support page.
The current map seems to suffer from an unability to handle the vertical dimension in a user-friendly way. In particular, there is no obvious way of mapping features that are placed exactly on top of each other, such as identical floors of a building or exits of an elevator.
Of course, the OSM database allows us to do it. We can create distinct nodes connected with distinct ways, all at the same co-ordinates. The ways would have different layer tags. Elevators and layered stairs could interconnect the end nodes of the layered ways from the different floors.
However, people are not used to this idea and the editor software has no support for it. Mappers would have to prepare the floors elsewhere and move them into place. As soon as they are in place, it is really hard to understand them. It was proposed somewhere to tag stairs at level *.5, but that would help only for one level of stairs and still not solve the problem of which end of the stairs is connected to which level.
This proposal provides a way of overcoming the difficulties by introducing the concept of a level map.
While it is a probably complete replacement for the level relation proposal, it does not compete with the site relation proposal. Instead, it solves the problems that these (feature focused) proposals do not solve. This proposal is routing focused, being able to carry the most important parts (the level names and their order). Doing so, it reduces the need for using the other two relation types.
The concept cannot be integrated into the site relation, because it is not necessarily linked to one site, building or building complex. It is quite independent and can also be used at the border between two sites or building complexes.
As this concept describes stacked structures, there is no inherent need for 2D graphical renderers to handle the proposed objects at all. That's why this paper does not propose to change anything that is interesting for these renderers. 3D renderers should make use of the methods described here, as the amount of information is bigger than in the level concept known before.
Routing software (or translators, such as mkgmap) must be enhanced in order to handle this proposal properly. The proposal is designed in a way that unaware programs see direct shortcuts through level-mapped structures, so they may miss the need to use stairs or elevators, but their routing will not break totally.
Another goal of this concept is to avoid nested relations. Of course, a wide support for nested relations in editing software would make many tasks easier, but people as well as most OSM editing software seem to have big difficulties in supporting them.
Finally, the proposal contains a set of sensible defaults, making the use of this system very intuitive and reducing the mapper's work to a minimum.
A level map is a way of virtually 'replicating' a set of objects (, , even if needed) and connecting the results to 'levels'. The 'replication' results are referred to as 'instances' in this proposal. All instances of an OSM database object share the same co-ordinates, they are 'stacked'. The instances are not actually stored in the OSM database, but created only inside programs interpreting the data.
The objects to be 'replicated' are added to the level map relation as members. The membership roles define which nodes are connected to which levels.
Tags from two categories can be added to the level map relation:
- Level Definition: Which levels do exist, what is their order and how are their names - in which language?
- Member Classification: How are membership roles to be interpreted? Fine-tuning mapping between membership roles and levels
A level is basically a name used inside a level map to identify a vertical position. All instances that are sharing the same level at a particular node are connected at that node. Levels are in a vertical order from the bottom to the top.
Levels are different from layers in multiple ways:
- Layers are mainly needed for visualisation, levels are mainly for routing
- Layers define the vertical order of different objects at the same place. Levels can (but usually do not do) be used to create multiple instances of one object from the OSM database.
- Layers are a a property of ways, levels are properties of relations with a defined set of objects they apply to.
- An OSM object can have only one layer tag, but multiple levels assigned in multiple level map relation memberships.
If the order of levels varies in different parts of a structure, two level maps can be created and interlinked easily.
The most important tag in a level map relation is the levels=* tag. Its content defines the (short) names of all levels and their order, from bottom to top. For example, the relation for a simple four storey building with a basement in England would be tagged "levels=B;G;1-3" (for "Basement", "Ground floor", "1st", "2nd" and "3rd". The level names should reflect the local signs, such as buttons in the elevator. So same building in Germany would probably be tagged "levels=U;E;1-3".
Long descriptions are allowed as well, to reflect local signs, such as "levels=B=Basement;G=Ground floor;1-2;3=Roof garden"
A general level height information (a relative vertical position, not the vertical size of an object) can optionally be added, separated by an "@" sign: "levels=B=Basement@-4;G=Ground floor@0;1@5;2@9;3=Roof garden@13". 0 is the street level (if available) or the main ground level otherwise. All height details are in metres if not coded otherwise ("@10 ft"). This general height information can be overriden in a level assignment, so levels don't need to be absolutely flat.
Languages can be added according to the two-letter ISO language code to the "levels" key, such as "levels:de=B=Untergeschoss;G=Erdgeschoss;1-2;3=Dachgarten" if the local signs are multilingual or not understood by the expected visitors.
If the elevator buttons contain non-ASCII characters, ASCII characters must be used before "=" separator. The non-ASCII button labels can be listed after the separator.
If members are to be instantiated in special level combinations, way roles can be defined to fine-tune the association between the members and the levels they occur in.
In this case, a tag "role:<a role name>" can be defined, describing on which levels the members occur that are added to the level map relation with the membership role defined here. The value field is structured as a semicolon separated list of assignments.
The assignments consist of keys and values, separated by a "=". Key names are from a fixed set that might be extended later, so software must ignore unknown keys.
Most keys select nodes of relation members and assign levels:
- all: Selects all nodes of the way. The value is the level to assign to it.
- first: Selects the first node. The value is the level to assign to it.
- intermediate: Selects all nodes, except the first and the last one. The value is the level to assign to it.
- middle: Selects the middle node of a way if the number of nodes is odd. If the number is even, selects the first node of the second half of the way.
- last: Selects the last node. The value is the level to assign to it.
Two special keys control the repetition across the levels:
- repeat: The repeat indicator defines a maximum number of repetitions. It is no error if the repetition ends due to a lack of available levels if the number given here is greater than the number of remaining levels. There is a special value "all", meaning that the repitition should not stop before all available levels are walked through.
- step: defines the step width of the repetition. Positive step indicators walk the level list from left to right, negative step indicators from right to left. To improve the readability, only positive step indicators should be used. The absolute value of he step indicator defines the step width. A step indicator of 2 will skip one level each step, enabling us to define things such as zig-zag stair cases - or triangular staircases with a step indicator of 3. A step indicator "0" is an error.
There are defaults for all of these values. For example, if the "Intermediate" key is missing, intermediate nodes up to including the middle node (if any) are assigned to the same level as the first node and intermediate notes after the middle node are assigned to the same level as the last node. The default for both "repeat" and "step" are 1.
Example: "role:link_up=first=B;last=G;repeat=all" will define a role "link_up" that connects the first part of all "link_up" role members to the "B" level and their last parts to the "G" level. As there is no step indicator, instances will be created for every available level, starting with the link from "B" to "G" and continuing with "G" to "1", etc. In our example, no instance starting at level "3" will be generated, because there is no level above "3").
N. b. The example above does not need to be defined explicitly. It is one of the defaults, making the mapper's life easier.
If the height of a specific level is different from its normal height at specific points, special height information can optionally be given in the role membership definition. In this example, the front staircase of a building with "levels=G@0;1@4;2@8;3@12" has got a plateau one metre below the normal floor level : "role:FrontStairsPlateau=1@3;repeat=all@4".
If a used role is not defined explicitly, but a level with the role's name is defined, the default definition for the role is "all=<the role name>", resulting in the whole member being instantiated for the named level only.
By default, all relation members will be replicated into all defined levels. Ways with all their nodes and relations with all their members. No member classification tags are needed for that. For example, the ways and other parts that are shared by all floors can just be added to the relation with an empty role.
If a role is defined explicitly using a role: tag in the level mapping relation, that tag is followed.
There are some predefined roles:
- bottom: adds the member to the lowest existing level only
- top: adds the member to the highest existing level only
- link_up: Adds the first nodes of the member to the lowest level and the last nodes of the member to the second lowest level. Repeats this for all levels
- link_down: The same as link_up, but assuming the link direction pointing downwards.
There is one special instance of all instances created from one OSM database object, which is the main instance. Usually, the main instance is the lowest actually existing instance (created from one and the same OSM database object). However, if there is an instance does exist at a vertical position of zero (@0), this instance is the the main instance of that particular object.
Connections to the outside
Nodes of instantiated ways will only be connected to ways that are member of the same or another level map. The main instance of an object is always the main one that will be "connected" to normal objects outside of any level map. If a way from the outside needs to be connected to a different instance, that way from the outside must be included in a level map (usually the same one) and connected to the correct level.
This prevents anomalies. For example, if the endpoints of instantiated ways inside a building touch the building outline and the building outline is not a member of the level map (because there is no reason for it), the common node with the building outline would interconnect all of these ways at that point.
Unlinke "normal" ways, it is possible to interconnect instances from different level maps. In this case, the existing instances are interconnected from bottom to top, regardless, of the internal level names. This makes it possible to interconnect incompatible level naming between buildings or even inside a building. If the numbers of instances at both ends of such a connection differ, the software should leave the unmatched (topmost) instances unconnected on the side with fewer instances and generate a warning.
True vertical ways such as vertical (small) elevators or ladders can be mapped as a node, as before. The way between instances of the node is created automatically if the node is tagged accordingly.
The tags for ways created out of a vertical way node are prefixed with "vway:". For example, a vertical elevator (lift) could be tagged like this:
If the vway does not need to be tagged (this is often the case if it is part of a multipolygon), its node will just be tagged vway=yes" The multipolygon would have to be extended to allow vway defining nodes as members. The advantage is that 2D renderers can safely ignore them, because they render the flat structure.
As always, the level map relation membership defines the connections of the vertical way. The node's height will be used as the vertical way's total length. Of course, the total length is not sufficient if the vertical way links more than two levels, but better than nothing. We may improve this part later.
If an "ele" tag is given, it applies to the main instance of the node.
A vertical way is not needed for nearly vertical elevators, because a way can be mapped between their endpoints, carrying the way tags. The level map relation membership roles for these elevators are the same as for stairs.
For "Long" true vertical elevators that are mapped as a piece of highway, one node that is part of the elevator way (preferrably one in the middle) has to carry the vertical way tags. As part of the elevator way, it will be instantiated correctly anyway.
Elevators with exits at both ends that are used on different levels need a little more care, because they must be split up into two separate ways, each one connecting its exit end with the middle vertical way node. Both ways will have their own level map relation membership roles, defining their own connections to the levels. The fact that both are connected to the middle vertical way node will instantiate the needed nodes for the vertical way automatically.
If a there is a need for modeling a complex building structure, this can also be accomplished using vertical ways. In this case, the building is described as a multipolygon and its outline objects are members of a level map. If the building outline levels are the same as the internal levels, the same level map can be used for both.
In a considerable number of cases, the instances of nodes or ways serve slightly different functions on the different levels. Two common cases:
- stacked highways, with one direction on one level and the opposite direction on the other level
- male toilets on one level and female toilets on the other
In both (and many more) cases, we can specify level specific details in the level map, adding them as a semicolon separated list inside square brackets. Examples (role member definition tags of a level map relation):
(for a male and female toilets in the basement, female-only in the 3rd floor and male-only on the 4th floor; the member node is tagged "toilets=yes")
(for a layered bridge with the lower level along the way direction and the upper level the opposite way; the member way is tagged "highway=trunk")
- The member must have sufficient tags left, so that level map unaware software (such as 2D renderers or unaware routers) can make sense of it. In our toilets case, the toilets are visible. In the highway case, the highway is visible as two-way, so routers will still use it for routing.
- This means that this instance tagging is not always usable. A bridge with a highway on top of a railway needs two separate ways.
- Common tags should go to the member itself. Only level specific tags should go into the level map.
Levels and Layers
Level maps as such do not need layers.
- The stacked instances of OSM database objects are in a vertical order already.
- A classic 2D renderer will see the original database objects and does not need to render the different instances.
- Objects connected to members of the level map are handled correctly.
However, when other objects are crossing above or below a level-mapped area, all objects must have layer tags in the same way they would be without a level map:
- Layer tags must always reflect the view of the objects from the top.
- If members of a particular level map have got a layer tag, they are usually (not always) all tagged with the same layer.
- Objects above the level mapped objects are usually one layer above that level, objects below are tagged one level below the level mapped object's level.
- No levels should be reserved for instantiated nodes or ways.
- If other crossing objects are interwoven with instantiated objects, the level of the topmost instance defines the level tag of the level map relation member that the instance is based on.
- Landuse areas are usually not layered, because they define a general dedication of a bigger area. So we do not need to start layer tagging because of an existing landuse.
When mapping a building, the building outline is normally not part of a layer map, because it does not contain any stacked elements that need mapping. Of course, if there is a need to map the building itself in 3D, it will be member of a level map.
If ways and other features are inside the building, they are covered by the building's roof. That's why buildings containing other features are usually one layer above their content. In most cases, the building's layer will be "1", while the building content's layer remains default ("0"), no matter how many floors are instantiated. As long as there is no better way of tagging indoor ways, the tunnel=yes is recommended for all ways covered by a roof.
If the building outline shares nodes with layer mapped objects, the main instances of these objects are connected to the building outline. This does not contradict the previous paragraph, because buildings have got a height.
Instantiated Objects and Relation Membership
Members of level map relations can be members of other relations at the same time. The meaning of a relation membership depends very much on the relation type. That's why the support for relations built into renderers and translators is very specific to the relation type.
Similarly, the exact handling of a relation membership of an OSM database object that is also a level map relation member may vary slightly depending on the relation type. The renderer or translator has to interpret the meaning according to its own purposes. For level map unaware software, there is no need to cope with this anyway.
However, this is the general idea: If a member of any other relation type happens also to be a level map relation member, all of its instances are part of the other relation, at the place where the original OSM database object is and in the order of level appearances in the used level map relation membership rule definition. If only special instances belong to the other relation, a separate OSM database object must be created.
While the above mentioned way of handling the relationships works works well and is easy to understand for most relation types, there are some worth mentioning:
Ways that are member of a (2D) multipolygon are fine - as long as there is only one instance of these ways. If one of these ways is instantiated more than one time, the multipolygon automatically becomes 3D, see the 3D multipolygon Section below. If the multipolygon is 2D, but occurs in multiple instances, the multipolygon relation itself must be part of the level map relation instead of its ways. As most OSM editing software can't handle nested relations properly and the meaning of multipolygon level map members is not fully defined yet, instancing of 2D multipolygons is discouraged for now.
Most existing routes currently in the OSM are handled like a bag of route elements. Sometimes (such as in the new public transport scheme), the order of the elements is important. In both cases, there can't be a simple general rule about which instances are part of the route or in which order (a route may come in on the bottom level, goes up two floors, which are instances of a stairway, then go out through the back door on that level). To make it worse, different routes may use different instances of one and the same stairway. On top of that, there is no clear standard of handling route alternatives. To make the long story short, the route relation must be modernised anyway. Until then, if a route member happens also to be a level map member, all of its instances are part of the route, at the place where the original OSM database object is and in the order of appearance in the rule definition. If only special instances are part of a route, they must be separate OSM database objects.
As (turn) restrictions allow multiple instances of the "to" role only, it does not make sense to have more than one instance of a "from" or "via" element. Please note that it makes sense to instantiate restriction relations themselves along with their instantiated elements (by adding the relations themselves to a level map), but this is discouraged for now, due to the unability of so many editors to handle nested relations.
Similar to closed combinations of ways (including vertical ways, vways) forming one or more areas, closed areas may form one or more open or closed 3D objects (which, strictly speaking, are not polygons any more, but can still be mapped this way).
Some precautions must be provided, so that level map unaware software can handle them properly:
- Inner and outer multipolygon ways may overlap or intersect when looking onto them from the top. If they do, different layer tags must give level map unaware software guidance in how to render the object in 2D.
- Holes in 3D multipolygons may be covered by other parts of the same multipolygon on top of them. 2D renderers should ignore such covered ways. In order to do so, the multipolgyon membership role of covered inner multipolygon ways is "3d_inner" instead of just "inner". This will make unaware renderers ignore them or handle them as outer ways. Both is sufficient for us here. However, the multipolygon relation definition has to be updated with the 3d_inner role.
Level Map Relation
|type||level_map||yes||none||type=level_map||defines the relation to be a level_map|
|levels||level_list||yes||none||levels=*||lists all levels, ordered from the lowest to the topmost level, semicolon separated.|
|levels:lang||level_list||no||none||levels:de=U=Untergeschoss;G=Erdgeschoss;1-2;3=Dach||same as above, but for a non-default language. Does not need to be complete. Keys must match the main "levels" key values.|
|Definining the meaning of a special (user defined) role membership|
|vway||no||if no vway:*=* are present||no||vway=yes||Marks a node as a vertial way|
|vway:way_tag||any_way_tag_value||per way tag||(none)||vway:highway=footway
|Defines tags for the vertical way|
Simple outside lifts and ladders
|No real life ladder found yet||type=level_map
|(empty)||vway:highway=steps||A simple ladder from a beach to a cliff top|
|An elevator from the street to a pedestrian zone, with a parking level in between. The pushbuttons are labelled 0, 1 and 2. The lift itself is a node here. The empty relation membership role is sufficient, because it stops at all levels. The same goes for the elevator entrance way. The other footways are the one on both parking levels and link the pedestrian zone. The street level ways don't need to be relation members, because they are connected in the OSM database, which connects them to the main instance by default. A service highway inside the parking lot is part of the relation as well. When the parking internal highways are known, they can be added to the relation.|
A tunnel with lifts and complex stairs
|Tunnel not visible; use link below
|Motor Vehicle Lift|
Buildings using a single level map
|Theoretical example; not actually mapped||type=level_map
|Trivial four storey building in the US, with two footways on all levels and an elevator inside. Usually, there is no need to add the outline to the relation. The outline is technically connected to the lowest level if a junction node exists (because the main instances are at that level here) and may have an own height tag that has no relevance to the relation.|
|Theoretical example; not actually mapped||type=level_map
|The same building in the UK, plus a footway coming in from outside at ground level and some toilets in the top floor|
|Theoretical example; not actually mapped||type=level_map
|The same building with a basement and three staircases. Only one of them (using the predefined "link_up" role) includes the basement, the other two are customer stairs.|
|ways on all levels
ways on Emb level
ways on Strand level
|Somerset House in London as an example where a good footway shortcut through the building needs multiple instances of a stairway|
|The Bing aerial photos suggest that Paderborn university building E seems not to be that simple and can't be mapped without a survey. It is not 3D mapped for now.||type=level_map
notes=n br edge
notes=s br edge
|A bridge shaped 3D building from User:Jongleur/MultiLevel, here with a (multipolygon) outline, tagged |
|Theoretical example; not actually mapped||type=level_map
notes=n br edge
notes=s br edge
|The same building as before, but with sloped legs, so it is more A shaped. No vways are needed here, because the slopes are not vertical and can be mapped as normal ways. Their way direction is from the ground to the bridge floor, the ends are mapped to levels as usual. The corners still need the vways.
Having more levels, archs and other more complex outlines can be modelled.
Interconnecting Level Maps
|Rel 1 Tags||Rel 1 Roles||Mem
|Main Element Tags||Rel 2 Roles||Rel 2 Tags||Description|
|Four storey building in the US, with two footways on all levels, a US elevator and another elevator with different button labels inside. While most parts are member the main level map , the lift with the special buttons is part of an own one. As the special lift node is instantiated four times and the connected one of the footways is also instantiated four times, all instances will be interconnected properly, even without adding the lift to the main level map.|
|Two buildings with different levels, linked with a two-floor bridge over a public street. As there are too many instances on the right side, there must be either stubs on the right side (which aren't there) or the footbridge must be added to both level maps (done here).|
2D graphical renderers remain unchanged.
3D renderers would have to support level maps and vertical ways. Vertical ways in particular as part of multipolygons.
- site relation proposal
- level relation proposal, might be replaced by this proposal
- Proposed_features/lifts, can be completed with pushbutton labels, exits, etc.
- Multipolygon, adding vway members and the 3d_inner role
see talk page
keywords: multilevel, multi-level, floors, vertical