Author: desruisseaux
Date: Fri Jun 6 11:40:46 2014
New Revision: 1600848
URL: http://svn.apache.org/r1600848
Log:
Ported CopyTransformTest.
Added:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java
(with props)
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
(with props)
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
(with props)
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
Added:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java?rev=1600848&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java
(added)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java
[UTF-8] Fri Jun 6 11:40:46 2014
@@ -0,0 +1,270 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import java.util.Random;
+import org.apache.sis.measure.Latitude;
+import org.apache.sis.measure.Longitude;
+import org.apache.sis.test.mock.GeodeticDatumMock;
+
+import static java.lang.StrictMath.*;
+
+
+/**
+ * The domain of input coordinates.
+ * This class can generate random number suitable for their domain.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.5 (derived from geotk-3.00)
+ * @version 0.5
+ * @module
+ */
+public strictfp enum CoordinateDomain {
+ /**
+ * Geocentric input coordinates. The input dimension must be 3.
+ */
+ GEOCENTRIC {
+ @Override double[] generateRandomInput(final Random random, final int
dimension, final int numPts) {
+ if (dimension != 3) {
+ throw new IllegalArgumentException();
+ }
+ final double axis =
GeodeticDatumMock.SPHERE.getEllipsoid().getSemiMajorAxis();
+ final double[] ordinates = GEOGRAPHIC.generateRandomInput(random,
dimension, numPts);
+ for (int i=0; i<ordinates.length;) {
+ final double phi = toRadians(ordinates[i ]);
+ final double theta = toRadians(ordinates[i+1]);
+ final double radius = axis + ordinates[i+2];
+ final double radXY = radius * cos(theta);
+ ordinates[i++] = radXY * cos(phi);
+ ordinates[i++] = radXY * sin(phi);
+ ordinates[i++] = radius * sin(theta);
+ }
+ return ordinates;
+ }
+ },
+
+ /**
+ * Geographic input coordinates with angles in decimal degrees.
+ * Ordinates are in (<var>longitude</var>, <var>latitude</var>,
<var>height</var>) order.
+ */
+ GEOGRAPHIC {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = Longitude.MAX_VALUE; break; // Full longitude
range.
+ case 1: range = Latitude.MAX_VALUE; break; // Full latitude
range.
+ case 2: range = 10000; break; // Ellipsoidal
height.
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Geographic input coordinates avoiding poles and anti-meridian.
+ * Ordinates are in (<var>longitude</var>, <var>latitude</var>,
<var>height</var>) order.
+ */
+ GEOGRAPHIC_SAFE {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = Longitude.MAX_VALUE - 1; break; // Longitude,
avoiding anti-meridian.
+ case 1: range = Latitude.MAX_VALUE - 20; break; // Latitude,
avoiding pole.
+ case 2: range = 5000; break; //
Ellipsoidal height.
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Geographic input coordinates close to the poles.
+ * Ordinates are in (<var>longitude</var>, <var>latitude</var>,
<var>height</var>) order.
+ */
+ GEOGRAPHIC_POLES {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = Longitude.MAX_VALUE; break;
+ case 1: range = 20; break;
+ case 2: range = 5000; break;
+ default: return super.generate(random, dimension);
+ }
+ double value = random.nextDouble() * (2*range) - range;
+ if (dimension == 1) {
+ if (value <= 0) {
+ value += Latitude.MAX_VALUE;
+ } else {
+ value += Latitude.MIN_VALUE;
+ }
+ }
+ return value;
+ }
+ },
+
+ /**
+ * Geographic input coordinates with angles in radians.
+ * Ordinates are in (<var>lambda</var>, <var>phi</var>, <var>height</var>)
order.
+ */
+ GEOGRAPHIC_RADIANS {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = PI; break; // Longitude.
+ case 1: range = PI/2; break; // Latitude.
+ case 2: range = 10000; break; // Ellipsoidal height.
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Geographic input coordinates with angles in radians and only half of
the longitude range.
+ * Ordinates are in (<var>lambda</var>, <var>phi</var>, <var>height</var>)
order.
+ */
+ GEOGRAPHIC_RADIANS_HALF {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = PI/2; break; // Longitude.
+ case 1: range = PI/2; break; // Latitude.
+ case 2: range = 10000; break; // Ellipsoidal height.
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Geographic input coordinates with angles in radians in the North
hemisphere only.
+ * Ordinates are in (<var>lambda</var>, <var>phi</var>, <var>height</var>)
order.
+ */
+ GEOGRAPHIC_RADIANS_NORTH {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = PI; break;
+ case 1: return +PI/2*random.nextDouble();
+ case 2: range = 10000; break;
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Geographic input coordinates with angles in radians in the South
hemisphere only.
+ * Ordinates are in (<var>lambda</var>, <var>phi</var>, <var>height</var>)
order.
+ */
+ GEOGRAPHIC_RADIANS_SOUTH {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = PI; break;
+ case 1: return -PI/2*random.nextDouble();
+ case 2: range = 10000; break;
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Geographic input coordinates with angles in radians in the East
hemisphere only.
+ * Ordinates are in (<var>lambda</var>, <var>phi</var>, <var>height</var>)
order.
+ */
+ GEOGRAPHIC_RADIANS_EAST {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: return +PI*random.nextDouble();
+ case 1: range = PI/2; break;
+ case 2: range = 10000; break;
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Geographic input coordinates with angles in radians in the West
hemisphere only.
+ * Ordinates are in (<var>lambda</var>, <var>phi</var>, <var>height</var>)
order.
+ */
+ GEOGRAPHIC_RADIANS_WEST {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: return -PI*random.nextDouble();
+ case 1: range = PI/2; break;
+ case 2: range = 10000; break;
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Projected input coordinates in a range suitable for UTM projections.
+ * Ordinates are in (<var>easting</var>, <var>northing</var>,
<var>height</var>) order.
+ */
+ PROJECTED {
+ @Override double generate(final Random random, final int dimension) {
+ final double range;
+ switch (dimension) {
+ case 0: range = 350000; break; // Easting.
+ case 1: range = 8000000; break; // Northing.
+ case 2: range = 10000; break; // Ellipsoidal height.
+ default: return super.generate(random, dimension);
+ }
+ return random.nextDouble() * (2*range) - range;
+ }
+ },
+
+ /**
+ * Gaussian numbers: can be positives or negatives, mostly close to zero
but some
+ * numbers can be arbitrarily large.
+ */
+ GAUSSIAN;
+
+ /**
+ * Generates random input coordinates.
+ *
+ * @param random The random number generator to use.
+ * @param dimension The number of dimension of the points to generate.
+ * @param numPts The number of points to generate.
+ * @return An array of length {@code numPts*dimension} filled with random
input ordinate values.
+ */
+ double[] generateRandomInput(final Random random, final int dimension,
final int numPts) {
+ final double[] ordinates = new double[numPts * dimension];
+ for (int i=0; i<ordinates.length; i++) {
+ ordinates[i] = generate(random, i % dimension);
+ }
+ return ordinates;
+ }
+
+ /**
+ * Generates a random number for the given dimension.
+ *
+ * @param random The random number generator to use.
+ * @param dimension The dimension for which to generate a random number.
+ * @return A random number suitable for the given dimension.
+ */
+ double generate(final Random random, final int dimension) {
+ return random.nextGaussian();
+ }
+}
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CoordinateDomain.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java?rev=1600848&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
(added)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
[UTF-8] Fri Jun 6 11:40:46 2014
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.referencing.operation.provider.Affine;
+import org.apache.sis.test.DependsOn;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+
+/**
+ * Tests the {@link CopyTransform} class.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.5 (derived from geotk-3.08)
+ * @version 0.5
+ * @module
+ */
+//@DependsOn(ProjectiveTransformTest.class)
+public final strictfp class CopyTransformTest extends MathTransformTestCase {
+ /**
+ * Generates random ordinates with approximatively 5% of NaN values in the
array.
+ */
+ private double[] generateRandomCoordinates() {
+ return generateRandomCoordinates(CoordinateDomain.GEOGRAPHIC, 0.05f);
+ }
+
+ /**
+ * Replaces the current {@link CopyTransform} by an instance of {@link
ProjectiveTransform}.
+ */
+ private void makeProjectiveTransform() {
+ transform = new ProjectiveTransform(((CopyTransform)
transform).getMatrix());
+ }
+
+ /**
+ * Tests an identity transform.
+ *
+ * @throws TransformException should never happen.
+ */
+ @Test
+ public void testIdentity() throws TransformException {
+ transform = new CopyTransform(3, 0, 1, 2);
+ validate();
+ verifyParameters(Affine.PARAMETERS, null);
+ assertTrue(((LinearTransform) transform).getMatrix().isIdentity());
+ assertTrue(transform.isIdentity());
+
+ final double[] source = generateRandomCoordinates();
+ final double[] target = source.clone();
+ verifyTransform(source, target);
+ stress(source);
+
+ makeProjectiveTransform();
+ verifyTransform(source, target);
+ stress(source);
+ }
+
+ /**
+ * Tests transform from 3D to 3D.
+ *
+ * @throws TransformException should never happen.
+ */
+ @Test
+ public void test3D() throws TransformException {
+ transform = new CopyTransform(3, 2, 1, 0);
+ validate();
+ assertFalse(transform.isIdentity());
+ assertFalse(((LinearTransform) transform).getMatrix().isIdentity());
+
+ final double[] source = generateRandomCoordinates();
+ final double[] target = new double[source.length];
+ for (int i=0; i<source.length; i++) {
+ final int r = i % 3;
+ final int b = i - r;
+ target[b + (2-r)] = source[i];
+ }
+ verifyTransform(source, target);
+ stress(source);
+
+ makeProjectiveTransform();
+ verifyTransform(source, target);
+ stress(source);
+ }
+
+ /**
+ * Tests transform from 3D to 2D.
+ *
+ * @throws TransformException should never happen.
+ */
+ @Test
+ public void test3Dto2D() throws TransformException {
+ transform = new CopyTransform(3, 0, 1);
+ isInverseTransformSupported = false;
+ validate();
+ assertFalse(transform.isIdentity());
+ assertFalse(((LinearTransform) transform).getMatrix().isIdentity());
+
+ final double[] source = generateRandomCoordinates();
+ final double[] target = new double[source.length * 2/3];
+ for (int i=0,j=0; i<source.length; i++) {
+ target[j++] = source[i++];
+ target[j++] = source[i++];
+ // Skip one i (in the for loop).
+ }
+ verifyTransform(source, target);
+ stress(source);
+
+ makeProjectiveTransform();
+ verifyTransform(source, target);
+ stress(source);
+ }
+}
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/CopyTransformTest.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Added:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java?rev=1600848&view=auto
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
(added)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
[UTF-8] Fri Jun 6 11:40:46 2014
@@ -0,0 +1,393 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.transform;
+
+import java.util.Random;
+import java.io.IOException;
+import java.io.PrintStream;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.MathTransform1D;
+import org.opengis.referencing.operation.MathTransform2D;
+import org.opengis.referencing.operation.TransformException;
+import org.opengis.parameter.ParameterDescriptorGroup;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.geometry.DirectPosition;
+import org.opengis.metadata.Identifier;
+import org.opengis.test.Validators;
+import org.opengis.test.CalculationType;
+import org.opengis.test.ToleranceModifier;
+import org.opengis.test.referencing.TransformTestCase;
+import org.apache.sis.parameter.Parameterized;
+import org.apache.sis.util.Debug;
+import org.apache.sis.util.Classes;
+import org.apache.sis.io.TableAppender;
+import org.apache.sis.io.wkt.Convention;
+import org.apache.sis.io.wkt.FormattableObject;
+import org.apache.sis.math.Statistics;
+import org.apache.sis.math.StatisticsFormat;
+import org.apache.sis.test.TestUtilities;
+import org.apache.sis.test.TestCase;
+
+import static java.lang.StrictMath.*;
+import static org.apache.sis.util.Classes.*;
+import static org.apache.sis.test.ReferencingAssert.*;
+
+
+/**
+ * Base class for tests of {@link AbstractMathTransform} implementations.
+ * This base class inherits the convenience methods defined in GeoAPI and adds
a few {@code verifyFoo} methods.
+ *
+ * @author Martin Desruisseaux (Geomatys)
+ * @since 0.5 (derived from geotk-2.0)
+ * @version 0.5
+ * @module
+ */
+public abstract strictfp class MathTransformTestCase extends TransformTestCase
{
+ /**
+ * The number of ordinates to use for stressing the math transform. We use
a number that
+ * encompass at least 2 time the default buffer size in order to test the
code that use
+ * the buffer. We add an arbitrary number just for making the transform
job harder.
+ */
+ static final int ORDINATE_COUNT =
AbstractMathTransform.MAXIMUM_BUFFER_SIZE * 2 + 137;
+
+ /**
+ * The dimension of longitude, or {@code null} if none. If non-null, then
the comparison of
+ * ordinate values along that dimension will ignore 360° offsets.
+ *
+ * <p>The first array element is the dimension during forward transforms,
and the second
+ * array element is the dimension during inverse transforms (can be
omitted if the later
+ * is the same than the dimension during forward transforms).</p>
+ */
+ protected int[] λDimension;
+
+ /**
+ * The vertical dimension, or {@code null} if none. This is the dimension
for which the
+ * {@link #zTolerance} value will be used rather than {@link #tolerance}.
+ *
+ * <p>The first array element is the dimension during forward transforms,
and the second
+ * array element is the dimension during inverse transforms (can be
omitted if the later
+ * is the same than the dimension during forward transforms).</p>
+ */
+ protected int[] zDimension;
+
+ /**
+ * The tolerance level for height above the ellipsoid. This tolerance is
usually higher
+ * than the {@linkplain #tolerance tolerance} level for horizontal
ordinate values.
+ */
+ protected double zTolerance;
+
+ /**
+ * An optional message to pre-concatenate to the error message if one of
the {@code assert}
+ * methods fail. This field shall contain information about the test
configuration that may
+ * be useful in determining the cause of a test failure.
+ */
+ protected String messageOnFailure;
+
+ /**
+ * Creates a new test case.
+ */
+ protected MathTransformTestCase() {
+ /*
+ * Use 'zTolerance' threshold instead of 'tolerance' when comparing
vertical coordinate values.
+ */
+ toleranceModifier = new ToleranceModifier() {
+ @Override
+ public void adjust(final double[] tolerance, final DirectPosition
coordinate, final CalculationType mode) {
+ if (mode != CalculationType.IDENTITY) {
+ final int i = forComparison(zDimension, mode);
+ if (i >= 0 && i < tolerance.length) {
+ tolerance[i] = zTolerance;
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * Returns the value to use from the {@link #λDimension} or {@link
zDimension} for the
+ * given comparison mode, or -1 if none.
+ */
+ @SuppressWarnings("fallthrough")
+ static int forComparison(final int[] config, final CalculationType mode) {
+ if (config != null) {
+ switch (mode) {
+ case INVERSE_TRANSFORM: if (config.length >= 2) return
config[1]; // Intentional fallthrough.
+ case DIRECT_TRANSFORM: if (config.length >= 1) return
config[0];
+ }
+ }
+ return -1;
+ }
+
+ /**
+ * Invoked by all {@code assertCoordinateEqual(…)} methods before two
positions are compared.
+ * The SIS implementation ensures that longitude values are contained in
the ±180° range,
+ * applying 360° shifts if needed.
+ *
+ * @param expected The expected ordinate value provided by the test case.
+ * @param actual The ordinate value computed by the {@linkplain
#transform transform} being tested.
+ * @param mode Indicates if the coordinates being compared are the
result of a direct
+ * or inverse transform, or if strict equality is
requested.
+ */
+ @Override
+ protected final void normalize(final DirectPosition expected, final
DirectPosition actual, final CalculationType mode) {
+ final int i = forComparison(λDimension, mode);
+ if (i >= 0) {
+ double e;
+ e = expected.getOrdinate(i); e -= 360*floor(e/360);
expected.setOrdinate(i, e);
+ e = actual.getOrdinate(i); e -= 360*floor(e/360);
actual.setOrdinate(i, e);
+ }
+ }
+
+ /**
+ * Returns a name for the current math transform. This method is used only
for reporting errors.
+ * This information is not reliable for the actual tests as the names may
not be stable.
+ *
+ * @return A name for the current math transform.
+ */
+ @Debug
+ private String getName() {
+ if (transform instanceof Parameterized) {
+ final ParameterDescriptorGroup descriptor = ((Parameterized)
transform).getParameterDescriptors();
+ if (descriptor != null) {
+ final Identifier identifier = descriptor.getName();
+ if (identifier != null) {
+ final String code = identifier.getCode();
+ if (code != null) {
+ return code;
+ }
+ }
+ }
+ }
+ return Classes.getShortClassName(transform);
+ }
+
+ /**
+ * Completes the error message by pre-concatenating {@link
#messageOnFailure} if non-null.
+ */
+ private String completeMessage(final String message) {
+ if (messageOnFailure == null) {
+ return message;
+ }
+ final String lineSeparator = System.lineSeparator();
+ // Note: JUnit message will begin with a space.
+ return messageOnFailure + lineSeparator + message + lineSeparator +
"JUnit message:";
+ }
+
+ /**
+ * Validates the current {@linkplain #transform transform}. This method
verifies that
+ * the transform implements {@link MathTransform1D} or {@link
MathTransform2D} if the
+ * transform dimension suggests that it should.
+ *
+ * @see Validators#validate(MathTransform)
+ */
+ protected final void validate() {
+ assertNotNull("The 'transform' field shall be assigned a value.",
transform);
+ Validators.validate(transform);
+ final int dimension = transform.getSourceDimensions();
+ if (transform.getTargetDimensions() == dimension) {
+ assertEquals(completeMessage("MathTransform1D"), dimension == 1,
(transform instanceof MathTransform1D));
+ assertEquals(completeMessage("MathTransform2D"), dimension == 2,
(transform instanceof MathTransform2D));
+ } else {
+ assertFalse(completeMessage("MathTransform1D"), transform
instanceof MathTransform1D);
+ assertFalse(completeMessage("MathTransform2D"), transform
instanceof MathTransform2D);
+ }
+ }
+
+ /**
+ * Asserts that the parameters of current {@linkplain #transform
transform} are equal to the given ones.
+ * This method can check the descriptor separately, for easier isolation
of mismatch in case of failure.
+ *
+ * @param descriptor
+ * The expected parameter descriptor, or {@code null} for
bypassing this check.
+ * The descriptor is required to be strictly the same instance,
since Apache SIS
+ * implementation returns constant values.
+ * @param values
+ * The expected parameter values, or {@code null} for bypassing
this check.
+ * Floating points values are compared in the units of the
expected value,
+ * tolerating a difference up to the {@linkplain
#tolerance(double) tolerance threshold}.
+ */
+ protected final void verifyParameters(final ParameterDescriptorGroup
descriptor, final ParameterValueGroup values) {
+ assertInstanceOf(completeMessage("TransformTestCase.transform"),
Parameterized.class, transform);
+ if (descriptor != null) {
+ assertSame("ParameterDescriptor", descriptor, ((Parameterized)
transform).getParameterDescriptors());
+ }
+ if (values != null) {
+ assertSame(descriptor, values.getDescriptor());
+ assertParameterEquals(values, ((Parameterized)
transform).getParameterValues(), tolerance);
+ }
+ }
+
+ /**
+ * Transforms the given coordinates and verifies that the result is equals
(within a positive
+ * delta) to the expected ones. If the difference between an expected and
actual ordinate value
+ * is greater than the {@linkplain #tolerance tolerance} threshold, then
the assertion fails.
+ *
+ * <p>If {@link #isInverseTransformSupported} is {@code true}, then this
method will also transform
+ * the expected coordinate points using the {@linkplain
MathTransform#inverse() inverse transform} and
+ * compare with the source coordinates.</p>
+ *
+ * @param coordinates The coordinate points to transform.
+ * @param expected The expect result of the transformation, or
+ * {@code null} if {@code coordinates} is expected to be null.
+ * @throws TransformException if the transformation failed.
+ */
+ @Override
+ protected final void verifyTransform(final double[] coordinates, final
double[] expected) throws TransformException {
+ super.verifyTransform(coordinates, expected);
+ /*
+ * In addition to the GeoAPI "verifyTransform" check, check also for
consistency.
+ * A previous version of Geotk had a bug with the Google projection
which was
+ * unnoticed because of lack of this consistency check.
+ */
+ final float[] copy = new float[coordinates.length];
+ for (int i=0; i<copy.length; i++) {
+ copy[i] = (float) coordinates[i];
+ }
+ final float[] result = verifyConsistency(copy);
+ /*
+ * The comparison below needs a higher tolerance threshold, because we
converted the source
+ * ordinates to floating points which induce a lost of precision. The
multiplication factor
+ * used here has been determined empirically. The value is quite high,
but this is only an
+ * oportunist check anyway. The "real" test is the one performed by
'verifyConsistency'.
+ */
+ final double tol = max(tolerance * 1000, 1);
+ for (int i=0; i<expected.length; i++) {
+ assertEquals(expected[i], result[i], tol);
+ }
+ }
+
+ /**
+ * Generates random numbers that can be used for the current transform.
+ *
+ * @param domain The domain of the numbers to be generated.
+ * @param propNaN Approximative percentage of NaN values as a fraction
between 0 and 1, or 0 if none.
+ * @return Random coordinates in the given domain.
+ */
+ protected final double[] generateRandomCoordinates(final CoordinateDomain
domain, final float propNaN) {
+ assertNotNull("Transform field must be assigned a value.", transform);
+ final int dimension = transform.getSourceDimensions();
+ final int numPts = ORDINATE_COUNT / dimension;
+ final Random random = TestUtilities.createRandomNumberGenerator();
+ final double[] coordinates = domain.generateRandomInput(random,
dimension, numPts);
+ for (int i = Math.round(coordinates.length * propNaN); --i >= 0;) {
+ coordinates[random.nextInt(coordinates.length)] = Double.NaN;
+ }
+ if (TestCase.verbose) {
+ final PrintStream out = out();
+ out.print("Random input coordinates for ");
+ out.print(domain); out.println(" domain:");
+ final Statistics[] stats = new Statistics[dimension];
+ for (int i=0; i<stats.length; i++) {
+ stats[i] = new Statistics(null);
+ }
+ for (int i=0; i<coordinates.length; i++) {
+ stats[i % dimension].accept(coordinates[i]);
+ }
+ final StatisticsFormat format = StatisticsFormat.getInstance();
+ format.setBorderWidth(1);
+ try {
+ format.format(stats, out);
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ out.println();
+ out.flush();
+ }
+ return coordinates;
+ }
+
+ /**
+ * Stress the current {@linkplain #transform transform} using the given
coordinates.
+ * This method do not {@linkplain #validate() validate} the transform.
+ * This is caller's responsibility to do so if applicable.
+ *
+ * @param source The input coordinates to use for testing.
+ * @throws TransformException If at transformation failed.
+ */
+ final void stress(final double[] source) throws TransformException {
+ final float[] asFloats = new float[source.length];
+ for (int i=0; i<source.length; i++) {
+ asFloats[i] = (float) source[i];
+ }
+ if (isInverseTransformSupported) {
+ verifyInverse(source);
+ }
+ for (int i=0; i<source.length; i++) {
+ assertEquals(completeMessage("Detected change in source
coordinates."),
+ asFloats[i], (float) source[i], 0f); // Paranoiac check.
+ }
+ verifyConsistency(asFloats);
+ for (int i=0; i<source.length; i++) {
+ assertEquals(completeMessage("Detected change in source
coordinates."),
+ (float) source[i], asFloats[i], 0f); // Paranoiac check.
+ }
+ }
+
+ /**
+ * Asserts that the current {@linkplain #transform transform} produces the
given WKT.
+ *
+ * @param expected The expected WKT.
+ *
+ * @see #printInternalWKT()
+ */
+ protected final void verifyWKT(final String expected) {
+ assertNotNull("Transform field must be assigned a value.", transform);
+ assertEquals("WKT comparison with tolerance not yet implemented.",
0.0, tolerance, 0.0);
+ assertWktEquals(Convention.WKT1, expected, transform);
+ }
+
+ /**
+ * Prints the current {@linkplain #transform transform} as normal and
internal WKT.
+ * This method is for debugging purpose only.
+ *
+ * @see #verifyWKT(String)
+ */
+ @Debug
+ protected final void printInternalWKT() {
+ final TableAppender table = new TableAppender(out());
+ table.setMultiLinesCells(true);
+ table.appendHorizontalSeparator();
+ table.append("WKT of “").append(getName()).append('”').nextColumn();
+ table.append("Internal WKT").appendHorizontalSeparator();
+ String wkt;
+ try {
+ wkt = transform.toWKT();
+ } catch (UnsupportedOperationException e) {
+ wkt = transform.toString();
+ }
+ table.append(wkt).nextColumn();
+ if (transform instanceof FormattableObject) {
+ wkt = ((FormattableObject)
transform).toString(Convention.INTERNAL);
+ } else {
+ wkt = transform.toString();
+ }
+ table.append(wkt).appendHorizontalSeparator();
+ try {
+ table.flush();
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * Where to write debugging information.
+ */
+ @Debug
+ private static PrintStream out() {
+ return System.out;
+ }
+}
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
------------------------------------------------------------------------------
svn:mime-type = text/plain;charset=UTF-8
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1600848&r1=1600847&r2=1600848&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
[UTF-8] Fri Jun 6 11:40:46 2014
@@ -42,6 +42,7 @@ import org.junit.BeforeClass;
org.apache.sis.referencing.operation.matrix.AffineTransforms2DTest.class,
org.apache.sis.referencing.operation.transform.IterationStrategyTest.class,
org.apache.sis.referencing.operation.transform.AbstractMathTransformTest.class,
+ org.apache.sis.referencing.operation.transform.CopyTransformTest.class,
org.apache.sis.internal.referencing.FormulasTest.class,
org.apache.sis.internal.referencing.VerticalDatumTypesTest.class,