/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2005-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2009-2012, Geomatys * * 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.geotoolkit.referencing.factory.epsg; import org.opengis.util.FactoryException; import org.opengis.referencing.operation.Transformation; import org.opengis.referencing.operation.CoordinateOperation; import org.opengis.referencing.operation.CoordinateOperationFactory; import org.opengis.referencing.operation.ConcatenatedOperation; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.geotoolkit.factory.AuthorityFactoryFinder; import org.junit.*; import static org.junit.Assume.*; import static org.geotoolkit.test.Assert.*; import static org.geotoolkit.test.Commons.decodeQuotes; /** * Tests the usage of {@link CoordinateOperationFactory} with the help of the EPSG database. * * @author Martin Desruisseaux (IRD) * @version 4.0-M2 * * @since 2.4 */ public final strictfp class OperationFactoryTest extends EpsgFactoryTestBase { /** * The operation factory being tested. */ private final CoordinateOperationFactory opFactory; /** * Creates a test suite. */ public OperationFactoryTest() { opFactory = AuthorityFactoryFinder.getCoordinateOperationFactory(null); } /** * Tests the creation of an operation from a geographic CRS to WGS84 which is expected * to be explicitly described in the database. The transformation involves a datum shift. * * @throws FactoryException Should not happen. */ @Test @Ignore("CachingCoordinateOperationFactory is (for now) hidden by SIS factory.") public final void testGeographicBacked() throws FactoryException { assumeNotNull(factory); final CoordinateReferenceSystem sourceCRS; final CoordinateReferenceSystem targetCRS; final CoordinateOperation operation; sourceCRS = factory.createCoordinateReferenceSystem("4230"); targetCRS = factory.createCoordinateReferenceSystem("4326"); operation = opFactory.createOperation(sourceCRS, targetCRS); assertSame(sourceCRS, operation.getSourceCRS()); assertSame(targetCRS, operation.getTargetCRS()); assertSame(operation, opFactory.createOperation(sourceCRS, targetCRS)); assertEquals("1133", getIdentifier(operation)); // See comment in DefaultDataSourceTest. assertEquals(10.0, org.apache.sis.referencing.operation.AbstractCoordinateOperation.castOrCopy(operation).getLinearAccuracy(), 1E-6); assertTrue(operation instanceof Transformation); } /** * Tests the creation of an operation from a geographic CRS to WGS84 <strong>not</strong> * backed directly by an authority factory. However, the inverse transform may exist in * the authority factory. * * @throws FactoryException Should not happen. */ @Test public final void testGeographicUnbacked() throws FactoryException { assumeNotNull(factory); final CoordinateReferenceSystem sourceCRS; final CoordinateReferenceSystem targetCRS; final CoordinateOperation operation; sourceCRS = factory.createCoordinateReferenceSystem("4326"); targetCRS = factory.createCoordinateReferenceSystem("2995"); operation = opFactory.createOperation(sourceCRS, targetCRS); assertTrue("This test needs an operation not backed by the EPSG factory.", operation.getIdentifiers().isEmpty()); /* * Should contains exactly one transformations and an arbitrary number of conversions. */ assertTrue(operation instanceof ConcatenatedOperation); int count = 0; for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) { if (op instanceof Transformation) { count++; } } assertEquals("The coordinate operation should contains exactly 1 transformation", 1, count); assertTrue(org.apache.sis.referencing.operation.AbstractCoordinateOperation.castOrCopy(operation).getLinearAccuracy() <= 25); } /** * Tests the creation of an operation from EPSG:27572 to WGS84. * We use the WKT format as a way to check the math transform. * The geocentric translation is specified in the EPSG database. * * @throws FactoryException Should not happen. */ @Test @Ignore public final void testProjected() throws FactoryException { assumeNotNull(factory); final CoordinateReferenceSystem sourceCRS; final CoordinateReferenceSystem targetCRS; final CoordinateOperation operation; sourceCRS = factory.createCoordinateReferenceSystem("27572"); targetCRS = factory.createCoordinateReferenceSystem("4326"); operation = opFactory.createOperation(sourceCRS, targetCRS); assertSame(sourceCRS, operation.getSourceCRS()); assertSame(targetCRS, operation.getTargetCRS()); assertSame(operation, opFactory.createOperation(sourceCRS, targetCRS)); String wkt = operation.getMathTransform().toString(); assertMultilinesEquals(decodeQuotes( "CONCAT_MT[INVERSE_MT[PARAM_MT[“Lambert_Conformal_Conic_1SP”,\n" + " PARAMETER[“semi_major”, 6378249.2],\n" + " PARAMETER[“semi_minor”, 6356515.0],\n" + " PARAMETER[“central_meridian”, 0.0],\n" + " PARAMETER[“latitude_of_origin”, 46.8],\n" + " PARAMETER[“scale_factor”, 0.99987742],\n" + " PARAMETER[“false_easting”, 600000.0],\n" + " PARAMETER[“false_northing”, 2200000.0]]],\n" + " PARAM_MT[“Affine”,\n" + " PARAMETER[“num_row”, 3],\n" + " PARAMETER[“num_col”, 3],\n" + " PARAMETER[“elt_0_2”, 2.33722917]],\n" + " PARAM_MT[“Ellipsoid_To_Geocentric”,\n" + " PARAMETER[“dim”, 2],\n" + " PARAMETER[“semi_major”, 6378249.2],\n" + " PARAMETER[“semi_minor”, 6356515.0]],\n" + " PARAM_MT[“Geocentric translations (geog2D domain)”,\n" + " PARAMETER[“dx”, -168.0],\n" + " PARAMETER[“dy”, -60.0],\n" + " PARAMETER[“dz”, 320.0]],\n" + " PARAM_MT[“Geocentric_To_Ellipsoid”,\n" + " PARAMETER[“dim”, 2],\n" + " PARAMETER[“semi_major”, 6378137.0],\n" + " PARAMETER[“semi_minor”, 6356752.314245179]],\n" + " PARAM_MT[“Affine”,\n" + " PARAMETER[“num_row”, 3],\n" + " PARAMETER[“num_col”, 3],\n" + " PARAMETER[“elt_0_0”, 0.0],\n" + " PARAMETER[“elt_0_1”, 1.0],\n" + " PARAMETER[“elt_1_0”, 1.0],\n" + " PARAMETER[“elt_1_1”, 0.0]]]"), wkt); } /** * Tests the selection of operations from NAD27 (EPSG:4267) or NAD83 (EPSG:4269) * to WGS84 (EPSG:4326) in different geographic areas. * * <p>Example of source CRS that we should test (not yet implemented, to do in Apache SIS):</p> * <table> * <tr><td>NAD27</td><td>NAD83</td> <td>Area</td></tr> * <tr><td>15851</td><td>1188</td><td>CONUS</td></tr> * <tr> <td>8609</td><td>1723</td><td>United States (USA) - Mississipi</td></tr> * <tr> <td>8630</td><td>1740</td><td>United States (USA) - Wyoming</td></tr> * <tr> <td>8624</td><td>1734</td><td>United States (USA) - Texas east of 100°W</td></tr> * <tr> <td>8625</td><td>1735</td><td>United States (USA) - Texas west of 100°W</td></tr> * </table> * * @throws FactoryException Should not happen. */ @Test @Ignore("Will be re-enabled after the port to Apache SIS.") public final void testAreaDependant() throws FactoryException { assumeNotNull(factory); final int[] codes = { /* * Columns: [source CRS], [target CRS], [expected coordinate operation] */ 4267, 4269, 1241, // NAD27 to NAD83 (1): United States (USA) - CONUS including EEZ 3814, 4326, 1723, // NAD83 to WGS84 (27): United States (USA) - Mississipi 32156, 4326, 1740, // NAD83 to WGS84 (44): United States (USA) - Wyoming 32139, 4326, 1188 // NAD83 to WGS84 (1): North America (source CRS was Texas central). }; for (int i=0; i<codes.length;) { final String sourceCode = Integer.toString(codes[i++]); final String targetCode = Integer.toString(codes[i++]); final String expectedOp = Integer.toString(codes[i++]); final CoordinateReferenceSystem sourceCRS = factory.createCoordinateReferenceSystem(sourceCode); final CoordinateReferenceSystem targetCRS = factory.createCoordinateReferenceSystem(targetCode); final CoordinateOperation operation = opFactory.createOperation(sourceCRS, targetCRS); final Transformation datumShift = getTransformation(operation); assertNotNull(expectedOp, datumShift); assertEquals(expectedOp, getIdentifier(datumShift)); } } /** * Returns the first coordinate operation which is a transformation. * The skipped part are the map projections, which is not the purpose of this test. */ private static Transformation getTransformation(final CoordinateOperation operation) { if (operation instanceof Transformation) { return (Transformation) operation; } if (operation instanceof ConcatenatedOperation) { for (final CoordinateOperation op : ((ConcatenatedOperation) operation).getOperations()) { final Transformation tr = getTransformation(op); if (tr != null) { return tr; } } } return null; } }