public Map<Integer, Integer> findSubnetworks() { Map<Integer, Integer> map = new HashMap<Integer, Integer>(); final AtomicInteger integ = new AtomicInteger(0); int locs = g.nodes(); final GHBitSet bs = new GHBitSetImpl(locs); for (int start = 0; start < locs; start++) { if (g.isNodeRemoved(start) || bs.contains(start)) continue; new XFirstSearch() { @Override protected GHBitSet createBitSet(int size) { return bs; } @Override protected boolean goFurther(int nodeId) { boolean ret = super.goFurther(nodeId); if (ret) integ.incrementAndGet(); return ret; } }.start(g, start, false); // System.out.println(start + " MAP "+map.size()); map.put(start, integ.get()); integ.set(0); } return map; }
@Test public void testDifferentEdgeFilter() { Graph g = new GraphBuilder(encodingManager).levelGraphCreate(); g.edge(4, 3, 10, true); g.edge(3, 6, 10, true); g.edge(4, 5, 10, true); g.edge(5, 6, 10, true); AlgorithmPreparation prep = prepareGraph(g); DijkstraOneToMany algo = (DijkstraOneToMany) prep.createAlgo(); algo.setEdgeFilter( new EdgeFilter() { @Override public boolean accept(EdgeIteratorState iter) { return iter.getAdjNode() != 5; } }); Path p = algo.calcPath(4, 6); assertEquals(Helper.createTList(4, 3, 6), p.calcNodes()); // important call! algo.clear(); algo.setEdgeFilter( new EdgeFilter() { @Override public boolean accept(EdgeIteratorState iter) { return iter.getAdjNode() != 3; } }); p = algo.calcPath(4, 6); assertEquals(Helper.createTList(4, 5, 6), p.calcNodes()); }
@Test public void testCopy() { Graph g = initUnsorted(createGraph()); EdgeIteratorState eb = g.edge(6, 5, 11, true); eb.setWayGeometry(Helper.createPointList(12, 10, -1, 3)); LevelGraph lg = new GraphBuilder(encodingManager).levelGraphCreate(); GHUtility.copyTo(g, lg); eb = lg.getEdgeProps(eb.getEdge(), 6); assertEquals(Helper.createPointList(-1, 3, 12, 10), eb.getWayGeometry()); assertEquals(0, lg.getLevel(0)); assertEquals(0, lg.getLevel(1)); assertEquals(0, lg.getLatitude(0), 1e-6); assertEquals(1, lg.getLongitude(0), 1e-6); assertEquals(2.5, lg.getLatitude(1), 1e-6); assertEquals(4.5, lg.getLongitude(1), 1e-6); assertEquals(9, lg.getNodes()); EdgeIterator iter = lg.createEdgeExplorer().setBaseNode(8); iter.next(); assertEquals(2.05, iter.getDistance(), 1e-6); assertEquals("11", BitUtil.toBitString(iter.getFlags(), 2)); iter.next(); assertEquals(0.5, iter.getDistance(), 1e-6); assertEquals("11", BitUtil.toBitString(iter.getFlags(), 2)); iter = lg.createEdgeExplorer().setBaseNode(7); iter.next(); assertEquals(2.1, iter.getDistance(), 1e-6); assertEquals("01", BitUtil.toBitString(iter.getFlags(), 2)); assertTrue(iter.next()); assertEquals(0.7, iter.getDistance(), 1e-6); }
@Test public void testMediumRead() throws IOException { Graph graph = new GraphBuilder().create(); new PrinctonReader(graph) .stream(new GZIPInputStream(PrinctonReader.class.getResourceAsStream("mediumEWD.txt.gz"))) .read(); assertEquals(250, graph.nodes()); assertEquals(13, count(graph.getOutgoing(244))); assertEquals(11, count(graph.getOutgoing(16))); }
@Test public void testRead() { Graph graph = new GraphBuilder().create(); new PrinctonReader(graph) .stream(PrinctonReader.class.getResourceAsStream("tinyEWD.txt")) .read(); assertEquals(8, graph.nodes()); assertEquals(2, count(graph.getOutgoing(0))); assertEquals(3, count(graph.getOutgoing(6))); }
@Test public void testSortDirected() { Graph g = createGraph(); g.setNode(0, 0, 1); g.setNode(1, 2.5, 2); g.setNode(2, 3.5, 3); g.edge(0, 1, 1.1, false); g.edge(2, 1, 1.1, false); GHUtility.sortDFS(g, createGraph()); }
public void plotNode(Graphics2D g2, int loc, Color c) { double lat = g.getLatitude(loc); double lon = g.getLongitude(loc); if (lat < bounds.minLat || lat > bounds.maxLat || lon < bounds.minLon || lon > bounds.maxLon) return; Color old = g2.getColor(); g2.setColor(c); plot(g2, lat, lon, 4); g2.setColor(old); }
@Test public void testCannotCalculateSP2() { Graph g = createGraph(10); g.edge(0, 1, 1, false); g.edge(1, 2, 1, false); DijkstraBidirectionRef db = new DijkstraBidirectionRef(g); db.addSkipNode(1); Path p = db.calcPath(0, 2); assertFalse(p.found()); }
/** * To avoid large processing and a large HashMap remove nodes with no edges up front * * @return removed nodes */ int removeZeroDegreeNodes() { int removed = 0; int locs = g.nodes(); for (int start = 0; start < locs; start++) { if (!g.getEdges(start).next()) { removed++; g.markNodeRemoved(start); } } return removed; }
@Test public void testSort2() { Graph g = initUnsorted(createGraph()); Graph newG = GHUtility.sortDFS(g, createGraph()); // TODO does not handle subnetworks // assertEquals(g.nodes(), newG.nodes()); assertEquals(0, newG.getLatitude(0), 1e-4); // 0 assertEquals(2.5, newG.getLatitude(1), 1e-4); // 1 assertEquals(4.5, newG.getLatitude(2), 1e-4); // 2 assertEquals(4.6, newG.getLatitude(3), 1e-4); // 8 }
@Test public void testNoErrorOnEdgeCase_lastIndex() { final EncodingManager encodingManager = new EncodingManager("car"); int locs = 10000; Graph g = AbstractLocationIndexTester.this.createGHStorage( new MMapDirectory(location), encodingManager, false); NodeAccess na = g.getNodeAccess(); Random rand = new Random(12); for (int i = 0; i < locs; i++) { na.setNode(i, (float) rand.nextDouble() * 10 + 10, (float) rand.nextDouble() * 10 + 10); } idx = createIndex(g, 200); Helper.close((Closeable) g); }
@Test public void testExtract() { Graph g = createGraph(); g.edge(1, 2, 10, true); PathBidirRef pw = new PathBidirRef(g, carEncoder); EdgeExplorer explorer = g.createEdgeExplorer(carOutEdges); EdgeIterator iter = explorer.setBaseNode(1); iter.next(); pw.edgeEntry = new EdgeEntry(iter.getEdge(), 2, 0); pw.edgeEntry.parent = new EdgeEntry(EdgeIterator.NO_EDGE, 1, 10); pw.edgeTo = new EdgeEntry(EdgeIterator.NO_EDGE, 2, 0); Path p = pw.extract(); assertEquals(Helper.createTList(1, 2), p.calcNodes()); assertEquals(10, p.getDistance(), 1e-4); }
int addEdge(int fromIndex, int toIndex, PointList pointList, int flags) { double towerNodeDistance = 0; double prevLat = pointList.latitude(0); double prevLon = pointList.longitude(0); double lat; double lon; PointList pillarNodes = new PointList(pointList.size() - 2); int nodes = pointList.size(); for (int i = 1; i < nodes; i++) { lat = pointList.latitude(i); lon = pointList.longitude(i); towerNodeDistance += callback.calcDist(prevLat, prevLon, lat, lon); prevLat = lat; prevLon = lon; if (nodes > 2 && i < nodes - 1) pillarNodes.add(lat, lon); } if (towerNodeDistance == 0) { // As investigation shows often two paths should have crossed via one identical point // but end up in two very close points. later this will be removed/fixed while // removing short edges where one node is of degree 2 zeroCounter++; towerNodeDistance = 0.0001; } EdgeIterator iter = g.edge(fromIndex, toIndex, towerNodeDistance, flags); if (nodes > 2) iter.wayGeometry(pillarNodes); return nodes; }
public MyGraphics(Graph g) { this.g = g; BBox b = g.bounds(); scaleX = scaleY = 0.002 * (b.maxLat - b.minLat); offsetY = b.maxLat - 90; offsetX = -b.minLon; }
// 8 // | // 6->0->1->3->7 // | | // | v // 10<-2---4<---5 // 9 public static void initDirected1(Graph g) { g.edge(0, 8, 1, true); g.edge(0, 1, 1, false); g.edge(1, 3, 1, false); g.edge(3, 7, 1, false); g.edge(3, 5, 1, false); g.edge(5, 4, 1, false); g.edge(4, 2, 1, true); g.edge(2, 9, 1, false); g.edge(2, 10, 1, false); g.edge(2, 6, 1, true); g.edge(6, 0, 1, false); }
public void doWork() { int del = removeZeroDegreeNodes(); Map<Integer, Integer> map = findSubnetworks(); keepLargeNetwork(map); logger.info( "optimize to remove subnetworks(" + map.size() + "), zero-degree-nodes(" + del + ")"); g.optimize(); subNetworks = map.size(); }
@Test public void testSort() { Graph g = initUnsorted(createGraph()); Graph newG = GHUtility.sortDFS(g, createGraph()); assertEquals(g.getNodes(), newG.getNodes()); assertEquals(0, newG.getLatitude(0), 1e-4); // 0 assertEquals(2.5, newG.getLatitude(1), 1e-4); // 1 assertEquals(4.5, newG.getLatitude(2), 1e-4); // 2 assertEquals(4.6, newG.getLatitude(3), 1e-4); // 8 assertEquals(3.0, newG.getLatitude(4), 1e-4); // 3 assertEquals(5.0, newG.getLatitude(5), 1e-4); // 7 assertEquals(4.2, newG.getLatitude(6), 1e-4); // 5 }
@Test public void testDifferentVehicles() { final EncodingManager encodingManager = new EncodingManager("car,foot"); Graph g = AbstractLocationIndexTester.this.createGHStorage(encodingManager); initSimpleGraph(g); idx = createIndex(g, -1); assertEquals(1, findID(idx, 1, -1)); // now make all edges from node 1 accessible for CAR only EdgeIterator iter = g.createEdgeExplorer().setBaseNode(1); CarFlagEncoder carEncoder = (CarFlagEncoder) encodingManager.getEncoder("car"); while (iter.next()) { iter.setFlags(carEncoder.setProperties(50, true, true)); } idx.close(); idx = createIndex(g, -1); FootFlagEncoder footEncoder = (FootFlagEncoder) encodingManager.getEncoder("foot"); assertEquals(2, idx.findClosest(1, -1, new DefaultEdgeFilter(footEncoder)).getClosestNode()); Helper.close((Closeable) g); }
public void initSimpleGraph(Graph g) { // 6 | 4 // 5 | // | 6 // 4 | 5 // 3 | // 2 | 1 // 1 | 3 // 0 | 2 // -1 | 0 // ---|------------------- // |-2 -1 0 1 2 3 4 // NodeAccess na = g.getNodeAccess(); na.setNode(0, -1, -2); na.setNode(1, 2, -1); na.setNode(2, 0, 1); na.setNode(3, 1, 2); na.setNode(4, 6, 1); na.setNode(5, 4, 4); na.setNode(6, 4.5, -0.5); g.edge(0, 1, 3.5, true); g.edge(0, 2, 2.5, true); g.edge(2, 3, 1, true); g.edge(3, 4, 3.2, true); g.edge(1, 4, 2.4, true); g.edge(3, 5, 1.5, true); // make sure 6 is connected g.edge(6, 4, 1.2, true); }
public static RoutingAlgorithm[] createAlgos(final Graph g) { LevelGraph graphSimpleSC = (LevelGraphStorage) g.copyTo(new LevelGraphStorage(new RAMDirectory()).createNew(10)); PrepareSimpleShortcuts prepare = new PrepareSimpleShortcuts().setGraph(graphSimpleSC); prepare.doWork(); AStarBidirection astarSimpleSC = (AStarBidirection) prepare.createAStar(); astarSimpleSC.setApproximation(false); LevelGraph graphCH = (LevelGraphStorage) g.copyTo(new LevelGraphStorage(new RAMDirectory()).createNew(10)); PrepareContractionHierarchies prepareCH = new PrepareContractionHierarchies().setGraph(graphCH); prepareCH.doWork(); return new RoutingAlgorithm[] { new AStar(g), new AStarBidirection(g), new DijkstraBidirectionRef(g), new DijkstraBidirection(g), new DijkstraSimple(g), prepare.createAlgo(), astarSimpleSC, prepareCH.createAlgo() }; }
void testIndex() { // query outside double qLat = 49.4000; double qLon = 9.9690; int id = idx.findID(qLat, qLon); double foundLat = unterfrankenGraph.getLatitude(id); double foundLon = unterfrankenGraph.getLongitude(id); double dist = new DistanceCalc().calcDistKm(qLat, qLon, foundLat, foundLon); double expectedDist = 5.5892; if (Math.abs(dist - expectedDist) > 1e-4) System.out.println( "ERROR in test index. queried lat,lon=" + (float) qLat + "," + (float) qLon + ", but was " + (float) foundLat + "," + (float) foundLon + "\n expected distance:" + expectedDist + ", but was:" + dist); }
// 0-1-2-3-4 // | / | // | 8 | // \ / / // 7-6-5-/ void initBiGraph(Graph graph) { graph.edge(0, 1, 100, true); graph.edge(1, 2, 1, true); graph.edge(2, 3, 1, true); graph.edge(3, 4, 1, true); graph.edge(4, 5, 25, true); graph.edge(5, 6, 25, true); graph.edge(6, 7, 5, true); graph.edge(7, 0, 5, true); graph.edge(3, 8, 20, true); graph.edge(8, 6, 20, true); }
/** Deletes all but the larges subnetworks. */ void keepLargeNetwork(Map<Integer, Integer> map) { if (map.size() < 2) return; int biggestStart = -1; int maxCount = -1; GHBitSetImpl bs = new GHBitSetImpl(g.nodes()); for (Entry<Integer, Integer> e : map.entrySet()) { if (biggestStart < 0) { biggestStart = e.getKey(); maxCount = e.getValue(); continue; } if (maxCount < e.getValue()) { // new biggest area found. remove old removeNetwork(biggestStart, maxCount, bs); biggestStart = e.getKey(); maxCount = e.getValue(); } else removeNetwork(e.getKey(), e.getValue(), bs); } }
@Test public void testGrid() { Graph g = createSampleGraph(new EncodingManager("car")); int locs = g.getNodes(); idx = createIndex(g, -1); // if we would use less array entries then some points gets the same key so avoid that for this // test // e.g. for 16 we get "expected 6 but was 9" i.e 6 was overwritten by node j9 which is a bit // closer to the grid center // go through every point of the graph if all points are reachable NodeAccess na = g.getNodeAccess(); for (int i = 0; i < locs; i++) { double lat = na.getLatitude(i); double lon = na.getLongitude(i); assertEquals("nodeId:" + i + " " + (float) lat + "," + (float) lon, i, findID(idx, lat, lon)); } // hit random lat,lon and compare result to full index Random rand = new Random(12); LocationIndex fullIndex; if (hasEdgeSupport()) fullIndex = new Location2IDFullWithEdgesIndex(g); else fullIndex = new Location2IDFullIndex(g); DistanceCalc dist = new DistanceCalcEarth(); for (int i = 0; i < 100; i++) { double lat = rand.nextDouble() * 5; double lon = rand.nextDouble() * 5; int fullId = findID(fullIndex, lat, lon); double fullLat = na.getLatitude(fullId); double fullLon = na.getLongitude(fullId); float fullDist = (float) dist.calcDist(lat, lon, fullLat, fullLon); int newId = findID(idx, lat, lon); double newLat = na.getLatitude(newId); double newLon = na.getLongitude(newId); float newDist = (float) dist.calcDist(lat, lon, newLat, newLon); if (testGridIgnore(i)) { continue; } assertTrue( i + " orig:" + (float) lat + "," + (float) lon + " full:" + fullLat + "," + fullLon + " fullDist:" + fullDist + " found:" + newLat + "," + newLon + " foundDist:" + newDist, Math.abs(fullDist - newDist) < 50000); } fullIndex.close(); Helper.close((Closeable) g); }
// 0-1-.....-9-10 // | ^ \ // | | | // 17-16-...-11<-/ public static void initDirected2(Graph g) { g.edge(0, 1, 1, true); g.edge(1, 2, 1, true); g.edge(2, 3, 1, true); g.edge(3, 4, 1, true); g.edge(4, 5, 1, true); g.edge(5, 6, 1, true); g.edge(6, 7, 1, true); g.edge(7, 8, 1, true); g.edge(8, 9, 1, true); g.edge(9, 10, 1, true); g.edge(10, 11, 1, false); g.edge(11, 12, 1, true); g.edge(11, 9, 3, false); g.edge(12, 13, 1, true); g.edge(13, 14, 1, true); g.edge(14, 15, 1, true); g.edge(15, 16, 1, true); g.edge(16, 17, 1, true); g.edge(17, 0, 1, true); }
void initRoundaboutGraph(Graph g) { // roundabout: // 16-0-9-10--11 12<-13 // \ \ / \ // 17 \| 7-8-.. // -15-1--2--3--4 / / // / \-5->6/ / // -14 \________/ g.edge(16, 0, 1, true); g.edge(0, 9, 1, true); g.edge(0, 17, 1, true); g.edge(9, 10, 1, true); g.edge(10, 11, 1, true); g.edge(11, 28, 1, true); g.edge(28, 29, 1, true); g.edge(29, 30, 1, true); g.edge(30, 31, 1, true); g.edge(31, 4, 1, true); g.edge(17, 1, 1, true); g.edge(15, 1, 1, true); g.edge(14, 1, 1, true); g.edge(14, 18, 1, true); g.edge(18, 19, 1, true); g.edge(19, 20, 1, true); g.edge(20, 15, 1, true); g.edge(19, 21, 1, true); g.edge(21, 16, 1, true); g.edge(1, 2, 1, true); g.edge(2, 3, 1, true); g.edge(3, 4, 1, true); g.edge(4, 5, 1, false); g.edge(5, 6, 1, false); g.edge(6, 7, 1, false); g.edge(7, 13, 1, false); g.edge(13, 12, 1, false); g.edge(12, 4, 1, false); g.edge(7, 8, 1, true); g.edge(8, 22, 1, true); g.edge(22, 23, 1, true); g.edge(23, 24, 1, true); g.edge(24, 25, 1, true); g.edge(25, 27, 1, true); g.edge(27, 5, 1, true); g.edge(25, 26, 1, false); g.edge(26, 25, 1, false); }
public void runShortestPathPerf(int runs, RoutingAlgorithm algo) throws Exception { BBox bbox = unterfrankenGraph.getBounds(); double minLat = bbox.minLat, minLon = bbox.minLon; double maxLat = bbox.maxLat, maxLon = bbox.maxLon; if (unterfrankenGraph instanceof LevelGraph) { if (algo instanceof DijkstraBidirectionRef) algo = new PrepareContractionHierarchies().setGraph(unterfrankenGraph).createAlgo(); // algo = new // PrepareSimpleShortcuts().setGraph(unterfrankenGraph).createAlgo(); else if (algo instanceof AStarBidirection) algo = new PrepareSimpleShortcuts().setGraph(unterfrankenGraph).createAStar(); else // level graph accepts all algorithms but normally we want to use an optimized one throw new IllegalStateException( "algorithm which boosts query time for levelgraph not found " + algo); logger.info("[experimental] using shortcuts with " + algo); } else logger.info("running " + algo); Random rand = new Random(123); StopWatch sw = new StopWatch(); // System.out.println("cap:" + ((GraphStorage) unterfrankenGraph).capacity()); for (int i = 0; i < runs; i++) { double fromLat = rand.nextDouble() * (maxLat - minLat) + minLat; double fromLon = rand.nextDouble() * (maxLon - minLon) + minLon; // sw.start(); int from = idx.findID(fromLat, fromLon); double toLat = rand.nextDouble() * (maxLat - minLat) + minLat; double toLon = rand.nextDouble() * (maxLon - minLon) + minLon; int to = idx.findID(toLat, toLon); // sw.stop(); // logger.info(i + " " + sw + " from (" + from + ")" + fromLat + ", " + fromLon // + " to (" + to + ")" + toLat + ", " + toLon); if (from == to) { logger.warn("skipping i " + i + " from==to " + from); continue; } algo.clear(); sw.start(); Path p = algo.calcPath(from, to); sw.stop(); if (!p.found()) { // there are still paths not found cause of oneway motorways => only routable in one // direction // e.g. unterfrankenGraph.getLatitude(798809) + "," + unterfrankenGraph.getLongitude(798809) logger.warn( "no route found for i=" + i + " !? " + "graph-from " + from + "(" + fromLat + "," + fromLon + "), " + "graph-to " + to + "(" + toLat + "," + toLon + ")"); continue; } if (i % 20 == 0) logger.info(i + " " + sw.getSeconds() / (i + 1) + " secs/run"); // (" + p + ")"); } }
Graph initUnsorted(Graph g) { g.setNode(0, 0, 1); g.setNode(1, 2.5, 4.5); g.setNode(2, 4.5, 4.5); g.setNode(3, 3, 0.5); g.setNode(4, 2.8, 2.8); g.setNode(5, 4.2, 1.6); g.setNode(6, 2.3, 2.2); g.setNode(7, 5, 1.5); g.setNode(8, 4.6, 4); g.edge(8, 2, 0.5, true); g.edge(7, 3, 2.1, false); g.edge(1, 0, 3.9, true); g.edge(7, 5, 0.7, true); g.edge(1, 2, 1.9, true); g.edge(8, 1, 2.05, true); return g; }
public Graph createSampleGraph(EncodingManager encodingManager) { Graph graph = AbstractLocationIndexTester.this.createGHStorage(encodingManager); // length does not matter here but lat,lon and outgoing edges do! // // lat /--------\ // 5 o- p--------\ q // \ /-----\-----n | | // 4 k /--l-- m/ // / \ j \ | // 3 | g \ h---i / // | \ / / // 2 e---------f-- / // / \-d // 1 /--b-- \ // | \--------c // 0 a // // lon: 0 1 2 3 4 5 int a0 = 0; NodeAccess na = graph.getNodeAccess(); na.setNode(0, 0, 1.0001f); int b1 = 1; na.setNode(1, 1, 2); int c2 = 2; na.setNode(2, 0.5f, 4.5f); int d3 = 3; na.setNode(3, 1.5f, 3.8f); int e4 = 4; na.setNode(4, 2.01f, 0.5f); int f5 = 5; na.setNode(5, 2, 3); int g6 = 6; na.setNode(6, 3, 1.5f); int h7 = 7; na.setNode(7, 2.99f, 3.01f); int i8 = 8; na.setNode(8, 3, 4); int j9 = 9; na.setNode(9, 3.3f, 2.2f); int k10 = 10; na.setNode(10, 4, 1); int l11 = 11; na.setNode(11, 4.1f, 3); int m12 = 12; na.setNode(12, 4, 4.5f); int n13 = 13; na.setNode(13, 4.5f, 4.1f); int o14 = 14; na.setNode(14, 5, 0); int p15 = 15; na.setNode(15, 4.9f, 2.5f); int q16 = 16; na.setNode(16, 5, 5); // => 17 locations graph.edge(a0, b1, 1, true); graph.edge(c2, b1, 1, true); graph.edge(c2, d3, 1, true); graph.edge(f5, b1, 1, true); graph.edge(e4, f5, 1, true); graph.edge(m12, d3, 1, true); graph.edge(e4, k10, 1, true); graph.edge(f5, d3, 1, true); graph.edge(f5, i8, 1, true); graph.edge(f5, j9, 1, true); graph.edge(k10, g6, 1, true); graph.edge(j9, l11, 1, true); graph.edge(i8, l11, 1, true); graph.edge(i8, h7, 1, true); graph.edge(k10, n13, 1, true); graph.edge(k10, o14, 1, true); graph.edge(l11, p15, 1, true); graph.edge(m12, p15, 1, true); graph.edge(q16, p15, 1, true); graph.edge(q16, m12, 1, true); return graph; }