Search in sources :

Example 81 with WritableRandomIter

use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.

the class OmsExtractNetwork method extractNetMode1.

/**
 * this method calculates the network imposing a threshold value on the
 * product of two quantities, for example the contributing area and the
 * slope.
 * @throws Exception
 */
private WritableRaster extractNetMode1(RenderedImage flowRI, int novalue, RenderedImage tcaRI, RenderedImage slopeRI) throws Exception {
    RandomIter flowRandomIter = RandomIterFactory.create(flowRI, null);
    RandomIter tcaRandomIter = RandomIterFactory.create(tcaRI, null);
    RandomIter slopeRandomIter = RandomIterFactory.create(slopeRI, null);
    // create new RasterData for the network matrix
    WritableRaster networkWR = CoverageUtilities.createWritableRaster(cols, rows, Short.class, null, shortNovalue);
    WritableRandomIter netRandomIter = RandomIterFactory.createWritable(networkWR, null);
    try {
        // $NON-NLS-1$
        pm.beginTask(msg.message("extractnetwork.extracting"), rows * cols);
        processGrid(cols, rows, false, (c, r) -> {
            if (pm.isCanceled()) {
                return;
            }
            double tcaValue = tcaRandomIter.getSample(c, r, 0);
            double slopeValue = slopeRandomIter.getSampleDouble(c, r, 0);
            if (!isNovalue(tcaValue) && !isNovalue(slopeValue)) {
                tcaValue = pow(tcaValue, pExp);
                if (tcaValue * slopeValue >= pThres) {
                    netRandomIter.setSample(c, r, 0, NETVALUE);
                    FlowNode flowNode = new FlowNode(flowRandomIter, cols, rows, c, r, novalue);
                    FlowNode runningNode = flowNode;
                    while ((runningNode = runningNode.goDownstream()) != null) {
                        int rCol = runningNode.col;
                        int rRow = runningNode.row;
                        int tmpNetValue = netRandomIter.getSample(rCol, rRow, 0);
                        if (!isNovalue(tmpNetValue)) {
                            break;
                        }
                        if (runningNode.isMarkedAsOutlet()) {
                            netRandomIter.setSample(rCol, rRow, 0, NETVALUE);
                            break;
                        } else if (runningNode.touchesBound()) {
                            Node goDownstream = runningNode.goDownstream();
                            if (goDownstream == null || !goDownstream.isValid()) {
                                netRandomIter.setSample(rCol, rRow, 0, NETVALUE);
                                break;
                            }
                        }
                        netRandomIter.setSample(rCol, rRow, 0, NETVALUE);
                    }
                }
            } else {
                netRandomIter.setSample(c, r, 0, shortNovalue);
            }
            pm.worked(1);
        });
        pm.done();
        return networkWR;
    } finally {
        flowRandomIter.done();
        tcaRandomIter.done();
        slopeRandomIter.done();
        netRandomIter.done();
    }
}
Also used : WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) WritableRaster(java.awt.image.WritableRaster) FlowNode(org.hortonmachine.gears.libs.modules.FlowNode) Node(org.hortonmachine.gears.libs.modules.Node) RandomIter(javax.media.jai.iterator.RandomIter) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) FlowNode(org.hortonmachine.gears.libs.modules.FlowNode)

Example 82 with WritableRandomIter

use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.

the class OmsNetNumbering method process.

