001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2005-2007, Geotools Project Managment Committee (PMC)
005: * (C) 2007, GeoSolutions S.A.S.
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.coverage.processing;
018:
019: import java.awt.geom.AffineTransform;
020: import java.awt.image.DataBuffer;
021: import java.awt.image.WritableRaster;
022:
023: import javax.media.jai.RasterFactory;
024:
025: import junit.framework.Test;
026: import junit.framework.TestCase;
027: import junit.framework.TestSuite;
028:
029: import org.geotools.coverage.FactoryFinder;
030: import org.geotools.coverage.grid.GridCoverage2D;
031: import org.geotools.coverage.grid.GridCoverageFactory;
032: import org.geotools.coverage.processing.operation.Extrema;
033: import org.geotools.coverage.processing.operation.Histogram;
034: import org.geotools.geometry.Envelope2D;
035: import org.geotools.referencing.crs.DefaultGeographicCRS;
036: import org.geotools.referencing.operation.matrix.XAffineTransform;
037: import org.opengis.geometry.Envelope;
038: import org.opengis.parameter.ParameterValueGroup;
039: import org.opengis.referencing.crs.CoordinateReferenceSystem;
040:
041: import com.vividsolutions.jts.geom.Coordinate;
042: import com.vividsolutions.jts.geom.GeometryFactory;
043: import com.vividsolutions.jts.geom.LinearRing;
044: import com.vividsolutions.jts.geom.Polygon;
045: import com.vividsolutions.jts.geom.PrecisionModel;
046:
047: /**
048: * Testing Extrema and {@link Histogram} operations.
049: *
050: * @author Simone Giannecchini, GeoSolutions.
051: *
052: */
053: public class StatisticsOperationsTest extends TestCase {
054:
055: protected void setUp() throws Exception {
056: super .setUp();
057: createFloatRaster();
058: createByteRaster();
059: }
060:
061: protected GridCoverage2D sampleFloatCoverage;
062:
063: protected GridCoverage2D sampleByteCoverage;
064:
065: /**
066: * @param name
067: */
068: public StatisticsOperationsTest(String name) {
069: super (name);
070: }
071:
072: /**
073: * Run the suite from the command line.
074: */
075: public static void main(final String[] args) {
076: junit.textui.TestRunner.run(suite());
077: }
078:
079: /**
080: * Returns the test suite.
081: */
082: public static Test suite() {
083: final TestSuite ts = new TestSuite();
084: ts.addTest(new StatisticsOperationsTest("testHistogram"));
085: ts.addTest(new StatisticsOperationsTest("testExtrema"));
086: return ts;
087: }
088:
089: /**
090: * Tests the creation of a floating point {@link WritableRaster}.
091: */
092: private void createFloatRaster() {
093: /*
094: * Set the pixel values. Because we use only one tile with one band, the
095: * code below is pretty similar to the code we would have if we were
096: * just setting the values in a matrix.
097: */
098: final int width = 500;
099: final int height = 500;
100: final WritableRaster raster = RasterFactory.createBandedRaster(
101: DataBuffer.TYPE_FLOAT, width, height, 1, null);
102: for (int y = 0; y < height; y++) {
103: for (int x = 0; x < width; x++) {
104: raster.setSample(x, y, 0, x + y);
105: }
106: }
107: /*
108: * Set some metadata (the CRS, the geographic envelope, etc.) and
109: * display the image. The display may be slow, since the translation
110: * from floating-point values to some color (or grayscale) is performed
111: * on the fly everytime the image is rendered.
112: */
113: final CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
114: final Envelope envelope = new Envelope2D(crs, 0, 0, 30, 30);
115: final GridCoverageFactory factory = FactoryFinder
116: .getGridCoverageFactory(null);
117: sampleFloatCoverage = factory.create(
118: "My grayscale float coverage", raster, envelope);
119:
120: }
121:
122: /**
123: * Tests the creation of a floating point {@link WritableRaster}.
124: */
125: private void createByteRaster() {
126: /*
127: * Set the pixel values. Because we use only one tile with one band, the
128: * code below is pretty similar to the code we would have if we were
129: * just setting the values in a matrix.
130: */
131: final int width = 500;
132: final int height = 500;
133: final WritableRaster raster = RasterFactory.createBandedRaster(
134: DataBuffer.TYPE_BYTE, width, height, 1, null);
135: for (int y = 0; y < height; y++) {
136: for (int x = 0; x < width; x++) {
137: // we exploit the clmaping capabilities of the sample model
138: raster.setSample(x, y, 0, x + y);
139: }
140: }
141: /*
142: * Set some metadata (the CRS, the geographic envelope, etc.) and
143: * display the image. The display may be slow, since the translation
144: * from floating-point values to some color (or grayscale) is performed
145: * on the fly everytime the image is rendered.
146: */
147: final CoordinateReferenceSystem crs = DefaultGeographicCRS.WGS84;
148: final Envelope envelope = new Envelope2D(crs, 0, 0, 30, 30);
149: final GridCoverageFactory factory = FactoryFinder
150: .getGridCoverageFactory(null);
151: sampleByteCoverage = factory.create(
152: "My grayscale byte coverage", raster, envelope);
153:
154: }
155:
156: public void testExtrema() {
157:
158: // /////////////////////////////////////////////////////////////////////
159: //
160: // Create the operation for the Extrema with a ROI
161: //
162: // /////////////////////////////////////////////////////////////////////
163: Operation2D op = (Operation2D) new DefaultProcessor(null)
164: .getOperation("Extrema");
165: ParameterValueGroup params = op.getParameters();
166: params.parameter("Source").setValue(sampleFloatCoverage);
167: params
168: .parameter("xPeriod")
169: .setValue(
170: 1 * XAffineTransform
171: .getScaleX0((AffineTransform) sampleFloatCoverage
172: .getGridGeometry()
173: .getGridToCRS()));
174: params
175: .parameter("yPeriod")
176: .setValue(
177: 1 * XAffineTransform
178: .getScaleY0((AffineTransform) sampleFloatCoverage
179: .getGridGeometry()
180: .getGridToCRS()));
181:
182: final PrecisionModel pm = new PrecisionModel();
183: final GeometryFactory gf = new GeometryFactory(pm, 0);
184: final Envelope2D rect = sampleFloatCoverage.getEnvelope2D();
185: final Coordinate[] coord = new Coordinate[] {
186: new Coordinate(rect.getMinX(), rect.getMinY()),
187: new Coordinate(rect.getMinX()
188: + (rect.getMaxX() - rect.getMinX()) / 2.0, rect
189: .getMinY()),
190: new Coordinate(rect.getMinX()
191: + (rect.getMaxX() - rect.getMinX()) / 2.0, rect
192: .getMinY()
193: + (rect.getMaxY() - rect.getMinY()) / 2.0),
194: new Coordinate(rect.getMinX(), rect.getMinY()
195: + (rect.getMaxY() - rect.getMinY()) / 2.0),
196: new Coordinate(rect.getMinX(), rect.getMinY()) };
197: final LinearRing ring = gf.createLinearRing(coord);
198: final Polygon p = new Polygon(ring, null, gf);
199: params.parameter("roi").setValue(p);
200:
201: GridCoverage2D coverage = (GridCoverage2D) op.doOperation(
202: params, null);
203: assertEquals(((double[]) coverage.getProperty("minimum"))[0],
204: 250.0, 0);
205: assertEquals(((double[]) coverage.getProperty("maximum"))[0],
206: 748.0, 0);
207:
208: // /////////////////////////////////////////////////////////////////////
209: //
210: // Create the operation for the Extrema with a ROI and subsampling by 2
211: //
212: // /////////////////////////////////////////////////////////////////////
213: op = new Extrema();
214: params = op.getParameters();
215: params.parameter("Source").setValue(sampleFloatCoverage);
216: params
217: .parameter("xPeriod")
218: .setValue(
219: 2 * XAffineTransform
220: .getScaleX0((AffineTransform) sampleFloatCoverage
221: .getGridGeometry()
222: .getGridToCRS()));
223: params
224: .parameter("yPeriod")
225: .setValue(
226: 2 * XAffineTransform
227: .getScaleY0((AffineTransform) sampleFloatCoverage
228: .getGridGeometry()
229: .getGridToCRS()));
230: params.parameter("roi").setValue(p);
231: coverage = (GridCoverage2D) op.doOperation(params, null);
232: assertEquals(((double[]) coverage.getProperty("minimum"))[0],
233: 250.0, 0);
234: assertEquals(((double[]) coverage.getProperty("maximum"))[0],
235: 746.0, 0);
236:
237: }
238:
239: public void testHistogram() {
240:
241: // /////////////////////////////////////////////////////////////////////
242: //
243: // Create the operation for the Extrema with a ROI
244: //
245: // /////////////////////////////////////////////////////////////////////
246: Operation2D op = (Operation2D) new DefaultProcessor(null)
247: .getOperation("Histogram");
248: ParameterValueGroup params = op.getParameters();
249: params.parameter("Source").setValue(sampleByteCoverage);
250: params
251: .parameter("xPeriod")
252: .setValue(
253: 1 * XAffineTransform
254: .getScaleX0((AffineTransform) sampleByteCoverage
255: .getGridGeometry()
256: .getGridToCRS()));
257: params
258: .parameter("yPeriod")
259: .setValue(
260: 1 * XAffineTransform
261: .getScaleY0((AffineTransform) sampleByteCoverage
262: .getGridGeometry()
263: .getGridToCRS()));
264:
265: final PrecisionModel pm = new PrecisionModel();
266: final GeometryFactory gf = new GeometryFactory(pm, 0);
267: final Envelope2D rect = sampleByteCoverage.getEnvelope2D();
268: final Coordinate[] coord = new Coordinate[] {
269: new Coordinate(rect.getMinX(), rect.getMaxY()),
270: new Coordinate(rect.getMinX()
271: + (rect.getMaxX() - rect.getMinX()) / 16.0,
272: rect.getMaxY()),
273: new Coordinate(rect.getMinX()
274: + (rect.getMaxX() - rect.getMinX()) / 16.0,
275: rect.getMaxY()
276: - (rect.getMaxY() - rect.getMinY())
277: / 16.0),
278: new Coordinate(rect.getMinX(), rect.getMaxY()
279: - (rect.getMaxY() - rect.getMinY()) / 16.0),
280: new Coordinate(rect.getMinX(), rect.getMaxY()) };
281: final LinearRing ring = gf.createLinearRing(coord);
282: final Polygon p = new Polygon(ring, null, gf);
283: params.parameter("roi").setValue(p);
284:
285: GridCoverage2D coverage = (GridCoverage2D) op.doOperation(
286: params, null);
287: javax.media.jai.Histogram histogram = (javax.media.jai.Histogram) coverage
288: .getProperty(Histogram.GT_SYNTHETIC_PROPERTY_HISTOGRAM);
289: assertEquals(0, histogram.getBinSize(0, 255));
290: assertEquals(1, histogram.getBinSize(0, 60));
291: // /////////////////////////////////////////////////////////////////////
292: //
293: // Create the operation for the Extrema with a ROI and subsampling by 7
294: //
295: // /////////////////////////////////////////////////////////////////////
296: op = new Histogram();
297: params = op.getParameters();
298: params.parameter("Source").setValue(sampleByteCoverage);
299: params
300: .parameter("xPeriod")
301: .setValue(
302: 7 * XAffineTransform
303: .getScaleX0((AffineTransform) sampleByteCoverage
304: .getGridGeometry()
305: .getGridToCRS()));
306: params
307: .parameter("yPeriod")
308: .setValue(
309: 7 * XAffineTransform
310: .getScaleY0((AffineTransform) sampleByteCoverage
311: .getGridGeometry()
312: .getGridToCRS()));
313: params.parameter("roi").setValue(p);
314: coverage = (GridCoverage2D) op.doOperation(params, null);
315: histogram = (javax.media.jai.Histogram) coverage
316: .getProperty(Histogram.GT_SYNTHETIC_PROPERTY_HISTOGRAM);
317: assertEquals(0, histogram.getBinSize(0, 255));
318: assertEquals(0, histogram.getBinSize(0, 60));
319: assertEquals(1, histogram.getBinSize(0, 56));
320:
321: }
322:
323: }
|