Skip to content

Commit e7aefc0

Browse files
Peterb3nn0
authored andcommitted
reintroduced TraversalMode enum
1 parent 094aee3 commit e7aefc0

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

47 files changed

+527
-382
lines changed

core/src/main/java/com/graphhopper/GraphHopper.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535
import java.io.IOException;
3636
import java.text.SimpleDateFormat;
3737
import java.util.*;
38+
import java.util.concurrent.atomic.AtomicLong;
39+
3840

3941
import org.slf4j.Logger;
4042
import org.slf4j.LoggerFactory;
@@ -65,6 +67,7 @@ public class GraphHopper implements GraphHopperAPI
6567
private boolean fullyLoaded = false;
6668
// for routing
6769
private boolean simplifyRequest = true;
70+
private TraversalMode traversalMode = TraversalMode.NODE_BASED;
6871
// for index
6972
private LocationIndex locationIndex;
7073
private int preciseIndexResolution = 300;
@@ -89,6 +92,7 @@ public class GraphHopper implements GraphHopperAPI
8992
// utils
9093
private final TranslationMap trMap = new TranslationMap().doImport();
9194
private ElevationProvider eleProvider = ElevationProvider.NOOP;
95+
private final AtomicLong visitedSum = new AtomicLong(0);
9296

9397
public GraphHopper()
9498
{
@@ -153,6 +157,15 @@ public GraphHopper setWayPointMaxDistance( double wayPointMaxDistance )
153157
return this;
154158
}
155159

160+
/**
161+
* Sets the default traversal mode used for the algorithms and preparation.
162+
*/
163+
public GraphHopper setTraversalMode( TraversalMode traversalMode )
164+
{
165+
this.traversalMode = traversalMode;
166+
return this;
167+
}
168+
156169
/**
157170
* Configures the underlying storage to be used on a well equipped server.
158171
*/
@@ -676,7 +689,7 @@ public boolean load( String graphHopperFolder )
676689

677690
if (chEnabled)
678691
graph = new LevelGraphStorage(dir, encodingManager, hasElevation());
679-
else if (encodingManager.needsTurnCostSupport())
692+
else if (encodingManager.needsTurnCostsSupport())
680693
graph = new GraphHopperStorage(dir, encodingManager, hasElevation(), new TurnCostStorage());
681694
else
682695
graph = new GraphHopperStorage(dir, encodingManager, hasElevation());
@@ -732,7 +745,7 @@ protected void initCHPrepare()
732745
{
733746
FlagEncoder encoder = encodingManager.getSingle();
734747
PrepareContractionHierarchies tmpPrepareCH = new PrepareContractionHierarchies(encoder,
735-
createWeighting(Weighting.Params.create(chWeighting), encoder), encodingManager.needsTurnCostSupport());
748+
createWeighting(Weighting.Params.create(chWeighting), encoder), traversalMode);
736749
tmpPrepareCH.setPeriodicUpdates(periodicUpdates).
737750
setLazyUpdates(lazyUpdates).
738751
setNeighborUpdates(neighborUpdates).
@@ -878,7 +891,7 @@ else if (algoStr.equals("astarbi"))
878891
} else
879892
{
880893
Weighting weighting = createWeighting(request.getHints(), encoder);
881-
prepare = NoOpAlgorithmPreparation.createAlgoPrepare(graph, algoStr, encoder, weighting, encoder.supportsTurnCosts());
894+
prepare = NoOpAlgorithmPreparation.createAlgoPrepare(graph, algoStr, encoder, weighting, traversalMode);
882895
algo = prepare.createAlgo();
883896
}
884897

@@ -891,6 +904,7 @@ else if (algoStr.equals("astarbi"))
891904

892905
paths.add(path);
893906
debug += ", " + algo.getName() + "-routing:" + sw.stop().getSeconds() + "s, " + path.getDebugInfo();
907+
visitedSum.addAndGet(algo.getVisitedNodes());
894908
fromRes = toRes;
895909
}
896910

@@ -1051,4 +1065,13 @@ protected void ensureWriteAccess()
10511065
if (!allowWrites)
10521066
throw new IllegalStateException("Writes are not allowed!");
10531067
}
1068+
1069+
/**
1070+
* Returns the current sum of the visited nodes while routing. Mainly for statistic and
1071+
* debugging purposes.
1072+
*/
1073+
public long getVisitedSum()
1074+
{
1075+
return visitedSum.get();
1076+
}
10541077
}

core/src/main/java/com/graphhopper/routing/AStar.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.PriorityQueue;
2424

