Offering effective directions for pedestrians, cyclists or drivers is much more than simply computing the most direct connection in the road network. The open source routing engine Project OSRM powering our upcoming Directions API implements an enhanced and detailed graph model that captures many features beyond the basic topology. With OSRM, you not only get the shortest or fastest route, but one that takes into account turn restrictions and cost like waiting at traffic lights, braking and accelerating at sharp turns, or steep hills for bicycle riders.

An OSRM route respecting turn restrictions using the OSRM graph model.

A graph is a mathematical tool for representing entities and the connections between them. In a simple graph model of a road network, the entities are intersections and the roads between them form the connections. Excess edges are added to model the curvature of the road, i.e. its geometry. The so-called weight of an edge denotes the cost to traverse it in the chosen mode of transport, for instance travel time for car routing, distance for walking directions, or a combination of time and energy-consumption for electric vehicles.

One of the basic algorithms for routing is Dijkstra’s Algorithm, which solves the problem of finding a shortest path, i. e. a path of minimum weight. In essence, it works like this: to route from A to B, start from a source A, and in each iteration, find and settle the nearest unsettled intersection. Settling means assigning a definitive distance. And this is the closest intersection to any previously settled ones which is still not settled itself Intersections adjacent to settled ones are assigned a tentative distance that may decrease if a lower distance — a better path — is found during the search. In a sense, the algorithm searches radially around the source until it finds the destination.

This looks like a decent way to find a path from A to B, but at a closer look it has major short-comings. First, it does not account for turn restrictions, a common occurrence in the road network. Even worse, this shortcoming is by design. Let’s look at a real-world example and its graph representation:

intraversible p-loop

A typical routing scenario navigating a turn restriction.

Assume we are trying to find a path from a to b. The search settles nodes a and subsequently f. The link to b is not explored as it is forbidden, and the search continues on the loop c, d, e. And then it is stopped, because node f is already settled previously with a lower weight. The bypass road is never found as a viable path. And if you allow the search to revisit the intersection after it is settled, you sacrifice efficiency and therefore practicality.

Our Detailed Model

The takeaway is that the simple model does not guarantee path finding when turn restrictions are involved. To solve this, OSRM transforms the road network graph. Instead of modeling intersections and the roads connecting them, it models roads and turns from one to the other. This is called the edge-expanded model. In the edge-expanded model we think of links between street when it is possible to turn from one street to other. In other words, roads are now our entities of interest and turns are the connections that we would like to model. Take a look at the following illustration of the edge expansion:

edge-expanded graph

Edge expanded model — OSRM models roads and actually possible turns rather than naively modeling the road network.

For every edge we add a node representing each direction of travel. The grey edges in the picture now reflect turning from one road to the next. The weight of each (expanded) edge is the cost of its first (original) edge plus the cost of the turn. Now, when going from edge a to b, we simply have to traverse the loop and so find the bypass road.

Obviously, we are adding much more detail into graph, which does increase the memory requirements of a factor of 3-4. After careful optimization the data set for planet-wide car routing consumes roughly 32 GB of RAM.

The Expressive Power of the Model

The detailed edge expanded model is obviously useful for car routing, but is it necessary for bike routes, which have many fewer turn restrictions? It turns out that the model has some features that make it useful for a variety of travel modes. Let’s look at two illustrative examples.

First, when traveling on a bike it makes sense to minimize the number of turns on a route. In urban areas with gridded streets there may be several equally long routes, but the best one would prefer long straightaways to stop-and-go turns, especially where a turn would cross traffic. Second, the angle with which you turn from one road to the other is important. The steeper the angle, the more you need to decelerate and accelerate again.

Second, look at this example of a route optimized for scooters with minimal number of turns and evading streets with an upper speed limit of 40 mph:

minimized number of turns

Optimized route for scooters through San Francisco avoiding turns and high speed traffic.

Turn costs are a factor for scooters, trucks, and bikes as well as cars. By explicitly modeling each turn, OSRM is able to account for the cost associated with each turn. For instance, how hard is the deceleration at a sharp turn, or how long is the average wait at an intersection? Turn angles, stop signs, traffic signals, and other factors are all taken into account.

Future Developments

We are gearing up for what’s going to be a set of exciting new and powerful features. One of them is enhanced turn restrictions, like Michigan Lefts that not only forbid traveling over a certain junction, but over multiple ways. See the following example from the OpenStreetMap Wiki.

complex turn restriction

Example of a complex intersection not allowing for U-turns.

Finally, we believe that no single routing profile will fit every use case, and that people have diverse and subjective preferences that should be configurable at query time. We are working on delivering highly configurable routing profiles, and our first results indicate that it is possible to cut down preprocessing times and memory requirements even further. Stay tuned!