/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2002-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.referencing.operation.transform;
import java.util.Arrays;
import java.awt.geom.AffineTransform;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;
import org.geotools.referencing.operation.TransformTestBase;
import org.geotools.referencing.operation.matrix.GeneralMatrix;
import org.junit.*;
import static org.junit.Assert.*;
/**
* Tests the following transforms:
*
* <ul>
* <li>{@link MathTransformFactory#createPassthroughTransform}</li>
* <li>{@link MathTransformFactory#createSubTransform}</li>
* <li>{@link MathTransformFactory#createFilterTransform}</li>
* </ul>
*
*
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux (IRD)
*/
public final class PassthroughTransformTest extends TransformTestBase {
/**
* Test the pass through transform using an affine transform. The "passthrough" of
* such transform are optimized in a special way.
*/
@Test
public void testLinear() throws FactoryException, TransformException {
runTest(mtFactory.createAffineTransform(
new GeneralMatrix(AffineTransform.getScaleInstance(4, 2))));
}
/**
* Test the general passthrough transform.
*/
@Test
public void testPassthrough() throws FactoryException, TransformException {
final ParameterValueGroup param = mtFactory.getDefaultParameters("Exponential");
runTest(mtFactory.createParameterizedTransform(param));
}
/**
* Test the pass through transform.
*/
private void runTest(final MathTransform sub) throws FactoryException, TransformException {
compare(sub, sub, 0);
try {
mtFactory.createPassThroughTransform(-1, sub, 0);
fail("An illegal argument should have been detected");
} catch (FactoryException e) {
// This is the expected exception.
}
try {
mtFactory.createPassThroughTransform(0, sub, -1);
fail("An illegal argument should have been detected");
} catch (FactoryException e) {
// This is the expected exception.
}
assertSame("Failed to recognize that no passthrough transform was needed",
sub, mtFactory.createPassThroughTransform(0, sub, 0));
final int subLower = 2;
final int subUpper = subLower + sub.getSourceDimensions();
final MathTransform passthrough = mtFactory.createPassThroughTransform(subLower, sub, 1);
assertEquals("Wrong number of source dimensions", sub.getSourceDimensions() + subLower + 1, passthrough.getSourceDimensions());
assertEquals("Wrong number of target dimensions", sub.getTargetDimensions() + subLower + 1, passthrough.getTargetDimensions());
compare(passthrough, sub, 2);
/*
* Try to split the pass through transform and get back the original one.
*/
final DimensionFilter filter = new DimensionFilter(mtFactory);
filter.addSourceDimensionRange(0, subLower);
assertTrue("Expected an identity transform", filter.separate(passthrough).isIdentity());
filter.clear();
filter.addSourceDimensionRange(subUpper, passthrough.getSourceDimensions());
assertTrue("Expected an identity transform", filter.separate(passthrough).isIdentity());
filter.clear();
filter.addSourceDimensionRange(subLower, subUpper);
assertEquals("Expected the sub-transform", sub, filter.separate(passthrough));
final int[] expectedDimensions = new int[sub.getTargetDimensions()];
for (int i=0; i<expectedDimensions.length; i++) {
expectedDimensions[i] = subLower + i;
}
assertTrue("Unexpected output dimensions", Arrays.equals(expectedDimensions,
filter.getTargetDimensions()));
}
/**
* Test the specified transform.
*
* @param mt The transform to test.
* @param submt The sub transform.
* @param subOffset Index of the first input/output dimension which correspond to
* <code>submt</code>.
*/
private void compare(final MathTransform mt,
final MathTransform submt, final int subOffset)
throws TransformException
{
final int pointCount = 200;
final int mtDimension = mt.getSourceDimensions();
final int atDimension = submt.getSourceDimensions();
final double[] atData = new double[pointCount * atDimension];
final double[] mtData = new double[pointCount * mtDimension];
for (int j=0; j<pointCount; j++) {
for (int i=0; i<mtDimension; i++) {
mtData[j*mtDimension + i] = 100*random.nextDouble() - 50;
}
for (int i=0; i<atDimension; i++) {
atData[j*atDimension + i] = mtData[j*mtDimension + subOffset + i];
}
}
if (atDimension == mtDimension) {
assertTrue("Test arrays are not correctly build.", Arrays.equals(atData, mtData));
}
final double[] reference = mtData.clone();
submt.transform(atData, 0, atData, 0, pointCount);
mt .transform(mtData, 0, mtData, 0, pointCount);
assertTrue("'subOffset' argument too high", subOffset + atDimension <= mtDimension);
for (int j=0; j<pointCount; j++) {
for (int i=0; i<mtDimension; i++) {
final double expected;
if (i<subOffset || i>=subOffset+atDimension) {
expected = reference[j*mtDimension + i];
} else {
expected = atData[j*atDimension + i - subOffset];
}
assertEquals("A transformed value is wrong",
expected, mtData[j*mtDimension + i], 1E-6);
}
}
}
}