In the recent days I’ve experimented with rendering floor plans using indoor data from OSM. The Simple Indoor Tagging schema suggests pretty lean additive tagging rules to specify the floor level of features and extends to drawing room/area shapes. Well done guys! It’s a very nice and flexible suggestion to add indoor data to OSM.
Turns out coverage of indoor data in OSM is quite limited:
- Only a few places mapped, mostly university buildings, subway stations and a few shopping centres.
- Walls are rarely drawn and room polygons touch each other.
- Doorways are not omitted when drawing walls, in other words there is no hole where doors are located.
This is expected given the difficulty to source indoor data paired with the limited editor support. And frankly, I don’t see much use in mapping indoor data (as part of OSM) except for POI floor levels.
The Simple Indoor Tagging is right in suggesting to map walls only if not already defined by room shapes. Having wall shapes in OSM would dramatically increase the number of nodes and make it more difficult than it already is to edit indoor data. Note that the spatially overlapping room shapes in the different floors are already troublesome to edit unless one uses things like JOSM’s filters extensively.
Being aware of these constraints I came up with the following process to generate walls on the fly:
- Cluster rooms, areas, walls, doors, floor level shape by floor level and spatial intersection. Basically collect what is close to each other.
- Create wireframes for the walls by collecting the outlines of the room shapes and explicitly drawn walls. This results in approximate centrelines of the walls.
- Calculate where the wall wireframe is close to door nodes, buffer (blow up) this part of the wall wireframe to gain the doorway polygons.
- Union buffered room polygons and the floor level polygon if available.
- Subtract walkable areas, add explicitly drawn walls, subtract doorways.
The process is slow as the above involves a lot of not so simple calculations. Luckily, JTS comes to the rescue and does most of the work. It’s still taking a few seconds for most buildings and annoyingly many seconds for buildings mapped in detail. However since the whole thing is just an experiment, I deemed it good enough.
Rendering of the polygons, including the complex wall polygons, was quick enough in OpenLayers to build a simple interactive map. Raw OSM data can be retrieved using Overpass API once one learned how to use its unfamiliar query language. It’s capabilities are impressive as it allows any motivated developer to make pretty specific queries and access the whole, global OSM dataset.
The remaining bit to make a map that is somewhat pleasant to look at was labelling. Sadly, OpenLayers is limited in this aspect and I found myself fiddling with quirky HTML DOM APIs trying to get text flows and label variants to work. I guess the result works reasonably well given the time spent on it.
An interactive map to play with is available on https://typescript-6ixy5d.stackblitz.io/ but you have been warned that buildings mapped in detail may hang your browser for a while.
In case you find nicely looking buildings or buildings which don’t render correctly even though they are mapped according to the Simple Indoor Tagging schema, please leave a comment.