use of com.graphhopper.util.EdgeIterator in project graphhopper by graphhopper.
the class TarjansSCCAlgorithm method strongConnect.
/**
* Find all components reachable from firstNode, add them to 'components'
* <p>
*
* @param firstNode start search of SCC at this node
*/
private void strongConnect(int firstNode) {
final Stack<TarjanState> stateStack = new Stack<TarjanState>();
stateStack.push(TarjanState.startState(firstNode));
// nextState label is equivalent to the function entry point in the recursive Tarjan's algorithm.
nextState: while (!stateStack.empty()) {
TarjanState state = stateStack.pop();
final int start = state.start;
final EdgeIterator iter;
if (state.isStart()) {
// We're traversing a new node 'start'. Set the depth index for this node to the smallest unused index.
nodeIndex[start] = index;
nodeLowLink[start] = index;
index++;
nodeStack.addLast(start);
onStack.add(start);
iter = graph.createEdgeExplorer(edgeFilter).setBaseNode(start);
} else {
// We're resuming iteration over the next child of 'start', set lowLink as appropriate.
iter = state.iter;
int prevConnectedId = iter.getAdjNode();
nodeLowLink[start] = Math.min(nodeLowLink[start], nodeLowLink[prevConnectedId]);
}
// a successor with a lower nodeLowLink.
while (iter.next()) {
int connectedId = iter.getAdjNode();
if (ignoreSet.contains(start))
continue;
if (nodeIndex[connectedId] == 0) {
// Push resume and start states onto state stack to continue our DFS through the graph after the jump.
// Ideally we'd just call strongConnectIterative(connectedId);
stateStack.push(TarjanState.resumeState(start, iter));
stateStack.push(TarjanState.startState(connectedId));
continue nextState;
} else if (onStack.contains(connectedId)) {
nodeLowLink[start] = Math.min(nodeLowLink[start], nodeIndex[connectedId]);
}
}
// Add all nodes higher up on nodeStack to this component.
if (nodeIndex[start] == nodeLowLink[start]) {
IntArrayList component = new IntArrayList();
int node;
while ((node = nodeStack.removeLast()) != start) {
component.add(node);
onStack.remove(node);
}
component.add(start);
component.trimToSize();
onStack.remove(start);
components.add(component);
}
}
}
use of com.graphhopper.util.EdgeIterator in project graphhopper by graphhopper.
the class AbstractEdgeElevationInterpolator method interpolateElevationsOfPillarNodes.
private void interpolateElevationsOfPillarNodes() {
final EdgeIterator edge = storage.getAllEdges();
final NodeAccess nodeAccess = storage.getNodeAccess();
while (edge.next()) {
if (isInterpolatableEdge(edge)) {
int firstNodeId = edge.getBaseNode();
int secondNodeId = edge.getAdjNode();
double lat0 = nodeAccess.getLat(firstNodeId);
double lon0 = nodeAccess.getLon(firstNodeId);
double ele0 = nodeAccess.getEle(firstNodeId);
double lat1 = nodeAccess.getLat(secondNodeId);
double lon1 = nodeAccess.getLon(secondNodeId);
double ele1 = nodeAccess.getEle(secondNodeId);
final PointList pointList = edge.fetchWayGeometry(0);
final int count = pointList.size();
for (int index = 0; index < count; index++) {
double lat = pointList.getLat(index);
double lon = pointList.getLon(index);
double ele = elevationInterpolator.calculateElevationBasedOnTwoPoints(lat, lon, lat0, lon0, ele0, lat1, lon1, ele1);
pointList.set(index, lat, lon, ele);
}
edge.setWayGeometry(pointList);
}
}
}
use of com.graphhopper.util.EdgeIterator in project graphhopper by graphhopper.
the class DijkstraOneToMany method findEndNode.
public int findEndNode(int from, int to) {
if (weights.length < 2)
return NOT_FOUND;
this.to = to;
if (doClear) {
doClear = false;
int vn = changedNodes.size();
for (int i = 0; i < vn; i++) {
int n = changedNodes.get(i);
weights[n] = Double.MAX_VALUE;
parents[n] = EMPTY_PARENT;
edgeIds[n] = EdgeIterator.NO_EDGE;
}
heap.clear();
// changedNodes.clear();
changedNodes.elementsCount = 0;
currNode = from;
if (!traversalMode.isEdgeBased()) {
weights[currNode] = 0;
changedNodes.add(currNode);
}
} else {
// Cached! Re-use existing data structures
int parentNode = parents[to];
if (parentNode != EMPTY_PARENT && weights[to] <= weights[currNode])
return to;
if (heap.isEmpty() || isMaxVisitedNodesExceeded())
return NOT_FOUND;
currNode = heap.poll_element();
}
visitedNodes = 0;
// we call 'finished' before heap.peek_element but this would add unnecessary overhead for this special case so we do it outside of the loop
if (finished()) {
// then we need a small workaround for special cases see #707
if (heap.isEmpty())
doClear = true;
return currNode;
}
while (true) {
visitedNodes++;
EdgeIterator iter = outEdgeExplorer.setBaseNode(currNode);
while (iter.next()) {
int adjNode = iter.getAdjNode();
int prevEdgeId = edgeIds[adjNode];
if (!accept(iter, prevEdgeId))
continue;
double tmpWeight = weighting.calcWeight(iter, false, prevEdgeId) + weights[currNode];
if (Double.isInfinite(tmpWeight))
continue;
double w = weights[adjNode];
if (w == Double.MAX_VALUE) {
parents[adjNode] = currNode;
weights[adjNode] = tmpWeight;
heap.insert_(tmpWeight, adjNode);
changedNodes.add(adjNode);
edgeIds[adjNode] = iter.getEdge();
} else if (w > tmpWeight) {
parents[adjNode] = currNode;
weights[adjNode] = tmpWeight;
heap.update_(tmpWeight, adjNode);
changedNodes.add(adjNode);
edgeIds[adjNode] = iter.getEdge();
}
}
if (heap.isEmpty() || isMaxVisitedNodesExceeded() || isWeightLimitExceeded())
return NOT_FOUND;
// calling just peek and not poll is important if the next query is cached
currNode = heap.peek_element();
if (finished())
return currNode;
heap.poll_element();
}
}
use of com.graphhopper.util.EdgeIterator in project graphhopper by graphhopper.
the class AbstractLocationIndexTester method testDifferentVehicles.
@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);
}
use of com.graphhopper.util.EdgeIterator in project graphhopper by graphhopper.
the class AStar method runAlgo.
private Path runAlgo() {
double currWeightToGoal, estimationFullWeight;
EdgeExplorer explorer = outEdgeExplorer;
while (true) {
int currVertex = currEdge.adjNode;
visitedCount++;
if (isMaxVisitedNodesExceeded())
return createEmptyPath();
if (finished())
break;
EdgeIterator iter = explorer.setBaseNode(currVertex);
while (iter.next()) {
if (!accept(iter, currEdge.edge))
continue;
double alreadyVisitedWeight = weighting.calcWeight(iter, false, currEdge.edge) + currEdge.weightOfVisitedPath;
if (Double.isInfinite(alreadyVisitedWeight))
continue;
int traversalId = traversalMode.createTraversalId(iter, false);
AStarEntry ase = fromMap.get(traversalId);
if (ase == null || ase.weightOfVisitedPath > alreadyVisitedWeight) {
int neighborNode = iter.getAdjNode();
currWeightToGoal = weightApprox.approximate(neighborNode);
estimationFullWeight = alreadyVisitedWeight + currWeightToGoal;
if (ase == null) {
ase = new AStarEntry(iter.getEdge(), neighborNode, estimationFullWeight, alreadyVisitedWeight);
fromMap.put(traversalId, ase);
} else {
// assert (ase.weight > 0.9999999 * estimationFullWeight) : "Inconsistent distance estimate. It is expected weight >= estimationFullWeight but was "
// + ase.weight + " < " + estimationFullWeight + " (" + ase.weight / estimationFullWeight + "), and weightOfVisitedPath:"
// + ase.weightOfVisitedPath + " vs. alreadyVisitedWeight:" + alreadyVisitedWeight + " (" + ase.weightOfVisitedPath / alreadyVisitedWeight + ")";
prioQueueOpenSet.remove(ase);
ase.edge = iter.getEdge();
ase.weight = estimationFullWeight;
ase.weightOfVisitedPath = alreadyVisitedWeight;
}
ase.parent = currEdge;
prioQueueOpenSet.add(ase);
updateBestPath(iter, ase, traversalId);
}
}
if (prioQueueOpenSet.isEmpty())
return createEmptyPath();
currEdge = prioQueueOpenSet.poll();
if (currEdge == null)
throw new AssertionError("Empty edge cannot happen");
}
return extractPath();
}
Aggregations