@Execute
public void process() throws Exception {
    if (!concatOr(outNetnum == null, doReset)) {
        return;
    }
    checkNull(inFlow, inNet);
    RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inFlow);
    nCols = regionMap.getCols();
    nRows = regionMap.getRows();
    xres = regionMap.getXres();
    yres = regionMap.getYres();
    RenderedImage flowRI = inFlow.getRenderedImage();
    WritableRaster flowWR = CoverageUtilities.renderedImage2IntWritableRaster(flowRI, true);
    WritableRandomIter flowIter = RandomIterFactory.createWritable(flowWR, null);
    RandomIter netIter = CoverageUtilities.getRandomIterator(inNet);
    List<Geometry> pointsList = null;
    if (inPoints != null) {
        pointsList = FeatureUtilities.featureCollectionToGeometriesList(inPoints, true, null);
    }
    WritableRandomIter netNumIter = null;
    try {
        List<NetLink> linksList = new ArrayList<NetLink>();
        WritableRaster netNumWR = ModelsEngine.netNumbering(inFlow, inNet, inTca, pointsList, linksList, pm);
        outNetnum = CoverageUtilities.buildCoverage("netnum", netNumWR, regionMap, inFlow.getCoordinateReferenceSystem());
        netNumIter = RandomIterFactory.createWritable(netNumWR, null);
        int novalue = HMConstants.getIntNovalue(inFlow);
        WritableRaster basinWR = ModelsEngine.extractSubbasins(flowIter, novalue, netIter, netNumIter, nRows, nCols, pm);
        outBasins = CoverageUtilities.buildCoverage("subbasins", basinWR, regionMap, inFlow.getCoordinateReferenceSystem());
        RandomIter subbasinIter = CoverageUtilities.getRandomIterator(outBasins);
        int validCount = 0;
        int invalidCount = 0;
        try {
            for (int r = 0; r < nRows; r++) {
                for (int c = 0; c < nCols; c++) {
                    int value = subbasinIter.getSample(c, r, 0);
                    if (!isNovalue(value)) {
                        validCount++;
                    } else {
                        invalidCount++;
                    }
                }
            }
            // now handle basin hierarchy
            for (NetLink nl1 : linksList) {
                for (NetLink nl2 : linksList) {
                    if (!nl1.equals(nl2)) {
                        nl1.connect(nl2);
                    }
                }
            }
            List<NetLink> rootNetLink = linksList.stream().filter(n -> n.getDownStreamLink() == null).collect(Collectors.toList());
            if (rootNetLink.size() > 1) {
                throw new ModelsRuntimeException("More than one link found to be root link. Check the dataset.", this);
            }
            // create mindmap
            NetLink rootLink = rootNetLink.get(0);
            StringBuilder sb = new StringBuilder();
            sb.append("@startmindmap\n");
            sb.append("* <b>basin stats</b>\\nvalid basin cells: " + validCount + "\\ntotal cells: " + (invalidCount + validCount) + "\\ntotal basin area: " + (validCount * xres * yres) + "\\nx res: " + xres + "\\ny res: " + yres + "\n");
            String level = "*";
            printLinkAsMindMap(rootLink, level, sb);
            sb.append("@endmindmap\n");
            outMindmap = sb.toString();
            if (pDesiredArea != null) {
                HashMap<Integer, Integer> conversionMap = new HashMap<>();
                double desArea = pDesiredArea;
                double minArea = desArea - desArea * pDesiredAreaDelta / 100.0;
                for (NetLink netLink : linksList) {
                    // first handle the most upstream ones and aggregate them with their parents
                    List<NetLink> upStreamLinks = netLink.getUpStreamLinks();
                    if (!netLink.isFixed() && upStreamLinks.isEmpty()) {
                        double area = getLinkOnlyArea(netLink);
                        if (area < minArea) {
                            NetLink parentLink = netLink.getDownStreamLink();
                            if (parentLink != null) {
                                netLink.desiredChainNetLink = parentLink.num;
                                conversionMap.put(netLink.num, parentLink.num);
                                parentLink.getUpStreamLinks().remove(netLink);
                            }
                        }
                    }
                    // point)
                    if (upStreamLinks.size() == 1 && upStreamLinks.get(0).isFixed()) {
                        NetLink fixed = upStreamLinks.get(0);
                        double area = getLinkOnlyArea(netLink);
                        if (area < minArea && !netLink.isFixed()) {
                            // if the area is too small we need to merge it downstream,
                            // but only if the basin itself is not fixed. In that case
                            // it just can't be changed in size, period.
                            NetLink parentLink = netLink.getDownStreamLink();
                            if (parentLink != null) {
                                netLink.desiredChainNetLink = parentLink.num;
                                conversionMap.put(netLink.num, parentLink.num);
                                parentLink.getUpStreamLinks().remove(netLink);
                                parentLink.getUpStreamLinks().add(fixed);
                            }
                        }
                    }
                }
                int convertedSize;
                int postConvertedSize;
                do {
                    convertedSize = conversionMap.size();
                    List<NetLink> links = Arrays.asList(rootLink);
                    aggregateBasins(links, conversionMap, minArea, desArea, 0);
                    postConvertedSize = conversionMap.size();
                } while (postConvertedSize - convertedSize > 0);
                // if (pMaxAllowedConfluences > 0) {
                // // review the tree and solve junctions with more than that number of
                // upstreams
                // do {
                // convertedSize = conversionMap.size();
                // List<NetLink> links = Arrays.asList(rootLink);
                // fixManyChannels(links, conversionMap);
                // postConvertedSize = conversionMap.size();
                // } while( postConvertedSize - convertedSize > 0 );
                // }
                sb = new StringBuilder();
                sb.append("@startmindmap\n");
                sb.append("* <b>basin stats</b>\\nvalid basin cells: " + validCount + "\\ntotal cells: " + (invalidCount + validCount) + "\\ntotal basin area: " + (validCount * xres * yres) + "\\nx res: " + xres + "\\ny res: " + yres + "\\ndesired cells: " + (desArea / xres / yres) + "\n");
                level = "*";
                printLinkAsMindMap(rootLink, level, sb);
                sb.append("@endmindmap\n");
                outDesiredMindmap = sb.toString();
                // build basins info
                StringBuilder basinsInfoSb = new StringBuilder();
                basinsInfoSb.append("basinid;outletX;outletY;area\n");
                printLinkAsIdOutletUpstreamArea(rootLink, inTca, inTca.getGridGeometry(), basinsInfoSb);
                outBasinsInfo = basinsInfoSb.toString();
                WritableRaster desiredSubbasinsWR = CoverageUtilities.createWritableRaster(nCols, nRows, Integer.class, null, HMConstants.intNovalue);
                WritableRandomIter desiredSubbasinsWIter = RandomIterFactory.createWritable(desiredSubbasinsWR, null);
                for (int r = 0; r < nRows; r++) {
                    for (int c = 0; c < nCols; c++) {
                        int value = subbasinIter.getSample(c, r, 0);
                        if (!isNovalue(value)) {
                            Integer convertedBasinNum = conversionMap.get(value);
                            if (convertedBasinNum != null) {
                                // check if the converted has been converted also in some
                                // different thread
                                Integer convertedBasinNumTmp = conversionMap.get(convertedBasinNum);
                                while (convertedBasinNumTmp != null) {
                                    convertedBasinNum = convertedBasinNumTmp;
                                    convertedBasinNumTmp = conversionMap.get(convertedBasinNumTmp);
                                }
                                desiredSubbasinsWIter.setSample(c, r, 0, convertedBasinNum);
                            } else {
                                desiredSubbasinsWIter.setSample(c, r, 0, value);
                            }
                        }
                    }
                }
                desiredSubbasinsWIter.done();
                outDesiredBasins = CoverageUtilities.buildCoverageWithNovalue("desiredsubbasins", desiredSubbasinsWR, regionMap, inFlow.getCoordinateReferenceSystem(), HMConstants.intNovalue);
            }
            // build geoframe topology input
            StringBuilder geoframeSb = new StringBuilder();
            geoframeSb.append(rootLink.num).append(" ").append(0).append("\n");
            printLinkAsGeoframe(rootLink, geoframeSb);
            outGeoframeTopology = geoframeSb.toString();
        } finally {
            subbasinIter.done();
        }
    } finally {
        flowIter.done();
        netIter.done();
        if (netNumIter != null)
            netNumIter.done();
    }
}
Also used : HMModel(org.hortonmachine.gears.libs.modules.HMModel) Arrays(java.util.Arrays) ModelsEngine(org.hortonmachine.gears.libs.modules.ModelsEngine) Label(oms3.annotations.Label) RandomIter(javax.media.jai.iterator.RandomIter) Author(oms3.annotations.Author) GridCoverage2D(org.geotools.coverage.grid.GridCoverage2D) Coordinate(org.locationtech.jts.geom.Coordinate) In(oms3.annotations.In) HashMap(java.util.HashMap) OMSNETNUMBERING_DESCRIPTION(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_DESCRIPTION) License(oms3.annotations.License) Status(oms3.annotations.Status) Execute(oms3.annotations.Execute) ArrayList(java.util.ArrayList) NETWORK(org.hortonmachine.gears.libs.modules.HMConstants.NETWORK) Description(oms3.annotations.Description) OMSNETNUMBERING_AUTHORNAMES(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_AUTHORNAMES) OMSNETNUMBERING_LICENSE(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_LICENSE) Name(oms3.annotations.Name) HMConstants(org.hortonmachine.gears.libs.modules.HMConstants) NetLink(org.hortonmachine.gears.libs.modules.NetLink) Unit(oms3.annotations.Unit) RandomIterFactory(javax.media.jai.iterator.RandomIterFactory) Out(oms3.annotations.Out) OMSNETNUMBERING_LABEL(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_LABEL) SimpleFeatureCollection(org.geotools.data.simple.SimpleFeatureCollection) GridGeometry2D(org.geotools.coverage.grid.GridGeometry2D) RenderedImage(java.awt.image.RenderedImage) HMConstants.isNovalue(org.hortonmachine.gears.libs.modules.HMConstants.isNovalue) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) OMSNETNUMBERING_STATUS(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_STATUS) FeatureUtilities(org.hortonmachine.gears.utils.features.FeatureUtilities) Collectors(java.util.stream.Collectors) CoverageUtilities(org.hortonmachine.gears.utils.coverage.CoverageUtilities) OMSNETNUMBERING_KEYWORDS(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_KEYWORDS) List(java.util.List) OMSNETNUMBERING_NAME(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_NAME) ModelsRuntimeException(org.hortonmachine.gears.libs.exceptions.ModelsRuntimeException) RegionMap(org.hortonmachine.gears.utils.RegionMap) OMSNETNUMBERING_AUTHORCONTACTS(org.hortonmachine.hmachine.modules.network.netnumbering.OmsNetNumbering.OMSNETNUMBERING_AUTHORCONTACTS) Geometry(org.locationtech.jts.geom.Geometry) WritableRaster(java.awt.image.WritableRaster) Keywords(oms3.annotations.Keywords) HashMap(java.util.HashMap) RegionMap(org.hortonmachine.gears.utils.RegionMap) ArrayList(java.util.ArrayList) RandomIter(javax.media.jai.iterator.RandomIter) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) Geometry(org.locationtech.jts.geom.Geometry) NetLink(org.hortonmachine.gears.libs.modules.NetLink) WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) WritableRaster(java.awt.image.WritableRaster) ModelsRuntimeException(org.hortonmachine.gears.libs.exceptions.ModelsRuntimeException) RenderedImage(java.awt.image.RenderedImage) Execute(oms3.annotations.Execute)

