Don’t hesitate to contact us:
Forum: discuss.graphhopper.com
Email: support@graphhopper.com
I often hear some misconceptions about the flexibility of GraphHopper. In this post I speak about GraphHopper core.
GraphHopper is designed to be fast and flexible. For example you can route through entire Germany in about 1 second on average without any speed-up method, I’ll call this ‘flexibility mode’. You have to keep in mind that this involves traversing millions of nodes in the road network. In this mode you have all possibilities and advantages like on-demand profiles, small base graph, support for multiple vehicles and so on. A naive implementation for OpenStreetMap data probably won’t reach this query speed, even if coded in C++. Additionally we fight with the memory waste and garbage collection in Java.
The main disadvantage for the flexibility mode is that long queries will need lots of RAM, which is also not very handy on mobile devices. So you’ll have to limit the length of the route, increase the heuristical nature of the algorithm OR which is our default mode: switch to the speed up mode which uses a special algorithm called contraction hierarchies. The speed up mode comes with disadvantes e.g. only one query profile is possible or a bigger base graph. But it dramatically reduces the necessary RAM per query and as a nice side effect makes the query 50-500 times faster, depending on the length of the route. These are the reasons that the default mode for GraphHopper is the speed up mode. (And our Directions API is provided only in this speed up mode.) With GraphHopper switching between modes is just a configuration change (chShortcuts=fastest or chShortcuts=no) and our architecture was build with this in mind and is open for new and completely different speed-up algorithms. The benefit of this simplicity is that you can play around and tune the routing of one or more vehicles with various options in the flexibility mode, and then if you need performance or want to use it on mobile devices you can switch to the speed up mode.
Recently I was asked again if I know a method, or even better a tool, which makes GPX points more align to the existing streets in OpenStreetMap. GraphHopper cannot do this out of the box but provides a toolchain which will make this digitalization easier.
Update: this is now open source and available as web API
The necessary process before an import would be Map Matching. Quoting (my own words ;)) from Wikipedia:
Map matching is the process of associating a sorted list of user or vehicle positions to the road network on a digital map. The main purposes are to track vehicles, analyze traffic flow and finding the start point of the driving directions.
Or as a picture:
I’m explaining in this blog post the simple steps which can taken to implement something like this with a very simple method. This is not an invention by me, other papers suggesting a similar technique. Also we should use some open testing data additionally to the normal unit tests. Some wordings are necessary before we go deeper:
Because:
All maps are from Lyrk and data is from OpenStreetMap contributors
In the left map you see the street parts highlighted where only the edges closest to the GPX points are selected. Whereas in the right map the most probable way was taken via a routing engine like GraphHopper.
The results for the map on the left side are easy to get, see the gist for example 1. For the map on the right side can try the following procedure explained in pseudocode here or see example 2 as gist for a more complete one:
This simple algorithm should work in the most cases and is very fast
There are two limitations of this simple algorithm:
The following improvements are possible
There are lots of other problems which you’ll encounter, that is the ugly real life with GPS signal errors, tunnels and so on. One example problem is if you are tracking e.g. a truck waiting in front of traffic lights in a one way street. You’ll see several nearly identical GPX points but as they have an error associated they won’t be identical and it could happen that they go ‘backwards’ in the one-way which will result in an extra loop if use the ‘step-by-step’ variant of the shortest path calculation: