Skip to content
This repository has been archived by the owner on Mar 1, 2021. It is now read-only.

Penalize inner-link U-turns (builds on #83) #88

Merged
merged 5 commits into from
Dec 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
* karussell, Peter Karich, GraphHopper GmbH, initial version
* michaz, very important hidden markov improvement via hmm-lib, see #49
* rory, support milisecond gpx timestamps, see #4
* stefanholder, Stefan Holder, BMW AG, creating and integrating the hmm-lib (!), see #49, #66 and #69
* kodonnell, adding support for CH and other algorithms as per #60
* stefanholder, Stefan Holder, BMW AG, creating and integrating the hmm-lib (#49, #66, #69) and
penalizing inner-link U-turns (#70)
* kodonnell, adding support for CH and other algorithms (#60) and penalizing inner-link U-turns (#70)

For GraphHopper contributors see [here](https://github.com/graphhopper/graphhopper/blob/master/CONTRIBUTORS.md).
Binary file added map-data/issue-70.osm.gz
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ public double getMinDistance() {

double min = Double.MAX_VALUE;
for (GPXExtension gpxExt : gpxExtensions) {
if (gpxExt.queryResult.getQueryDistance() < min) {
min = gpxExt.queryResult.getQueryDistance();
if (gpxExt.getQueryResult().getQueryDistance() < min) {
min = gpxExt.getQueryResult().getQueryDistance();
}
}
return min;
Expand Down
100 changes: 86 additions & 14 deletions matching-core/src/main/java/com/graphhopper/matching/GPXExtension.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,108 @@
*/
package com.graphhopper.matching;

import com.graphhopper.routing.VirtualEdgeIteratorState;
import com.graphhopper.storage.index.QueryResult;
import com.graphhopper.util.EdgeIteratorState;
import com.graphhopper.util.GPXEntry;

/**
* During map matching this represents a map matching candidate, i.e. a potential snapped
* point of a GPX entry. After map matching, this represents the map matched point of
* an GPX entry.
* <p>
* A GPXEntry can either be at an undirected real (tower) node or at a directed virtual node.
* If this is at a directed virtual node then incoming paths from any previous GPXExtension
* should arrive through {@link #getIncomingVirtualEdge()} and outgoing paths to any following
* GPXExtension should start with {@link #getOutgoingVirtualEdge()}. This is achieved by
* penalizing other edges for routing. Note that virtual nodes are always connected to their
* adjacent nodes via 2 virtual edges (not counting reverse virtual edges).
*
* @author Peter Karich
* @author kodonnell
* @author Stefan Holder
*/
public class GPXExtension {
final GPXEntry entry;
final QueryResult queryResult;
final int gpxListIndex;
private final GPXEntry entry;
private final QueryResult queryResult;
private final boolean isDirected;
private final EdgeIteratorState incomingVirtualEdge;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because queryResult is now public final. This achieves the same as this getter with less boilerplate code.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point - I prefer this in terms of code cleanliness/development (though I'm not sure if it's good/bad practice etc.).

private final EdgeIteratorState outgoingVirtualEdge;

public GPXExtension(GPXEntry entry, QueryResult queryResult, int gpxListIndex) {
/**
* Creates an undirected candidate for a real node.
*/
public GPXExtension(GPXEntry entry, QueryResult queryResult) {
this.entry = entry;
this.queryResult = queryResult;
this.gpxListIndex = gpxListIndex;
this.isDirected = false;
this.incomingVirtualEdge = null;
this.outgoingVirtualEdge = null;
}

@Override
public String toString() {
return "entry:" + entry
+ ", query distance:" + queryResult.getQueryDistance()
+ ", gpxListIndex:" + gpxListIndex;
/**
* Creates a directed candidate for a virtual node.
*/
public GPXExtension(GPXEntry entry, QueryResult queryResult,
VirtualEdgeIteratorState incomingVirtualEdge,
VirtualEdgeIteratorState outgoingVirtualEdge) {
this.entry = entry;
this.queryResult = queryResult;
this.isDirected = true;
this.incomingVirtualEdge = incomingVirtualEdge;
this.outgoingVirtualEdge = outgoingVirtualEdge;
}

public GPXEntry getEntry() {
return entry;
}

public QueryResult getQueryResult() {
return this.queryResult;
return queryResult;
}

public GPXEntry getEntry() {
return entry;
/**
* Returns whether this GPXExtension is directed. This is true if the snapped point
* is a virtual node, otherwise the snapped node is a real (tower) node and false is returned.
*/
public boolean isDirected() {
return isDirected;
}

/**
* Returns the virtual edge that should be used by incoming paths.
*
* @throws IllegalStateException if this GPXExtension is not directed.
*/
public EdgeIteratorState getIncomingVirtualEdge() {
if (!isDirected) {
throw new IllegalStateException(
"This method may only be called for directed GPXExtensions");
}
return incomingVirtualEdge;
}

/**
* Returns the virtual edge that should be used by outgoing paths.
*
* @throws IllegalStateException if this GPXExtension is not directed.
*/
public EdgeIteratorState getOutgoingVirtualEdge() {
if (!isDirected) {
throw new IllegalStateException(
"This method may only be called for directed GPXExtensions");
}
return outgoingVirtualEdge;
}

@Override
public String toString() {
return "GPXExtension{" +
"closest node=" + queryResult.getClosestNode() +
" at " + queryResult.getSnappedPoint().getLat() + "," +
queryResult.getSnappedPoint().getLon() +
", incomingEdge=" + incomingVirtualEdge +
", outgoingEdge=" + outgoingVirtualEdge +
'}';
}
}
}
Loading