/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014-2015, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * 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 * Lesser General Public License for more details. */ package org.geotools.coverage.processing; import it.geosolutions.jaiext.JAIExt; import it.geosolutions.jaiext.range.Range; import it.geosolutions.jaiext.range.RangeFactory; import java.awt.Rectangle; import java.awt.geom.AffineTransform; import java.awt.image.RenderedImage; import java.util.Map; import javax.media.jai.Interpolation; import javax.media.jai.PlanarImage; import javax.media.jai.ROI; import javax.media.jai.ROIShape; import org.opengis.parameter.ParameterValueGroup; import org.geotools.coverage.grid.Viewer; import org.geotools.coverage.grid.GridCoverage2D; import org.junit.*; import static org.junit.Assert.*; /** * Tests the scale operation. * * @source $URL$ * @version $Id$ * @author Simone Giannecchini (GeoSolutions) * * @since 12.0 */ public class AffineTest extends GridProcessingTestBase { /** * The processor to be used for all tests. */ private CoverageProcessor processor; /** * Set up common objects used for all tests. */ @Before public void setUp() { JAIExt.initJAIEXT(); processor = CoverageProcessor.getInstance(null); } /** * Tests the "Scale" operation. * * @todo Disabled for now because seems to be trapped in a never ending loop. */ @Test public void testAffine() { final GridCoverage2D originallyIndexedCoverage = EXAMPLES.get(0); final GridCoverage2D indexedCoverage = EXAMPLES.get(2); final GridCoverage2D indexedCoverageWithTransparency = EXAMPLES.get(3); final GridCoverage2D floatCoverage = EXAMPLES.get(4); /////////////////////////////////////////////////////////////////////// // // Nearest neighbor interpolation // /////////////////////////////////////////////////////////////////////// Interpolation interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST); affine(originallyIndexedCoverage , interp, null, null); affine(indexedCoverage , interp, null, null); affine(indexedCoverageWithTransparency, interp, null, null); /////////////////////////////////////////////////////////////////////// // // Nearest neighbor interpolation and ROI / NoData. // /////////////////////////////////////////////////////////////////////// RenderedImage src = originallyIndexedCoverage.getRenderedImage(); ROI roi = new ROIShape(new Rectangle(src.getMinX() + 1, src.getMinY() + 1, src.getWidth()/2, src.getHeight()/2)); Range nodata = RangeFactory.create(12, 12); affine(originallyIndexedCoverage , interp, roi, null); affine(originallyIndexedCoverage , interp, null, nodata); /////////////////////////////////////////////////////////////////////// // // Bilinear interpolation // /////////////////////////////////////////////////////////////////////// interp = Interpolation.getInstance(Interpolation.INTERP_BILINEAR); affine(indexedCoverage , interp, null, null); affine(indexedCoverageWithTransparency, interp, null, null); /////////////////////////////////////////////////////////////////////// // // Nearest neighbor interpolation for a float coverage // /////////////////////////////////////////////////////////////////////// interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST); affine(floatCoverage, interp, null, null); // Play with a rotated coverage affine(rotate(floatCoverage, Math.PI/4), null, null, null); } /** * Applies an affine operation on the photographic view of the given coverage. * * @param coverage The coverage to transfor. * @param interp The interpolation to use. */ private void affine(final GridCoverage2D coverage, final Interpolation interp, final ROI roi, final Range nodata) { // Caching initial properties. final RenderedImage originalImage = coverage.getRenderedImage(); final int w = originalImage.getWidth(); final int h = originalImage.getHeight(); // Getting parameters for doing a scale. final ParameterValueGroup param = processor.getOperation("Affine").getParameters(); param.parameter("Source").setValue(coverage); param.parameter("transform").setValue(new AffineTransform(0.5,0.0,0.0,0.5,0.0,0.0)); param.parameter("Interpolation").setValue(interp); boolean jaiextAffine = JAIExt.isJAIExtOperation("Affine"); if(roi != null && jaiextAffine){ param.parameter("roi").setValue(roi); } // Doing a first scale. GridCoverage2D scaled = (GridCoverage2D) processor.doOperation(param); assertEnvelopeEquals(coverage, scaled); RenderedImage scaledImage = scaled.getRenderedImage(); assertEquals(w / 2.0, scaledImage.getWidth(), EPS); assertEquals(h / 2.0, scaledImage.getHeight(), EPS); if (SHOW) { Viewer.show(coverage); Viewer.show(scaled); } else { // Force computation assertNotNull(PlanarImage.wrapRenderedImage(coverage.getRenderedImage()).getTiles()); assertNotNull(PlanarImage.wrapRenderedImage(scaledImage).getTiles()); } // Ensure a new ROI property has been created Map<String, Object> properties = scaled.getProperties(); if(jaiextAffine && roi != null){ assertNotNull(properties); assertTrue(properties.containsKey("GC_ROI")); assertTrue(properties.get("GC_ROI") instanceof ROI); } // Doing another scale using the default processor. scaled = (GridCoverage2D) Operations.DEFAULT.affine(scaled, AffineTransform.getScaleInstance(3, 3), interp,null); scaledImage = scaled.getRenderedImage(); assertEnvelopeEquals(coverage, scaled); assertEquals(w * 1.5, scaledImage.getWidth(), EPS); assertEquals(h * 1.5, scaledImage.getHeight(), EPS); if (SHOW) { Viewer.show(scaled); } else { // Force computation assertNotNull(scaledImage.getData()); } } }