Example 83 with WritableRandomIter

use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.

the class OmsMorpher method dilate.

/**
 * Morphologically dilates an input raster by a given kernel.
 *
 * @param inWR the input raster.
 * @param regionMap the {@link RegionMap}.
 * @param outWR the raster to modify.
 * @param kernelArray the kernel to use.
 * @param binary if <code>true</code>, binary mode is used.
 * @param pm
 */
public static void dilate(WritableRaster inWR, double inNovalue, RegionMap regionMap, WritableRaster outWR, int[] kernelArray, boolean binary, IHMProgressMonitor pm) {
    int cols = regionMap.getCols();
    int rows = regionMap.getRows();
    double xres = regionMap.getXres();
    double yres = regionMap.getYres();
    WritableRandomIter inIter = RandomIterFactory.createWritable(inWR, null);
    WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);
    int[][] kernel = MorpherHelp.getSquareKernelMatrix(kernelArray);
    pm.beginTask("Perform dilation...", cols);
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            GridNode node = new GridNode(inIter, cols, rows, xres, yres, c, r, inNovalue);
            if (!node.isValid()) {
                double[][] nodeNeighbours = node.getWindow(kernel.length, false);
                // apply the kernel
                boolean set = false;
                boolean doBreak = false;
                double max = Double.NEGATIVE_INFINITY;
                for (int kr = 0; kr < kernel.length; kr++) {
                    for (int kc = 0; kc < kernel[0].length; kc++) {
                        if (kernel[kr][kc] == 1) {
                            // valid kernel value
                            if (!isNovalue(nodeNeighbours[kr][kc]) && nodeNeighbours[kr][kc] > max) {
                                max = nodeNeighbours[kr][kc];
                                set = true;
                                if (binary) {
                                    break;
                                }
                            }
                        }
                    }
                    if (doBreak) {
                        break;
                    }
                }
                if (set) {
                    node.setDoubleValueInMap(outIter, max);
                } else {
                    node.setDoubleValueInMap(outIter, HMConstants.doubleNovalue);
                }
                continue;
            } else {
                node.setDoubleValueInMap(outIter, node.elevation);
            }
        }
        pm.worked(1);
    }
    pm.done();
}
Also used : WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) GridNode(org.hortonmachine.gears.libs.modules.GridNode)

