graphhopper / map-matching

The map matching functionality is now located in the main repository https://github.com/graphhopper/graphhopper#map-matching
https://www.graphhopper.com/open-source/
Apache License 2.0
785 stars 274 forks source link

support CH for matching #60

Closed karussell closed 7 years ago

karussell commented 8 years ago

Currently it is based on none-CH routing giving us several advantages. We should try CH and see if it is faster.

kodonnell commented 8 years ago

I've quickly hacked this, and in my (single) test case (three points separated by a few hundred kms), I go from 38s to 2.8s, which is pretty significant. (Benefits are likely to be less for frequent GPS points, I'm guessing ...)

I'm happy to try to implement CH, but first I'd be interested in hearing the following:

karussell commented 8 years ago

are the main disadvantages of CH that we lose flexibility (turn restrictions, alternative routes, etc.)?

Both mentioned points are not yet implemented with CH but are at least possible. Still 'loosing flexibility' is correct: if you want to change something 'per-request' then it is a lot harder with CH, if possible at all.

any suggestions on how to do it?

The GraphHopper.getAlgorithmFactory picks the correct algorithm and replace the new DijkstraBidirection call. Probably not much more necessary.

then optionally use cached one-to-many Dijkstra to improve speed?

For map matching we use hidden markov chain where we have several possibilities per measurement and we need all combinations of distances to estimate the transition probability and therefor we can use a faster one-to-many algorithm, but CH should speed this up already enough. Also one-to-many improvement is a lot easier applicable after #66

kodonnell commented 8 years ago

The GraphHopper.getAlgorithmFactory picks the correct algorithm and replace the new DijkstraBidirection call. Probably not much more necessary.

Hmmm, I played with that, but then it requires duplicating a lot of the logic in GraphHopper.calcPaths (setting up weights, etc.). I thought it'd be better to just use GraphHopper.calcPaths directly, but that comes with a downside: a new QueryGraph is created each time, so we lose the virtual nodes (which are required later on in the map matching). I've hacked around this by changing virtualEdgesMapKey and (reverseVirtualEdgesMapKey) to return a key based on fetchWayGeometry (so it's independent of the virtualNode IDs and still matches those in here). It works, but isn't pretty - what do you suggest?

It'd be good if we consider this part of a bigger scope to allow the user to e.g. change/configure the algorithm (if that's in scope).

karussell commented 8 years ago

I'm not sure about the problem. I think you just need to replace the call to new DijkstraBidirectionRef with the factory.createAlgo()? (Of course as I didn't try it it might not be sufficient)

kodonnell commented 8 years ago

To call createAlgo you need e.g. AlgorithmOptions. Unless there's a way to get that easily, then don't you have to do all of this?