/*
* 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;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CompoundCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.CoordinateOperationFactory;
import org.opengis.referencing.operation.Conversion;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.Operation;
import org.opengis.referencing.operation.OperationNotFoundException;
import org.opengis.referencing.operation.Projection;
import org.opengis.referencing.operation.Transformation;
import org.geotools.factory.Hints;
import org.geotools.referencing.WKT;
import org.geotools.referencing.ReferencingFactoryFinder;
import org.geotools.referencing.crs.DefaultCompoundCRS;
import org.geotools.referencing.crs.DefaultVerticalCRS;
import org.geotools.referencing.crs.DefaultTemporalCRS;
import org.geotools.referencing.crs.DefaultGeographicCRS;
import org.geotools.metadata.iso.quality.PositionalAccuracyImpl;
import static org.geotools.referencing.crs.DefaultGeographicCRS.WGS84;
import static org.geotools.referencing.crs.DefaultEngineeringCRS.GENERIC_2D;
import static org.geotools.referencing.crs.DefaultEngineeringCRS.GENERIC_3D;
import static org.geotools.referencing.crs.DefaultEngineeringCRS.CARTESIAN_2D;
import static org.geotools.referencing.crs.DefaultEngineeringCRS.CARTESIAN_3D;
import org.junit.*;
import static org.junit.Assert.*;
/**
* Test the default coordinate operation factory.
* <p>
* <strong>NOTE:</strong> Some tests are disabled in the particular case when the
* {@link CoordinateOperationFactory} is actually an {@link AuthorityBackedFactory}
* instance. This is because the later can replace source or target CRS by some CRS
* found in the EPSG authority factory, causing {@code assertSame} to fails. It may
* also returns a more accurate operation than the one expected from the WKT in the
* code below, causing transformation checks to fail as well. This situation occurs
* only if some EPSG authority factory like {@code plugin/epsg-hsql} is found in the
* classpath while the test are running. It should not occurs during Maven build, so
* all tests should be executed with Maven. It may occurs during an execution from
* the IDE however, in which case the tests are disabled in order to allows normal
* execution of other tests.
*
* @source $URL$
* @version $Id$
* @author Martin Desruisseaux (IRD)
*/
public final class CoordinateOperationFactoryTest extends TransformTestBase {
/**
* WKT of compound CRS to be tested.
*/
private static final String
WGS84_Z = "COMPD_CS[\"WGS84 + Z\"," + WKT.WGS84_DMHS + ',' + WKT.Z + ']',
NAD27_Z = "COMPD_CS[\"NAD27 + Z\"," + WKT.NAD27 + ',' + WKT.Z + ']',
Z_NAD27 = "COMPD_CS[\"Z + NAD27\"," + WKT.Z + ',' + WKT.NAD27 + ']',
WGS84_H = "COMPD_CS[\"WGS84 + H\"," + WKT.WGS84_DMHS + ',' + WKT.HEIGHT + ']',
NAD27_H = "COMPD_CS[\"NAD27 + Z\"," + WKT.NAD27 + ',' + WKT.HEIGHT + ']';
/**
* {@code true} if {@link #opFactory} is <strong>not</strong> an instance of
* {@link AuthorityBackedFactory}. See class javadoc for rational.
*/
private boolean usingDefaultFactory;
/**
* Ensures that positional accuracy dependencies are properly loaded. This is not needed for
* normal execution, but JUnit behavior with class loaders is sometime surprising.
*/
@Before
public void ensureClassLoaded() {
assertNotNull(PositionalAccuracyImpl.DATUM_SHIFT_APPLIED);
assertNotNull(PositionalAccuracyImpl.DATUM_SHIFT_OMITTED);
usingDefaultFactory = !(opFactory instanceof AuthorityBackedFactory);
}
/**
* Make sure that a factory can be find in the presence of some global hints.
*
* @see http://jira.codehaus.org/browse/GEOT-1618
*/
@Test
public void testFactoryWithHints() {
final Hints hints = new Hints();
hints.put(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER, Boolean.TRUE);
hints.put(Hints.FORCE_STANDARD_AXIS_DIRECTIONS, Boolean.TRUE);
hints.put(Hints.FORCE_STANDARD_AXIS_UNITS, Boolean.TRUE);
final CoordinateOperationFactory factory =
ReferencingFactoryFinder.getCoordinateOperationFactory(hints);
assertSame(opFactory, factory);
}
/**
* Make sure that <code>createOperation(sourceCRS, targetCRS)</code>
* returns an identity transform when <code>sourceCRS</code> and <code>targetCRS</code>
* are identical, and tests the generic CRS.
*/
@Test
public void testGenericTransform() throws FactoryException {
assertTrue(opFactory.createOperation(WGS84, WGS84 ).getMathTransform().isIdentity());
assertTrue(opFactory.createOperation(CARTESIAN_2D, CARTESIAN_2D).getMathTransform().isIdentity());
assertTrue(opFactory.createOperation(CARTESIAN_3D, CARTESIAN_3D).getMathTransform().isIdentity());
assertTrue(opFactory.createOperation(GENERIC_2D, GENERIC_2D ).getMathTransform().isIdentity());
assertTrue(opFactory.createOperation(GENERIC_2D, CARTESIAN_2D).getMathTransform().isIdentity());
assertTrue(opFactory.createOperation(CARTESIAN_2D, GENERIC_2D ).getMathTransform().isIdentity());
assertTrue(opFactory.createOperation(WGS84, GENERIC_2D ).getMathTransform().isIdentity());
assertTrue(opFactory.createOperation(GENERIC_2D, WGS84 ).getMathTransform().isIdentity());
try {
opFactory.createOperation(CARTESIAN_2D, WGS84);
fail();
} catch (OperationNotFoundException exception) {
// This is the expected exception.
}
try {
opFactory.createOperation(WGS84, CARTESIAN_2D);
fail();
} catch (OperationNotFoundException exception) {
// This is the expected exception.
}
}
/**
* Tests a transformation with unit conversion.
*/
@Test
public void testUnitConversion() throws Exception {
// NOTE: TOWGS84[0,0,0,0,0,0,0] is used here as a hack for
// avoiding datum shift. Shifts will be tested later.
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(
"PROJCS[\"TransverseMercator\",\n" +
" GEOGCS[\"Sphere\",\n" +
" DATUM[\"Sphere\",\n" +
" SPHEROID[\"Sphere\", 6370997.0, 0.0],\n" +
" TOWGS84[0,0,0,0,0,0,0]],\n" +
" PRIMEM[\"Greenwich\", 0.0],\n" +
" UNIT[\"degree\", 0.017453292519943295],\n" +
" AXIS[\"Longitude\", EAST],\n" +
" AXIS[\"Latitude\", NORTH]],\n" +
" PROJECTION[\"Transverse_Mercator\",\n" +
" AUTHORITY[\"OGC\",\"Transverse_Mercator\"]],\n" +
" PARAMETER[\"central_meridian\", 170.0],\n" +
" PARAMETER[\"latitude_of_origin\", 50.0],\n" +
" PARAMETER[\"scale_factor\", 0.95],\n" +
" PARAMETER[\"false_easting\", 0.0],\n" +
" PARAMETER[\"false_northing\", 0.0],\n" +
" UNIT[\"feet\", 0.304800609601219],\n" +
" AXIS[\"x\", EAST],\n" +
" AXIS[\"y\", NORTH]]\n");
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.SPHERE);
final CoordinateOperation operation = opFactory.createOperation(sourceCRS, targetCRS);
assertEquals(sourceCRS, operation.getSourceCRS());
assertEquals(targetCRS, operation.getTargetCRS());
assertTrue (operation instanceof Projection);
final ParameterValueGroup param = ((Operation) operation).getParameterValues();
assertEquals("semi_major", 6370997.0, param.parameter("semi_major" ).doubleValue(), 1E-5);
assertEquals("semi_minor", 6370997.0, param.parameter("semi_minor" ).doubleValue(), 1E-5);
assertEquals("latitude_of_origin", 50.0, param.parameter("latitude_of_origin").doubleValue(), 1E-8);
assertEquals("central_meridian", 170.0, param.parameter("central_meridian" ).doubleValue(), 1E-8);
assertEquals("scale_factor", 0.95, param.parameter("scale_factor" ).doubleValue(), 1E-8);
assertEquals("false_easting", 0.0, param.parameter("false_easting" ).doubleValue(), 1E-8);
assertEquals("false_northing", 0.0, param.parameter("false_northing" ).doubleValue(), 1E-8);
final MathTransform transform = operation.getMathTransform();
assertInterfaced(transform);
assertTransformEquals2_2(transform.inverse(), 0, 0, 170, 50);
assertTransformEquals2_2(transform, 170, 50, 0, 0);
}
/**
* Tests a transformation that requires a datum shift with TOWGS84[0,0,0].
* In addition, this method tests datum aliases.
*/
@Test
public void testEllipsoidShift() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.NAD83);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(
"GEOGCS[\"GCS_WGS_1984\",\n" +
" DATUM[\"D_WGS_1984\",\n" +
" SPHEROID[\"WGS_1984\", 6378137.0, 298.257223563]],\n" +
" PRIMEM[\"Greenwich\", 0.0],\n" +
" UNIT[\"degree\", 0.017453292519943295],\n" +
" AXIS[\"Lon\", EAST],\n" +
" AXIS[\"Lat\", NORTH]]");
final CoordinateOperation operation = opFactory.createOperation(sourceCRS, targetCRS);
if (usingDefaultFactory) {
assertSame(sourceCRS, operation.getSourceCRS());
assertSame(targetCRS, operation.getTargetCRS());
}
final MathTransform transform = operation.getMathTransform();
assertInterfaced(transform);
assertTransformEquals2_2(transform, -180, -88.21076182660325, -180, -88.21076182655470);
assertTransformEquals2_2(transform, +180, 85.41283436546335, -180, 85.41283436531322);
// assertTransformEquals2_2(transform, +180, 85.41283436546335, +180, 85.41283436548373);
// Note 1: Expected values above were computed with Geotools (not an external library).
// Note 2: The commented-out test it the one we get when using geocentric instead of
// Molodenski method.
}
/**
* Tests a transformation that requires a datum shift.
*/
@Test
public void testDatumShift() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.GEOGRAPHIC_NTF);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.WGS84);
final CoordinateOperation operation = opFactory.createOperation(sourceCRS, targetCRS);
if (usingDefaultFactory) {
assertSame (sourceCRS, operation.getSourceCRS());
assertSame (targetCRS, operation.getTargetCRS());
assertTrue (operation.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_APPLIED));
assertFalse(operation.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_OMITTED));
}
final MathTransform transform = operation.getMathTransform();
assertInterfaced(transform);
assertTransformEquals2_2(transform, 0, 0, 2.3367521703619816, 0.0028940088671177986);
assertTransformEquals2_2(transform, 20, -10, -6.663517606186469, 18.00134508026729);
// Note: Expected values above were computed with Geotools (not an external library).
// However, it was tested with both Molodenski and Geocentric transformations.
/*
* Remove the TOWGS84 element and test again. An exception should be throws,
* since no Bursa-Wolf parameters were available.
*/
final CoordinateReferenceSystem amputedCRS;
if (true) {
String wkt = sourceCRS.toWKT();
final int start = wkt.indexOf("TOWGS84"); assertTrue(start >= 0);
final int end = wkt.indexOf(']', start); assertTrue(end >= 0);
final int comma = wkt.indexOf(',', end); assertTrue(comma >= 0);
wkt = wkt.substring(0, start) + wkt.substring(comma+1);
amputedCRS = crsFactory.createFromWKT(wkt);
} else {
amputedCRS = sourceCRS;
}
try {
assertNotNull(opFactory.createOperation(amputedCRS, targetCRS));
fail("Operation without Bursa-Wolf parameters should not have been allowed.");
} catch (OperationNotFoundException excption) {
// This is the expected exception.
}
/*
* Try again with hints, asking for a lenient factory.
*/
CoordinateOperationFactory lenientFactory;
Hints hints = new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.FALSE);
lenientFactory = ReferencingFactoryFinder.getCoordinateOperationFactory(hints);
assertSame(opFactory, lenientFactory);
hints.put(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
lenientFactory = ReferencingFactoryFinder.getCoordinateOperationFactory(hints);
assertNotSame(opFactory, lenientFactory);
final CoordinateOperation lenient = lenientFactory.createOperation(amputedCRS, targetCRS);
assertSame(amputedCRS, lenient.getSourceCRS());
assertSame( targetCRS, lenient.getTargetCRS());
assertFalse(lenient.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_APPLIED));
assertTrue (lenient.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_OMITTED));
final MathTransform lenientTr = lenient.getMathTransform();
assertInterfaced(lenientTr);
assertTransformEquals2_2(lenientTr, 0, 0, 2.33722917, 0.0);
assertTransformEquals2_2(lenientTr, 20, -10, -6.66277083, 17.99814879585781);
// assertTransformEquals2_2(lenientTr, 20, -10, -6.66277083, 17.998143675921714);
// Note 1: Expected values above were computed with Geotools (not an external library).
// Note 2: The commented-out test is the one we get with "Abridged_Molodenski" method
// instead of "Molodenski".
}
/**
* Tests a transformation that requires a datum shift with 7 parameters.
*/
@Test
public void testDatumShift7Param() throws Exception {
final CoordinateReferenceSystem sourceCRS = DefaultGeographicCRS.WGS84;
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.UTM_58S);
CoordinateOperation operation = opFactory.createOperation(sourceCRS, targetCRS);
if (usingDefaultFactory) {
assertSame(sourceCRS, operation.getSourceCRS());
assertSame(targetCRS, operation.getTargetCRS());
assertTrue (operation.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_APPLIED));
assertFalse(operation.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_OMITTED));
}
MathTransform transform = operation.getMathTransform();
assertInterfaced(transform);
assertTransformEquals2_2(transform, 168.1075, -21.597283333333, 822023.338884308, 7608648.67486555);
// Note: Expected values above were computed with Geotools (not an external library).
/*
* Try again using lenient factory. The result should be identical, since we do have
* Bursa-Wolf parameters. This test failed before GEOT-661 fix.
*/
final Hints hints = new Hints(Hints.LENIENT_DATUM_SHIFT, Boolean.TRUE);
final CoordinateOperationFactory lenientFactory =
ReferencingFactoryFinder.getCoordinateOperationFactory(hints);
assertNotSame(opFactory, lenientFactory);
operation = lenientFactory.createOperation(sourceCRS, targetCRS);
if (usingDefaultFactory) {
assertSame(sourceCRS, operation.getSourceCRS());
assertSame(targetCRS, operation.getTargetCRS());
assertTrue (operation.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_APPLIED));
assertFalse(operation.getCoordinateOperationAccuracy().contains(PositionalAccuracyImpl.DATUM_SHIFT_OMITTED));
}
transform = operation.getMathTransform();
assertInterfaced(transform);
assertTransformEquals2_2(transform, 168.1075, -21.597283333333, 822023.338884308, 7608648.67486555);
// Note: Expected values above were computed with Geotools (not an external library).
}
/**
* Tests a CRS involving DMHS units.
*/
@Test
public void testDMHS() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.NAD27);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.WGS84_DMHS);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
assertTrue(op instanceof Transformation);
if (usingDefaultFactory) {
assertSame(sourceCRS, op.getSourceCRS());
assertSame(targetCRS, op.getTargetCRS());
}
assertFalse(mt.isIdentity());
assertInterfaced(mt);
if (usingDefaultFactory) {
// Note: Expected values below were computed with Geotools (not an external library).
// However, it was tested with both Molodenski and Geocentric transformations.
assertTransformEquals2_2(mt, 0.0, 0.0,
0.001654978796746043, 0.0012755944235822696);
assertTransformEquals2_2(mt, 5.0, 8.0,
5.001262960018587, 8.001271733843957);
}
}
/**
* Tests transformation between vertical CRS.
*/
@Test
public void testZIdentity() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.Z);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.Z);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertSame(sourceCRS, op.getSourceCRS());
assertSame(targetCRS, op.getTargetCRS());
}
assertTrue(op instanceof Conversion);
assertTrue(mt.isIdentity());
assertInterfaced(mt);
}
/**
* Tests transformation between vertical CRS.
*/
@Test
public void testHeightIdentity() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.HEIGHT);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.HEIGHT);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertSame(sourceCRS, op.getSourceCRS());
assertSame(targetCRS, op.getTargetCRS());
}
assertTrue(op instanceof Conversion);
assertTrue(mt.isIdentity());
assertInterfaced(mt);
}
/**
* Tests transformation between incompatible vertical CRS.
*/
@Test(expected = OperationNotFoundException.class)
public void testIncompatibleVertical() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.Z);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.HEIGHT);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
assertNull(op); // We should not reach this point.
}
/**
* Tests transformation involving 3D Geographic CRS.
*/
@Test
public void testGeographic3D() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(NAD27_Z);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WGS84_Z);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
assertNotSame(sourceCRS, op.getSourceCRS());
assertNotSame(targetCRS, op.getTargetCRS());
assertTrue(op instanceof Transformation);
assertTrue(sourceCRS instanceof CompoundCRS);
assertTrue(op.getSourceCRS() instanceof GeographicCRS); // 2D + 1D ---> 3D
assertTrue(targetCRS instanceof CompoundCRS);
assertTrue(op.getTargetCRS() instanceof GeographicCRS); // 2D + 1D ---> 3D
assertFalse(sourceCRS.equals(targetCRS));
assertFalse(op.getSourceCRS().equals(op.getTargetCRS()));
assertFalse(mt.isIdentity());
assertInterfaced(mt);
// Note: Expected values below were computed with Geotools (not an external library).
// However, it was tested with both Molodenski and Geocentric transformations.
assertTransformEquals3_3(mt, 0, 0, 0,
0.001654978796746043, 0.0012755944235822696, 66.4042236590758);
assertTransformEquals3_3(mt, 5, 8, 20,
5.0012629560319874, 8.001271729856333, 120.27929787151515);
assertTransformEquals3_3(mt, 5, 8, -20,
5.001262964005206, 8.001271737831601, 80.2792978901416);
assertTransformEquals3_3(mt,-5, -8, -20,
-4.99799698932651, -7.998735783965731, 9.007854541763663);
}
/**
* Tests transformation involving 3D Geographic CRS.
*/
@Test
public void testGeographic3D_ZFirst() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(Z_NAD27);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WGS84_Z);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
assertNotSame(sourceCRS, op.getSourceCRS());
assertNotSame(targetCRS, op.getTargetCRS());
assertTrue(op instanceof Transformation);
assertTrue(sourceCRS instanceof CompoundCRS);
assertTrue(op.getSourceCRS() instanceof GeographicCRS); // 2D + 1D ---> 3D
assertTrue(targetCRS instanceof CompoundCRS);
assertTrue(op.getTargetCRS() instanceof GeographicCRS); // 2D + 1D ---> 3D
assertFalse(sourceCRS.equals(targetCRS));
assertFalse(op.getSourceCRS().equals(op.getTargetCRS()));
assertFalse(mt.isIdentity());
assertInterfaced(mt);
// Note: Expected values below were computed with Geotools (not an external library).
// However, it was tested with both Molodenski and Geocentric transformations.
assertTransformEquals3_3(mt, 0, 0, 0,
0.001654978796746043, 0.0012755944235822696, 66.4042236590758);
assertTransformEquals3_3(mt, -20, 5, 8,
5.001262964005206, 8.001271737831601, 80.2792978901416);
}
/**
* Tests transformation from 3D to 2D Geographic CRS.
*/
@Test
public void test3D_to_2D() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(NAD27_Z);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.WGS84_DMHS);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertNotSame(sourceCRS, op.getSourceCRS());
assertSame (targetCRS, op.getTargetCRS());
}
assertFalse(mt.isIdentity());
assertInterfaced(mt);
// Note: Expected values below were computed with Geotools (not an external library).
// However, it was tested with both Molodenski and Geocentric transformations.
assertTransformEquals3_2(mt, 0, 0, 0,
0.001654978796746043, 0.0012755944235822696);
assertTransformEquals3_2(mt, 5, 8, 20,
5.0012629560319874, 8.001271729856333);
assertTransformEquals3_2(mt, 5, 8, -20,
5.001262964005206, 8.001271737831601);
}
/**
* Tests transformation from 3D to vertical CRS.
*/
@Test
public void test3D_to_Z() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(NAD27_Z);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.Z);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertSame(sourceCRS, op.getSourceCRS());
assertSame(targetCRS, op.getTargetCRS());
}
assertFalse(mt.isIdentity());
assertInterfaced(mt);
assertTransformEquals3_1(mt, 0, 0, 0, 0);
assertTransformEquals3_1(mt, 5, 8, 20, 20);
assertTransformEquals3_1(mt, -5, -8, 20, 20);
}
/**
* Tests transformation from 2D to 3D with Z above the ellipsoid.
*/
@Test
public void test2D_to_3D() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.NAD27);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WGS84_Z);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertSame (sourceCRS, op.getSourceCRS());
assertNotSame(targetCRS, op.getTargetCRS());
}
assertFalse(mt.isIdentity());
assertInterfaced(mt);
// Note: Expected values below were computed with Geotools (not an external library).
// However, it was tested with both Molodenski and Geocentric transformations.
assertTransformEquals2_3(mt, 0, 0,
0.001654978796746043, 0.0012755944235822696, 66.4042236590758);
assertTransformEquals2_3(mt, 5, 8,
5.001262960018587, 8.001271733843957, 100.27929787896574);
}
/**
* Should fails unless GEOT-352 has been fixed.
*/
@Test(expected = OperationNotFoundException.class)
public void testHtoZ() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(NAD27_H);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(NAD27_Z);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
assertNotSame(sourceCRS, op.getSourceCRS());
assertNotSame(targetCRS, op.getTargetCRS());
assertFalse(mt.isIdentity());
assertInterfaced(mt);
}
/**
* Should fails unless GEOT-352 has been fixed.
*/
@Test(expected = OperationNotFoundException.class)
public void testHtoH() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(NAD27_H);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WGS84_H);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
assertNotSame(sourceCRS, op.getSourceCRS());
assertNotSame(targetCRS, op.getTargetCRS());
assertFalse(mt.isIdentity());
assertInterfaced(mt);
}
/**
* Should fails unless GEOT-352 has been fixed.
*/
@Test(expected = OperationNotFoundException.class)
public void test2DtoH() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(WKT.NAD27);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WGS84_H);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertSame (sourceCRS, op.getSourceCRS());
assertNotSame(targetCRS, op.getTargetCRS());
}
assertFalse(mt.isIdentity());
assertInterfaced(mt);
}
/**
* Tests transformation from a 3D Geographic CRS to a single height.
*/
@Test
public void test3D_to_H() throws Exception {
final CoordinateReferenceSystem sourceCRS = crsFactory.createFromWKT(NAD27_H);
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.HEIGHT);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertSame(sourceCRS, op.getSourceCRS());
assertSame(targetCRS, op.getTargetCRS());
}
assertFalse(mt.isIdentity());
assertInterfaced(mt);
assertTransformEquals3_1(mt, 0, 0, 0, 0);
assertTransformEquals3_1(mt, 5, 8, 20, 20);
assertTransformEquals3_1(mt, -5, -8, 20, 20);
}
/**
* Tests transformation from 4D to 2D projected.
*/
@Test
public void test4D_to_2D() throws Exception {
final CoordinateReferenceSystem targetCRS = crsFactory.createFromWKT(WKT.MERCATOR);
CoordinateReferenceSystem sourceCRS = targetCRS;
sourceCRS = new DefaultCompoundCRS("Mercator 3D", sourceCRS, DefaultVerticalCRS.ELLIPSOIDAL_HEIGHT);
sourceCRS = new DefaultCompoundCRS("Mercator 4D", sourceCRS, DefaultTemporalCRS.MODIFIED_JULIAN);
final CoordinateOperation op = opFactory.createOperation(sourceCRS, targetCRS);
final MathTransform mt = op.getMathTransform();
if (usingDefaultFactory) {
assertSame(sourceCRS, op.getSourceCRS());
assertSame(targetCRS, op.getTargetCRS());
}
assertFalse(mt.isIdentity());
assertTrue("The somewhat complex MathTransform chain should have been simplified " +
"to a single affine transform.", mt instanceof LinearTransform);
assertTrue("The operation should be a simple axis change, not a complex" +
"chain of ConcatenatedOperations.", op instanceof Conversion);
}
}