use of com.graphhopper.coll.GHBitSetImpl in project graphhopper by graphhopper.
the class AbstractEdgeElevationInterpolator method interpolateElevationsOfTowerNodes.
private void interpolateElevationsOfTowerNodes() {
final AllEdgesIterator edge = storage.getAllEdges();
final GHBitSet visitedEdgeIds = new GHBitSetImpl(edge.getMaxId());
final EdgeExplorer edgeExplorer = storage.createEdgeExplorer();
while (edge.next()) {
final int edgeId = edge.getEdge();
if (isInterpolatableEdge(edge)) {
if (!visitedEdgeIds.contains(edgeId)) {
interpolateEdge(edge, visitedEdgeIds, edgeExplorer);
}
}
visitedEdgeIds.add(edgeId);
}
}
use of com.graphhopper.coll.GHBitSetImpl in project graphhopper by graphhopper.
the class Location2IDQuadtree method fillQuadtree.
private GHBitSet fillQuadtree(int size) {
int locs = graph.getNodes();
if (locs <= 0) {
throw new IllegalStateException("check your graph - it is empty!");
}
GHBitSet filledIndices = new GHBitSetImpl(size);
GHPoint coord = new GHPoint();
for (int nodeId = 0; nodeId < locs; nodeId++) {
double lat = nodeAccess.getLatitude(nodeId);
double lon = nodeAccess.getLongitude(nodeId);
int key = (int) keyAlgo.encode(lat, lon);
long bytePos = (long) key * 4;
if (filledIndices.contains(key)) {
int oldNodeId = index.getInt(bytePos);
keyAlgo.decode(key, coord);
// decide which one is closer to 'key'
double distNew = distCalc.calcNormalizedDist(coord.lat, coord.lon, lat, lon);
double oldLat = nodeAccess.getLatitude(oldNodeId);
double oldLon = nodeAccess.getLongitude(oldNodeId);
double distOld = distCalc.calcNormalizedDist(coord.lat, coord.lon, oldLat, oldLon);
// new point is closer to quad tree point (key) so overwrite old
if (distNew < distOld) {
index.setInt(bytePos, nodeId);
}
} else {
index.setInt(bytePos, nodeId);
filledIndices.add(key);
}
}
return filledIndices;
}
use of com.graphhopper.coll.GHBitSetImpl in project graphhopper by graphhopper.
the class PrepareRoutingSubnetworks method findSubnetworks.
/**
* This method finds the double linked components according to the specified filter.
*/
List<IntArrayList> findSubnetworks(PrepEdgeFilter filter) {
final FlagEncoder encoder = filter.getEncoder();
final EdgeExplorer explorer = ghStorage.createEdgeExplorer(filter);
int locs = ghStorage.getNodes();
List<IntArrayList> list = new ArrayList<IntArrayList>(100);
final GHBitSet bs = new GHBitSetImpl(locs);
for (int start = 0; start < locs; start++) {
if (bs.contains(start))
continue;
final IntArrayList intList = new IntArrayList(20);
list.add(intList);
new BreadthFirstSearch() {
int tmpCounter = 0;
@Override
protected GHBitSet createBitSet() {
return bs;
}
@Override
protected final boolean goFurther(int nodeId) {
if (tmpCounter > maxEdgesPerNode.get())
maxEdgesPerNode.set(tmpCounter);
tmpCounter = 0;
intList.add(nodeId);
return true;
}
@Override
protected final boolean checkAdjacent(EdgeIteratorState edge) {
if (encoder.isForward(edge.getFlags()) || encoder.isBackward(edge.getFlags())) {
tmpCounter++;
return true;
}
return false;
}
}.start(explorer, start);
intList.trimToSize();
}
return list;
}
use of com.graphhopper.coll.GHBitSetImpl in project graphhopper by graphhopper.
the class BaseGraph method inPlaceNodeRemove.
/**
* This methods disconnects all edges from removed nodes. It does no edge compaction. Then it
* moves the last nodes into the deleted nodes, where it needs to update the node ids in every
* edge.
*/
void inPlaceNodeRemove(int removeNodeCount) {
// Prepare edge-update of nodes which are connected to deleted nodes
int toMoveNodes = getNodes();
int itemsToMove = 0;
// sorted map when we access it via keyAt and valueAt - see below!
final SparseIntIntArray oldToNewMap = new SparseIntIntArray(removeNodeCount);
GHBitSet toRemoveSet = new GHBitSetImpl(removeNodeCount);
removedNodes.copyTo(toRemoveSet);
Logger logger = LoggerFactory.getLogger(getClass());
if (removeNodeCount > getNodes() / 2.0)
logger.warn("More than a half of the network should be removed!? " + "Nodes:" + getNodes() + ", remove:" + removeNodeCount);
EdgeExplorer delExplorer = createEdgeExplorer();
// create map of old node ids pointing to new ids
for (int removeNode = removedNodes.next(0); removeNode >= 0; removeNode = removedNodes.next(removeNode + 1)) {
EdgeIterator delEdgesIter = delExplorer.setBaseNode(removeNode);
while (delEdgesIter.next()) {
toRemoveSet.add(delEdgesIter.getAdjNode());
}
toMoveNodes--;
for (; toMoveNodes >= 0; toMoveNodes--) {
if (!removedNodes.contains(toMoveNodes))
break;
}
if (toMoveNodes >= removeNode)
oldToNewMap.put(toMoveNodes, removeNode);
itemsToMove++;
}
EdgeIterable adjNodesToDelIter = (EdgeIterable) createEdgeExplorer();
// all deleted nodes could be connected to existing. remove the connections
for (int removeNode = toRemoveSet.next(0); removeNode >= 0; removeNode = toRemoveSet.next(removeNode + 1)) {
// remove all edges connected to the deleted nodes
adjNodesToDelIter.setBaseNode(removeNode);
long prev = EdgeIterator.NO_EDGE;
while (adjNodesToDelIter.next()) {
int nodeId = adjNodesToDelIter.getAdjNode();
// already invalidated
if (nodeId != EdgeAccess.NO_NODE && removedNodes.contains(nodeId)) {
int edgeToRemove = adjNodesToDelIter.getEdge();
long edgeToRemovePointer = edgeAccess.toPointer(edgeToRemove);
edgeAccess.internalEdgeDisconnect(edgeToRemove, prev, removeNode, nodeId);
edgeAccess.invalidateEdge(edgeToRemovePointer);
} else {
prev = adjNodesToDelIter.edgePointer;
}
}
}
GHBitSet toMoveSet = new GHBitSetImpl(removeNodeCount * 3);
EdgeExplorer movedEdgeExplorer = createEdgeExplorer();
// marks connected nodes to rewrite the edges
for (int i = 0; i < itemsToMove; i++) {
int oldI = oldToNewMap.keyAt(i);
EdgeIterator movedEdgeIter = movedEdgeExplorer.setBaseNode(oldI);
while (movedEdgeIter.next()) {
int nodeId = movedEdgeIter.getAdjNode();
if (nodeId == EdgeAccess.NO_NODE)
continue;
if (removedNodes.contains(nodeId))
throw new IllegalStateException("shouldn't happen the edge to the node " + nodeId + " should be already deleted. " + oldI);
toMoveSet.add(nodeId);
}
}
// move nodes into deleted nodes
for (int i = 0; i < itemsToMove; i++) {
int oldI = oldToNewMap.keyAt(i);
int newI = oldToNewMap.valueAt(i);
long newOffset = (long) newI * nodeEntryBytes;
long oldOffset = (long) oldI * nodeEntryBytes;
for (long j = 0; j < nodeEntryBytes; j += 4) {
nodes.setInt(newOffset + j, nodes.getInt(oldOffset + j));
}
}
// *rewrites* all edges connected to moved nodes
// go through all edges and pick the necessary <- this is easier to implement than
// a more efficient (?) breadth-first search
EdgeIterator iter = getAllEdges();
while (iter.next()) {
int nodeA = iter.getBaseNode();
int nodeB = iter.getAdjNode();
if (!toMoveSet.contains(nodeA) && !toMoveSet.contains(nodeB))
continue;
// now overwrite exiting edge with new node ids
// also flags and links could have changed due to different node order
int updatedA = oldToNewMap.get(nodeA);
if (updatedA < 0)
updatedA = nodeA;
int updatedB = oldToNewMap.get(nodeB);
if (updatedB < 0)
updatedB = nodeB;
int edgeId = iter.getEdge();
long edgePointer = edgeAccess.toPointer(edgeId);
int linkA = edgeAccess.getEdgeRef(nodeA, nodeB, edgePointer);
int linkB = edgeAccess.getEdgeRef(nodeB, nodeA, edgePointer);
long flags = edgeAccess.getFlags_(edgePointer, false);
edgeAccess.writeEdge(edgeId, updatedA, updatedB, linkA, linkB);
edgeAccess.setFlags_(edgePointer, updatedA > updatedB, flags);
if (updatedA < updatedB != nodeA < nodeB)
setWayGeometry_(fetchWayGeometry_(edgePointer, true, 0, -1, -1), edgePointer, false);
}
// clear N_EDGE_REF
initNodeRefs((nodeCount - removeNodeCount) * nodeEntryBytes, nodeCount * nodeEntryBytes);
if (removeNodeCount >= nodeCount)
throw new IllegalStateException("graph is empty after in-place removal but was " + removeNodeCount);
// we do not remove the invalid edges => edgeCount stays the same!
nodeCount -= removeNodeCount;
// health check
if (isTestingEnabled()) {
EdgeExplorer explorer = createEdgeExplorer();
iter = getAllEdges();
while (iter.next()) {
int base = iter.getBaseNode();
int adj = iter.getAdjNode();
String str = iter.getEdge() + ", r.contains(" + base + "):" + removedNodes.contains(base) + ", r.contains(" + adj + "):" + removedNodes.contains(adj) + ", tr.contains(" + base + "):" + toRemoveSet.contains(base) + ", tr.contains(" + adj + "):" + toRemoveSet.contains(adj) + ", base:" + base + ", adj:" + adj + ", nodeCount:" + nodeCount;
if (adj >= nodeCount)
throw new RuntimeException("Adj.node problem with edge " + str);
if (base >= nodeCount)
throw new RuntimeException("Base node problem with edge " + str);
try {
explorer.setBaseNode(adj).toString();
} catch (Exception ex) {
org.slf4j.LoggerFactory.getLogger(getClass()).error("adj:" + adj);
}
try {
explorer.setBaseNode(base).toString();
} catch (Exception ex) {
org.slf4j.LoggerFactory.getLogger(getClass()).error("base:" + base);
}
}
// access last node -> no error
explorer.setBaseNode(nodeCount - 1).toString();
}
removedNodes = null;
}
use of com.graphhopper.coll.GHBitSetImpl in project graphhopper by graphhopper.
the class Location2IDQuadtree method fillEmptyIndices.
private int fillEmptyIndices(GHBitSet filledIndices) {
int len = latSize * lonSize;
DataAccess indexCopy = new RAMDirectory().find("temp_index_copy");
indexCopy.setSegmentSize(index.getSegmentSize()).create(index.getCapacity());
GHBitSet indicesCopy = new GHBitSetImpl(len);
int initializedCounter = filledIndices.getCardinality();
// fan out initialized entries to avoid "nose-artifacts"
// we 1. do not use the same index for check and set and iterate until all indices are set
// and 2. use a taken-from array to decide which of the colliding should be preferred
int[] takenFrom = new int[len];
Arrays.fill(takenFrom, -1);
for (int i = filledIndices.next(0); i >= 0; i = filledIndices.next(i + 1)) {
takenFrom[i] = i;
}
if (initializedCounter == 0) {
throw new IllegalStateException("at least one entry has to be != null, which should have happened in initIndex");
}
int tmp = initializedCounter;
while (initializedCounter < len) {
index.copyTo(indexCopy);
filledIndices.copyTo(indicesCopy);
initializedCounter = filledIndices.getCardinality();
for (int i = 0; i < len; i++) {
int to = -1, from = -1;
if (indicesCopy.contains(i)) {
// check change "initialized to empty"
if ((i + 1) % lonSize != 0 && !indicesCopy.contains(i + 1)) {
// set right from current
from = i;
to = i + 1;
} else if (i + lonSize < len && !indicesCopy.contains(i + lonSize)) {
// set below from current
from = i;
to = i + lonSize;
}
} else // check change "empty to initialized"
if ((i + 1) % lonSize != 0 && indicesCopy.contains(i + 1)) {
// set from right
from = i + 1;
to = i;
} else if (i + lonSize < len && indicesCopy.contains(i + lonSize)) {
// set from below
from = i + lonSize;
to = i;
}
if (to >= 0) {
if (takenFrom[to] >= 0) {
// takenFrom[to] == to -> special case for normedDist == 0
if (takenFrom[to] == to || getNormedDist(from, to) >= getNormedDist(takenFrom[to], to)) {
continue;
}
}
index.setInt(to * 4, indexCopy.getInt(from * 4));
takenFrom[to] = takenFrom[from];
filledIndices.add(to);
initializedCounter++;
}
}
}
return initializedCounter - tmp;
}
Aggregations