Package org.geotools.referencing.operation

Source Code of org.geotools.referencing.operation.CoordinateOperationFactoryTest

/*
*    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, +18085.41283436546335, -18085.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,   02.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,   02.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.0016549787967460430.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,  00, 0,   0);
        assertTransformEquals3_1(mt,  58, 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,  00, 0,   0);
        assertTransformEquals3_1(mt,  58, 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);
    }
}
TOP

Related Classes of org.geotools.referencing.operation.CoordinateOperationFactoryTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.