001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2002, Institut de Recherche pour le Développement
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation; either
010: * version 2.1 of the License, or (at your option) any later version.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.referencing.operation;
018:
019: // J2SE dependencies
020: import java.util.Random;
021: import junit.framework.TestCase;
022:
023: // Geotools dependencies
024: import org.geotools.referencing.ReferencingFactoryFinder;
025:
026: // OpenGIS dependencis
027: import org.opengis.referencing.crs.CRSFactory;
028: import org.opengis.referencing.datum.DatumFactory;
029: import org.opengis.referencing.operation.CoordinateOperationFactory;
030: import org.opengis.referencing.operation.MathTransform;
031: import org.opengis.referencing.operation.MathTransform1D;
032: import org.opengis.referencing.operation.MathTransform2D;
033: import org.opengis.referencing.operation.MathTransformFactory;
034: import org.opengis.referencing.operation.TransformException;
035:
036: // Geotools dependencies
037: import org.geotools.factory.Hints;
038: import org.geotools.geometry.DirectPosition2D;
039: import org.geotools.geometry.GeneralDirectPosition;
040:
041: /**
042: * Base class for transform test cases. This class is not a test in itself;
043: * only subclasses will be.
044: *
045: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/test/java/org/geotools/referencing/operation/TestTransform.java $
046: * @version $Id: TestTransform.java 25262 2007-04-23 21:11:16Z desruisseaux $
047: * @author Martin Desruisseaux
048: */
049: public abstract class TestTransform extends TestCase {
050: /**
051: * Small values for comparaisons of floating point numbers after transformations.
052: */
053: private static final double EPS = 1E-6;
054:
055: /**
056: * The default datum factory.
057: */
058: protected DatumFactory datumFactory;
059:
060: /**
061: * The default coordinate reference system factory.
062: */
063: protected CRSFactory crsFactory;
064:
065: /**
066: * The default math transform factory.
067: */
068: protected MathTransformFactory mtFactory;
069:
070: /**
071: * The default transformations factory.
072: */
073: protected CoordinateOperationFactory opFactory;
074:
075: /**
076: * Random numbers generator.
077: */
078: protected static final Random random = new Random(
079: -3531834320875149028L);
080:
081: /**
082: * Constructs a test case with the given name.
083: */
084: public TestTransform(final String name) {
085: super (name);
086: }
087:
088: /**
089: * Setup the factories using the hints provided by {@link #getHintsForTesting}.
090: */
091: protected void setUp() throws Exception {
092: super .setUp();
093: Hints hints = getHintsForTesting();
094: datumFactory = ReferencingFactoryFinder.getDatumFactory(hints);
095: crsFactory = ReferencingFactoryFinder.getCRSFactory(hints);
096: mtFactory = ReferencingFactoryFinder
097: .getMathTransformFactory(hints);
098: opFactory = ReferencingFactoryFinder
099: .getCoordinateOperationFactory(hints);
100: }
101:
102: /**
103: * Returns the hints to be used by {@link #setUp} in order to fetch the factories.
104: * The default implementation returns {@code null}. Subclasses can override.
105: */
106: protected Hints getHintsForTesting() {
107: return null;
108: }
109:
110: /**
111: * Returns <code>true</code> if the specified number is real
112: * (neither NaN or infinite).
113: */
114: public static boolean isReal(final double value) {
115: return !Double.isNaN(value) && !Double.isInfinite(value);
116: }
117:
118: /**
119: * Verify that the specified transform implements {@link MathTransform1D}
120: * or {@link MathTransform2D} as needed.
121: *
122: * @param transform The transform to test.
123: */
124: public static void assertInterfaced(final MathTransform transform) {
125: int dim = transform.getSourceDimensions();
126: if (transform.getTargetDimensions() != dim) {
127: dim = 0;
128: }
129: assertTrue("MathTransform1D",
130: (dim == 1) == (transform instanceof MathTransform1D));
131: assertTrue("MathTransform2D",
132: (dim == 2) == (transform instanceof MathTransform2D));
133: }
134:
135: /**
136: * Transforms a two-dimensional point and compare the result with the expected value.
137: *
138: * @param transform The transform to test.
139: * @param x The x value to transform.
140: * @param y The y value to transform.
141: * @param ex The expected x value.
142: * @param ey The expected y value.
143: */
144: public static void assertTransformEquals2_2(
145: final MathTransform transform, final double x,
146: final double y, final double ex, final double ey)
147: throws TransformException {
148: final DirectPosition2D source = new DirectPosition2D(x, y);
149: final DirectPosition2D target = new DirectPosition2D();
150: assertSame(target, transform.transform(source, target));
151: final String message = "Expected (" + ex + ", " + ey + "), "
152: + "transformed=(" + target.x + ", " + target.y + ")";
153: assertEquals(message, ex, target.x, EPS);
154: assertEquals(message, ey, target.y, EPS);
155: }
156:
157: /**
158: * Transforms a three-dimensional point and compare the result with the expected value.
159: *
160: * @param transform The transform to test.
161: * @param x The x value to transform.
162: * @param y The y value to transform.
163: * @param z The z value to transform.
164: * @param ex The expected x value.
165: * @param ey The expected y value.
166: * @param ez The expected z value.
167: */
168: public static void assertTransformEquals3_3(
169: final MathTransform transform, final double x,
170: final double y, final double z, final double ex,
171: final double ey, final double ez) throws TransformException {
172: final GeneralDirectPosition source = new GeneralDirectPosition(
173: x, y, z);
174: final GeneralDirectPosition target = new GeneralDirectPosition(
175: 3);
176: assertSame(target, transform.transform(source, target));
177: final String message = "Expected (" + ex + ", " + ey + ", "
178: + ez + "), " + "transformed=(" + target.ordinates[0]
179: + ", " + target.ordinates[1] + ", "
180: + target.ordinates[2] + ")";
181: assertEquals(message, ex, target.ordinates[0], EPS);
182: assertEquals(message, ey, target.ordinates[1], EPS);
183: assertEquals(message, ez, target.ordinates[2], 1E-2); // Greater tolerance level for Z.
184: }
185:
186: /**
187: * Transforms a two-dimensional point and compare the result with the expected
188: * three-dimensional value.
189: *
190: * @param transform The transform to test.
191: * @param x The x value to transform.
192: * @param y The y value to transform.
193: * @param ex The expected x value.
194: * @param ey The expected y value.
195: * @param ez The expected z value.
196: */
197: public static void assertTransformEquals2_3(
198: final MathTransform transform, final double x,
199: final double y, final double ex, final double ey,
200: final double ez) throws TransformException {
201: final GeneralDirectPosition source = new GeneralDirectPosition(
202: x, y);
203: final GeneralDirectPosition target = new GeneralDirectPosition(
204: 3);
205: assertSame(target, transform.transform(source, target));
206: final String message = "Expected (" + ex + ", " + ey + ", "
207: + ez + "), " + "transformed=(" + target.ordinates[0]
208: + ", " + target.ordinates[1] + ", "
209: + target.ordinates[2] + ")";
210: assertEquals(message, ex, target.ordinates[0], EPS);
211: assertEquals(message, ey, target.ordinates[1], EPS);
212: assertEquals(message, ez, target.ordinates[2], 1E-2); // Greater tolerance level for Z.
213: }
214:
215: /**
216: * Transforms a three-dimensional point and compare the result with the expected
217: * two-dimensional value.
218: *
219: * @param transform The transform to test.
220: * @param x The x value to transform.
221: * @param y The y value to transform.
222: * @param z The z value to transform.
223: * @param ex The expected x value.
224: * @param ey The expected y value.
225: */
226: public static void assertTransformEquals3_2(
227: final MathTransform transform, final double x,
228: final double y, final double z, final double ex,
229: final double ey) throws TransformException {
230: final GeneralDirectPosition source = new GeneralDirectPosition(
231: x, y, z);
232: final GeneralDirectPosition target = new GeneralDirectPosition(
233: 2);
234: assertSame(target, transform.transform(source, target));
235: final String message = "Expected (" + ex + ", " + ey + "), "
236: + "transformed=(" + target.ordinates[0] + ", "
237: + target.ordinates[1] + ")";
238: assertEquals(message, ex, target.ordinates[0], EPS);
239: assertEquals(message, ey, target.ordinates[1], EPS);
240: }
241:
242: /**
243: * Transforms a three-dimensional point and compare the result with the expected
244: * one-dimensional value.
245: *
246: * @param transform The transform to test.
247: * @param x The x value to transform.
248: * @param y The y value to transform.
249: * @param z The z value to transform.
250: * @param ez The expected z value.
251: */
252: public static void assertTransformEquals3_1(
253: final MathTransform transform, final double x,
254: final double y, final double z, final double ez)
255: throws TransformException {
256: final GeneralDirectPosition source = new GeneralDirectPosition(
257: x, y, z);
258: final GeneralDirectPosition target = new GeneralDirectPosition(
259: 1);
260: assertSame(target, transform.transform(source, target));
261: final String message = "Expected (" + ez + "), "
262: + "transformed=(" + target.ordinates[0] + ")";
263: assertEquals(message, ez, target.ordinates[0], 1E-2); // Greater tolerance level for Z.
264: }
265:
266: /**
267: * Compare two arrays of points.
268: *
269: * @param name The name of the comparaison to be performed.
270: * @param expected The expected array of points.
271: * @param actual The actual array of points.
272: * @param delta The maximal difference tolerated in comparaisons for each dimension.
273: * This array length must be equal to coordinate dimension (usually 1, 2 or 3).
274: */
275: public static void assertPointsEqual(final String name,
276: final double[] expected, final double[] actual,
277: final double[] delta) {
278: final int dimension = delta.length;
279: final int stop = Math.min(expected.length, actual.length)
280: / dimension * dimension;
281: assertEquals("Array length for expected points", stop,
282: expected.length);
283: assertEquals("Array length for actual points", stop,
284: actual.length);
285: final StringBuffer buffer = new StringBuffer(name);
286: buffer.append(": point[");
287: final int start = buffer.length();
288: for (int i = 0; i < stop; i++) {
289: buffer.setLength(start);
290: buffer.append(i / dimension);
291: buffer.append(", dimension ");
292: buffer.append(i % dimension);
293: buffer.append(" of ");
294: buffer.append(dimension);
295: buffer.append(']');
296: if (isReal(expected[i])) {
297: // The "two steps" method in ConcatenatedTransformTest sometime produces
298: // random NaN numbers. This "two steps" is used only for comparaison purpose;
299: // the "real" (tested) method work better.
300: assertEquals(buffer.toString(), expected[i], actual[i],
301: delta[i % dimension]);
302: }
303: }
304: }
305: }
|