The walls of the buildings¶
duckOSM can give each wall of each building a type: front, back, side, party or court. The build writes the walls to the table
main.building_faces. The fixes editor shows them in colors, and you can change the type of a
wall there (Edit OSM data).
This page tells how the build finds the type of a wall. The method is a rule of thumb: it uses only the shape of the buildings, the streets and a few OSM tags. Check its result by eye where the result is important to you.
Turn it on¶
The walls need the Rust engine (the default), a PBF source and a boundary. The config templates turn them on:
options:
building_faces: true
The sample config/sample_monaco.yaml has the option too. A build that cannot make the walls (--engine python, a clip from a parent
database, no boundary) writes a warning and makes no walls. A config file with no building_faces key makes no walls.
The step is fast: on Monaco it makes 10,909 walls of 1,262 buildings in about 0.2 s.
The five types¶
| Type | Color in the editor | The wall |
|---|---|---|
front |
green | faces a street that it can see, or has an entrance. A corner building can have more than one front |
back |
red | points away from the front and faces no near street |
side |
grey | every other wall of the outer ring |
party |
purple | is shared with another building: the two buildings have the same two nodes |
court |
cyan | is a wall of a courtyard: an inner ring of a building that is a multipolygon relation |
A building with no street near it, no entrance and no street within 150 m has no front and no back: all its walls are side or party.
What the build uses¶
- The buildings. A way with a
buildingtag (notbuilding=no) and a closed ring of three nodes or more. A multipolygon relation with abuildingtag: its member ways are joined into rings by their end nodes, and a chain that does not close is dropped. The outer rings get the same types as a way. The inner rings getcourtwalls. - The streets. The edges of the driving and walking networks of the build, but not
footway,path,steps,corridor,bridleway,cyclewayandtrack. A footpath along a street would else be the nearest "street" of a wall that faces the real street. - The entrances. The nodes with an
entrancetag, but notentrance=no,service,emergencyorexit: these are not a way in for people. - The address. The
addr:streettag of the building.
The method¶
1. The walls¶
Each segment of a ring is a wall. The key of a wall is the building and its two nodes, (building, node, node). This key does not change
when the ring gets a node in another place. face_index (the place of the wall in the ring) can change. A wall shorter than 0.1 m has no
row.
The build uses one local metric scale for the whole area (the middle of the buildings). It turns each outer ring counter-clockwise, so the normal of each wall points out of the building. An inner ring turns the other way, so the normal of a courtyard wall points into the courtyard.
2. The street of each wall¶
For each wall, the candidates are the street segments within 60 m of the middle of the wall that the wall points at. align is the
cosine of the angle between the normal of the wall and the line to the nearest point of the street; a candidate must have align more
than 0. Each candidate gets a score:
score = align / sqrt(distance + 1) × (1 + ln(length + 1)) × class weight × address
distanceis in meters from the middle of the wall.lengthis the length of the wall in meters: a long wall is more of a facade.- The class weight.
motorway,trunkandprimary1.3;secondary1.25;tertiary1.15;service0.7; every other class 1.0. A_linkhas the weight of its class. - The address. 1.8 when the name of the street is the
addr:streetof the building, else 1.
The street of the wall is the candidate with the best score that the wall can see. A wall sees a street when the line from one of
three points of the wall (at 50, 20 and 80 percent of its length) to the nearest point of the street crosses no wall of any building. Three
points let a wall see past a small building in front of its middle. When two streets have the same score, the lower edge_id wins.
3. The party walls¶
A wall is party when two rings have the same two nodes. A party wall is never a front, a back or a side.
4. The main front wall¶
The build looks for the main front wall in this order:
- A street. The wall with the best street score among the walls that are not party walls and have
alignof 0.5 or more (the street is within 60 degrees of the normal). The reason isaddresswhen its street is the street of the address, elsestreet. - An entrance. With no such wall: the first wall in the ring with an entrance node at one of its ends. An entrance in the middle of a
straight wall splits it in two walls, so both get the entrance. The reason is
entrance. - The nearest street. With no entrance either (a building behind other buildings): the wall that faces the nearest street within
150 m with
alignof 0.5 or more, with no test of the line of sight. The reason isinferred. - None. The building has no front. Its walls are
sidewith the reasonnone.
5. The runs¶
A person sees a curved facade or a facade with small steps as one wall. So the build joins walls into runs: consecutive walls of a ring whose normals differ by at most 25 degrees, and that are not party walls. The first and the last wall of a ring can be in one run. A run gets one type, and the street and the distance of its longest wall.
6. The type of each run¶
The rules run in this order. A run keeps the first type that it gets, except in rule 5.
- Fixed types. A party run is
party(reasonshared). The run of the main front wall isfront. A run with an entrance isfront(reasonentrance). -
More front runs (a corner). A run is also a front when all of these are true:
- it faces its street with
alignof 0.65 or more (about 50 degrees); - its street is at most 20 m away, and at most 8 m farther than the street of the main front;
- its street has a class weight of at least 0.6 times the weight of the main front's street: a service lane does not give a front to a building that has a primary road on the other side;
- its street is another street than the main front's street (another name; with no name, another way), or the run is on the same facade (its normal is within 25 degrees of the main front's normal).
Of these runs, the two with the best street scores are
front(reasoncorner). The others areside. A building on a corner of three streets can have three fronts. 3. Back runs. A run isback(reasonopposite) when its normal points away from the main front (the cosine of the angle between the two normals is -0.4 or less, about 114 degrees or more), and it faces no near street: itsalignis 0.1 or less, or its street is more than 25 m away. 4. Side runs. Every other run isside(reasonother;nonefor a building with no front). 5. Short runs. A run shorter than 3 m in all (a chamfer, a step) gets the type and the reason of its longer neighbour run. A fixed run (party, main front, entrance) does not change, and a party neighbour gives no type. - it faces its street with
7. Your rules¶
Last, the build applies the wall rules of the fixes file (extra.building_faces, Edit OSM data).
A rule finds its wall by the building and the two nodes, in either order.
| Column | With a rule |
|---|---|
face_type |
the type of the rule |
computed_type |
the type of the method, steps 1 to 6 |
edited |
true when the rule gives another type than the method |
door |
the kind of door of the rule (main, service, …); NULL for no door |
A rule that gives the computed type, or only a door, does not make edited true.
Why a wall has its type¶
The column type_reason tells which rule gave the type. The editor shows a note for entrance, address, inferred and none.
type_reason |
Type | The rule |
|---|---|---|
street |
front |
the main front wall: the best street that the wall can see |
address |
front |
the main front wall, and its street is the street of addr:street |
entrance |
front |
an entrance node is on the wall |
corner |
front |
a second or third front: another street at a corner, or the same facade |
inferred |
front |
no street can be seen and no entrance: the nearest street within 150 m. Check it |
opposite |
back |
it points away from the front and faces no near street |
shared |
party |
another building has the same two nodes |
other |
side |
a wall of a building that has a front |
none |
side |
the building has no front |
inner |
court |
a wall of a courtyard |
The numbers¶
The numbers of the method are named constants at the top of rust/duckosm-core/src/building_faces.rs.
| Constant | Value | Use |
|---|---|---|
MAX_STREET_M |
60 m | a street farther from the middle of a wall is not its street |
FRONT_ALIGN |
0.5 (60°) | the main front wall faces its street at least this much |
CORNER_ALIGN |
0.65 (about 50°) | a corner front faces its street at least this much |
CORNER_DIST_M, CORNER_EXTRA_M |
20 m, 8 m | a corner front is near its street, and not much farther than the main front |
CORNER_CLASS |
0.6 | a corner front's street has at least this part of the class weight of the main front's street |
FACADE_DOT, RUN_DOT |
0.906 (25°) | the same facade; the walls of one run |
MAX_EXTRA_FRONTS |
2 | the most corner fronts of one building |
MIN_RUN_M |
3 m | a shorter run takes the type of its neighbour |
BACK_DOT, BACK_ALIGN, BACK_FAR_M |
-0.4, 0.1, 25 m | a back wall points away from the front and faces no near street |
INFER_STREET_M |
150 m | the farthest street for an inferred front |
ADDRESS_BOOST |
1.8 | the street of the address scores this much more |
MIN_FACE_M |
0.1 m | a shorter wall has no row |
The result on Monaco¶
The Monaco sample (config/sample_monaco.yaml), 10,909 walls of 1,262 buildings (1,231 ways and 31 relations):
| Type | Walls | Share | By reason |
|---|---|---|---|
side |
4,632 | 42 % | other 4,602, none 30 |
front |
3,134 | 29 % | street 1,478, corner 1,136, address 320, entrance 116, inferred 84 |
back |
1,614 | 15 % | opposite 1,614 |
party |
1,130 | 10 % | shared 1,130 |
court |
399 | 4 % | inner 399 |
5 buildings have no front, and 509 buildings have no back wall. A building in a row between two streets has two fronts and no back, which is correct.
The same rows each time¶
The rows come in the order of the ways and of each ring. A tie between two streets goes to the lower edge_id. So two builds of the same
data give the same rows.
Limits¶
- No reference data tells which wall is the real front. The numbers above show a pattern, not the truth.
- The method does not know the blocks of the city. A building that sees no street can get a street across another block (
inferred). - At most two corner fronts: a building with four streets around it has at most three fronts from the streets. A wall with an entrance is a front too.
- An entrance tag on a node of the wall gives a front, also when the entrance is at the back of the building.