@Override protected GraphHopperStorage newGHStorage(Directory dir, boolean is3D) { turnCostStorage = new TurnCostExtension(); return new GraphHopperStorage(dir, encodingManager, is3D, turnCostStorage); }
public void processRelation(ReaderRelation relation) throws XMLStreamException { if (relation.hasTag("type", "restriction")) { OSMTurnRelation turnRelation = createTurnRelation(relation); if (turnRelation != null) { GraphExtension extendedStorage = graph.getExtension(); if (extendedStorage instanceof TurnCostExtension) { TurnCostExtension tcs = (TurnCostExtension) extendedStorage; Collection<TurnCostTableEntry> entries = analyzeTurnRelation(turnRelation); for (TurnCostTableEntry entry : entries) { tcs.addTurnInfo(entry.edgeFrom, entry.nodeVia, entry.edgeTo, entry.flags); } } } } }
/** * This method calculates the turn weight separately. */ public double calcTurnWeight(int edgeFrom, int nodeVia, int edgeTo) { long turnFlags = turnCostExt.getTurnCostFlags(edgeFrom, nodeVia, edgeTo); if (turnCostEncoder.isTurnRestricted(turnFlags)) return Double.POSITIVE_INFINITY; return turnCostEncoder.getTurnCost(turnFlags); }
assertEquals(128, turnCostStorage.getCapacity()); turnCostStorage.addTurnInfo(edgeId, 50, edgeId + 50, 1337); turnCostStorage.addTurnInfo(edgeId + 50, 50, edgeId, 1337); turnCostStorage.addTurnInfo(0, 50, 1, 1337); assertEquals(104, turnCostStorage.getCapacity() / 16); // we are still good here turnCostStorage.addTurnInfo(0, 50, 2, 1337); assertEquals(112, turnCostStorage.getCapacity() / 16);
tcs.mergeOrOverwriteTurnInfo(edge42, 2, edge23, carRestricted, true); tcs.mergeOrOverwriteTurnInfo(edge42, 2, edge23, bikeRestricted, true); tcs.mergeOrOverwriteTurnInfo(edge23, 3, edge31, carRestricted, true); tcs.mergeOrOverwriteTurnInfo(edge23, 3, edge31, bikeCosts, true); tcs.mergeOrOverwriteTurnInfo(edge31, 1, edge10, carCosts, true); tcs.mergeOrOverwriteTurnInfo(edge31, 1, edge10, bikeRestricted, true); tcs.mergeOrOverwriteTurnInfo(edge02, 2, edge24, carRestricted, false); tcs.mergeOrOverwriteTurnInfo(edge02, 2, edge24, bikeRestricted, false); long flags423 = tcs.getTurnCostFlags(edge42, 2, edge23); assertEquals(Double.POSITIVE_INFINITY, carEncoder.getTurnCost(flags423), 0); assertEquals(Double.POSITIVE_INFINITY, bikeEncoder.getTurnCost(flags423), 0); long flags231 = tcs.getTurnCostFlags(edge23, 3, edge31); assertEquals(Double.POSITIVE_INFINITY, carEncoder.getTurnCost(flags231), 0); assertEquals(2.0, bikeEncoder.getTurnCost(flags231), 0); long flags310 = tcs.getTurnCostFlags(edge31, 1, edge10); assertEquals(2.0, carEncoder.getTurnCost(flags310), 0); assertEquals(Double.POSITIVE_INFINITY, bikeEncoder.getTurnCost(flags310), 0); long flags024 = tcs.getTurnCostFlags(edge02, 2, edge24); assertEquals(0.0, carEncoder.getTurnCost(flags024), 0); assertEquals(Double.POSITIVE_INFINITY, bikeEncoder.getTurnCost(flags024), 0); tcs.addTurnInfo(edge02, 2, edge23, carRestricted); tcs.addTurnInfo(edge02, 2, edge23, bikeRestricted); long flags023 = tcs.getTurnCostFlags(edge02, 2, edge23); assertEquals(Double.POSITIVE_INFINITY, carEncoder.getTurnCost(flags023), 0);
@Test public void testMergeFlagsBeforeAdding() { FlagEncoder carEncoder = new CarFlagEncoder(5, 5, 3); FlagEncoder bikeEncoder = new BikeFlagEncoder(5, 5, 3); EncodingManager manager = new EncodingManager(carEncoder, bikeEncoder); GraphHopperStorage g = new GraphBuilder(manager).create(); initGraph(g); TurnCostExtension tcs = (TurnCostExtension) g.getExtension(); long carRestricted = carEncoder.getTurnFlags(true, 0); long bikeRestricted = bikeEncoder.getTurnFlags(true, 0); int edge23 = getEdge(g, 2, 3).getEdge(); int edge02 = getEdge(g, 0, 2).getEdge(); tcs.addTurnInfo(edge02, 2, edge23, carRestricted | bikeRestricted); long flags023 = tcs.getTurnCostFlags(edge02, 2, edge23); assertEquals(Double.POSITIVE_INFINITY, carEncoder.getTurnCost(flags023), 0); assertEquals(Double.POSITIVE_INFINITY, bikeEncoder.getTurnCost(flags023), 0); } }
@Test public void testTurnCostsProperlyPropagated_Issue282() { TurnCostExtension turnExt = new TurnCostExtension(); FlagEncoder encoder = new CarFlagEncoder(5, 5, 15); GraphHopperStorage graphWithTurnCosts = new GraphHopperStorage(new RAMDirectory(), new EncodingManager(encoder), false, turnExt). create(100); NodeAccess na = graphWithTurnCosts.getNodeAccess(); na.setNode(0, .00, .00); na.setNode(1, .00, .01); na.setNode(2, .01, .01); EdgeIteratorState edge0 = graphWithTurnCosts.edge(0, 1, 10, true); EdgeIteratorState edge1 = graphWithTurnCosts.edge(2, 1, 10, true); QueryGraph qGraph = new QueryGraph(graphWithTurnCosts); FastestWeighting weighting = new FastestWeighting(encoder); TurnWeighting turnWeighting = new TurnWeighting(weighting, (TurnCostExtension) qGraph.getExtension()); assertEquals(0, turnWeighting.calcTurnWeight(edge0.getEdge(), 1, edge1.getEdge()), .1); // now use turn costs and QueryGraph turnExt.addTurnInfo(edge0.getEdge(), 1, edge1.getEdge(), encoder.getTurnFlags(false, 10)); assertEquals(10, turnWeighting.calcTurnWeight(edge0.getEdge(), 1, edge1.getEdge()), .1); QueryResult res1 = createLocationResult(0.000, 0.005, edge0, 0, QueryResult.Position.EDGE); QueryResult res2 = createLocationResult(0.005, 0.010, edge1, 0, QueryResult.Position.EDGE); qGraph.lookup(Arrays.asList(res1, res2)); int fromQueryEdge = GHUtility.getEdge(qGraph, res1.getClosestNode(), 1).getEdge(); int toQueryEdge = GHUtility.getEdge(qGraph, res2.getClosestNode(), 1).getEdge(); assertEquals(10, turnWeighting.calcTurnWeight(fromQueryEdge, 1, toQueryEdge), .1); graphWithTurnCosts.close(); }
public TurnCostExtension() { TC_FROM = nextTurnCostEntryIndex(); TC_TO = nextTurnCostEntryIndex(); TC_FLAGS = nextTurnCostEntryIndex(); TC_NEXT = nextTurnCostEntryIndex(); turnCostsEntryBytes = turnCostsEntryIndex + 4; turnCostsCount = 0; }
/** * @return turn flags of the specified node and edge properties. */ public long getTurnCostFlags(int edgeFrom, int nodeVia, int edgeTo) { if (edgeFrom == EdgeIterator.NO_EDGE || edgeTo == EdgeIterator.NO_EDGE) throw new IllegalArgumentException("from and to edge cannot be NO_EDGE"); if (nodeVia < 0) throw new IllegalArgumentException("via node cannot be negative"); return nextCostFlags(edgeFrom, nodeVia, edgeTo); }
ensureTurnCostIndex(newEntryIndex); boolean oldEntryFound = false; long newFlags = turnFlags;
/** * Add an entry which is a turn restriction or cost information via the turnFlags. Overwrite existing information * if it is the same edges and node. */ public void addTurnInfo(int fromEdge, int viaNode, int toEdge, long turnFlags) { // no need to store turn information if (turnFlags == EMPTY_FLAGS) return; mergeOrOverwriteTurnInfo(fromEdge, viaNode, toEdge, turnFlags, true); }
graph.edge(1, 2, 120, false); turnCostStorage.addTurnInfo(iter1.getEdge(), 0, iter2.getEdge(), 1337); turnCostStorage.addTurnInfo(iter2.getEdge(), 0, iter1.getEdge(), 666); turnCostStorage.addTurnInfo(iter1.getEdge(), 1, iter2.getEdge(), 815); assertEquals("named street2", graph.getEdgeIteratorState(iter2.getEdge(), iter2.getAdjNode()).getName()); assertEquals(1337, turnCostStorage.getTurnCostFlags(iter1.getEdge(), 0, iter2.getEdge())); assertEquals(666, turnCostStorage.getTurnCostFlags(iter2.getEdge(), 0, iter1.getEdge())); assertEquals(815, turnCostStorage.getTurnCostFlags(iter1.getEdge(), 1, iter2.getEdge())); assertEquals(0, turnCostStorage.getTurnCostFlags(iter1.getEdge(), 3, iter2.getEdge()));
public TurnCostExtension() { TC_FROM = nextTurnCostEntryIndex(); TC_TO = nextTurnCostEntryIndex(); TC_FLAGS = nextTurnCostEntryIndex(); TC_NEXT = nextTurnCostEntryIndex(); turnCostsEntryBytes = turnCostsEntryIndex + 4; turnCostsCount = 0; }
/** * @return turn flags of the specified node and edge properties. */ public long getTurnCostFlags(int edgeFrom, int nodeVia, int edgeTo) { if (edgeFrom == EdgeIterator.NO_EDGE || edgeTo == EdgeIterator.NO_EDGE) throw new IllegalArgumentException("from and to edge cannot be NO_EDGE"); if (nodeVia < 0) throw new IllegalArgumentException("via node cannot be negative"); return nextCostFlags(edgeFrom, nodeVia, edgeTo); }
ensureTurnCostIndex(newEntryIndex);
/** * Add an entry which is a turn restriction or cost information via the turnFlags. Overwrite existing information * if it is the same edges and node. */ public void addTurnInfo(int fromEdge, int viaNode, int toEdge, long turnFlags) { // no need to store turn information if (turnFlags == EMPTY_FLAGS) return; mergeOrOverwriteTurnInfo(fromEdge, viaNode, toEdge, turnFlags, true); }
/** * Default graph is a {@link GraphHopperStorage} with an in memory directory and disabled storing on flush. * Afterwards you'll need to call {@link GraphHopperStorage#create} to have a usable object. Better use * {@link GraphHopperStorage#create} directly. */ public GraphHopperStorage build() { Directory dir = mmap ? new MMapDirectory(location) : new RAMDirectory(location, store); GraphHopperStorage graph; if (encodingManager.needsTurnCostsSupport() || singleCHWeighting == null) graph = new GraphHopperStorage(dir, encodingManager, elevation, new TurnCostExtension()); else graph = new GraphHopperStorage(Arrays.asList(singleCHWeighting), dir, encodingManager, elevation, new TurnCostExtension.NoOpExtension()); return graph; }
private void blockNode3(Graph g, TurnCostExtension tcs, TurnCostEncoder tEncoder) { // Totally block this node (all 9 turn relations) final long BLOCK = tEncoder.getTurnFlags(true, 0); tcs.addTurnInfo(getEdge(g, 2, 3).getEdge(), 3, getEdge(g, 3, 1).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 2, 3).getEdge(), 3, getEdge(g, 3, 4).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 4, 3).getEdge(), 3, getEdge(g, 3, 1).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 4, 3).getEdge(), 3, getEdge(g, 3, 2).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 6, 3).getEdge(), 3, getEdge(g, 3, 1).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 6, 3).getEdge(), 3, getEdge(g, 3, 4).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 1, 3).getEdge(), 3, getEdge(g, 3, 6).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 1, 3).getEdge(), 3, getEdge(g, 3, 2).getEdge(), BLOCK); tcs.addTurnInfo(getEdge(g, 1, 3).getEdge(), 3, getEdge(g, 3, 4).getEdge(), BLOCK); }
@Override public long getTurnCostFlags(int edgeFrom, int nodeVia, int edgeTo) { if (isVirtualNode(nodeVia)) { return 0; } else if (isVirtualEdge(edgeFrom) || isVirtualEdge(edgeTo)) { if (isVirtualEdge(edgeFrom)) { edgeFrom = queryResults.get((edgeFrom - mainEdges) / 4).getClosestEdge().getEdge(); } if (isVirtualEdge(edgeTo)) { edgeTo = queryResults.get((edgeTo - mainEdges) / 4).getClosestEdge().getEdge(); } return mainTurnExtension.getTurnCostFlags(edgeFrom, nodeVia, edgeTo); } else { return mainTurnExtension.getTurnCostFlags(edgeFrom, nodeVia, edgeTo); } } }
public TurnCostExtension() { TC_FROM = nextTurnCostEntryIndex(); TC_TO = nextTurnCostEntryIndex(); TC_FLAGS = nextTurnCostEntryIndex(); TC_NEXT = nextTurnCostEntryIndex(); turnCostsEntryBytes = turnCostsEntryIndex + 4; turnCostsCount = 0; }