private void expandEdge(CHEdgeIteratorState edge, boolean reverse) { if (!edge.isShortcut()) { distance += edge.getDistance(); time += weighting.calcMillis(edge, reverse, EdgeIterator.NO_EDGE); addEdge(edge.getEdge()); return; } expandSkippedEdges(edge.getSkippedEdge1(), edge.getSkippedEdge2(), edge.getBaseNode(), edge.getAdjNode(), reverse); }
@Test public void testGetWeightIfAdvancedEncoder() { FlagEncoder customEncoder = new Bike2WeightFlagEncoder(); EncodingManager em = new EncodingManager(customEncoder); FastestWeighting weighting = new FastestWeighting(customEncoder); GraphHopperStorage ghStorage = new GraphBuilder(em).setCHGraph(weighting).create(); ghStorage.edge(0, 2); ghStorage.freeze(); CHGraphImpl lg = (CHGraphImpl) ghStorage.getGraph(CHGraph.class, weighting); CHEdgeIteratorState sc1 = lg.shortcut(0, 1); long flags = customEncoder.setProperties(10, false, true); sc1.setFlags(flags); sc1.setWeight(100.123); assertEquals(100.123, lg.getEdgeIteratorState(sc1.getEdge(), sc1.getAdjNode()).getWeight(), 1e-3); assertEquals(100.123, lg.getEdgeIteratorState(sc1.getEdge(), sc1.getBaseNode()).getWeight(), 1e-3); assertEquals(100.123, ((CHEdgeIteratorState) GHUtility.getEdge(lg, sc1.getBaseNode(), sc1.getAdjNode())).getWeight(), 1e-3); assertEquals(100.123, ((CHEdgeIteratorState) GHUtility.getEdge(lg, sc1.getAdjNode(), sc1.getBaseNode())).getWeight(), 1e-3); sc1 = lg.shortcut(1, 0); assertTrue(sc1.isShortcut()); sc1.setFlags(PrepareEncoder.getScDirMask()); sc1.setWeight(1.011011); assertEquals(1.011011, sc1.getWeight(), 1e-3); }
CHEdgeIteratorState edgeState = prepareGraph.shortcut(sc.from, sc.to); edgeState.setFlags(sc.flags); edgeState.setWeight(sc.weight); edgeState.setDistance(sc.dist); edgeState.setSkippedEdges(sc.skippedEdge1, sc.skippedEdge2); setOrigEdgeCount(edgeState.getEdge(), sc.originalEdges); tmpNewShortcuts++;
@Override public double calcWeight(EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) { CHEdgeIteratorState tmp = (CHEdgeIteratorState) edgeState; if (tmp.isShortcut()) // if a shortcut is in both directions the weight is identical => no need for 'reverse' return tmp.getWeight(); return userWeighting.calcWeight(edgeState, reverse, prevOrNextEdgeId); }
graph = createGHStorage(); CHGraphImpl g = (CHGraphImpl) getGraph(graph); assertFalse(g.edge(0, 1).isShortcut()); assertFalse(g.edge(1, 2).isShortcut()); assertTrue(sc1.isShortcut()); sc1.setWeight(2.001); assertEquals(2.001, sc1.getWeight(), 1e-3); sc1.setWeight(100.123); assertEquals(100.123, sc1.getWeight(), 1e-3); sc1.setWeight(Double.MAX_VALUE); assertTrue(Double.isInfinite(sc1.getWeight())); sc1.setFlags(flags); sc1.setWeight(100.123); assertEquals(100.123, sc1.getWeight(), 1e-3); assertTrue(sc1.isForward(carEncoder)); assertTrue(sc1.isBackward(carEncoder)); sc1.setFlags(flags); sc1.setWeight(100.123); assertEquals(100.123, sc1.getWeight(), 1e-3); assertFalse(sc1.isForward(carEncoder)); assertTrue(sc1.isBackward(carEncoder)); sc1.setFlags(flags); sc1.setWeight(1e-5); assertEquals(1e-3, sc1.getWeight(), 1e-10);
CHEdgeIteratorState sc0_2 = g.shortcut(0, 2); int x = EdgeIterator.NO_EDGE; sc0_2.setWeight(w.calcWeight(edgeState01, false, x) + w.calcWeight(edgeState12, false, x)).setDistance(2 * dist).setFlags(oneDirFlags); sc0_2.setSkippedEdges(tmpEdgeId, edgeState12.getEdge()); tmpEdgeId = sc0_2.getEdge(); CHEdgeIteratorState sc0_3 = g.shortcut(0, 3); sc0_3.setWeight(sc0_2.getWeight() + w.calcWeight(edgeState23, false, x)).setDistance(3 * dist).setFlags(oneDirFlags); sc0_3.setSkippedEdges(tmpEdgeId, edgeState23.getEdge()); tmpEdgeId = sc0_3.getEdge(); CHEdgeIteratorState sc0_4 = g.shortcut(0, 4); sc0_4.setWeight(sc0_3.getWeight() + w.calcWeight(edgeState34, false, x)).setDistance(4).setFlags(oneDirFlags); sc0_4.setSkippedEdges(tmpEdgeId, edgeState34.getEdge()); tmpEdgeId = sc0_4.getEdge(); CHEdgeIteratorState sc0_5 = g.shortcut(0, 5); sc0_5.setWeight(sc0_4.getWeight() + w.calcWeight(edgeState45, false, x)).setDistance(5).setFlags(oneDirFlags); sc0_5.setSkippedEdges(tmpEdgeId, edgeState45.getEdge()); tmpEdgeId = sc0_5.getEdge(); CHEdgeIteratorState sc0_6 = g.shortcut(0, 6); sc0_6.setWeight(sc0_5.getWeight() + w.calcWeight(edgeState56, false, x)).setDistance(6).setFlags(oneDirFlags); sc0_6.setSkippedEdges(tmpEdgeId, edgeState56.getEdge()); g.setLevel(0, 10); g.setLevel(6, 9);
@Test public void testEdgeFilter() { graph = createGHStorage(); CHGraph g = getGraph(graph); g.edge(0, 1, 10, true); g.edge(0, 2, 20, true); g.edge(2, 3, 30, true); g.edge(10, 11, 1, true); graph.freeze(); CHEdgeIteratorState tmpIter = g.shortcut(3, 4); tmpIter.setDistance(40).setFlags(carEncoder.setAccess(0, true, true)); assertEquals(EdgeIterator.NO_EDGE, tmpIter.getSkippedEdge1()); assertEquals(EdgeIterator.NO_EDGE, tmpIter.getSkippedEdge2()); g.shortcut(0, 4).setDistance(40).setFlags(carEncoder.setAccess(0, true, true)); g.setLevel(0, 1); g.setLevel(4, 1); EdgeIterator iter = g.createEdgeExplorer(new LevelEdgeFilter(g)).setBaseNode(0); assertEquals(1, GHUtility.count(iter)); iter = g.createEdgeExplorer().setBaseNode(2); assertEquals(2, GHUtility.count(iter)); tmpIter = g.shortcut(5, 6); tmpIter.setSkippedEdges(1, 2); assertEquals(1, tmpIter.getSkippedEdge1()); assertEquals(2, tmpIter.getSkippedEdge2()); }
long flags = car.setProperties(60, true, true); CHEdgeIteratorState iter5 = lg.shortcut(0, 2); iter5.setDistance(20).setFlags(flags); iter5.setSkippedEdges(iter1.getEdge(), iter2.getEdge()); CHEdgeIteratorState iter6 = lg.shortcut(2, 4); iter6.setDistance(28).setFlags(flags); iter6.setSkippedEdges(iter3.getEdge(), iter4.getEdge()); CHEdgeIteratorState tmp = lg.shortcut(0, 4); tmp.setDistance(40).setFlags(flags); tmp.setSkippedEdges(iter5.getEdge(), iter6.getEdge());
EdgeIteratorState carSC02 = carCHGraph.shortcut(0, 2).setWeight(10).setFlags(PrepareEncoder.getScFwdDir()).setDistance(20); EdgeIteratorState bikeSC02 = bikeCHGraph.shortcut(0, 2).setWeight(10).setFlags(PrepareEncoder.getScDirMask()).setDistance(20); assertTrue(carCHGraph.getEdgeIteratorState(carSC02.getEdge(), 2).isForward(tmpCar)); assertFalse(carCHGraph.getEdgeIteratorState(carSC02.getEdge(), 2).isBackward(tmpCar)); assertFalse(carCHGraph.getEdgeIteratorState(carSC02.getEdge(), 2).isForward(tmpBike)); fail(); } catch (AssertionError ex) { assertTrue(bikeCHGraph.getEdgeIteratorState(bikeSC02.getEdge(), 2).isForward(tmpBike)); assertTrue(bikeCHGraph.getEdgeIteratorState(bikeSC02.getEdge(), 2).isBackward(tmpBike)); assertFalse(bikeCHGraph.getEdgeIteratorState(bikeSC02.getEdge(), 2).isBackward(tmpCar)); fail(); } catch (AssertionError ex) {
@Override public boolean isShortcut() { EdgeIteratorState edge = edges.get(current); return edge instanceof CHEdgeIteratorState && ((CHEdgeIteratorState) edge).isShortcut(); }
@Test public void testSimpleShortcutCreationAndTraversal() { graph = createGHStorage(); graph.edge(1, 3, 10, true); graph.edge(3, 4, 10, true); graph.freeze(); CHGraph lg = graph.getGraph(CHGraph.class); lg.shortcut(1, 4).setWeight(3).setFlags(carEncoder.setProperties(10, true, true)); EdgeExplorer vehicleOutExplorer = lg.createEdgeExplorer(DefaultEdgeFilter.outEdges(carEncoder)); // iteration should result in same nodes even if reusing the iterator assertEquals(GHUtility.asSet(3, 4), GHUtility.getNeighbors(vehicleOutExplorer.setBaseNode(1))); assertEquals(GHUtility.asSet(3, 4), GHUtility.getNeighbors(vehicleOutExplorer.setBaseNode(1))); }
graph.freeze(); CHEdgeIteratorState tmp = lg.shortcut(1, 2); tmp.setDistance(10).setFlags(flags); tmp.setSkippedEdges(10, 11); tmp = lg.shortcut(1, 0); tmp.setDistance(20).setFlags(flags2); tmp.setSkippedEdges(12, 13); tmp = lg.shortcut(3, 1); tmp.setDistance(30).setFlags(flags2); tmp.setSkippedEdges(14, 15);
@Override public double getWeight() { // will be called only from PreparationWeighting and if isShortcut is true return ((CHEdgeIteratorState) edges.get(current)).getWeight(); }
@Override public EdgeIteratorState edge(int a, int b, double distance, boolean bothDirections) { return edge(a, b).setDistance(distance).setFlags(baseGraph.encodingManager.flagsDefault(true, bothDirections)); }
@Test public void testAddShortcutSkippedEdgesWriteRead_writeWithCHEdgeIterator() { graph = createGHStorage(); final EdgeIteratorState edge1 = graph.edge(1, 3, 10, true); final EdgeIteratorState edge2 = graph.edge(3, 4, 10, true); graph.freeze(); CHGraph lg = graph.getGraph(CHGraph.class); CHEdgeIteratorState shortcut = lg.shortcut(1, 4); shortcut.setSkippedEdges(edge1.getEdge(), edge2.getEdge()); AllCHEdgesIterator iter = lg.getAllEdges(); iter.next(); iter.next(); iter.next(); assertTrue(iter.isShortcut()); assertEquals(edge1.getEdge(), iter.getSkippedEdge1()); assertEquals(edge2.getEdge(), iter.getSkippedEdge2()); }
iter2_1.setDistance(2.8).setFlags(encoder.setProperties(10, true, false)); iter2_1.setSkippedEdges(iter1_1.getEdge(), iter1_2.getEdge()); CHEdgeIteratorState tmp = g2.shortcut(0, 7); tmp.setDistance(4.2).setFlags(encoder.setProperties(10, true, false)); tmp.setSkippedEdges(iter2_1.getEdge(), iter2_2.getEdge()); g2.setLevel(1, 0); g2.setLevel(3, 1);
@Override public double calcWeight( EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId ) { CHEdgeIteratorState tmp = (CHEdgeIteratorState) edgeState; if (tmp.isShortcut()) // if a shortcut is in both directions the weight is identical => no need for 'reverse' return tmp.getWeight(); return userWeighting.calcWeight(edgeState, reverse, prevOrNextEdgeId); }
@Override public boolean accept(EdgeIteratorState edgeIterState) { int base = edgeIterState.getBaseNode(); int adj = edgeIterState.getAdjNode(); // always accept virtual edges, see #288 if (base >= maxNodes || adj >= maxNodes) return true; // minor performance improvement: shortcuts in wrong direction are disconnected, so no need to exclude them if (((CHEdgeIteratorState) edgeIterState).isShortcut()) return true; return graph.getLevel(base) <= graph.getLevel(adj); } }
@Override public double getWeight() { // will be called only from PreparationWeighting and if isShortcut is true return ((CHEdgeIteratorState) edges.get(current)).getWeight(); }
@Override public EdgeIteratorState edge( int a, int b, double distance, boolean bothDirections ) { return edge(a, b).setDistance(distance).setFlags(baseGraph.encodingManager.flagsDefault(true, bothDirections)); }