2525
import com.graphhopper.routing.util.FlagEncoder;
26+
import com.graphhopper.routing.util.TraversalMode;
2627
import com.graphhopper.routing.util.Weighting;
2728
import com.graphhopper.storage.EdgeEntry;
2829
import com.graphhopper.storage.Graph;
@@ -51,9 +52,9 @@ public class AStar extends AbstractRoutingAlgorithm
5152
private double toLat;
5253
private double toLon;
5354

54-
public AStar( Graph g, FlagEncoder encoder, Weighting weighting, boolean edgeBased )
55+
public AStar( Graph g, FlagEncoder encoder, Weighting weighting, TraversalMode tMode )
5556
{
56-
super(g, encoder, weighting, edgeBased);
57+
super(g, encoder, weighting, tMode);
5758
initCollections(1000);
5859
setApproximation(true);
5960
}
@@ -85,7 +86,7 @@ public Path calcPath( int from, int to )
8586
toLon = nodeAccess.getLongitude(to);
8687
to1 = to;
8788
currEdge = createEdgeEntry(from, 0);
88-
if (!isEdgeBased())
89+
if (!traversalMode.isEdgeBased())
8990
{
9091
fromMap.put(from, currEdge);
9192
}
@@ -110,8 +111,10 @@ private Path runAlgo()
110111
continue;
111112

112113
int neighborNode = iter.getAdjNode();
113-
int iterationKey = createIdentifier(iter, false);
114+
int iterationKey = traversalMode.createIdentifier(iter, false);
114115
double alreadyVisitedWeight = weighting.calcWeight(iter, false, currEdge.edge) + currEdge.weightToCompare;
116+
if (Double.isInfinite(alreadyVisitedWeight))
117+
continue;
115118

116119
AStarEdge ase = fromMap.get(iterationKey);
117120
if (ase == null || ase.weightToCompare > alreadyVisitedWeight)

core/src/main/java/com/graphhopper/routing/AStarBidirection.java

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import com.graphhopper.routing.AStar.AStarEdge;
2626
import com.graphhopper.routing.util.FlagEncoder;
27+
import com.graphhopper.routing.util.TraversalMode;
2728
import com.graphhopper.routing.util.Weighting;
2829
import com.graphhopper.storage.Graph;
2930
import com.graphhopper.util.*;
@@ -71,9 +72,9 @@ public class AStarBidirection extends AbstractBidirAlgo
7172
private GHPoint toCoord;
7273
protected PathBidirRef bestPath;
7374

