Search in sources :

Example 1 with BitMatrix

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);
            }
        }
    }
}
Also used : BitMatrix(org.hortonmachine.gears.utils.BitMatrix)

Example 2 with BitMatrix

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);
}
Also used : GridNode(org.hortonmachine.gears.libs.modules.GridNode) ArrayList(java.util.ArrayList) BitMatrix(org.hortonmachine.gears.utils.BitMatrix) TreeSet(java.util.TreeSet)

Example 3 with BitMatrix

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();
    }
}
Also used : WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) GridNode(org.hortonmachine.gears.libs.modules.GridNode) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) WritableRaster(java.awt.image.WritableRaster) RegionMap(org.hortonmachine.gears.utils.RegionMap) BitMatrix(org.hortonmachine.gears.utils.BitMatrix) Execute(oms3.annotations.Execute)

Example 4 with BitMatrix

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;
}
Also used : GridNode(org.hortonmachine.gears.libs.modules.GridNode) BitMatrix(org.hortonmachine.gears.utils.BitMatrix) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue)

Example 5 with BitMatrix

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;
}
Also used : GridNode(org.hortonmachine.gears.libs.modules.GridNode) BitMatrix(org.hortonmachine.gears.utils.BitMatrix) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue)

Aggregations

BitMatrix (org.hortonmachine.gears.utils.BitMatrix)8 GridNode (org.hortonmachine.gears.libs.modules.GridNode)5 WritableRaster (java.awt.image.WritableRaster)3 WritableRandomIter (javax.media.jai.iterator.WritableRandomIter)3 Execute (oms3.annotations.Execute)3 RegionMap (org.hortonmachine.gears.utils.RegionMap)3 ArrayList (java.util.ArrayList)2 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)2 RandomIter (javax.media.jai.iterator.RandomIter)2 Color (java.awt.Color)1 Graphics2D (java.awt.Graphics2D)1 Rectangle (java.awt.Rectangle)1 Point2D (java.awt.geom.Point2D)1 BufferedImage (java.awt.image.BufferedImage)1 RenderedImage (java.awt.image.RenderedImage)1 IOException (java.io.IOException)1 TreeSet (java.util.TreeSet)1 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)1 ReferencedEnvelope (org.geotools.geometry.jts.ReferencedEnvelope)1 GridNodeElevationToLeastComparator (org.hortonmachine.gears.libs.modules.GridNodeElevationToLeastComparator)1