use of com.graphhopper.routing.util.FlagEncoder in project graphhopper by graphhopper.
the class DefaultWeightingFactory method createWeighting.
@Override
public Weighting createWeighting(Profile profile, PMap requestHints, boolean disableTurnCosts) {
// Merge profile hints with request hints, the request hints take precedence.
// Note that so far we do not check if overwriting the profile hints actually works with the preparation
// for LM/CH. Later we should also limit the number of parameters that can be used to modify the profile.
// todo: since we are not dealing with block_area here yet we cannot really apply any merging rules
// for it, see discussion here: https://github.com/graphhopper/graphhopper/pull/1958#discussion_r395462901
PMap hints = new PMap();
hints.putAll(profile.getHints());
hints.putAll(requestHints);
FlagEncoder encoder = encodingManager.getEncoder(profile.getVehicle());
TurnCostProvider turnCostProvider;
if (profile.isTurnCosts() && !disableTurnCosts) {
if (!encoder.supportsTurnCosts())
throw new IllegalArgumentException("Encoder " + encoder + " does not support turn costs");
int uTurnCosts = hints.getInt(Parameters.Routing.U_TURN_COSTS, INFINITE_U_TURN_COSTS);
turnCostProvider = new DefaultTurnCostProvider(encoder, ghStorage.getTurnCostStorage(), uTurnCosts);
} else {
turnCostProvider = NO_TURN_COST_PROVIDER;
}
String weightingStr = toLowerCase(profile.getWeighting());
if (weightingStr.isEmpty())
throw new IllegalArgumentException("You have to specify a weighting");
Weighting weighting = null;
if (CustomWeighting.NAME.equalsIgnoreCase(weightingStr)) {
if (!(profile instanceof CustomProfile))
throw new IllegalArgumentException("custom weighting requires a CustomProfile but was profile=" + profile.getName());
CustomModel queryCustomModel = requestHints.getObject(CustomModel.KEY, null);
CustomProfile customProfile = (CustomProfile) profile;
if (queryCustomModel != null)
queryCustomModel.checkLMConstraints(customProfile.getCustomModel());
queryCustomModel = CustomModel.merge(customProfile.getCustomModel(), queryCustomModel);
weighting = CustomModelParser.createWeighting(encoder, encodingManager, turnCostProvider, queryCustomModel);
} else if ("shortest".equalsIgnoreCase(weightingStr)) {
weighting = new ShortestWeighting(encoder, turnCostProvider);
} else if ("fastest".equalsIgnoreCase(weightingStr)) {
if (encoder.supports(PriorityWeighting.class))
weighting = new PriorityWeighting(encoder, hints, turnCostProvider);
else
weighting = new FastestWeighting(encoder, hints, turnCostProvider);
} else if ("curvature".equalsIgnoreCase(weightingStr)) {
if (encoder.supports(CurvatureWeighting.class))
weighting = new CurvatureWeighting(encoder, hints, turnCostProvider);
} else if ("short_fastest".equalsIgnoreCase(weightingStr)) {
weighting = new ShortFastestWeighting(encoder, hints, turnCostProvider);
}
if (weighting == null)
throw new IllegalArgumentException("Weighting '" + weightingStr + "' not supported");
return weighting;
}
use of com.graphhopper.routing.util.FlagEncoder in project graphhopper by graphhopper.
the class CHPreparationGraph method buildTurnCostFunctionFromTurnCostStorage.
/**
* Builds a turn cost function for a given graph('s turn cost storage) and a weighting.
* The trivial implementation would be simply returning {@link Weighting#calcTurnWeight}. However, it turned out
* that reading all turn costs for the current encoder and then storing them in separate arrays upfront speeds up
* edge-based CH preparation by about 25%. See #2084
*/
public static TurnCostFunction buildTurnCostFunctionFromTurnCostStorage(Graph graph, Weighting weighting) {
FlagEncoder encoder = weighting.getFlagEncoder();
String key = TurnCost.key(encoder.toString());
if (!encoder.hasEncodedValue(key))
return (inEdge, viaNode, outEdge) -> 0;
DecimalEncodedValue turnCostEnc = encoder.getDecimalEncodedValue(key);
TurnCostStorage turnCostStorage = graph.getTurnCostStorage();
// we maintain a list of inEdge/outEdge/turn-cost triples (we use two arrays for this) that is sorted by nodes
LongArrayList turnCostEdgePairs = new LongArrayList();
DoubleArrayList turnCosts = new DoubleArrayList();
// for each node we store the index of the first turn cost entry/triple in the list
final int[] turnCostNodes = new int[graph.getNodes() + 1];
TurnCostStorage.TurnRelationIterator tcIter = turnCostStorage.getAllTurnRelations();
int lastNode = -1;
while (tcIter.next()) {
int viaNode = tcIter.getViaNode();
if (viaNode < lastNode)
throw new IllegalStateException();
long edgePair = BitUtil.LITTLE.combineIntsToLong(tcIter.getFromEdge(), tcIter.getToEdge());
// note that as long as we only use OSM turn restrictions all the turn costs are infinite anyway
double turnCost = tcIter.getCost(turnCostEnc);
int index = turnCostEdgePairs.size();
turnCostEdgePairs.add(edgePair);
turnCosts.add(turnCost);
if (viaNode != lastNode) {
for (int i = lastNode + 1; i <= viaNode; i++) {
turnCostNodes[i] = index;
}
}
lastNode = viaNode;
}
for (int i = lastNode + 1; i <= turnCostNodes.length - 1; i++) {
turnCostNodes[i] = turnCostEdgePairs.size();
}
turnCostNodes[turnCostNodes.length - 1] = turnCostEdgePairs.size();
// currently the u-turn costs are the same for all junctions, so for now we just get them for one of them
double uTurnCosts = weighting.calcTurnWeight(1, 0, 1);
return (inEdge, viaNode, outEdge) -> {
if (!EdgeIterator.Edge.isValid(inEdge) || !EdgeIterator.Edge.isValid(outEdge))
return 0;
else if (inEdge == outEdge)
return uTurnCosts;
// traverse all turn cost entries we have for this viaNode and return the turn costs if we find a match
for (int i = turnCostNodes[viaNode]; i < turnCostNodes[viaNode + 1]; i++) {
long l = turnCostEdgePairs.get(i);
if (inEdge == BitUtil.LITTLE.getIntLow(l) && outEdge == BitUtil.LITTLE.getIntHigh(l))
return turnCosts.get(i);
}
return 0;
};
}
use of com.graphhopper.routing.util.FlagEncoder in project graphhopper by graphhopper.
the class DepthFirstSearchTest method testDFS2.
@Test
public void testDFS2() {
DepthFirstSearch dfs = new DepthFirstSearch() {
@Override
protected GHBitSet createBitSet() {
return new GHBitSetImpl();
}
@Override
public boolean goFurther(int v) {
counter++;
assertTrue(!set.contains(v), "v " + v + " is already contained in set. iteration:" + counter);
set.add(v);
list.add(v);
return super.goFurther(v);
}
};
EncodingManager em = EncodingManager.create("car");
FlagEncoder encoder = em.getEncoder("car");
Graph g = new GraphBuilder(em).create();
GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 2).setDistance(1));
GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 4).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 3).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(2, 3).setDistance(1));
GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 3).setDistance(1));
dfs.start(g.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())), 1);
assertTrue(counter > 0);
assertEquals(list.toString(), "[1, 2, 3, 4]");
}
use of com.graphhopper.routing.util.FlagEncoder in project graphhopper by graphhopper.
the class DepthFirstSearchTest method testDFS1.
@Test
public void testDFS1() {
DepthFirstSearch dfs = new DepthFirstSearch() {
@Override
protected GHBitSet createBitSet() {
return new GHBitSetImpl();
}
@Override
public boolean goFurther(int v) {
counter++;
assertTrue(!set.contains(v), "v " + v + " is already contained in set. iteration:" + counter);
set.add(v);
list.add(v);
return super.goFurther(v);
}
};
EncodingManager em = EncodingManager.create("car");
FlagEncoder encoder = em.getEncoder("car");
Graph g = new GraphBuilder(em).create();
GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 2).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 5).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(1, 4).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(2, 3).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(3, 4).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(5, 6).setDistance(1));
GHUtility.setSpeed(60, true, false, encoder, g.edge(6, 4).setDistance(1));
dfs.start(g.createEdgeExplorer(AccessFilter.outEdges(encoder.getAccessEnc())), 1);
assertTrue(counter > 0);
assertEquals(list.toString(), "[1, 2, 3, 4, 5, 6]");
}
use of com.graphhopper.routing.util.FlagEncoder in project graphhopper by graphhopper.
the class BreadthFirstSearchTest method testBFS.
@Test
public void testBFS() {
BreadthFirstSearch bfs = new BreadthFirstSearch() {
@Override
protected GHBitSet createBitSet() {
return new GHTBitSet();
}
@Override
public boolean goFurther(int v) {
counter++;
assertFalse(set.contains(v), "v " + v + " is already contained in set. iteration:" + counter);
set.add(v);
list.add(v);
return super.goFurther(v);
}
};
FlagEncoder encoder = new CarFlagEncoder();
Graph g = new GraphBuilder(EncodingManager.create(encoder)).create();
GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 1).setDistance(85));
GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 2).setDistance(217));
GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 3).setDistance(173));
GHUtility.setSpeed(60, true, true, encoder, g.edge(0, 5).setDistance(173));
GHUtility.setSpeed(60, true, true, encoder, g.edge(1, 6).setDistance(75));
GHUtility.setSpeed(60, true, true, encoder, g.edge(2, 7).setDistance(51));
GHUtility.setSpeed(60, true, true, encoder, g.edge(3, 8).setDistance(23));
GHUtility.setSpeed(60, true, true, encoder, g.edge(4, 8).setDistance(793));
GHUtility.setSpeed(60, true, true, encoder, g.edge(8, 10).setDistance(343));
GHUtility.setSpeed(60, true, true, encoder, g.edge(6, 9).setDistance(72));
GHUtility.setSpeed(60, true, true, encoder, g.edge(9, 10).setDistance(8));
GHUtility.setSpeed(60, true, true, encoder, g.edge(5, 10).setDistance(1));
bfs.start(g.createEdgeExplorer(), 0);
assertTrue(counter > 0);
assertEquals(g.getNodes(), counter);
assertEquals("[0, 5, 3, 2, 1, 10, 8, 7, 6, 9, 4]", list.toString());
}
Aggregations