/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2002-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * 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.geotoolkit.coverage.processing; import java.util.Collections; import java.util.Map; import java.awt.geom.AffineTransform; import java.awt.image.RenderedImage; import java.util.logging.Level; import javax.media.jai.RenderedOp; import org.opengis.parameter.ParameterValueGroup; import org.opengis.referencing.operation.MathTransform; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.SingleCRS; import org.geotoolkit.factory.Hints; import org.geotoolkit.coverage.grid.Viewer; import org.geotoolkit.coverage.grid.ViewType; import org.geotoolkit.coverage.grid.GridGeometry2D; import org.geotoolkit.coverage.grid.GridCoverage2D; import org.geotoolkit.coverage.grid.GridCoverageTestBase; import org.apache.sis.referencing.crs.DefaultDerivedCRS; import org.geotoolkit.referencing.operation.MathTransforms; import org.apache.sis.internal.referencing.provider.Affine; import org.apache.sis.referencing.operation.DefaultConversion; import static org.junit.Assert.*; import static org.geotoolkit.test.Commons.*; import static java.lang.StrictMath.*; /** * Base class for grid processing tests. This class provides a few convenience * methods performing some operations on {@link GridCoverage2D}. * * @author Martin Desruisseaux (IRD, Geomatys) * @version 3.02 * * @since 2.1 */ public abstract strictfp class GridProcessingTestBase extends GridCoverageTestBase { /** * Creates a new test suite for the given class. * * @param testing The class to be tested. */ protected GridProcessingTestBase(final Class<?> testing) { super(testing); } /** * Rotates the {@linkplain #coverage current coverage} by the given angle. This * method replaces the coverage CRS by a derived one containing the rotated axes. * * @param angle The rotation angle, in degrees. */ protected final void rotate(final double angle) { final AffineTransform atr = AffineTransform.getRotateInstance(toRadians(angle)); atr.concatenate(getAffineTransform(coverage)); final MathTransform tr = MathTransforms.linear(atr); SingleCRS crs = (SingleCRS) coverage.getCoordinateReferenceSystem(); final Map<String, String> name = Collections.singletonMap(DefaultDerivedCRS.NAME_KEY, "Rotation " + angle + "°"); crs = DefaultDerivedCRS.create(name, crs, new DefaultConversion(name, new Affine(), tr, null), crs.getCoordinateSystem()); resample(crs, null, null, true); } /** * Resamples the {@linkplain #coverage current coverage} by a new coverage using * the specified CRS. * * @param targetCRS The target CRS, or {@code null} if the same. * @param geometry The target geometry, or {@code null} if the same. * @param hints An optional set of hints, or {@code null} if none. * @param useGeophysics {@code true} for resampling the geophysics view. */ protected final void resample(final CoordinateReferenceSystem targetCRS, final GridGeometry2D geometry, final Hints hints, final boolean useGeophysics) { final AbstractCoverageProcessor processor = AbstractOperation.getProcessor(hints); final String arg1, arg2; final Object value1, value2; if (targetCRS != null) { arg1 = "CoordinateReferenceSystem"; value1 = targetCRS; if (geometry != null) { arg2 = "GridGeometry"; value2 = geometry; } else { arg2 = "InterpolationType"; value2 = "bilinear"; } } else { arg1 = "GridGeometry"; value1 = geometry; arg2 = "InterpolationType"; value2 = "bilinear"; } coverage = coverage.view(useGeophysics ? ViewType.GEOPHYSICS : ViewType.PACKED); final ParameterValueGroup param = processor.getOperation("Resample").getParameters(); param.parameter("Source").setValue(coverage); param.parameter(arg1).setValue(value1); param.parameter(arg2).setValue(value2); coverage = (GridCoverage2D) processor.doOperation(param); } /** * Resamples the {@linkplain #coverage current coverage} to the specified CRS using the specified * hints. The result will be displayed in a window if {@link #viewEnabled} is set to {@code true}. * * @param targetCRS The target CRS, or {@code null} if the same. * @param geometry The target geometry, or {@code null} if the same. * @param hints An optional set of hints, or {@code null} if none. * @param useGeophysics {@code true} for projecting the geophysics view. * @return The operation name which was applied on the image, or {@code null} if none. */ protected final String showResampled(final CoordinateReferenceSystem targetCRS, final GridGeometry2D geometry, final Hints hints, final boolean useGeophysics) { resample(targetCRS, geometry, hints, useGeophysics); final RenderedImage image = coverage.getRenderedImage(); String operation = null; if (image instanceof RenderedOp) { operation = ((RenderedOp) image).getOperationName(); AbstractCoverageProcessor.LOGGER.log(Level.FINE, "Applied \"{0}\" JAI operation.", operation); } coverage = coverage.view(ViewType.PACKED); if (viewEnabled) { /* * Note: In current Resample implementation, simple affine transforms like * translations will not be visible with the simple viewer used here. * It would be visible however with more elaborated viewers. */ Viewer.show(coverage, operation); } else { // Forces computation in order to check if an exception is thrown. assertNotNull(coverage.getRenderedImage().getData()); } return operation; } /** * Performs an affine transformation on the {@linkplain #coverage current coverage}. * The transformation is a translation by 5 units along x and y axes. The result will * be displayed in a window if {@link #viewEnabled} is set to {@code true}. * * @param hints * An optional set of hints, or {@code null} if none. * @param useGeophysics * {@code true} for performing the operation on the geophysics view. * @param asCRS * The expected operation name if the resampling is performed as a CRS change. * @param asGG * The expected operation name if the resampling is performed as a Grid Geometry change. */ protected final void showTranslated(final Hints hints, final boolean useGeophysics, final String asCRS, final String asGG) { // final AffineTransform atr = AffineTransform.getTranslateInstance(5, 5); // atr.concatenate(getAffineTransform(coverage)); // final MathTransform tr = MathTransforms.linear(atr); // SingleCRS crs = (SingleCRS) coverage.getCoordinateReferenceSystem(); // crs = new DefaultDerivedCRS("Translated", crs, tr, crs.getCoordinateSystem()); // assertEquals(asCRS, showResampled(crs, null, hints, useGeophysics)); // // // Same operation, given the translation in the GridGeometry argument rather than the CRS. // final GridGeometry2D gg = new GridGeometry2D(null, tr, null); // assertEquals(asGG, showResampled(null, gg, hints, useGeophysics)); // TODO: we should probably invoke "assertRasterEquals" with both coverages. } }