/* * JGrass - Free Open Source Java GIS http://www.jgrass.org * (C) HydroloGIS - www.hydrologis.com * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Library General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) any * later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more * details. * * You should have received a copy of the GNU Library General Public License * along with this library; if not, write to the Free Foundation, Inc., 59 * Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.jgrasstools.hortonmachine.modules.demmanipulation.splitsubbasin; import static org.jgrasstools.gears.libs.modules.JGTConstants.isNovalue; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_AUTHORCONTACTS; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_AUTHORNAMES; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_KEYWORDS; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_LABEL; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_LICENSE; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_NAME; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_STATUS; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_inFlow_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_inHack_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_outNetnum_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_outSubbasins_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSSPLITSUBBASINS_pHackorder_DESCRIPTION; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import javax.media.jai.iterator.RandomIter; import javax.media.jai.iterator.RandomIterFactory; import javax.media.jai.iterator.WritableRandomIter; import oms3.annotations.Author; import oms3.annotations.Description; import oms3.annotations.Execute; import oms3.annotations.In; import oms3.annotations.Keywords; import oms3.annotations.Label; import oms3.annotations.License; import oms3.annotations.Name; import oms3.annotations.Out; import oms3.annotations.Status; import org.geotools.coverage.grid.GridCoverage2D; import org.jgrasstools.gears.libs.exceptions.ModelsIllegalargumentException; import org.jgrasstools.gears.libs.modules.JGTConstants; import org.jgrasstools.gears.libs.modules.JGTModel; import org.jgrasstools.gears.libs.modules.ModelsEngine; import org.jgrasstools.gears.libs.modules.ModelsSupporter; import org.jgrasstools.gears.utils.RegionMap; import org.jgrasstools.gears.utils.coverage.CoverageUtilities; import org.jgrasstools.gears.utils.math.NumericsUtilities; @Description(OMSSPLITSUBBASINS_DESCRIPTION) @Author(name = OMSSPLITSUBBASINS_AUTHORNAMES, contact = OMSSPLITSUBBASINS_AUTHORCONTACTS) @Keywords(OMSSPLITSUBBASINS_KEYWORDS) @Label(OMSSPLITSUBBASINS_LABEL) @Name(OMSSPLITSUBBASINS_NAME) @Status(OMSSPLITSUBBASINS_STATUS) @License(OMSSPLITSUBBASINS_LICENSE) public class OmsSplitSubbasins extends JGTModel { @Description(OMSSPLITSUBBASINS_inFlow_DESCRIPTION) @In public GridCoverage2D inFlow = null; @Description(OMSSPLITSUBBASINS_inHack_DESCRIPTION) @In public GridCoverage2D inHack = null; @Description(OMSSPLITSUBBASINS_pHackorder_DESCRIPTION) @In public Double pHackorder = null; @Description(OMSSPLITSUBBASINS_outNetnum_DESCRIPTION) @Out public GridCoverage2D outNetnum = null; @Description(OMSSPLITSUBBASINS_outSubbasins_DESCRIPTION) @Out public GridCoverage2D outSubbasins = null; private int[][] dir = ModelsSupporter.DIR_WITHFLOW_ENTERING; private int nCols; private int nRows; private double hackOrder; @Execute public void process() { if (!concatOr(outSubbasins == null, doReset)) { return; } checkNull(inFlow, inHack, pHackorder); RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inFlow); nCols = regionMap.getCols(); nRows = regionMap.getRows(); hackOrder = pHackorder; RenderedImage flowRI = inFlow.getRenderedImage(); WritableRaster flowWR = CoverageUtilities.renderedImage2WritableRaster(flowRI, true); RenderedImage hacksRI = inHack.getRenderedImage(); WritableRaster hackWR = CoverageUtilities.renderedImage2WritableRaster(hacksRI, true); WritableRandomIter flowIter = RandomIterFactory.createWritable(flowWR, null); WritableRandomIter hacksIter = RandomIterFactory.createWritable(hackWR, null); WritableRaster netImage = CoverageUtilities.createDoubleWritableRaster(nCols, nRows, null, null, JGTConstants.doubleNovalue); WritableRandomIter netIter = RandomIterFactory.createWritable(netImage, null); net(hacksIter, netIter); WritableRaster netNumberWR = netNumber(flowIter, hacksIter, netIter); WritableRandomIter netNumberIter = RandomIterFactory.createWritable(netNumberWR, null); WritableRaster subbasinWR = ModelsEngine.extractSubbasins(flowIter, netIter, netNumberIter, nRows, nCols, pm); outNetnum = CoverageUtilities.buildCoverage("netnum", netNumberWR, regionMap, inFlow.getCoordinateReferenceSystem()); //$NON-NLS-1$ outSubbasins = CoverageUtilities.buildCoverage("subbasins", subbasinWR, regionMap, inFlow.getCoordinateReferenceSystem()); //$NON-NLS-1$ } /** * Return the map of the network with only the river of the choosen order. * * @param hacksIter the hack stream map. * @param netIter the network map to build on the required hack orders. * @return the map of the network with the choosen order. */ private void net( WritableRandomIter hacksIter, WritableRandomIter netIter ) { // calculates the max order of basin (max hackstream value) pm.beginTask("Extraction of rivers of chosen order...", nRows); for( int r = 0; r < nRows; r++ ) { for( int c = 0; c < nCols; c++ ) { double value = hacksIter.getSampleDouble(c, r, 0); if (!isNovalue(value)) { /* * if the hack value is in the asked range * => keep it as net */ if (value <= hackOrder) { netIter.setSample(c, r, 0, 2); } else { hacksIter.setSample(c, r, 0, JGTConstants.doubleNovalue); } } } pm.worked(1); } pm.done(); } private WritableRaster netNumber( RandomIter flowIter, RandomIter hacksIter, RandomIter netIter ) { int drainingPixelNum = 0; int[] flowColRow = new int[2]; WritableRaster netNumberingImage = CoverageUtilities.createDoubleWritableRaster(nCols, nRows, null, null, 0.0); WritableRandomIter netNumberRandomIter = RandomIterFactory.createWritable(netNumberingImage, null); int n = 0; pm.beginTask("Numbering network...", nRows); for( int r = 0; r < nRows; r++ ) { for( int c = 0; c < nCols; c++ ) { flowColRow[0] = c; flowColRow[1] = r; if (!isNovalue(netIter.getSampleDouble(c, r, 0)) && flowIter.getSampleDouble(c, r, 0) != 10.0 && NumericsUtilities.dEq(netNumberRandomIter.getSampleDouble(c, r, 0), 0.0)) { boolean isSource = true; for( int k = 1; k <= 8; k++ ) { boolean isDraining = flowIter.getSampleDouble(flowColRow[0] + dir[k][1], flowColRow[1] + dir[k][0], 0) == dir[k][2]; boolean isOnNet = !isNovalue(netIter.getSampleDouble(flowColRow[0] + dir[k][1], flowColRow[1] + dir[k][0], 0)); if (isDraining && isOnNet) { isSource = false; break; } } /* * if it is source pixel, go down */ if (isSource) { n++; netNumberRandomIter.setSample(c, r, 0, n); if (!ModelsEngine.go_downstream(flowColRow, flowIter.getSampleDouble(flowColRow[0], flowColRow[1], 0))) throw new ModelsIllegalargumentException("go_downstream failure...", this, pm); /* * while it is on the network, go downstream */ while( !isNovalue(flowIter.getSampleDouble(flowColRow[0], flowColRow[1], 0)) && netNumberRandomIter.getSampleDouble(flowColRow[0], flowColRow[1], 0) == 0 ) { /* * calculate how many pixels drain into the current pixel. */ drainingPixelNum = 0; for( int k = 1; k <= 8; k++ ) { if (!isNovalue(netIter.getSampleDouble(flowColRow[0] + dir[k][1], flowColRow[1] + dir[k][0], 0)) && flowIter.getSampleDouble(flowColRow[0] + dir[k][1], flowColRow[1] + dir[k][0], 0) == dir[k][2]) { drainingPixelNum++; } } if (drainingPixelNum > 1) { n++; } netNumberRandomIter.setSample(flowColRow[0], flowColRow[1], 0, n); if (!ModelsEngine .go_downstream(flowColRow, flowIter.getSampleDouble(flowColRow[0], flowColRow[1], 0))) throw new ModelsIllegalargumentException("go_downstream failure...", this, pm); } } } } pm.worked(1); } pm.done(); return netNumberingImage; } }