@Override public int getBaseNode() { return edges.get(current).getBaseNode(); }
@Override public String toString() { if (closestEdge != null) return closestEdge.getBaseNode() + "-" + closestEdge.getAdjNode() + " " + snappedPoint; return closestNode + ", " + queryPoint + ", " + wayIndex; }
public void gatherOuterAndInnerNodeIds(final EdgeExplorer edgeExplorer, final EdgeIteratorState interpolatableEdge, final GHBitSet visitedEdgesIds, final IntSet outerNodeIds, final GHIntHashSet innerNodeIds) { final BreadthFirstSearch gatherOuterAndInnerNodeIdsSearch = new BreadthFirstSearch() { @Override protected boolean checkAdjacent(EdgeIteratorState edge) { visitedEdgesIds.add(edge.getEdge()); final int baseNodeId = edge.getBaseNode(); boolean isInterpolatableEdge = isInterpolatableEdge(edge); if (!isInterpolatableEdge) { innerNodeIds.remove(baseNodeId); outerNodeIds.add(baseNodeId); } else if (!outerNodeIds.contains(baseNodeId)) { innerNodeIds.add(baseNodeId); } return isInterpolatableEdge; } }; gatherOuterAndInnerNodeIdsSearch.start(edgeExplorer, interpolatableEdge.getBaseNode()); }
private static void printUnitTestEdge(FlagEncoder flagEncoder, EdgeIteratorState edge) { boolean fwd = edge.isForward(flagEncoder); boolean bwd = edge.isBackward(flagEncoder); if (!fwd && !bwd) { return; } int from = fwd ? edge.getBaseNode() : edge.getAdjNode(); int to = fwd ? edge.getAdjNode() : edge.getBaseNode(); System.out.printf(Locale.ROOT, "graph.edge(%d, %d, %f, %s);\n", from, to, edge.getDistance(), fwd && bwd ? "true" : "false"); }
@Override public double calcWeight(EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) { double weight = superWeighting.calcWeight(edgeState, reverse, prevOrNextEdgeId); if (prevOrNextEdgeId == EdgeIterator.NO_EDGE) return weight; int edgeId = edgeState.getEdge(); double turnCosts; if (reverse) turnCosts = calcTurnWeight(edgeId, edgeState.getBaseNode(), prevOrNextEdgeId); else turnCosts = calcTurnWeight(prevOrNextEdgeId, edgeState.getBaseNode(), edgeId); if (turnCosts == 0 && edgeId == prevOrNextEdgeId) return weight + defaultUTurnCost; return weight + turnCosts; }
@Override public long calcMillis(EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) { long millis = superWeighting.calcMillis(edgeState, reverse, prevOrNextEdgeId); if (prevOrNextEdgeId == EdgeIterator.NO_EDGE) return millis; // TODO for now assume turn costs are returned in milliseconds? // should we also separate weighting vs. time for turn? E.g. a fast but dangerous turn - is this common? long turnCostsInMillis; if (reverse) turnCostsInMillis = (long) calcTurnWeight(edgeState.getEdge(), edgeState.getBaseNode(), prevOrNextEdgeId); else turnCostsInMillis = (long) calcTurnWeight(prevOrNextEdgeId, edgeState.getBaseNode(), edgeState.getEdge()); return millis + turnCostsInMillis; }
@Override public boolean accept(EdgeIteratorState iter) { return iter.getBaseNode() == 2 || iter.getAdjNode() == 2; } }).getClosestNode());
/** * This method adds the traversal IDs of the specified path as set to the specified map. */ AtomicInteger addToMap(GHIntObjectHashMap<IntSet> map, Path path) { IntSet set = new GHIntHashSet(); final AtomicInteger startTID = new AtomicInteger(-1); for (EdgeIteratorState iterState : path.calcEdges()) { int tid = traversalMode.createTraversalId(iterState, false); set.add(tid); if (startTID.get() < 0) { // for node based traversal we need to explicitely add base node as starting node and to list if (!traversalMode.isEdgeBased()) { tid = iterState.getBaseNode(); set.add(tid); } startTID.set(tid); } } map.put(startTID.get(), set); return startTID; } }
@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); } }
/** * Returns the identifier to access the map of the shortest path tree according to the traversal * mode. E.g. returning the adjacent node id in node-based behavior whilst returning the edge id * in edge-based behavior * <p> * * @param iterState the current {@link EdgeIteratorState} * @param reverse <code>true</code>, if traversal in backward direction. Will be true only for * backward searches in bidirectional algorithms. * @return the identifier to access the shortest path tree */ public final int createTraversalId(EdgeIteratorState iterState, boolean reverse) { if (edgeBased) { if (noOfStates == 1) return iterState.getEdge(); return GHUtility.createEdgeKey(iterState.getBaseNode(), iterState.getAdjNode(), iterState.getEdge(), reverse); } return iterState.getAdjNode(); }
@Override public List<Path> calcPaths(QueryGraph queryGraph, RoutingAlgorithmFactory algoFactory, AlgorithmOptions algoOpts) { pathList = new ArrayList<>(queryResults.size() - 1); AvoidEdgesWeighting avoidPathWeighting = new AvoidEdgesWeighting(algoOpts.getWeighting()); avoidPathWeighting.setEdgePenaltyFactor(5); algoOpts = AlgorithmOptions.start(algoOpts). algorithm(Parameters.Algorithms.ASTAR_BI). weighting(avoidPathWeighting).build(); algoOpts.getHints().put(Algorithms.AStarBi.EPSILON, 2); long visitedNodesSum = 0L; QueryResult start = queryResults.get(0); for (int qrIndex = 1; qrIndex < queryResults.size(); qrIndex++) { RoutingAlgorithm algo = algoFactory.createAlgo(queryGraph, algoOpts); // instead getClosestNode (which might be a virtual one and introducing unnecessary tails of the route) // use next tower node -> getBaseNode or getAdjNode // Later: remove potential route tail QueryResult startQR = queryResults.get(qrIndex - 1); int startNode = (startQR == start) ? startQR.getClosestNode() : startQR.getClosestEdge().getBaseNode(); QueryResult endQR = queryResults.get(qrIndex); int endNode = (endQR == start) ? endQR.getClosestNode() : endQR.getClosestEdge().getBaseNode(); Path path = algo.calcPath(startNode, endNode); visitedNodesSum += algo.getVisitedNodes(); pathList.add(path); // it is important to avoid previously visited nodes for future paths avoidPathWeighting.addEdges(path.calcEdges()); } ghResponse.getHints().put("visited_nodes.sum", visitedNodesSum); ghResponse.getHints().put("visited_nodes.average", (float) visitedNodesSum / (queryResults.size() - 1)); return pathList; }
private String getCoords(EdgeIteratorState edge, Graph graph) { NodeAccess na = graph.getNodeAccess(); int base = edge.getBaseNode(); int adj = edge.getAdjNode(); return base + "->" + adj + " (" + edge.getEdge() + "); " + na.getLat(base) + "," + na.getLon(base) + " -> " + na.getLat(adj) + "," + na.getLon(adj); }
@Override protected boolean checkAdjacent(EdgeIteratorState edge) { visitedEdgesIds.add(edge.getEdge()); final int baseNodeId = edge.getBaseNode(); boolean isInterpolatableEdge = isInterpolatableEdge(edge); if (!isInterpolatableEdge) { innerNodeIds.remove(baseNodeId); outerNodeIds.add(baseNodeId); } else if (!outerNodeIds.contains(baseNodeId)) { innerNodeIds.add(baseNodeId); } return isInterpolatableEdge; } };
/** * Iterates over all edges in this path sorted from start to end and calls the visitor callback * for every edge. * <p> * * @param visitor callback to handle every edge. The edge is decoupled from the iterator and can * be stored. */ private void forEveryEdge(EdgeVisitor visitor) { int tmpNode = getFromNode(); int len = edgeIds.size(); int prevEdgeId = EdgeIterator.NO_EDGE; for (int i = 0; i < len; i++) { EdgeIteratorState edgeBase = graph.getEdgeIteratorState(edgeIds.get(i), tmpNode); if (edgeBase == null) throw new IllegalStateException("Edge " + edgeIds.get(i) + " was empty when requested with node " + tmpNode + ", array index:" + i + ", edges:" + edgeIds.size()); tmpNode = edgeBase.getBaseNode(); // more efficient swap, currently not implemented for virtual edges: visitor.next(edgeBase.detach(true), i); edgeBase = graph.getEdgeIteratorState(edgeBase.getEdge(), tmpNode); visitor.next(edgeBase, i, prevEdgeId); prevEdgeId = edgeBase.getEdge(); } visitor.finish(); }
/** * Creates query result on edge (node1-node2) very close to node1. */ QueryResult newQR(Graph graph, int node1, int node2) { EdgeIteratorState edge = GHUtility.getEdge(graph, node1, node2); if (edge == null) throw new IllegalStateException("edge not found? " + node1 + "-" + node2); NodeAccess na = graph.getNodeAccess(); double lat = na.getLatitude(edge.getBaseNode()); double lon = na.getLongitude(edge.getBaseNode()); double latAdj = na.getLatitude(edge.getAdjNode()); double lonAdj = na.getLongitude(edge.getAdjNode()); // calculate query point near the base node but not directly on it! QueryResult res = new QueryResult(lat + (latAdj - lat) * .1, lon + (lonAdj - lon) * .1); res.setClosestNode(edge.getBaseNode()); res.setClosestEdge(edge); res.setWayIndex(0); res.setSnappedPosition(QueryResult.Position.EDGE); res.calcSnappedPoint(distCalc); return res; }
@Override public double calcWeight(EdgeIteratorState edgeState, boolean reverse, int prevOrNextEdgeId) { int adj = edgeState.getAdjNode(); int base = edgeState.getBaseNode(); if (reverse) { int tmp = base; base = adj; adj = tmp; } // a 'hill' at node 6 if (adj == 6) return 3 * edgeState.getDistance(); else if (base == 6) return edgeState.getDistance() * 0.9; else if (adj == 4) return 2 * edgeState.getDistance(); return edgeState.getDistance() * 0.8; }
@Override public void disconnect(CHEdgeExplorer explorer, EdgeIteratorState edgeState) { // search edge with opposite direction but we need to know the previousEdge for the internalEdgeDisconnect so we cannot simply do: // EdgeIteratorState tmpIter = getEdgeProps(iter.getEdge(), iter.getBaseNode()); CHEdgeIterator tmpIter = explorer.setBaseNode(edgeState.getAdjNode()); int tmpPrevEdge = EdgeIterator.NO_EDGE; while (tmpIter.next()) { if (tmpIter.isShortcut() && tmpIter.getEdge() == edgeState.getEdge()) { // TODO this is ugly, move this somehow into the underlying iteration logic long edgePointer = tmpPrevEdge == EdgeIterator.NO_EDGE ? -1 : isShortcut(tmpPrevEdge) ? chEdgeAccess.toPointer(tmpPrevEdge) : baseGraph.edgeAccess.toPointer(tmpPrevEdge); chEdgeAccess.internalEdgeDisconnect(edgeState.getEdge(), edgePointer, edgeState.getAdjNode(), edgeState.getBaseNode()); break; } tmpPrevEdge = tmpIter.getEdge(); } }
@Test public void testEdgeReturn() { graph = createGHStorage(); EdgeIteratorState iter = graph.edge(4, 10).setDistance(100).setFlags(carEncoder.setProperties(10, true, false)); assertEquals(4, iter.getBaseNode()); assertEquals(10, iter.getAdjNode()); iter = graph.edge(14, 10).setDistance(100).setFlags(carEncoder.setProperties(10, true, false)); assertEquals(14, iter.getBaseNode()); assertEquals(10, iter.getAdjNode()); }
assertEquals(2, iter.getBaseNode()); assertEquals(0, iter.getAdjNode()); assertEquals(20, iter.getDistance(), 1e-5); assertEquals(0, iter.getBaseNode()); assertEquals(2, iter.getAdjNode()); assertEquals(20, iter.getDistance(), 1e-5); assertEquals(0, iter.getBaseNode()); assertEquals(2, iter.getAdjNode()); iter = graph.getEdgeIteratorState(edgeId, 1);
@Test public void internalDisconnect() { GraphHopperStorage storage = createGHStorage(); BaseGraph graph = (BaseGraph) storage.getGraph(Graph.class); EdgeIteratorState iter0 = graph.edge(0, 1, 10, true); EdgeIteratorState iter2 = graph.edge(1, 2, 10, true); EdgeIteratorState iter3 = graph.edge(0, 3, 10, true); EdgeExplorer explorer = graph.createEdgeExplorer(); assertEquals(GHUtility.asSet(3, 1), GHUtility.getNeighbors(explorer.setBaseNode(0))); assertEquals(GHUtility.asSet(2, 0), GHUtility.getNeighbors(explorer.setBaseNode(1))); // remove edge "1-2" but only from 1 not from 2 graph.edgeAccess.internalEdgeDisconnect(iter2.getEdge(), -1, iter2.getBaseNode(), iter2.getAdjNode()); assertEquals(GHUtility.asSet(0), GHUtility.getNeighbors(explorer.setBaseNode(1))); assertEquals(GHUtility.asSet(1), GHUtility.getNeighbors(explorer.setBaseNode(2))); // let 0 unchanged -> no side effects assertEquals(GHUtility.asSet(3, 1), GHUtility.getNeighbors(explorer.setBaseNode(0))); // remove edge "0-1" but only from 0 graph.edgeAccess.internalEdgeDisconnect(iter0.getEdge(), (long) iter3.getEdge() * graph.edgeEntryBytes, iter0.getBaseNode(), iter0.getAdjNode()); assertEquals(GHUtility.asSet(3), GHUtility.getNeighbors(explorer.setBaseNode(0))); assertEquals(GHUtility.asSet(0), GHUtility.getNeighbors(explorer.setBaseNode(3))); assertEquals(GHUtility.asSet(0), GHUtility.getNeighbors(explorer.setBaseNode(1))); storage.close(); }