use of org.hortonmachine.gears.utils.BitMatrix in project hortonmachine by TheHortonMachine.
the class TestGeneric method testBitMatrix.
public void testBitMatrix() throws Exception {
BitMatrix m = new BitMatrix(5, 5);
m.mark(0, 0);
m.mark(1, 1);
m.mark(2, 2);
m.mark(3, 3);
m.mark(4, 4);
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
boolean isMarked = m.isMarked(i, j);
if (i == j) {
assertTrue(isMarked);
} else {
assertFalse(isMarked);
}
}
}
}
use of org.hortonmachine.gears.utils.BitMatrix in project hortonmachine by TheHortonMachine.
the class OmsDePitter method processPitNode.
private void processPitNode(GridNode originalPitNode, BitMatrix allPitsPositions, int count, WritableRandomIter pitIter) {
if (allPitsPositions.isMarked(originalPitNode.col, originalPitNode.row)) {
if (verbose)
pm.worked(1);
return;
}
List<GridNode> nodesInPit = new ArrayList<>();
nodesInPit.add(originalPitNode);
allPitsPositions.mark(originalPitNode.col, originalPitNode.row);
int workingIndex = 0;
double minExitValue = Double.POSITIVE_INFINITY;
TreeSet<GridNode> orderedExitNodes = new TreeSet<>(new Comparator<GridNode>() {
@Override
public int compare(GridNode o1, GridNode o2) {
// argument is less than, equal to, or greater than the second.
if (o1.elevation < o2.elevation) {
return -1;
} else if (o1.elevation > o2.elevation) {
return 1;
} else
return 0;
}
});
processSinglePit: {
boolean surroundingAdded = true;
while (surroundingAdded) {
surroundingAdded = false;
while (workingIndex < nodesInPit.size()) {
if (pm.isCanceled()) {
return;
}
GridNode currentPitNode = nodesInPit.get(workingIndex);
List<GridNode> surroundingNodes = new ArrayList<>(currentPitNode.getValidSurroundingNodes());
removeExistingPits(allPitsPositions, surroundingNodes);
GridNode minEqualNode = getMinEqualElevNode(surroundingNodes, allPitsPositions);
if (minEqualNode == null) {
workingIndex++;
continue;
}
List<GridNode> minElevSurroundingNodes = new ArrayList<>(minEqualNode.getValidSurroundingNodes());
removeExistingPits(allPitsPositions, minElevSurroundingNodes);
if (!minEqualNode.isPitFor(minElevSurroundingNodes)) {
/*
* case of a pit that is solved by the nearby exit cell
*/
if (minEqualNode != null && minEqualNode.elevation < minExitValue) {
minExitValue = minEqualNode.elevation;
orderedExitNodes.add(minEqualNode);
}
workingIndex++;
continue;
}
/*
* can't find a non pit exit in the nearest surrounding, therefore
* we need to have a look at all the surrounding and have a look
* of any of those cells are able to flow out somewhere, i.e. are not pit
*/
for (GridNode tmpNode : surroundingNodes) {
if (tmpNode.touchesBound() || !tmpNode.isValid()) {
continue;
}
List<GridNode> subSurroundingNodes = new ArrayList<>(tmpNode.getValidSurroundingNodes());
removeExistingPits(allPitsPositions, subSurroundingNodes);
if (tmpNode.isPitFor(subSurroundingNodes)) {
nodesInPit.add(tmpNode);
allPitsPositions.mark(tmpNode.col, tmpNode.row);
/*
* if the added pit node is the current potential exit
* node, we need to remove the node from the tree
*/
if (orderedExitNodes.size() > 0) {
GridNode potentialExit = orderedExitNodes.first();
if (tmpNode.equals(potentialExit)) {
orderedExitNodes.remove(potentialExit);
if (orderedExitNodes.size() > 0) {
minExitValue = orderedExitNodes.first().elevation;
} else {
minExitValue = Double.POSITIVE_INFINITY;
}
}
}
// GridNode subMinNode =
// getMinEqualElevNode(subSurroundingNodes,
// allPitsPositions);
//
// if (subMinNode != null && subMinNode.elevation <
// minExitValue) {
// minExitValue = subMinNode.elevation;
// minExitValueNode = subMinNode;
// }
}
}
workingIndex++;
}
if (Double.isInfinite(minExitValue)) {
for (GridNode gridNode : nodesInPit) {
if (gridNode.elevation < minExitValue) {
minExitValue = gridNode.elevation;
orderedExitNodes.add(gridNode);
}
}
}
if (Double.isInfinite(minExitValue) || Double.isNaN(minExitValue)) {
throw new RuntimeException("Found invalid value at: " + count);
}
PitInfo info = new PitInfo();
// info.originalPitNode = originalPitNode;
info.pitfillExitNode = orderedExitNodes.first();
info.nodes = nodesInPit;
// processedNodesInPit.addAll(nodesInPit);
GridNode pitfillExitNode = info.pitfillExitNode;
List<GridNode> allPitsOfCurrent = info.nodes;
BitMatrix floodedPositions = new BitMatrix(cols, rows);
List<GridNode> nodesToCheck = new ArrayList<>();
nodesToCheck.add(pitfillExitNode);
floodAndFlow(0, nodesToCheck, pitfillExitNode.elevation, allPitsOfCurrent, floodedPositions, pitIter);
// // update and check broders
// List<GridNode> updated = new ArrayList<>();
// for( GridNode gridNode : nodesInPit ) {
// GridNode updatedNode = new GridNode(pitIter, gridNode.cols,
// gridNode.rows, gridNode.xRes,
// gridNode.yRes, gridNode.col, gridNode.row);
// updated.add(updatedNode);
// }
// nodesInPit = updated;
//
// ConcurrentLinkedQueue<GridNode> surroundingAddedPitNodes =
// getPitsList(nodesInPit, allPitsPositions);
// if (surroundingAddedPitNodes.size() > 0) {
// workingIndex = nodesInPit.size();
// nodesInPit.addAll(surroundingAddedPitNodes);
// surroundingAdded = true;
// for( GridNode gridNode : surroundingAddedPitNodes ) {
// System.out.print(gridNode.col + "/" + gridNode.row + "/" +
// gridNode.elevation + " ");
// allPitsPositions.mark(gridNode.col, gridNode.row);
// }
// System.out.println();
// }
}
// while
}
if (verbose)
pm.worked(1);
}
use of org.hortonmachine.gears.utils.BitMatrix in project hortonmachine by TheHortonMachine.
the class OmsDePitter method process.
@Execute
public void process() throws Exception {
checkNull(inElev);
RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inElev);
cols = regionMap.getCols();
rows = regionMap.getRows();
xRes = regionMap.getXres();
yRes = regionMap.getYres();
novalue = HMConstants.getNovalue(inElev);
// output raster
WritableRaster pitRaster = CoverageUtilities.renderedImage2DoubleWritableRaster(inElev.getRenderedImage(), false);
WritableRandomIter pitIter = CoverageUtilities.getWritableRandomIterator(pitRaster);
try {
ConcurrentLinkedQueue<GridNode> pitsList = getPitsList(cols, rows, xRes, yRes, pitIter);
AtomicInteger count = new AtomicInteger();
// int count = 0;
int iteration = 1;
while (pitsList.size() > 0) {
if (pm.isCanceled()) {
return;
}
int pitCount = pitsList.size();
BitMatrix allPitsPositions = new BitMatrix(cols, rows);
// List<GridNode> processedNodesInPit = new ArrayList<>();
int shownCount = pitCount;
if (!verbose) {
shownCount = IHMProgressMonitor.UNKNOWN;
}
pm.beginTask("Processing " + pitCount + " pits (iteration N." + iteration++ + ")... ", shownCount);
if (doParallel) {
pitsList.parallelStream().forEach(originalPitNode -> {
int _count = count.incrementAndGet();
if (pm.isCanceled()) {
return;
}
processPitNode(originalPitNode, allPitsPositions, _count, pitIter);
});
} else {
pitsList.stream().forEach(originalPitNode -> {
int _count = count.incrementAndGet();
if (pm.isCanceled()) {
return;
}
processPitNode(originalPitNode, allPitsPositions, _count, pitIter);
});
}
// for( GridNode originalPitNode : pitsList ) {
// count++;
// if (pm.isCanceled()) {
// return;
// }
// processPitNode(originalPitNode, allPitsPositions, count, pitIter);
// }
pm.done();
// if (true && iteration < 3) {
// outPit = CoverageUtilities.buildCoverage("pitfiller", pitRaster, regionMap,
// inElev.getCoordinateReferenceSystem());
// OmsRasterWriter.writeRaster("/home/hydrologis/Dropbox/hydrologis/lavori/2017_06_mapzone/test/dtm_test2_pit_"
// + iteration + ".tiff", outPit);
// }
pitsList = getPitsList(cols, rows, xRes, yRes, pitIter, allPitsPositions);
int size = pitsList.size();
if (verbose) {
pm.message("Left pits: " + size);
pm.message("---------------------------------------------------------------------");
}
if (size < 10000) {
verbose = false;
}
}
outPit = CoverageUtilities.buildCoverageWithNovalue("pitfiller", pitRaster, regionMap, inElev.getCoordinateReferenceSystem(), novalue);
if (doFlow) {
WritableRaster flowRaster = CoverageUtilities.createWritableRaster(cols, rows, Short.class, null, null);
WritableRandomIter flowIter = CoverageUtilities.getWritableRandomIterator(flowRaster);
try {
pm.beginTask("Calculating flowdirections...", rows * cols);
processGrid(cols, rows, false, (c, r) -> {
if (pm.isCanceled()) {
return;
}
GridNode node = new GridNode(pitIter, cols, rows, xRes, yRes, c, r, novalue);
boolean isValid = node.isValid();
if (!isValid || node.touchesBound() || node.touchesNovalue()) {
flowIter.setSample(c, r, 0, HMConstants.intNovalue);
} else {
GridNode nextDown = node.goDownstreamSP();
if (nextDown == null) {
flowIter.setSample(c, r, 0, HMConstants.intNovalue);
} else {
int newFlow = node.getFlow();
flowIter.setSample(c, r, 0, newFlow);
}
}
pm.worked(1);
});
pm.done();
outFlow = CoverageUtilities.buildCoverageWithNovalue("flow", flowRaster, regionMap, inElev.getCoordinateReferenceSystem(), HMConstants.intNovalue);
} finally {
flowIter.done();
}
}
} finally {
pitIter.done();
}
}
use of org.hortonmachine.gears.utils.BitMatrix in project hortonmachine by TheHortonMachine.
the class OmsDePitter method getPitsList.
private ConcurrentLinkedQueue<GridNode> getPitsList(int nCols, int nRows, double xRes, double yRes, WritableRandomIter pitIter, BitMatrix allPitsPositions) {
ConcurrentLinkedQueue<GridNode> pitsList = new ConcurrentLinkedQueue<>();
BitMatrix currentMarked = new BitMatrix(nCols, nRows);
if (verbose)
pm.beginTask("Extract pits from DTM...", nRows);
for (int row = 0; row < nRows; row++) {
for (int col = 0; col < nCols; col++) {
if (!allPitsPositions.isMarked(col, row)) {
continue;
}
GridNode node = new GridNode(pitIter, nCols, nRows, xRes, yRes, col, row, novalue);
if (node.isPit()) {
double surroundingMin = node.getSurroundingMin();
if (Double.isInfinite(surroundingMin)) {
continue;
}
pitsList.add(node);
}
// check also border ones
List<GridNode> validSurroundingNodes = node.getValidSurroundingNodes();
for (GridNode gridNode : validSurroundingNodes) {
if (allPitsPositions.isMarked(gridNode.col, gridNode.row) || currentMarked.isMarked(gridNode.col, gridNode.row)) {
// we want only border
continue;
}
if (gridNode.isPit()) {
double surroundingMin = gridNode.getSurroundingMin();
if (Double.isInfinite(surroundingMin)) {
continue;
}
pitsList.add(gridNode);
currentMarked.mark(gridNode.col, gridNode.row);
}
}
}
if (verbose)
pm.worked(1);
}
if (verbose)
pm.done();
return pitsList;
}
use of org.hortonmachine.gears.utils.BitMatrix in project hortonmachine by TheHortonMachine.
the class OmsDePitter method getPitsList.
private ConcurrentLinkedQueue<GridNode> getPitsList(List<GridNode> nodesToCheckForLeftPits, BitMatrix allPitsPositions) {
ConcurrentLinkedQueue<GridNode> pitsList = new ConcurrentLinkedQueue<>();
if (nodesToCheckForLeftPits.size() > 0) {
GridNode tmp = nodesToCheckForLeftPits.get(0);
BitMatrix existing = new BitMatrix(tmp.cols, tmp.rows);
// pm.beginTask("Extract pits from the cells surrounding the pit pool...",
// nodesToCheckForLeftPits.size());
nodesToCheckForLeftPits.stream().forEach(node -> {
List<GridNode> validSurroundingNodes = node.getValidSurroundingNodes();
for (GridNode gridNode : validSurroundingNodes) {
if (allPitsPositions.isMarked(gridNode.col, gridNode.row)) {
continue;
}
if (gridNode.isPit()) {
double surroundingMin = gridNode.getSurroundingMin();
if (Double.isInfinite(surroundingMin)) {
continue;
}
if (!existing.isMarked(gridNode.col, gridNode.row)) {
pitsList.add(gridNode);
existing.mark(gridNode.col, gridNode.row);
}
}
}
// pm.worked(1);
});
// pm.done();
}
return pitsList;
}
Aggregations