001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2004-2006, Geotools Project Managment Committee (PMC)
005: * (C) 2004, 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 and JUnit dependencies
020: import java.util.Random;
021: import javax.units.SI;
022: import javax.units.Unit;
023: import junit.framework.Test;
024: import junit.framework.TestCase;
025: import junit.framework.TestSuite;
026:
027: // OpenGIS dependencies
028: import org.opengis.parameter.ParameterValueGroup;
029: import org.opengis.referencing.FactoryException;
030: import org.opengis.referencing.cs.AxisDirection;
031: import org.opengis.referencing.operation.MathTransform;
032: import org.opengis.referencing.operation.MathTransformFactory;
033: import org.opengis.referencing.operation.Matrix;
034:
035: // Geotools dependencies
036: import org.geotools.referencing.crs.DefaultGeographicCRS;
037: import org.geotools.referencing.crs.DefaultProjectedCRS;
038: import org.geotools.referencing.cs.AbstractCS;
039: import org.geotools.referencing.cs.DefaultCartesianCS;
040: import org.geotools.referencing.cs.DefaultCoordinateSystemAxis;
041: import org.geotools.referencing.datum.DefaultEllipsoid;
042: import org.geotools.referencing.operation.matrix.Matrix2;
043: import org.geotools.referencing.operation.matrix.Matrix3;
044: import org.geotools.referencing.operation.matrix.GeneralMatrix;
045:
046: /**
047: * Tests some operation steps involved in coordinate operation creation.
048: *
049: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/test/java/org/geotools/referencing/operation/LinearConversionTest.java $
050: * @version $Id: LinearConversionTest.java 27848 2007-11-12 13:10:32Z desruisseaux $
051: * @author Martin Desruisseaux
052: */
053: public final class LinearConversionTest extends TestCase {
054: /**
055: * Run the suite from the command line.
056: */
057: public static void main(String[] args) {
058: org.geotools.util.logging.Logging.GEOTOOLS
059: .forceMonolineConsoleOutput();
060: junit.textui.TestRunner.run(suite());
061: }
062:
063: /**
064: * Returns the test suite.
065: */
066: public static Test suite() {
067: return new TestSuite(LinearConversionTest.class);
068: }
069:
070: /**
071: * Constructs a test case.
072: */
073: public LinearConversionTest(String testName) {
074: super (testName);
075: }
076:
077: /**
078: * Tests matrix inversion and multiplication using {@link Matrix2}.
079: */
080: public void testMatrix2() {
081: final Matrix2 m = new Matrix2();
082: assertTrue(m.isAffine());
083: assertTrue(m.isIdentity());
084: final Random random = new Random(8447482612423035360L);
085: final GeneralMatrix identity = new GeneralMatrix(2);
086: for (int i = 0; i < 100; i++) {
087: m.setElement(0, 0, 100 * random.nextDouble());
088: m.setElement(0, 1, 100 * random.nextDouble());
089: m.setElement(1, 0, 100 * random.nextDouble());
090: m.setElement(1, 1, 100 * random.nextDouble());
091: final Matrix2 original = (Matrix2) m.clone();
092: final GeneralMatrix check = new GeneralMatrix(m);
093: m.invert();
094: check.invert();
095: assertTrue(check.epsilonEquals(new GeneralMatrix(m), 1E-9));
096: m.multiply(original);
097: assertTrue(identity.epsilonEquals(new GeneralMatrix(m),
098: 1E-9));
099: }
100: }
101:
102: /**
103: * Tests axis swapping using {@link GeneralMatrix}.
104: */
105: public void testAxisSwapping() {
106: AxisDirection[] srcAxis = { AxisDirection.NORTH,
107: AxisDirection.EAST, AxisDirection.UP };
108: AxisDirection[] dstAxis = { AxisDirection.NORTH,
109: AxisDirection.EAST, AxisDirection.UP };
110: GeneralMatrix matrix = new GeneralMatrix(srcAxis, dstAxis);
111: assertTrue(matrix.isAffine());
112: assertTrue(matrix.isIdentity());
113: dstAxis = new AxisDirection[] { AxisDirection.WEST,
114: AxisDirection.UP, AxisDirection.SOUTH };
115: matrix = new GeneralMatrix(srcAxis, dstAxis);
116: assertTrue(matrix.isAffine());
117: assertFalse(matrix.isIdentity());
118: assertEquals(new GeneralMatrix(new double[][] {
119: { 0, -1, 0, 0 }, { 0, 0, 1, 0 }, { -1, 0, 0, 0 },
120: { 0, 0, 0, 1 } }), matrix);
121: dstAxis = new AxisDirection[] { AxisDirection.DOWN,
122: AxisDirection.NORTH };
123: matrix = new GeneralMatrix(srcAxis, dstAxis);
124: assertFalse(matrix.isIdentity());
125: assertEquals(new GeneralMatrix(new double[][] {
126: { 0, 0, -1, 0 }, { 1, 0, 0, 0 }, { 0, 0, 0, 1 } }),
127: matrix);
128: dstAxis = new AxisDirection[] { AxisDirection.DOWN,
129: AxisDirection.DOWN };
130: matrix = new GeneralMatrix(srcAxis, dstAxis);
131: assertFalse(matrix.isIdentity());
132: assertEquals(new GeneralMatrix(new double[][] {
133: { 0, 0, -1, 0 }, { 0, 0, -1, 0 }, { 0, 0, 0, 1 } }),
134: matrix);
135: dstAxis = new AxisDirection[] { AxisDirection.DOWN,
136: AxisDirection.GEOCENTRIC_X };
137: try {
138: matrix = new GeneralMatrix(srcAxis, dstAxis);
139: fail();
140: } catch (IllegalArgumentException exception) {
141: // This is the expected exception (axis not in source).
142: }
143: srcAxis = dstAxis;
144: dstAxis = new AxisDirection[] { AxisDirection.NORTH,
145: AxisDirection.EAST, AxisDirection.UP,
146: AxisDirection.WEST };
147: try {
148: matrix = new GeneralMatrix(srcAxis, dstAxis);
149: fail();
150: } catch (IllegalArgumentException exception) {
151: // This is the expected exception (colinear axis).
152: }
153: }
154:
155: /**
156: * Tests an example similar to the one provided in the
157: * {@link AbstractCS#testScaleAndSwapAxis} javadoc.
158: */
159: public void testScaleAndSwapAxis() {
160: final Unit cm = SI.CENTI(SI.METER);
161: final Unit mm = SI.MILLI(SI.METER);
162: final AbstractCS cs = new DefaultCartesianCS("Test",
163: new DefaultCoordinateSystemAxis("y",
164: AxisDirection.SOUTH, cm),
165: new DefaultCoordinateSystemAxis("x",
166: AxisDirection.EAST, mm));
167: Matrix matrix;
168: matrix = AbstractCS.swapAndScaleAxis(
169: DefaultCartesianCS.GENERIC_2D, cs);
170: assertEquals(new GeneralMatrix(new double[][] { { 0, -100, 0 },
171: { 1000, 0, 0 }, { 0, 0, 1 } }), matrix);
172: matrix = AbstractCS.swapAndScaleAxis(
173: DefaultCartesianCS.GENERIC_3D, cs);
174: assertEquals(
175: new GeneralMatrix(new double[][] { { 0, -100, 0, 0 },
176: { 1000, 0, 0, 0 }, { 0, 0, 0, 1 } }), matrix);
177: }
178:
179: /**
180: * Test the {@link DefaultProjectedCRS#createLinearConversion} method.
181: * Note: this requires a working {@link MathTransformFactory}.
182: */
183: public void testCreateLinearConversion() throws FactoryException {
184: final double EPS = 1E-12;
185: final MathTransformFactory factory = new DefaultMathTransformFactory();
186: final ParameterValueGroup parameters = factory
187: .getDefaultParameters("Mercator_1SP");
188: DefaultProjectedCRS sourceCRS, targetCRS;
189: MathTransform transform;
190: Matrix conversion;
191:
192: parameters.parameter("semi_major").setValue(
193: DefaultEllipsoid.WGS84.getSemiMajorAxis());
194: parameters.parameter("semi_minor").setValue(
195: DefaultEllipsoid.WGS84.getSemiMinorAxis());
196: transform = factory.createParameterizedTransform(parameters);
197: sourceCRS = new DefaultProjectedCRS("source",
198: new DefaultOperationMethod(transform),
199: DefaultGeographicCRS.WGS84, transform,
200: DefaultCartesianCS.PROJECTED);
201:
202: parameters.parameter("false_easting").setValue(1000);
203: parameters.parameter("false_northing").setValue(2000);
204: transform = factory.createParameterizedTransform(parameters);
205: targetCRS = new DefaultProjectedCRS("source",
206: new DefaultOperationMethod(transform),
207: DefaultGeographicCRS.WGS84, transform,
208: DefaultCartesianCS.PROJECTED);
209:
210: conversion = ProjectionAnalyzer.createLinearConversion(
211: sourceCRS, targetCRS, EPS);
212: assertEquals(new Matrix3(1, 0, 1000, 0, 1, 2000, 0, 0, 1),
213: conversion);
214:
215: parameters.parameter("scale_factor").setValue(2);
216: transform = factory.createParameterizedTransform(parameters);
217: targetCRS = new DefaultProjectedCRS("source",
218: new DefaultOperationMethod(transform),
219: DefaultGeographicCRS.WGS84, transform,
220: DefaultCartesianCS.PROJECTED);
221:
222: conversion = ProjectionAnalyzer.createLinearConversion(
223: sourceCRS, targetCRS, EPS);
224: assertEquals(new Matrix3(2, 0, 1000, 0, 2, 2000, 0, 0, 1),
225: conversion);
226:
227: parameters.parameter("semi_minor").setValue(
228: DefaultEllipsoid.WGS84.getSemiMajorAxis());
229: transform = factory.createParameterizedTransform(parameters);
230: targetCRS = new DefaultProjectedCRS("source",
231: new DefaultOperationMethod(transform),
232: DefaultGeographicCRS.WGS84, transform,
233: DefaultCartesianCS.PROJECTED);
234: conversion = ProjectionAnalyzer.createLinearConversion(
235: sourceCRS, targetCRS, EPS);
236: assertNull(conversion);
237: }
238: }
|