Example 84 with WritableRandomIter

use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.

the class OmsMorpher method skeletonize.

public static void skeletonize(WritableRaster inWR, RegionMap regionMap, WritableRaster outWR, int[][] kernels) {
    int cols = regionMap.getCols();
    int rows = regionMap.getRows();
    WritableRandomIter inIter = RandomIterFactory.createWritable(inWR, null);
    WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);
    BinaryFast binaryData = toBinaryFast(cols, rows, inIter);
    new Thin().processSkeleton(binaryData, kernels);
    fromBinaryFast(cols, rows, outIter, binaryData);
}
Also used : WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) BinaryFast(org.hortonmachine.gears.modules.utils.BinaryFast)

Example 85 with WritableRandomIter

use of javax.media.jai.iterator.WritableRandomIter in project hortonmachine by TheHortonMachine.

the class OmsMorpher method erode.

/**
 * Morphologically erodes an input raster by a given kernel.
 *
 * @param inWR the input raster.
 * @param regionMap the {@link RegionMap}.
 * @param outWR the raster to modify.
 * @param kernelArray the kernel to use.
 */
public static void erode(WritableRaster inWR, double inNovalue, RegionMap regionMap, WritableRaster outWR, int[] kernelArray, IHMProgressMonitor pm) {
    int cols = regionMap.getCols();
    int rows = regionMap.getRows();
    double xres = regionMap.getXres();
    double yres = regionMap.getYres();
    WritableRandomIter inIter = RandomIterFactory.createWritable(inWR, null);
    WritableRandomIter outIter = RandomIterFactory.createWritable(outWR, null);
    int[][] kernel = MorpherHelp.getSquareKernelMatrix(kernelArray);
    pm.beginTask("Perform erosion...", cols);
    for (int r = 0; r < rows; r++) {
        for (int c = 0; c < cols; c++) {
            GridNode node = new GridNode(inIter, cols, rows, xres, yres, c, r, inNovalue);
            if (node.isValid()) {
                double[][] nodeNeighbours = node.getWindow(kernel.length, false);
                // apply the kernel
                boolean set = false;
                double min = Double.POSITIVE_INFINITY;
                for (int kr = 0; kr < kernel.length; kr++) {
                    for (int kc = 0; kc < kernel[0].length; kc++) {
                        if (kernel[kr][kc] == 1) {
                            // valid kernel value
                            if (isNovalue(nodeNeighbours[kr][kc])) {
                                // novalue is the absolute min
                                min = doubleNovalue;
                                set = true;
                                break;
                            } else if (nodeNeighbours[kr][kc] < min) {
                                min = nodeNeighbours[kr][kc];
                                set = true;
                            }
                        }
                    }
                    if (isNovalue(min)) {
                        break;
                    }
                }
                if (set) {
                    node.setDoubleValueInMap(outIter, min);
                } else {
                    node.setDoubleValueInMap(outIter, node.elevation);
                }
                continue;
            }
        }
        pm.worked(1);
    }
    pm.done();
}
Also used : WritableRandomIter(javax.media.jai.iterator.WritableRandomIter) GridNode(org.hortonmachine.gears.libs.modules.GridNode)

