Skip to content

Commit

Permalink
Use non-normalized transition metric and remove timeDiff check (#70)
Browse files Browse the repository at this point in the history
For GPX traces with equal timestamps, all transitions had a
probability of 1 and hence transitions were not considered during map
matching. With directed candidates the siutation got even worse
because it could happen that the Viterbi algorithm chose a candidate
with wrong direction because penalties from unfavored edges would still
result in a transition probability of 1. In this case the resulting
map matching path would take unnecessary detours.
  • Loading branch information
stefanholder committed Dec 20, 2016
1 parent c0d3323 commit cec230b
Show file tree
Hide file tree
Showing 4 changed files with 10 additions and 61 deletions.
Expand Up @@ -71,7 +71,7 @@ public class MapMatching {
private final Graph routingGraph;
private final LocationIndexMatch locationIndex;
private double measurementErrorSigma = 50.0;
private double transitionProbabilityBeta = 0.00959442;
private double transitionProbabilityBeta = 2.0;
private final int nodeCount;
private DistanceCalc distanceCalc = new DistancePlaneProjection();
private final RoutingAlgorithmFactory algoFactory;
Expand Down Expand Up @@ -474,8 +474,7 @@ private void computeTransitionProbabilities(TimeStep<GPXExtension, GPXEntry, Pat
from, to, penalizedPathDistance);

final double transitionLogProbability = probabilities
.transitionLogProbability(penalizedPathDistance, linearDistance,
timeDiff);
.transitionLogProbability(penalizedPathDistance, linearDistance);
timeStep.addTransitionLogProbability(from, to, transitionLogProbability);
} else {
logger.debug("No path found for from: {}, to: {}", from, to);
Expand Down
Expand Up @@ -89,7 +89,8 @@ private void start(CmdArgs args) {
hints(new HintsMap().put("weighting", "fastest").put("vehicle", firstEncoder.toString())).
build();
MapMatching mapMatching = new MapMatching(hopper, opts);
mapMatching.setTransitionProbabilityBeta(args.getDouble("transition_probability_beta", 0.00959442));
mapMatching.setTransitionProbabilityBeta(args.getDouble
("transition_probability_beta", 2.0));
mapMatching.setMeasurementErrorSigma(gpsAccuracy);

// do the actual matching, get the GPX entries from a file or via stream
Expand Down
Expand Up @@ -26,23 +26,11 @@ public class HmmProbabilities {
private final double sigma;
private final double beta;

/**
* Sets default values for sigma and beta.
*/
public HmmProbabilities() {
/*
* Sigma taken from Newson&Krumm.
* Beta empirically computed from the Microsoft ground truth data for shortest route
* lengths and 60 s sampling interval but also works for other sampling intervals.
*/
this(4.07, 0.00959442);
}

/**
* @param sigma standard deviation of the normal distribution [m] used for
* modeling the GPS error
* @param beta beta parameter of the exponential distribution for 1 s
* sampling interval, used for modeling transition probabilities
* @param beta beta parameter of the exponential distribution used for modeling
* transition probabilities
*/
public HmmProbabilities(double sigma, double beta) {
this.sigma = sigma;
Expand All @@ -67,33 +55,12 @@ public double emissionLogProbability(double distance) {
* consecutive map matching candidates.
* @param linearDistance Linear distance [m] between two consecutive GPS
* measurements.
* @param timeDiff time difference [s] between two consecutive GPS
* measurements.
*/
public double transitionLogProbability(double routeLength, double linearDistance,
double timeDiff) {
if (timeDiff == 0) {
return 0;
}
Double transitionMetric = normalizedTransitionMetric(routeLength, linearDistance, timeDiff);
return Distributions.logExponentialDistribution(beta, transitionMetric);
}
public double transitionLogProbability(double routeLength, double linearDistance) {
// Transition metric taken from Newson & Krumm.
Double transitionMetric = Math.abs(linearDistance - routeLength);

/**
* Returns a transition metric for the transition between two consecutive
* map matching candidates.
*
* In contrast to Newson & Krumm the absolute distance difference is divided
* by the quadratic time difference to make the beta parameter of the
* exponential distribution independent of the sampling interval.
*/
private double normalizedTransitionMetric(double routeLength, double linearDistance,
double timeDiff) {
if (timeDiff < 0.0) {
throw new IllegalStateException(
"Time difference between subsequent location measurements must be >= 0.");
}
return Math.abs(linearDistance - routeLength) / (timeDiff * timeDiff);
return Distributions.logExponentialDistribution(beta, transitionMetric);
}

}

This file was deleted.

0 comments on commit cec230b

Please sign in to comment.