use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class ViaRoutingTemplate method calcPaths.
@Override
public List<Path> calcPaths(QueryGraph queryGraph, RoutingAlgorithmFactory algoFactory, AlgorithmOptions algoOpts) {
long visitedNodesSum = 0L;
boolean viaTurnPenalty = ghRequest.getHints().getBool(Routing.PASS_THROUGH, false);
int pointCounts = ghRequest.getPoints().size();
pathList = new ArrayList<>(pointCounts - 1);
QueryResult fromQResult = queryResults.get(0);
StopWatch sw;
for (int placeIndex = 1; placeIndex < pointCounts; placeIndex++) {
if (placeIndex == 1) {
// enforce start direction
queryGraph.enforceHeading(fromQResult.getClosestNode(), ghRequest.getFavoredHeading(0), false);
} else if (viaTurnPenalty) {
// enforce straight start after via stop
Path prevRoute = pathList.get(placeIndex - 2);
if (prevRoute.getEdgeCount() > 0) {
EdgeIteratorState incomingVirtualEdge = prevRoute.getFinalEdge();
queryGraph.unfavorVirtualEdgePair(fromQResult.getClosestNode(), incomingVirtualEdge.getEdge());
}
}
QueryResult toQResult = queryResults.get(placeIndex);
// enforce end direction
queryGraph.enforceHeading(toQResult.getClosestNode(), ghRequest.getFavoredHeading(placeIndex), true);
sw = new StopWatch().start();
RoutingAlgorithm algo = algoFactory.createAlgo(queryGraph, algoOpts);
String debug = ", algoInit:" + sw.stop().getSeconds() + "s";
sw = new StopWatch().start();
List<Path> tmpPathList = algo.calcPaths(fromQResult.getClosestNode(), toQResult.getClosestNode());
debug += ", " + algo.getName() + "-routing:" + sw.stop().getSeconds() + "s";
if (tmpPathList.isEmpty())
throw new IllegalStateException("At least one path has to be returned for " + fromQResult + " -> " + toQResult);
int idx = 0;
for (Path path : tmpPathList) {
if (path.getTime() < 0)
throw new RuntimeException("Time was negative " + path.getTime() + " for index " + idx + ". Please report as bug and include:" + ghRequest);
pathList.add(path);
debug += ", " + path.getDebugInfo();
idx++;
}
altResponse.addDebugInfo(debug);
// reset all direction enforcements in queryGraph to avoid influencing next path
queryGraph.clearUnfavoredStatus();
if (algo.getVisitedNodes() >= algoOpts.getMaxVisitedNodes())
throw new IllegalArgumentException("No path found due to maximum nodes exceeded " + algoOpts.getMaxVisitedNodes());
visitedNodesSum += algo.getVisitedNodes();
fromQResult = toQResult;
}
ghResponse.getHints().put("visited_nodes.sum", visitedNodesSum);
ghResponse.getHints().put("visited_nodes.average", (float) visitedNodesSum / (pointCounts - 1));
return pathList;
}
use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class OSMShapeFileReader method addEdge.
private void addEdge(int fromTower, int toTower, SimpleFeature road, double distance, GHPoint estmCentre, PointList pillarNodes) {
EdgeIteratorState edge = graph.edge(fromTower, toTower);
// read the OSM id, should never be null
long id = getOSMId(road);
// Make a temporary ReaderWay object with the properties we need so we
// can use the enocding manager
// We (hopefully don't need the node structure on here as we're only
// calling the flag
// encoders, which don't use this...
ReaderWay way = new ReaderWay(id);
way.setTag("estimated_distance", distance);
way.setTag("estimated_center", estmCentre);
// read the highway type
Object type = road.getAttribute("fclass");
if (type != null) {
way.setTag("highway", type.toString());
}
// read maxspeed filtering for 0 which for Geofabrik shapefiles appears
// to correspond to no tag
Object maxSpeed = road.getAttribute("maxspeed");
if (maxSpeed != null && !maxSpeed.toString().trim().equals("0")) {
way.setTag("maxspeed", maxSpeed.toString());
}
for (String tag : DIRECT_COPY_TAGS) {
Object val = road.getAttribute(tag);
if (val != null) {
way.setTag(tag, val.toString());
}
}
// read oneway
Object oneway = road.getAttribute("oneway");
if (oneway != null) {
// Geofabrik is using an odd convention for oneway field in
// shapefile.
// We map back to the standard convention so that tag can be dealt
// with correctly by the flag encoder.
String val = toLowerCase(oneway.toString().trim());
if (val.equals("b")) {
// both ways
val = "no";
} else if (val.equals("t")) {
// one way against the direction of digitisation
val = "-1";
} else if (val.equals("f")) {
// one way Forward in the direction of digitisation
val = "yes";
} else {
throw new RuntimeException("Unrecognised value of oneway field \"" + val + "\" found in road with OSM id " + id);
}
way.setTag("oneway", val);
}
// Process the flags using the encoders
long includeWay = encodingManager.acceptWay(way);
if (includeWay == 0) {
return;
}
// TODO we're not using the relation flags
long relationFlags = 0;
long wayFlags = encodingManager.handleWayTags(way, includeWay, relationFlags);
if (wayFlags == 0)
return;
edge.setDistance(distance);
edge.setFlags(wayFlags);
edge.setWayGeometry(pillarNodes);
if (edgeAddedListeners.size() > 0) {
// listeners
for (EdgeAddedListener l : edgeAddedListeners) {
l.edgeAdded(way, edge);
}
}
}
use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class NodeContractorTest method testShortcutMergeBug.
@Test
public void testShortcutMergeBug() {
// We refer to this real world situation http://www.openstreetmap.org/#map=19/52.71205/-1.77326
// assume the following graph:
//
// ---1---->----2-----3
// \--------/
//
// where there are two roads from 1 to 2 and the directed road has a smaller weight
// leading to two shortcuts sc1 (unidir) and sc2 (bidir) where the second should NOT be rejected due to the larger weight
final EdgeIteratorState edge1to2bidirected = graph.edge(1, 2, 1, true);
final EdgeIteratorState edge1to2directed = graph.edge(1, 2, 1, false);
final EdgeIteratorState edge2to3 = graph.edge(2, 3, 1, true);
graph.freeze();
setMaxLevelOnAllNodes();
NodeContractor nodeContractor = createNodeContractor();
nodeContractor.contractNode(2);
checkShortcuts(expectedShortcut(1, 3, edge2to3, edge1to2bidirected, false, true), expectedShortcut(1, 3, edge1to2directed, edge2to3, true, false));
}
use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class NodeContractorTest method testContractNode_directed_shortcutRequired_reverse.
@Test
public void testContractNode_directed_shortcutRequired_reverse() {
// 0 <-- 1 <-- 2
final EdgeIteratorState edge1 = graph.edge(2, 1, 1, false);
final EdgeIteratorState edge2 = graph.edge(1, 0, 2, false);
graph.freeze();
setMaxLevelOnAllNodes();
createNodeContractor().contractNode(1);
checkShortcuts(expectedShortcut(0, 2, edge1, edge2, false, true));
}
use of com.graphhopper.util.EdgeIteratorState in project graphhopper by graphhopper.
the class NodeContractorTest method testContractNode_directed_shortcutRequired.
@Test
public void testContractNode_directed_shortcutRequired() {
// 0 --> 1 --> 2
final EdgeIteratorState edge1 = graph.edge(0, 1, 1, false);
final EdgeIteratorState edge2 = graph.edge(1, 2, 2, false);
graph.freeze();
setMaxLevelOnAllNodes();
createNodeContractor().contractNode(1);
checkShortcuts(expectedShortcut(0, 2, edge1, edge2, true, false));
}
Aggregations