74-
public AStarBidirection( Graph graph, FlagEncoder encoder, Weighting weighting, boolean edgeBased )
75+
public AStarBidirection( Graph graph, FlagEncoder encoder, Weighting weighting, TraversalMode tMode )
7576
{
76-
super(graph, encoder, weighting, edgeBased);
77+
super(graph, encoder, weighting, tMode);
7778
int nodes = Math.max(20, graph.getNodes());
7879
initCollections(nodes);
7980

@@ -127,8 +128,8 @@ public void initFrom( int from, double dist )
127128
{
128129
currFrom = createEdgeEntry(from, dist);
129130
fromCoord = new GHPoint(nodeAccess.getLatitude(from), nodeAccess.getLongitude(from));
130-
prioQueueOpenSetFrom.add(currFrom);
131-
if (!isEdgeBased())
131+
prioQueueOpenSetFrom.add(currFrom);
132+
if (!traversalMode.isEdgeBased())
132133
{
133134
bestWeightMapFrom.put(from, currFrom);
134135
if (currTo != null)
@@ -152,7 +153,7 @@ public void initTo( int to, double dist )
152153
currTo = createEdgeEntry(to, dist);
153154
toCoord = new GHPoint(nodeAccess.getLatitude(to), nodeAccess.getLongitude(to));
154155
prioQueueOpenSetTo.add(currTo);
155-
if (!isEdgeBased())
156+
if (!traversalMode.isEdgeBased())
156157
{
157158
bestWeightMapTo.put(to, currTo);
158159
if (currFrom != null)
@@ -242,11 +243,13 @@ private void fillEdges( AStarEdge currEdge, GHPoint goal,
242243
continue;
243244

244245
int neighborNode = iter.getAdjNode();
245-
int iterationKey = createIdentifier(iter, reverse);
246+
int iterationKey = traversalMode.createIdentifier(iter, reverse);
246247
// TODO performance: check if the node is already existent in the opposite direction
247248
// then we could avoid the approximation as we already know the exact complete path!
248249
double alreadyVisitedWeight = weighting.calcWeight(iter, reverse, currEdge.edge) + currEdge.weightToCompare;
249-
250+
if (Double.isInfinite(alreadyVisitedWeight))
251+
continue;
252+
250253
AStarEdge aee = shortestWeightMap.get(iterationKey);
251254
if (aee == null || aee.weightToCompare > alreadyVisitedWeight)
252255
{
@@ -276,29 +279,37 @@ private void fillEdges( AStarEdge currEdge, GHPoint goal,
276279
}
277280

278281
// @Override -> TODO use only weight => then a simple EdgeEntry is possible
279-
public void updateBestPath( EdgeIteratorState edgeState, AStarEdge shortestEE, int currLoc )
282+
public void updateBestPath( EdgeIteratorState edgeState, AStarEdge entryCurrent, int currLoc )
280283
{
281284
AStarEdge entryOther = bestWeightMapOther.get(currLoc);
282285
if (entryOther == null)
283286
return;
284287

285288
boolean reverse = bestWeightMapFrom == bestWeightMapOther;
286289
// update μ
287-
double newWeight = shortestEE.weightToCompare + entryOther.weightToCompare;
288-
if (isEdgeBased())
290+
double newWeight = entryCurrent.weightToCompare + entryOther.weightToCompare;
291+
if (traversalMode.isEdgeBased())
289292
{
290-
if (entryOther.edge != shortestEE.edge)
293+
if (entryOther.edge != entryCurrent.edge)
291294
throw new IllegalStateException("cannot happen for edge based execution of " + getName());
292295

293296
// see DijkstraBidirectionRef
294-
shortestEE = (AStar.AStarEdge) shortestEE.parent;
295-
newWeight -= weighting.calcWeight(edgeState, reverse, EdgeIterator.NO_EDGE);
297+
if (entryOther.adjNode != entryCurrent.adjNode)
298+
{
299+
entryCurrent = (AStar.AStarEdge) entryCurrent.parent;
300+
newWeight -= weighting.calcWeight(edgeState, reverse, EdgeIterator.NO_EDGE);
301+
} else
302+
{
303+
// we detected a u-turn at meeting point, skip if not supported
304+
if (!traversalMode.hasUTurnSupport())
305+
return;
306+
}
296307
}
297308

298309
if (newWeight < bestPath.getWeight())
299310
{
300311
bestPath.setSwitchToFrom(reverse);
301-
bestPath.edgeEntry = shortestEE;
312+
bestPath.edgeEntry = entryCurrent;
302313
bestPath.edgeTo = entryOther;
303314
bestPath.setWeight(newWeight);
304315
}

core/src/main/java/com/graphhopper/routing/AbstractBidirAlgo.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.graphhopper.routing;
1919

2020
import com.graphhopper.routing.util.FlagEncoder;
21+
import com.graphhopper.routing.util.TraversalMode;
2122
import com.graphhopper.routing.util.Weighting;
2223
import com.graphhopper.storage.Graph;
2324

@@ -45,9 +46,9 @@ public abstract class AbstractBidirAlgo extends AbstractRoutingAlgorithm
4546

4647
abstract boolean fillEdgesTo();
4748

48-
public AbstractBidirAlgo( Graph graph, FlagEncoder encoder, Weighting weighting, boolean edgeBased )
49+
public AbstractBidirAlgo( Graph graph, FlagEncoder encoder, Weighting weighting, TraversalMode tMode )
4950
{
50-
super(graph, encoder, weighting, edgeBased);
51+
super(graph, encoder, weighting, tMode);
5152
}
5253

5354
@Override

core/src/main/java/com/graphhopper/routing/AbstractRoutingAlgorithm.java

Lines changed: 6 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717
*/
1818
package com.graphhopper.routing;
1919

20-
import com.graphhopper.routing.util.DefaultEdgeFilter;
21-
import com.graphhopper.routing.util.EdgeFilter;
22-
import com.graphhopper.routing.util.FlagEncoder;
23-
import com.graphhopper.routing.util.Weighting;
20+
import com.graphhopper.routing.util.*;
2421
import com.graphhopper.storage.EdgeEntry;
2522
import com.graphhopper.storage.Graph;
2623
import com.graphhopper.storage.NodeAccess;
@@ -45,47 +42,23 @@ public abstract class AbstractRoutingAlgorithm implements RoutingAlgorithm
4542
protected EdgeExplorer outEdgeExplorer;
4643
protected final Weighting weighting;
4744
protected final FlagEncoder flagEncoder;
48-
private final boolean edgeBased;
45+
protected final TraversalMode traversalMode;
4946
private boolean alreadyRun;
5047

5148
/**
5249
* @param graph specifies the graph where this algorithm will run on
5350
* @param encoder sets the used vehicle (bike, car, foot)
5451
* @param weighting set the used weight calculation (e.g. fastest, shortest).
55-
* @param edgeBased if true edges are traversed whilst considering its direction which is
56-
* required to support turn costs and restrictions
52+
* @param traversalMode how the graph is traversed e.g. if via nodes or edges.
5753
*/
58-
public AbstractRoutingAlgorithm( Graph graph, FlagEncoder encoder, Weighting weighting, boolean edgeBased )
54+
public AbstractRoutingAlgorithm( Graph graph, FlagEncoder encoder, Weighting weighting, TraversalMode traversalMode )
5955
{
6056
this.weighting = weighting;
6157
this.flagEncoder = encoder;
62-
this.edgeBased = edgeBased;
58+
this.traversalMode = traversalMode;
6359
setGraph(graph);
6460
}
6561

66-
/**
67-
* Returns the identifier to access the map of the shortest weight tree according to the
68-
* traversal mode. E.g. returning the adjacent node id in node-based behavior whilst returning
69-
* the edge id in edge-based behavior
70-
* <p>
71-
* @param iter the current {@link EdgeIterator}
72-
* @param reverse <code>true</code>, if traversal in backward direction (bidirectional path
73-
* searches)
74-
* @return the identifier to access the shortest weight tree
75-
*/
76-
protected int createIdentifier( EdgeIterator iter, boolean reverse )
77-
{
78-
if (edgeBased)
79-
return GHUtility.createEdgeKey(iter.getAdjNode(), iter.getBaseNode(), iter.getEdge(), reverse);
80-
81-
return iter.getAdjNode();
82-
}
83-
84-
protected boolean isEdgeBased()
85-
{
86-
return edgeBased;
87-
}
88-
8962
/**
9063
* Specify the graph on which this algorithm should operate. API glitch: this method overwrites
9164
* graph specified while constructing the algorithm. Only necessary if graph is a QueryGraph.
@@ -124,7 +97,7 @@ public RoutingAlgorithm setEdgeFilter( EdgeFilter additionalEdgeFilter )
12497

12598
protected boolean accept( EdgeIterator iter, int prevOrNextEdgeId )
12699
{
127-
if (!edgeBased && iter.getEdge() == prevOrNextEdgeId)
100+
if (!traversalMode.hasUTurnSupport() && iter.getEdge() == prevOrNextEdgeId)
128101
return false;
129102

130103
return additionalEdgeFilter == null || additionalEdgeFilter.accept(iter);

core/src/main/java/com/graphhopper/routing/Dijkstra.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.PriorityQueue;
2424

2525
import com.graphhopper.routing.util.FlagEncoder;
26+
import com.graphhopper.routing.util.TraversalMode;
2627
import com.graphhopper.routing.util.Weighting;
2728
import com.graphhopper.storage.EdgeEntry;
2829
import com.graphhopper.storage.Graph;
@@ -43,9 +44,9 @@ public class Dijkstra extends AbstractRoutingAlgorithm
4344
private int to = -1;
4445
private EdgeEntry currEdge;
4546

46-
public Dijkstra( Graph g, FlagEncoder encoder, Weighting weighting, boolean edgeBased )
47+
public Dijkstra( Graph g, FlagEncoder encoder, Weighting weighting, TraversalMode tMode )
4748
{
48-
super(g, encoder, weighting, edgeBased);
49+
super(g, encoder, weighting, tMode);
4950
initCollections(1000);
5051
}
5152

@@ -61,7 +62,7 @@ public Path calcPath( int from, int to )
6162
checkAlreadyRun();
6263
this.to = to;
6364
currEdge = createEdgeEntry(from, 0);
64-
if (!isEdgeBased())
65+
if (!traversalMode.isEdgeBased())
6566
{
6667
fromMap.put(from, currEdge);
6768
}
@@ -84,7 +85,7 @@ private Path runAlgo()
8485
if (!accept(iter, currEdge.edge))
8586
continue;
8687

87-
int iterationKey = createIdentifier(iter, false);
88+
int iterationKey = traversalMode.createIdentifier(iter, false);
8889
double tmpWeight = weighting.calcWeight(iter, false, currEdge.edge) + currEdge.weight;
8990
if (Double.isInfinite(tmpWeight))
9091
continue;

0 commit comments

Comments
 (0)