Aggregations

WritableRandomIter (javax.media.jai.iterator.WritableRandomIter)99 WritableRaster (java.awt.image.WritableRaster)85 RandomIter (javax.media.jai.iterator.RandomIter)60 RegionMap (org.hortonmachine.gears.utils.RegionMap)59 Execute (oms3.annotations.Execute)49 Coordinate (org.locationtech.jts.geom.Coordinate)20 GridCoverage2D (org.geotools.coverage.grid.GridCoverage2D)18 ModelsIllegalargumentException (org.hortonmachine.gears.libs.exceptions.ModelsIllegalargumentException)18 GridGeometry2D (org.geotools.coverage.grid.GridGeometry2D)17 RenderedImage (java.awt.image.RenderedImage)16 Point (java.awt.Point)11 ArrayList (java.util.ArrayList)11 Geometry (org.locationtech.jts.geom.Geometry)11 GridCoordinates2D (org.geotools.coverage.grid.GridCoordinates2D)10 FlowNode (org.hortonmachine.gears.libs.modules.FlowNode)10 DirectPosition2D (org.geotools.geometry.DirectPosition2D)9 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)8 Envelope (org.locationtech.jts.geom.Envelope)7 DirectPosition (org.opengis.geometry.DirectPosition)7 SampleModel (java.awt.image.SampleModel)6