/* * This file is part of JGrasstools (http://www.jgrasstools.org) * (C) HydroloGIS - www.hydrologis.com * * JGrasstools is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.jgrasstools.hortonmachine.modules.geomorphology.draindir; import static org.jgrasstools.gears.libs.modules.JGTConstants.doubleNovalue; import static org.jgrasstools.gears.libs.modules.JGTConstants.isNovalue; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_AUTHORCONTACTS; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_AUTHORNAMES; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_DOCUMENTATION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_KEYWORDS; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_LABEL; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_LICENSE; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_NAME; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_STATUS; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_doLad_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_inFlow_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_inFlownet_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_inPit_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_outFlow_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_outTca_DESCRIPTION; import static org.jgrasstools.hortonmachine.i18n.HortonMessages.OMSDRAINDIR_pLambda_DESCRIPTION; import java.awt.image.RenderedImage; import java.awt.image.WritableRaster; import java.util.HashMap; 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.Documentation; 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.modules.JGTModel; import org.jgrasstools.gears.libs.modules.ModelsSupporter; import org.jgrasstools.gears.utils.BitMatrix; import org.jgrasstools.gears.utils.coverage.CoverageUtilities; import org.jgrasstools.gears.utils.sorting.QuickSortAlgorithm; import org.jgrasstools.hortonmachine.i18n.HortonMessageHandler; @Description(OMSDRAINDIR_DESCRIPTION) @Documentation(OMSDRAINDIR_DOCUMENTATION) @Author(name = OMSDRAINDIR_AUTHORNAMES, contact = OMSDRAINDIR_AUTHORCONTACTS) @Keywords(OMSDRAINDIR_KEYWORDS) @Label(OMSDRAINDIR_LABEL) @Name(OMSDRAINDIR_NAME) @Status(OMSDRAINDIR_STATUS) @License(OMSDRAINDIR_LICENSE) public class OmsDrainDir extends JGTModel { @Description(OMSDRAINDIR_inPit_DESCRIPTION) @In public GridCoverage2D inPit = null; @Description(OMSDRAINDIR_inFlow_DESCRIPTION) @In public GridCoverage2D inFlow = null; @Description(OMSDRAINDIR_inFlownet_DESCRIPTION) @In public GridCoverage2D inFlownet = null; @Description(OMSDRAINDIR_pLambda_DESCRIPTION) @In public double pLambda = 1.0; @Description(OMSDRAINDIR_doLad_DESCRIPTION) @In public boolean doLad = true; @Description(OMSDRAINDIR_outFlow_DESCRIPTION) @Out public GridCoverage2D outFlow = null; @Description(OMSDRAINDIR_outTca_DESCRIPTION) @Out public GridCoverage2D outTca = null; private HortonMessageHandler msg = HortonMessageHandler.getInstance(); private static final double PI = Math.PI; private static final double NaN = doubleNovalue; /* * indicates the position of the triangle's vertexes */ private int[][] order = ModelsSupporter.DIR; private int cols; private int rows; private double xRes; private double yRes; /** * Calculates new drainage directions * * @throws Exception */ @Execute public void process() throws Exception { if (!concatOr(outFlow == null, doReset)) { return; } checkNull(inFlow, inPit); double[] orderedelev, indexes; int nelev; HashMap<String, Double> regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inPit); cols = regionMap.get(CoverageUtilities.COLS).intValue(); rows = regionMap.get(CoverageUtilities.ROWS).intValue(); xRes = regionMap.get(CoverageUtilities.XRES); yRes = regionMap.get(CoverageUtilities.YRES); RenderedImage pitfillerRI = inPit.getRenderedImage(); WritableRaster pitfillerWR = CoverageUtilities.renderedImage2WritableRaster(pitfillerRI, true); RenderedImage flowRI = inFlow.getRenderedImage(); WritableRaster flowWR = CoverageUtilities.renderedImage2WritableRaster(flowRI, true); RandomIter pitRandomIter = RandomIterFactory.create(pitfillerWR, null); // create new matrix orderedelev = new double[cols * rows]; indexes = new double[cols * rows]; nelev = 0; for( int j = 0; j < rows; j++ ) { if (isCanceled(pm)) { return; } for( int i = 0; i < cols; i++ ) { orderedelev[((j) * cols) + i] = pitRandomIter.getSampleDouble(i, j, 0); indexes[((j) * cols) + i] = ((j) * cols) + i + 1; if (!isNovalue(pitRandomIter.getSampleDouble(i, j, 0))) { nelev = nelev + 1; } } } QuickSortAlgorithm t = new QuickSortAlgorithm(pm); t.sort(orderedelev, indexes); pm.message(msg.message("draindir.initializematrix")); // Initialize new RasterData and set value WritableRaster tcaWR = CoverageUtilities.createDoubleWritableRaster(cols, rows, Double.class, null, NaN); WritableRaster dirWR = CoverageUtilities.createDoubleWritableRaster(cols, rows, Double.class, null, NaN); // it contains the analyzed cells WritableRaster deviationsWR = CoverageUtilities.createDoubleWritableRaster(cols, rows, null, null, null); BitMatrix analizedMatrix = new BitMatrix(cols, rows); if (doLad) { OrlandiniD8_LAD(indexes, deviationsWR, analizedMatrix, pitfillerWR, flowWR, tcaWR, dirWR, nelev); } else { OrlandiniD8_LTD(indexes, deviationsWR, analizedMatrix, pitfillerWR, flowWR, tcaWR, dirWR, nelev); // only if required executes this method if (inFlownet != null) { newDirections(pitfillerWR, dirWR); } } if (isCanceled(pm)) { return; } outFlow = CoverageUtilities.buildCoverage("draindir", dirWR, regionMap, inPit.getCoordinateReferenceSystem()); outTca = CoverageUtilities.buildCoverage("tca", tcaWR, regionMap, inPit.getCoordinateReferenceSystem()); } /** * routine that defines the draining directions * * @param indexes * vector containing the order of elevation * @param deviationsImage * the map containing the deviation * @param analizedMatrix * @param nelev * @return */ private void OrlandiniD8_LAD( double[] indexes, WritableRaster deviationsImage, BitMatrix analizedMatrix, WritableRaster pitImage, WritableRaster flowImage, WritableRaster tcaImage, WritableRaster dirImage, int nelev ) { int row, col, ncelle, nr, nc; double dev1, dev2, sumdev1, sumdev2, sumdev; /* * it contains: * pend,dir,e0,e1,e2,sumdev, * didren1,dirdren2,sigma */ double[] dati = new double[10]; double count, flow; double[] u = {xRes, yRes}; double[] v = {NaN, NaN}; // get rows and cols from the active region ncelle = 0; RandomIter pitRandomIter = RandomIterFactory.create(pitImage, null); RandomIter flowRandomIter = RandomIterFactory.create(flowImage, null); WritableRandomIter tcaRandomIter = RandomIterFactory.createWritable(tcaImage, null); WritableRandomIter deviationRandomIter = RandomIterFactory.createWritable(deviationsImage, null); WritableRandomIter dirRandomIter = RandomIterFactory.createWritable(dirImage, null); pm.beginTask(msg.message("draindir.orlandinilad"), rows * cols); for( int i = rows * cols - 1; i >= 0; i-- ) { if (isCanceled(pm)) { return; } count = indexes[i] - 1; row = (int) Math.floor(count / cols); col = (int) (count % cols); if (!isNovalue(pitRandomIter.getSampleDouble(col, row, 0)) && !isNovalue(flowRandomIter.getSampleDouble(col, row, 0))) { ncelle = ncelle + 1; compose(analizedMatrix, pitRandomIter, tcaRandomIter, dati, u, v, col, row); if (dati[1] > 0) { dev1 = dati[2]; dev2 = (PI / 4) - dati[2]; if (dati[9] == 1) { dev2 = -dev2; } else { dev1 = -dev1; } calcarea(row, col, dati, v, analizedMatrix, deviationRandomIter, pitRandomIter, tcaRandomIter, dirRandomIter, i, i); sumdev = dati[6]; sumdev1 = dev1 + (pLambda * sumdev); sumdev2 = dev2 + (pLambda * sumdev); if ((Math.abs(sumdev1) <= Math.abs(sumdev2)) && ((dati[3] - dati[4]) > 0.0)) { dirRandomIter.setSample(col, row, 0, dati[7]); deviationRandomIter.setSample(col, row, 0, sumdev1); } else if (Math.abs(sumdev1) > Math.abs(sumdev2) || (dati[3] - dati[5]) > 0.0) { dirRandomIter.setSample(col, row, 0, dati[8]); deviationRandomIter.setSample(col, row, 0, sumdev2); } else { break; } } else if (dati[1] == 0) { if (ncelle == nelev) { /* sono all'uscita */ calcarea(row, col, dati, v, analizedMatrix, deviationRandomIter, pitRandomIter, tcaRandomIter, dirRandomIter, cols, rows); dirRandomIter.setSample(col, row, 0, 10); deviationRandomIter.setSample(col, row, 0, pLambda * dati[6]); if (tcaRandomIter.getSampleDouble(col, row, 0) != ncelle) { pm.done(); return; } else { pm.done(); return; } } else { calcarea(row, col, dati, v, analizedMatrix, deviationRandomIter, pitRandomIter, tcaRandomIter, dirRandomIter, cols, rows); sumdev = pLambda * dati[6]; dirRandomIter.setSample(col, row, 0, flowRandomIter.getSampleDouble(col, row, 0)); flow = dirRandomIter.getSampleDouble(col, row, 0); nr = row + order[(int) flow][0]; nc = col + order[(int) flow][1]; while( analizedMatrix.isMarked(nc, nr) ) { tcaRandomIter.setSample(nc, nr, 0, tcaRandomIter.getSampleDouble(nc, nr, 0) + tcaRandomIter.getSampleDouble(col, row, 0)); flow = dirRandomIter.getSampleDouble(nc, nr, 0); nr = nr + order[(int) flow][0]; nc = nc + order[(int) flow][1]; } deviationRandomIter.setSample(col, row, 0, sumdev); } } } pm.worked(1); } pm.done(); dirRandomIter.done(); pitRandomIter.done(); flowRandomIter.done(); deviationRandomIter.done(); tcaRandomIter.done(); } /** * routine that defines the draining directions * * @param indexes * vector containing the order of elevation * @param deviationsImage * the map containing the deviation * @param analizedMatrix * @param nelev * @return */ private void OrlandiniD8_LTD( double[] indexes, WritableRaster deviationsImage, BitMatrix analizedMatrix, WritableRaster pitImage, WritableRaster flowImage, WritableRaster tcaImage, WritableRaster dirImage, int nelev ) { int row, col, ncelle, nr, nc; double dx, dev1, dev2, sumdev1, sumdev2, sumdev; /* * it contains: * pend,dir,e0,e1,e2,sumdev, * didren1,dirdren2,sigma */ double[] dati = new double[10]; double count, flow; /* * it indicates the position of the triangle's vertexes */ ncelle = 0; RandomIter pitRandomIter = RandomIterFactory.create(pitImage, null); RandomIter flowRandomIter = RandomIterFactory.create(flowImage, null); WritableRandomIter tcaRandomIter = RandomIterFactory.createWritable(tcaImage, null); WritableRandomIter deviationRandomIter = RandomIterFactory.createWritable(deviationsImage, null); WritableRandomIter dirRandomIter = RandomIterFactory.createWritable(dirImage, null); double[] u = {xRes, yRes}; double[] v = {NaN, NaN}; dx = u[0]; // get rows and cols from the active region rows = pitImage.getHeight(); cols = pitImage.getWidth(); ncelle = 0; pm.beginTask(msg.message("draindir.orlandiniltd"), rows * cols); for( int i = rows * cols - 1; i >= 0; i-- ) { if (isCanceled(pm)) { return; } count = indexes[i] - 1; row = (int) Math.floor(count / cols); col = (int) (count % cols); if (!isNovalue(pitRandomIter.getSampleDouble(col, row, 0)) && !isNovalue(flowRandomIter.getSampleDouble(col, row, 0))) { ncelle = ncelle + 1; compose(analizedMatrix, pitRandomIter, tcaRandomIter, dati, u, v, col, row); if (dati[1] > 0) { dev1 = dx * Math.sin(dati[2]); dev2 = dx * Math.sqrt(2.0) * Math.sin(PI / 4 - dati[2]); if (dati[9] == 1) { dev2 = -dev2; } else { dev1 = -dev1; } calcarea(row, col, dati, v, analizedMatrix, deviationRandomIter, pitRandomIter, tcaRandomIter, dirRandomIter, cols, rows); sumdev = dati[6]; sumdev1 = dev1 + pLambda * sumdev; sumdev2 = dev2 + pLambda * sumdev; if (Math.abs(sumdev1) <= Math.abs(sumdev2) && (dati[3] - dati[4]) > 0.0) { dirRandomIter.setSample(col, row, 0, dati[7]); deviationRandomIter.setSample(col, row, 0, sumdev1); } else if (Math.abs(sumdev1) > Math.abs(sumdev2) || (dati[3] - dati[5]) > 0.0) { dirRandomIter.setSample(col, row, 0, dati[8]); deviationRandomIter.setSample(col, row, 0, sumdev2); } else { break; } } else if (dati[1] == 0) { if (ncelle == nelev) { /* sono all'uscita */ calcarea(row, col, dati, v, analizedMatrix, deviationRandomIter, pitRandomIter, tcaRandomIter, dirRandomIter, cols, rows); dirRandomIter.setSample(col, row, 0, 10); deviationRandomIter.setSample(col, row, 0, pLambda * dati[6]); if (tcaRandomIter.getSampleDouble(col, row, 0) != ncelle) { pm.done(); return; } else { pm.done(); return; } } else { calcarea(row, col, dati, v, analizedMatrix, deviationRandomIter, pitRandomIter, tcaRandomIter, dirRandomIter, cols, rows); sumdev = pLambda * dati[6]; dirRandomIter.setSample(col, row, 0, flowRandomIter.getSampleDouble(col, row, 0)); flow = dirRandomIter.getSampleDouble(col, row, 0); nr = row + order[(int) flow][0]; nc = col + order[(int) flow][1]; while( analizedMatrix.isMarked(nc, nr) ) { tcaRandomIter.setSample(nc, nr, 0, (tcaRandomIter.getSampleDouble(nc, nr, 0) + tcaRandomIter.getSampleDouble(col, row, 0))); flow = dirRandomIter.getSampleDouble(nc, nr, 0); nr = nr + order[(int) flow][0]; nc = nc + order[(int) flow][1]; } deviationRandomIter.setSample(col, row, 0, sumdev); } } } pm.worked(1); } pm.done(); dirRandomIter.done(); pitRandomIter.done(); flowRandomIter.done(); deviationRandomIter.done(); tcaRandomIter.done(); } /** * It calculates the drainage area for a cell[rows][cols] * * @param row * @param col * @param dati * @param v * @param analizedMatrix * @param deviation */ private void calcarea( int row, int col, double[] dati, double[] v, BitMatrix analizedMatrix, WritableRandomIter deviation, RandomIter pitRandomIter, WritableRandomIter tcaRandomIter, WritableRandomIter dirRandomIter, int nCols, int nRows ) { int conta, ninflow; int outdir; double sumdev; double[] dev = new double[8]; double[] are = new double[8]; ninflow = 0; sumdev = 0; for( int n = 1; n <= 8; n++ ) { conta = (col + order[n][1] - 1) * nCols + row + order[n][0]; /* * verifico se la cella che sto considerando e' stata gia' processata */ if (analizedMatrix.isMarked(col + order[n][1], row + order[n][0])) { if (!isNovalue(pitRandomIter.getSampleDouble(col + order[n][1], row + order[n][0], 0)) || conta <= nRows * nCols) { outdir = (int) dirRandomIter.getSampleDouble(col + order[n][1], row + order[n][0], 0); /* * verifico se la cella che sto considerando drena nel pixel * centrale */ if (outdir - n == 4 || outdir - n == -4) { ninflow = ninflow + 1; tcaRandomIter.setSample( col, row, 0, tcaRandomIter.getSampleDouble(col, row, 0) + tcaRandomIter.getSampleDouble(col + order[n][1], row + order[n][0], 0)); dev[ninflow] = deviation.getSampleDouble(col + order[n][1], row + order[n][0], 0); are[ninflow] = tcaRandomIter.getSampleDouble(col + order[n][1], row + order[n][0], 0); } } } } for( int i = 1; i <= ninflow; i++ ) { sumdev = sumdev + are[i] * dev[i] / tcaRandomIter.getSampleDouble(col, row, 0); } dati[6] = sumdev; } /** * It calculates the direction of maximun slope. * * @param analizedMatrix * @param dati * @param u * @param v * @param col * @param row */ private void compose( BitMatrix analizedMatrix, RandomIter pitRandomIter, WritableRandomIter tcaRandomIter, double[] dati, double[] u, double[] v, int col, int row ) { int n = 1, m = 1; double pendmax, dirmax = 0.0, e1min = -9999.0, e2min = -9999.0; int[][] tri = {{1, 2, 1}, /* tri 012 */ {3, 2, -1}, /* tri 023 |4|3|2| */ {3, 4, 1}, /* tri 034 |5|0|1| drainage direction. */ {5, 4, -1}, /* tri 045 |6|7|8| */ {5, 6, 1}, /* * tri 056 indico direzioni di drenaggio corrispondenti ai * verici */ {7, 6, -1}, /* * tri 067 dei triangoli (colonne 1,2) e il segno (sigma) * associato */ {7, 8, 1}, /* tri 078 al triangolo stesso (colonna 3). */ {1, 8, -1} /* tri 089 */ }; analizedMatrix.mark(col, row); tcaRandomIter.setSample(col, row, 0, 1.0); pendmax = 0.0; dati[3] = pitRandomIter.getSampleDouble(col, row, 0); /* * per ogni triangolo calcolo la pendenza massima e la direzione di * deflusso reale. */ for( int j = 0; j <= 7; j++ ) { n = tri[j][0]; m = tri[j][1]; dati[4] = pitRandomIter.getSampleDouble(col + order[n][1], row + order[n][0], 0); dati[5] = pitRandomIter.getSampleDouble(col + order[m][1], row + order[m][0], 0); /* * verifico che i punti attorno al pixel considerato non siano * novalue. In questo caso trascuro il triangolo. */ if (!isNovalue(dati[4]) && !isNovalue(dati[5])) { triangoli(u, dati); if (dati[1] > pendmax) { dirmax = dati[2]; pendmax = dati[1]; /* - direzione cardinale */ dati[7] = tri[j][0]; /* - direzione diagonale */ dati[8] = tri[j][1]; /* - segno del triangolo */ dati[9] = tri[j][2]; /* * - quote del triangolo avente pendenza * maggiore */ e1min = dati[4]; /* * non necessariamente sono le quote * minime. */ e2min = dati[5]; } } } dati[1] = pendmax; dati[2] = dirmax; dati[4] = e1min; dati[5] = e2min; } /** * Calcola per ogni triangolo la direzione e la pendenza massima. * * @param u * @param dati */ private void triangoli( double[] u, double[] dati ) { double pend1, pend2, sp, sd, dx, dy; /* definsco le dim. del pixel */ dx = u[0]; dy = u[1]; pend1 = (dati[3] - dati[4]) / dy; pend2 = (dati[4] - dati[5]) / dx; if (pend1 == 0.0) { if (pend2 >= 0.0) { dati[2] = +PI / 2; } else { dati[2] = -PI / 2; } } else { dati[2] = Math.atan(pend2 / pend1); } sp = Math.sqrt(pend1 * pend1 + pend2 * pend2); sd = (dati[3] - dati[5]) / Math.sqrt(dx * dx + dy * dy); if (dati[2] >= 0 && dati[2] <= PI / 4 && pend1 >= 0) { dati[1] = sp; } else { if (pend1 > sd) { dati[1] = pend1; dati[2] = 0; } else { dati[1] = sd; dati[2] = PI / 4; } } } /** * The fixed network method allows you to assign a known channel network and * to then correct the drainage directions. */ private void newDirections( WritableRaster pitWR, WritableRaster dirWR ) { int[][] odir = {{0, 0, 0}, {0, 1, 1}, {-1, 1, 2}, {-1, 0, 3}, {-1, -1, 4}, {0, -1, 5}, {1, -1, 6}, {1, 0, 7}, {1, 1, 8}, {0, 0, 9}, {0, 0, 10}}; double elev = 0.0; int[] flow = new int[2], nflow = new int[2]; RandomIter pitRandomIter = RandomIterFactory.create(pitWR, null); RenderedImage flowFixedRI = inFlownet.getRenderedImage(); WritableRaster flowFixedWR = CoverageUtilities.renderedImage2WritableRaster(flowFixedRI, true); RandomIter flowFixedIter = RandomIterFactory.create(flowFixedWR, null); WritableRandomIter dirRandomIter = RandomIterFactory.createWritable(dirWR, null); WritableRaster modflowImage = CoverageUtilities.createDoubleWritableRaster(pitWR.getWidth(), pitWR.getHeight(), null, null, null); WritableRandomIter modflowRandomIter = RandomIterFactory.createWritable(modflowImage, null); pm.beginTask("Correcting drainage directions...", rows); for( int j = 0; j < rows; j++ ) { if (isCanceled(pm)) { return; } for( int i = 0; i < cols; i++ ) { if (!isNovalue(flowFixedIter.getSampleDouble(i, j, 0))) { flow[0] = i; flow[1] = j; for( int k = 1; k <= 8; k++ ) { nflow[0] = flow[0] + odir[k][1]; nflow[1] = flow[1] + odir[k][0]; if (modflowRandomIter.getSampleDouble(nflow[0], nflow[1], 0) == 0 && isNovalue(flowFixedIter.getSampleDouble(nflow[0], nflow[1], 0))) { elev = pitRandomIter.getSampleDouble(nflow[0] + odir[1][1], nflow[1] + odir[1][0], 0); for( int n = 2; n <= 8; n++ ) { if (nflow[0] + odir[n][0] >= 0 && nflow[0] + odir[n][1] < rows && nflow[1] + odir[n][0] >= 0 && nflow[1] + odir[n][0] < cols) { if (pitRandomIter.getSampleDouble(nflow[0] + odir[n][1], nflow[1] + odir[n][0], 0) >= elev) { elev = pitRandomIter.getSampleDouble(nflow[0] + odir[n][1], nflow[1] + odir[n][0], 0); dirRandomIter.setSample(nflow[0], nflow[1], 0, odir[n][2]); } } } for( int s = 1; s <= 8; s++ ) { if (nflow[0] + odir[s][0] >= 0 && nflow[0] + odir[s][0] < rows && nflow[1] + odir[s][1] >= 0 && nflow[1] + odir[s][1] < cols) { if (!isNovalue(flowFixedIter.getSampleDouble(nflow[0] + odir[s][1], nflow[1] + odir[s][0], 0))) { if (pitRandomIter.getSampleDouble(nflow[0] + odir[s][1], nflow[1] + odir[s][0], 0) <= elev) { elev = pitRandomIter.getSampleDouble(nflow[0] + odir[s][1], nflow[1] + odir[s][0], 0); dirRandomIter.setSample(nflow[0], nflow[1], 0, odir[s][2]); } } } } modflowRandomIter.setSample(nflow[0], nflow[1], 0, 1); } } } if (!isNovalue(flowFixedIter.getSampleDouble(i, j, 0))) { dirRandomIter.setSample(i, j, 0, flowFixedIter.getSampleDouble(i, j, 0)); } } pm.worked(1); } pm.done(); dirRandomIter.done(); pitRandomIter.done(); modflowRandomIter.done(); flowFixedIter.done(); } }