Roof lines can be traced in order to improve rendering of buildings. This could be used in 3D applications and isometric maps. Please note that this example is just a mockup and does not exist in the OSM database in this form. But the building footprint has been exported from OSM .
- 1 Motivation
- 2 Approach
- 3 Building Relation
- 4 Use and Limitations
- 5 Tutorial on how to model roofs in JOSM
- 6 Pitfalls
- 7 Tool support
Reconstructing roof shapes from meta information and attributes can become extremely difficult. Roof type and orientation could be easily tagged but require an algorithm for guessing the position and alignment of roof ridges, edges and angles. It could work for very simple rectangular building shapes. But not for complex footprints imported from cadastre data. As an alternative, roof lines could be traced directly from imagery
Roof lines are traced as ways and nodes and connected to the building via relations. There are two types of roof lines:
The areas between eaves, edges and ridges are expected to be coplanar so that they can be easily polygonized. Some buildings have little jutties and ledges along the edge. In this case the intersection of the roof surface with the wall must be approximated so that the roof surface remains flat. Im my example the ledge in the middle of the building would be modeled by adding a flat top. Alternatively, the roof surface could continue downwards cutting away a part of the wall.
They measure the distance from ground to the roof top/ridge. What is missing is the height of the roof base. It can be either explicitly set by building:eaves:height=* or building:eaves:levels=*, or it can be calculated if other attributes are available, e.g. roof:height=* and roof:angle=*.
The Following combinations are possible:
Note that the result may be undefined if too many and conflicting attributes are present.
Using one the above tagging scheme and adding a few lines could work for the majority of small residential buildings. For more complex buildings with many ridges it is necessary to attach the exact height to the ways directly: roof:ridge=yes and building:ridge:height=*. If this attribute is present, it supersedes the attributes attached to the building. In the example on this page you can see one part on the right which is a bit lower than the main roof. Its ridge is tagged with a height value.
Roof structures must be connected to buildings using relations. Otherwise it would be difficult to detect, which ways tagged as roof lines belong to which building. The following table is based on the Relations/Proposed/Buildings proposal and on Multipolygon, which is often used for complex buildings.
|type||building||A relation that combines all node, ways, and other relations that belong to a single building.|
|Way, Node, Area or Relation||Role||Recurrence?||Discussion|
|outline||zero or more||The building footprint that is used for 2D renderings. If building parts are present, the outline member shall not be used for building the 3D model.|
|label||zero or one||This should be used to set the name of the building and to tag the whole building as a POI if desired. The idea behind this is, that this mark should tell the renderer where the name and maybe the symbol of the building should be displayed. That could be necessary if the building includes many details.
This single node could be used also to mark a building if the walls can not be drawn.
|entrance||zero or more||Entrances into the building. Big entrances could be areas, but mostly a single node is enough. They might have to be individually tagged as to what kind of entrance they are. There are existing some proposals for entrances (examples:Proposed features/entrance, Tag:railway=subway entrance), so tag it as you like.
Also entrances can be used to tag different adresses of a building. See section "Postal Address Information" above.
|contains||zero or more||This should be used for POIs inside a building. If you have detailed information of such POI (separate entrance, different address or something like that), you should better build a separate building relation for each POI and than put this relations as members in right here.|
|address||zero or more||This should be used for nodes and relations, who were only tagged with address informations. See section "Postal Address Information" above.|
|part||one or more||Building parts. These parts differ from each other in terms of height, roof-shape, colour, material, ... The part members may be closed ways tagged as building:part=yes or multipolygon relations.|
|ridge||zero or more||Ways which make up the roof ridges of a building or building part.|
|edge||zero or more||Ways which make up the roof edges of a building or building part.|
Use and Limitations
This form of roof tracing could be accomplished with current OSM editors. Some nodes may overlap with existing ways like the tip node of a gable. A very small displacement could help. In general, vertical structures and overhanging structures cannot be captured with this approach. For example, overhanging roof parts at the eaves are not possible, but this is a very small detail. Also, modeling post modern skyscapers like this one  could be difficult and 2D views in editors could become cluttered. But this one  could be possible.
Tutorial on how to model roofs in JOSM
This sections is intended to provide some guidelines on how complex roof structures can be modeled using the popular JOSM editor. Although JOSM is designed as a 2D editor, it can be used to add roof details to building footprints, but it requires a good sense of spatial imagination. JOSM provides some tools such as arranging rings to form rectangular shapes and straighten lines, which are quite useful for our task. It also allows to switch between different image sources and detects whether high quality local imagery is available, making it easy to pick the besst possible source for tracing roof lines. In the following example I use the same building as above and focus on the lower left part. The structure of this building is quite complex. It featurese a hipped roof, many dormers, ledges, some portals with figures on them, varying roof heights, round staircases etc. Most problematic is that the height of the roof base or eaves is not consistent and that the roof stretches down to lower levels at the wings. A possible solution to fix this is to split the building into several parts so that the building:eaves:height tag could be assign accordingly. However, in this example, I use vertical roof structures to model facade parts that reach higher than the specified eaves height, so that the 2D rendering remains unaffected.
Step 1: trace horizonal lines
First, trace the horizonal lines along the eaves and ridges. The outer eaves line is tagged as building and should already contain information on maximum roof height, roof type, architecture, facade and roof colors, etc. The topmost roof:ridge=yes line must contain a height value, measured from the bottom of the building (ground level). Insert an additional roof:ridge=yes line at the sharp kink between the lower and the upper part of the roof. Provide exact height values for all ridge lines (default unit is meters). Use the according JOSM tool to make these line rectangular, so that all angles are either 90 or 180 degrees.
Step 2: correct perspective distortions
All lines traced from aerial imagery are positioned incorrectly, due to the perspective distortions. At large buildings you might even see that vertical edges have different angles. This is because aerial imagery is never exactly oblique, even if it has been rectified. For the sake of simplicity, we assume that at least the proportions of structures at the same height level are already correct. In our example, we assume that the roof is axis symmetric along the outer lines. Select all lines with the same height value and move them so that all distances betweem them and to the outer ring are equlized (a'=d', b'=c', e'=h', f'=g').
Step 3: add vertical parts
The small side wing on the right side of the image has an additional full floor and the facade is higher. Thus the roof also starts at a higher level. The gap between the regular eaves and the bottom of the roof must be filled with a vertical roof part. Draw an additional line with 3 edges near the outer ring. This line represents the upper part of the vertical face. Assign the tag roof:ridge=yes to this line and add the correct height value. Then connect this line with nodes of the outer ring. Add tag roof:edge=yes to these connecting lines. Finally move each node so that the line lies exactly over the building eaves. Zoom in to get better precision.
Step 4: add connecting roof lines
Now that we have all the horizontal lines, we must connect them in order to form polygons that can be rendered by 3D software. Add connecting edges between the ridge lines and the outer rings by connecting the nodes. Tag these lines as roof:edge=yes. Straighten lines using appropriate JOSM tools if necessary. Please note that the polygons that are formed in this way must be coplanar. For 3D rendering, the polygons must be triangulated, and if their vertices do not lie exactly on a plane, then this will be visible due to the slightly different surface angles between triangles. In order to avaoid such effects, try to avoid polygons with more than 4 nodes. Also try to make ridge lines parallel to each other.
Step 5: add portal
There is a portal with a plat top at the left side of the building. First draw a ring represting the top edges and tag it as roof:ridge=yes and add the correct height value. You don't need to take care about the exact shape yet. Only the topology is important while drawing. Add the bottom edge as roof:ridge=yes and use the building eaves height as height value. Fill the vertical lateral parts by adding roof:edge=yes lines. Finally move the modes so that the top becomes rectangle and the left side is aligned with the outer ring of the building.
Step 6: move roof to final position
Now that we have finished the roof, we must move it to the final position. So far we modeled at the roof base height, but the final building footprint must be at the location where the building touches the ground. Select everything and move it where it belongs.
Correctly placing dormers can be problematic because the position where the dormer touches the roof surface cannot be seen in a horizontal projection of a 3D model. It is advisable to know the height of the dormer and to tag it explicitly, instead of relying on some functions to derive it from the roof shape. Although the curve or line at the upper part between the dormer and the roof can be traced from the imagery, it is difficult to capture the the exact position on the 3D plane that defines the roof facet on which we want to place the dormer. Either the dormer penetrates the roof or a gap occurs. While the first case is unproblematic for 3D rendering, gaps should be avoided. However, they can only be detected in the final 3D rendering, because there is no tool for placing points on an inclined surface as of yet. In order to fix gaps, move the nodes at the upper part slightly inwards.
The following tools support this tagging guideline: