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

Association of all provided GPXEntry to the corresponding EdgeMatch #64

Open Vannav opened 8 years ago

Vannav commented 8 years ago

Discussion: https://discuss.graphhopper.com/t/map-matchresult-to-gpxentry/977

The plan was that all GPXEntries which we used for matching should be associated to EdgeMatch

This doesn't work since the rework of the matching algorithm in doWork(List<GPXEntry> gpxList) from the pull-request https://github.com/graphhopper/map-matching/pull/49

The main reason for this is the filtering of GPXEntries by a distance threshold distance(previousGPX, currentGPX) > 2 * measurementErrorSigma which are never considered again in the the following resolvation of MostLikelySequence to EdgeMatch

GPXEntries are disregarded to avoid too many (superfluous) calculations.

kodonnell commented 8 years ago

The plan was that all GPXEntries which we used for matching should be associated to EdgeMatch

I believe this is (technically) happening - the points not used for matching are not included. @karussel is the intention that all GPXEntries (even those that are not used for matching) be associated with an edges?

@Vannav, the reason for the filtering you referred to is directly from the published algorithm - e.g. if the GPS accuracy is 10m, but you've recorded points only one meter apart in your GPX entries, then it's assumed OK to ignore most of them as they don't provide much additional information (but do slow down the process a lot), and (I think) can cause problems (e.g. if you're sitting stationary at the lights, it may looks like you're moving back and forward - due to GPS measurements fluctuating - etc.)

karussell commented 8 years ago

@Vannav can you elaborate why you 'need the internalEdgeId for every GPXEntry I have inputed'?

@karussel is the intention that all GPXEntries (even those that are not used for matching) be associated with an edges?

We should make this somehow happening to make post processing easier, maybe doing the matching first with only a few candidates and then doing an 'association step' for all GPXEntries in the range.

kodonnell commented 8 years ago

... maybe doing the matching first with only a few candidates and then doing an 'association step' for all GPXEntries in the range.

Agreed. Shouldn't be too hard ...

Vannav commented 8 years ago

Hi @karussell and @kodonnell

my main goal is to associate every gps point inputed with the matched way segments in OSM data for other tracking purposes.

With the internalEdgeId I can map them with this extension to osm ways.

My current approach is to convert the resulted polyline to a osm way segment by querying for osm nodes which are epsilon-near the nodes of the polyline.

Greetings

karussell commented 7 years ago

This is kind of duplicate of #23

nikolauskrismer commented 7 years ago

OK... I had a similar issue that might be solved. Isn't just taking the edgeMatches and computing distances to every input point the correct solution?

Something like (untested code):

// ... creation of MapMatching class (variable mapMatching)
// ... the array gpxEntries contains the source points from the gps file (as GPXEntry objects)

final Map<Integer, EdgeMatch> mMatch = new HashMap<>();
final Map<Integer, PointList> mPoints = new HashMap<>();

final MatchResult mr = mapMatching.doWork(gpxEntries);
final List<EdgeMatch> matches = mr.getEdgeMatches();

for (final EdgeMatch match : matches) {
    final EdgeIteratorState s = match.getEdgeState();
    final int eId = s.getEdge();
    mMatch.put(eId, match);
    mPoints.put(eId, s.fetchWayGeometry(1));
}

final EdgeMatch[] result = new EdgeMatch[gpxEntries.length];
for (int i = 0; i < gpxEntries.length - 1; ++i) {
    final GPXEntry gpx = gpxEntries[i];

    double minDistance = Integer.MAX_VALUE;
    int minEdgeId = -1;
    final Set<Entry<Integer, PointList>> s = mPoints.entrySet();
    for (final Entry<Integer, PointList> e : s) {
        final PointList points = e.getValue();
        for (final GHPoint3D p : points) {
            final double d = Math.abs(distCalc.calcDist(gpx.getLat(), gpx.getLon(), p.getLat(), p.getLon()));
            if (d < minDistance) {
                minDistance = d;
                minEdgeId = e.getKey();
            }
        }
    }

    if(minEdgeId >= 0) {
        result[i] = mMatch.get(minEdgeId);
    }
}

// now the result array should contain a matching point on the map matching result (matching the array indices from the source gpx entries), isn't it?

I know that this solution is not very fast, but is it what would solve this issue (or is it incorrect, to inaccurate??)?

If it is what's needed I can also send a PR :-)

kodonnell commented 7 years ago

There's a plan for this to happen in #87 - see here and below.

INRIX-Trang-Nguyen commented 6 years ago

Since the work on completing this task is delayed, is there a possibility to separate the GPX point filter threshold from the map matching logic? ie instead of measurementErrorSigma for both GPX point filtering as well as map matching algorithm, add a new parameter such as "gpsFilterDistance".

I need to snap the original GPX points but am unable to do this accurately and in a performant way. I've branched off master and made this change locally.

Thanks, Trang

jetsetjim commented 6 years ago

I've got another vote for Trang's suggestion - I've got some data with variable accuracy, so if I use a high "GPS accuracy" value, lots of good points get deleted (often too many to perform map-matching at all) and inaccurate points are kept. Then the map-matching attempts to route via the bad points, leading to a really bad fit

Cheers, Pete

karussell commented 6 years ago

Please use our forum in the first place. Issues should be specific to bugs and features.

INRIX-Trang-Nguyen commented 6 years ago

I've updated comments here: https://discuss.graphhopper.com/t/map-matchresult-to-gpxentry/977/9. Pete you can add additional comments to that thread. Cheers, Trang