14.06.2019 | Michael Reichert
We recently rewrote the OSM Inspector Routing View. The old views were used quite a lot by mappers to find potential routing errors. Unfortunately, they made use of PostGIS to find nearby, unconnected roads which meant having to import the whole road network into a PostGIS database every day. To make matters worse, the island and duplicate segment detection was implemented using OSRM which also has relatively heavy system requirements, especially if you do not limit yourself to automobile routing. This made us have a closer look at using GraphHopper to generate the routing view.
The new backend code was implemented from scratch and does not aim to be a one-by-one reimplementation. It uses GraphHopper to read the planet, build up the graph, analyse it and find nearby edges. Our code uses a forked version of GraphHopper 0.12 with the following changes:
OSMReader
class. Our changes allow us to build additional indexes and populate maps mapping from internal edge or node IDs to OSM object IDs.PrepareRoutingSubnetworks
class which removes islands from the graph is not extensible but we need to write the edges being removed to a GeoJSON file.In addition to forking, we implemented a new routing profile (“flag encoder” in GraphHopper speak) accepting any road and ignoring access restrictions. It is used to find duplicated edges, unconnected roads, and islands.
The backend code is available on GitHub.
The new routing view has the following groups of layers:
These layers show edges which exist twice in the graph. The blue ones are almost always real errors and should be fixed by comparing the tags and history of both ways. The purple ones are locations where two edges have equal geometry and at least one of them is an area. Opinions whether areas should share nodes with neighbouring roads are diverse among the OSM community. Therefore, these cases are shown in a separate layer at high zoom levels only.
The results of the duplicated edges layer (not involving areas) are similar to those of OSRM. Minor differences are possible where OSRM excluded a road due to access restrictions while our new implementation includes it.
The use of GraphHopper allows us to identify routing islands for multiple types of vehicles in one go. The OSM Inspector now provides islands for cars and bicycles using slightly modified version of the original profiles of GraphHopper (we use fewer bits to store the speed because island detection does not take travel times or distances into account). In addition, a layer with islands inaccessible to any vehicle is provided. This layer contains fewer entries in total but those contained are more serious because they are not caused by correct or incorrect access restriction tagging in OSM.
Most development time was spent finding a set of unconnected nodes layers with a proper separation of very likely, likely, potential errors and likely false positives. We are grateful to the folks on the German OSM forum who pointed out many bugs and too high rates of false positives.
Nodes where a single edge ends but with other edges within 15 meters are assigned to one of 6 priority classes. A distance below 2 meters makes a unconnected node appear in the top layer. The further composition of the layers depends on the road class, the distance, and access restrictions. The priority of unconnected nodes involving private access roads is reduced by 1. Service roads and footpaths get low default levels. In addition, the following rules avoid too many false positives:
noexit=yes
and entrance=*
make unconnected nodes disappear.The “snap points” layer shows the snap points of open ends helping to understand the situation.
Not all entries in the unconnected nodes layers are mistakes. Often, adding a linear barrier is helpful. The more blueish a point is, the less likely it is a mistake at all. Don’t feel forced to add noexit=yes
to every point the OSM Inspector complains about. You are not mapping for the validator 😉