/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2006-2008, 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 java.awt.image.IndexColorModel;
import java.awt.image.RenderedImage;
import javax.media.jai.Interpolation;
import javax.media.jai.InterpolationNearest;
import org.opengis.parameter.ParameterValueGroup;
import org.geotools.factory.Hints;
import org.geotools.coverage.grid.Viewer;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.resources.coverage.CoverageUtilities;
import static org.geotools.coverage.grid.ViewType.*;
import org.junit.*;
import static org.junit.Assert.*;
/**
* Tests the "filtered subsample" operation.
*
* @source $URL$
* @version $Id$
* @author Simone Giannecchini (GeoSolutions)
* @author Martin Desruisseaux (Geomatys)
*
* @since 2.3
*/
public final class FilteredSubsampleTest extends GridProcessingTestBase {
/**
* The processors to be used for all tests.
*/
private DefaultProcessor processor;
/**
* Set up common objects used for all tests.
*/
@Before
public void setUp() {
processor = new DefaultProcessor(null);
}
/**
* Tests the "SubsampleAverage" operation.
*/
@Test
public void testSubsampleAverage() {
final GridCoverage2D originallyIndexedCoverage = EXAMPLES.get(0);
final GridCoverage2D indexedCoverage = EXAMPLES.get(2);
final GridCoverage2D indexedCoverageWithTransparency = EXAMPLES.get(3);
final GridCoverage2D floatCoverage = EXAMPLES.get(4);
// On this one the Subsample average should do an RGB expansion
float[] filter = new float[] {1};
Interpolation interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
filteredSubsample(indexedCoverage.view(GEOPHYSICS), interp, filter);
// On this one the Subsample average should do an RGB expansion preserving alpha.
filteredSubsample(indexedCoverageWithTransparency.view(GEOPHYSICS), interp, filter);
// On this one the subsample average should go back to the geophysic
// view before being applied.
filteredSubsample(originallyIndexedCoverage.view(PACKED), interp, filter);
// On this one the Subsample average should do an RGB expansion.
interp = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
filteredSubsample(indexedCoverage.view(GEOPHYSICS), interp, filter);
// On this one the Subsample average should do an RGB expansion preserving alpha.
filteredSubsample(indexedCoverageWithTransparency.view(GEOPHYSICS), interp, filter);
// On this one the subsample average should go back to the geophysics
// view before being applied.
filteredSubsample(originallyIndexedCoverage.view(PACKED), interp, filter);
// On this one the Subsample average should do an RGB expansion.
filter = new float[] { 0.5F, 1.0F / 3.0F,
0.0F, -1.0F / 12.0F };
interp = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
filteredSubsample(indexedCoverage.view(GEOPHYSICS), interp, filter);
// On this one the Subsample average should do an RGB expansion
// preserving alpha.
filteredSubsample(indexedCoverageWithTransparency.view(GEOPHYSICS), interp, filter);
// On this one the subsample average should go back to the geophysiscs
// view before being applied.
filteredSubsample(originallyIndexedCoverage.view(PACKED), interp, filter);
// On this one the Subsample average should do an RGB expansion.
interp = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
filteredSubsample(indexedCoverage.view(GEOPHYSICS), interp, filter);
// On this one the Subsample average should do an RGB expansion
// preserving alpha.
filteredSubsample(indexedCoverageWithTransparency.view(GEOPHYSICS), interp, filter);
// On this one the subsample average should go back to the geophysiscs
// view before being applied.
filteredSubsample(originallyIndexedCoverage.view(PACKED), interp, filter);
// On this one the subsample average should go back to the
// geophysics view before being applied.
filteredSubsample(floatCoverage.view(PACKED), interp, new float[]{1},
new Hints(Hints.COVERAGE_PROCESSING_VIEW, PHOTOGRAPHIC));
// Play with a rotated coverage.
filteredSubsample(rotate(floatCoverage.view(GEOPHYSICS), Math.PI/4), interp, filter);
}
/**
* Tests the "FilteredSubsamble" operation.
*
* @param coverage The coverage on which to apply the operation.
* @param interp The interpolation to use.
* @param filter The filter to be used.
*/
private void filteredSubsample(final GridCoverage2D coverage, final Interpolation interp,
final float[] filter)
{
filteredSubsample(coverage, interp, filter, null);
}
/**
* Tests the "FilteredSubsamble" operation using the given hints.
*
* @param coverage The coverage on which to apply the operation.
* @param interp The interpolation to use.
* @param filter The filter to be used.
* @param hints An optional set of hints, or {@code null} if none.
*/
private void filteredSubsample(final GridCoverage2D coverage, final Interpolation interp,
final float[] filter, final Hints hints)
{
// Caching initial properties.
RenderedImage originalImage = coverage.getRenderedImage();
boolean isIndexed = originalImage.getColorModel() instanceof IndexColorModel;
int w = originalImage.getWidth();
int h = originalImage.getHeight();
// Creating a default processor.
final DefaultProcessor processor = (hints != null) ? new DefaultProcessor(hints) : this.processor;
// Getting parameters for the FilteredSubsample operation.
final ParameterValueGroup param = processor.getOperation("FilteredSubsample").getParameters();
param.parameter("Source").setValue(coverage);
param.parameter("scaleX").setValue(Integer.valueOf(2));
param.parameter("scaleY").setValue(Integer.valueOf(2));
param.parameter("qsFilterArray").setValue(filter);
param.parameter("Interpolation").setValue(interp);
// Scale a first time by 2.
GridCoverage2D scaled = (GridCoverage2D) processor.doOperation(param);
RenderedImage scaledImage = scaled.getRenderedImage();
assertEquals(w / 2.0, scaledImage.getWidth(), EPS);
assertEquals(h / 2.0, scaledImage.getHeight(), EPS);
assertTrue(!isIndexed
|| (interp instanceof InterpolationNearest)
|| !(scaledImage.getColorModel() instanceof IndexColorModel)
|| CoverageUtilities.preferredViewForOperation(coverage, interp, false, null) == GEOPHYSICS);
isIndexed = scaledImage.getColorModel() instanceof IndexColorModel;
w = scaledImage.getWidth();
h = scaledImage.getHeight();
assertEnvelopeEquals(coverage, scaled);
if (SHOW) {
Viewer.show(coverage);
Viewer.show(scaled);
} else {
// Force computation
assertNotNull(coverage.getRenderedImage().getData());
assertNotNull(scaled.getRenderedImage().getData());
}
// Scale a second time by 3.
scaled = (GridCoverage2D) Operations.DEFAULT.filteredSubsample(scaled, 3, 3, filter, interp);
scaledImage = scaled.getRenderedImage();
assertEquals(w / 3.0, scaledImage.getWidth(), 1.0/3 + EPS);
assertEquals(h / 3.0, scaledImage.getHeight(), 1.0/3 + EPS);
assertTrue(!isIndexed
|| (interp instanceof InterpolationNearest)
|| !(scaledImage.getColorModel() instanceof IndexColorModel)
||CoverageUtilities.preferredViewForOperation(coverage, interp, false, null) == GEOPHYSICS);
assertEnvelopeEquals(coverage, scaled);
if (SHOW) {
Viewer.show(scaled);
} else {
// Force computation
assertNotNull(scaledImage.getData());
}
}
}