/* * 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.gears.modules.r.windowsampler; import static java.lang.Math.ceil; import static java.lang.Math.max; import static java.lang.Math.min; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_AUTHORCONTACTS; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_AUTHORNAMES; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_DOCUMENTATION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_KEYWORDS; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_LABEL; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_LICENSE; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_NAME; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_STATUS; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_IN_GEODATA_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_OUT_GEODATA_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_P_COLS_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_P_MODE_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_P_ROWS_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_P_X_STEP_DESCRIPTION; import static org.jgrasstools.gears.i18n.GearsMessages.OMSWINDOWSAMPLER_P_Y_STEP_DESCRIPTION; import static org.jgrasstools.gears.libs.modules.JGTConstants.isNovalue; import java.awt.Dimension; import java.awt.Point; import java.awt.image.WritableRaster; 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.jaitools.imageutils.iterator.WindowIterator; 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.utils.RegionMap; import org.jgrasstools.gears.utils.coverage.CoverageUtilities; @Description(OMSWINDOWSAMPLER_DESCRIPTION) @Documentation(OMSWINDOWSAMPLER_DOCUMENTATION) @Author(name = OMSWINDOWSAMPLER_AUTHORNAMES, contact = OMSWINDOWSAMPLER_AUTHORCONTACTS) @Keywords(OMSWINDOWSAMPLER_KEYWORDS) @Label(OMSWINDOWSAMPLER_LABEL) @Name(OMSWINDOWSAMPLER_NAME) @Status(OMSWINDOWSAMPLER_STATUS) @License(OMSWINDOWSAMPLER_LICENSE) public class OmsWindowSampler extends JGTModel { @Description(OMSWINDOWSAMPLER_IN_GEODATA_DESCRIPTION) @In public GridCoverage2D inGeodata; @Description(OMSWINDOWSAMPLER_P_MODE_DESCRIPTION) @In public int pMode = 0; @Description(OMSWINDOWSAMPLER_P_ROWS_DESCRIPTION) @In public int pRows = 3; @Description(OMSWINDOWSAMPLER_P_COLS_DESCRIPTION) @In public int pCols = 3; @Description(OMSWINDOWSAMPLER_P_X_STEP_DESCRIPTION) @In public Integer pXstep; @Description(OMSWINDOWSAMPLER_P_Y_STEP_DESCRIPTION) @In public Integer pYstep; @Description(OMSWINDOWSAMPLER_OUT_GEODATA_DESCRIPTION) @Out public GridCoverage2D outGeodata; @Execute public void process() throws Exception { checkNull(inGeodata); RegionMap regionMap = CoverageUtilities.getRegionParamsFromGridCoverage(inGeodata); int cols = regionMap.getCols(); int rows = regionMap.getRows(); int xstep = pCols; int ystep = pRows; if (pXstep != null) { xstep = pXstep; } if (pYstep != null) { ystep = pYstep; } // new rows and cols are all that have space rounding down int newRows = (int) ceil((double) rows / (double) ystep); int newCols = (int) ceil((double) cols / (double) xstep); WritableRaster outputWR = CoverageUtilities.createDoubleWritableRaster(newCols, newRows, null, null, JGTConstants.doubleNovalue); WindowIterator iter = new WindowIterator(inGeodata.getRenderedImage(), null, new Dimension(pCols, pRows), new Point(0, 0), xstep, ystep, JGTConstants.doubleNovalue); for( int r = 0; r < newRows; r++ ) { for( int c = 0; c < newCols; c++ ) { double[][] window = iter.getWindowDouble(null); double newValue = calculateValue(window); iter.next(); outputWR.setSample(c, r, 0, newValue); } } outGeodata = CoverageUtilities .buildCoverage("downsampled", outputWR, regionMap, inGeodata.getCoordinateReferenceSystem()); } private double calculateValue( double[][] window ) { switch( pMode ) { case 0: double avg = 0; int num = 0; for( int i = 0; i < window.length; i++ ) { for( int j = 0; j < window[0].length; j++ ) { if (!isNovalue(window[i][j])) { avg = avg + window[i][j]; num++; } } } avg = avg / num; return avg; case 1: double sum = 0; for( int i = 0; i < window.length; i++ ) { for( int j = 0; j < window[0].length; j++ ) { if (!isNovalue(window[i][j])) { sum = sum + window[i][j]; } } } return sum; case 2: double max = Double.NEGATIVE_INFINITY; for( int i = 0; i < window.length; i++ ) { for( int j = 0; j < window[0].length; j++ ) { if (!isNovalue(window[i][j])) { max = max(window[i][j], max); } } } return max; case 3: double min = Double.POSITIVE_INFINITY; for( int i = 0; i < window.length; i++ ) { for( int j = 0; j < window[0].length; j++ ) { if (!isNovalue(window[i][j])) { min = min(window[i][j], min); } } } return min; default: throw new ModelsIllegalargumentException("Mode not recognized: " + pMode, this, pm); } } }