001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * http://www.geoapi.org 004 * 005 * Copyright (C) 2011-2019 Open Geospatial Consortium, Inc. 006 * All Rights Reserved. http://www.opengeospatial.org/ogc/legal 007 * 008 * Permission to use, copy, and modify this software and its documentation, with 009 * or without modification, for any purpose and without fee or royalty is hereby 010 * granted, provided that you include the following on ALL copies of the software 011 * and documentation or portions thereof, including modifications, that you make: 012 * 013 * 1. The full text of this NOTICE in a location viewable to users of the 014 * redistributed or derivative work. 015 * 2. Notice of any changes or modifications to the OGC files, including the 016 * date changes were made. 017 * 018 * THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE 019 * NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 020 * TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT 021 * THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY 022 * PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. 023 * 024 * COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR 025 * CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. 026 * 027 * The name and trademarks of copyright holders may NOT be used in advertising or 028 * publicity pertaining to the software without specific, written prior permission. 029 * Title to copyright in this software and any associated documentation will at all 030 * times remain with copyright holders. 031 */ 032package org.opengis.test.referencing.gigs; 033 034import java.util.List; 035 036import org.opengis.util.Factory; 037import org.opengis.util.FactoryException; 038import org.opengis.util.NoSuchIdentifierException; 039import org.opengis.referencing.operation.Transformation; 040import org.opengis.referencing.operation.CoordinateOperation; 041import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory; 042import org.opengis.referencing.operation.OperationMethod; 043import org.opengis.test.Configuration; 044import org.opengis.test.FactoryFilter; 045 046import org.junit.Test; 047import org.junit.runner.RunWith; 048import org.junit.runners.Parameterized; 049 050import static org.junit.Assume.*; 051import static org.opengis.test.Assert.*; 052 053 054/** 055 * Verifies reference vertical transformations bundled with the geoscience software. 056 * 057 * <table class="gigs" summary="Test description"><tr> 058 * <th>Test method:</th> 059 * <td>Compare transformation definitions included in the software against the EPSG Dataset.</td> 060 * </tr><tr> 061 * <th>Test data:</th> 062 * <td><a href="doc-files/GIGS_2009_libVertTfm.csv">{@code GIGS_2009_libVertTfm.csv}</a> 063 * and EPSG Dataset.</td> 064 * </tr><tr> 065 * <th>Tested API:</th> 066 * <td>{@link CoordinateOperationAuthorityFactory#createCoordinateOperation(String)}.</td> 067 * </tr><tr> 068 * <th>Expected result:</th> 069 * <td>Transformation definitions bundled with the software should have same name, method name, 070 * defining parameters and parameter values as in EPSG Dataset. See current version of the EPSG Dataset. 071 * The values of the parameters should be correct to at least 10 significant figures. 072 * Transformations missing from the software or at variance with those in the EPSG Dataset should be reported.</td> 073 * </tr></table> 074 * 075 * 076 * <div class="note"><b>Usage example:</b> 077 * in order to specify their factories and run the tests in a JUnit framework, implementors can 078 * define a subclass in their own test suite as in the example below: 079 * 080 * <blockquote><pre>import org.junit.runner.RunWith; 081 *import org.junit.runners.JUnit4; 082 *import org.opengis.test.referencing.gigs.GIGS2009; 083 * 084 *@RunWith(JUnit4.class) 085 *public class MyTest extends GIGS2009 { 086 * public MyTest() { 087 * super(new MyCoordinateOperationAuthorityFactory()); 088 * } 089 *}</pre></blockquote> 090 * </div> 091 * 092 * @author GIGS (IOGP) 093 * @author Martin Desruisseaux (Geomatys) 094 * @author Alexis Manin (Geomatys) 095 * @version 3.1 096 * @since 3.1 097 */ 098@RunWith(Parameterized.class) 099public strictfp class GIGS2009 extends AuthorityFactoryTestCase<Transformation> { 100 /** 101 * Name of the expected transformation method. 102 */ 103 public String methodName; 104 105 /** 106 * The coordinate transformation created by the factory, 107 * or {@code null} if not yet created or if CRS creation failed. 108 * 109 * @see #copAuthorityFactory 110 */ 111 private Transformation transformation; 112 113 /** 114 * Factory to use for building {@link Transformation} instances, or {@code null} if none. 115 * This is the factory used by the {@link #getIdentifiedObject()} method. 116 */ 117 protected final CoordinateOperationAuthorityFactory copAuthorityFactory; 118 119 /** 120 * Returns a default set of factories to use for running the tests. Those factories are given 121 * in arguments to the constructor when this test class is instantiated directly by JUnit (for 122 * example as a {@linkplain org.junit.runners.Suite.SuiteClasses suite} element), instead than 123 * subclassed by the implementor. The factories are fetched as documented in the 124 * {@link #factories(Class[])} javadoc. 125 * 126 * @return the default set of arguments to be given to the {@code GIGS2009} constructor. 127 */ 128 @Parameterized.Parameters 129 @SuppressWarnings("unchecked") 130 public static List<Factory[]> factories() { 131 return factories(FactoryFilter.ByAuthority.EPSG, CoordinateOperationAuthorityFactory.class); 132 } 133 134 /** 135 * Creates a new test using the given factory. If a given factory is {@code null}, 136 * then the tests which depend on it will be skipped. 137 * 138 * @param copFactory factory for creating {@link Transformation} instances. 139 */ 140 public GIGS2009(final CoordinateOperationAuthorityFactory copFactory) { 141 super(copFactory); 142 copAuthorityFactory = copFactory; 143 } 144 145 /** 146 * Returns information about the configuration of the test which has been run. 147 * This method returns a map containing: 148 * 149 * <ul> 150 * <li>All the following values associated to the {@link org.opengis.test.Configuration.Key} of the same name: 151 * <ul> 152 * <li>{@link #isStandardNameSupported}</li> 153 * <li>{@link #isStandardAliasSupported}</li> 154 * <li>{@link #isDependencyIdentificationSupported}</li> 155 * <li>{@link #copAuthorityFactory}</li> 156 * </ul> 157 * </li> 158 * </ul> 159 * 160 * @return the configuration of the test being run. 161 */ 162 @Override 163 public Configuration configuration() { 164 final Configuration op = super.configuration(); 165 assertNull(op.put(Configuration.Key.copAuthorityFactory, copAuthorityFactory)); 166 return op; 167 } 168 169 /** 170 * Returns the transformation instance to be tested. When this method is invoked for the first time, it creates the 171 * transformation to test by invoking the {@link CoordinateOperationAuthorityFactory#createCoordinateOperation(String)} 172 * method with the current {@link #code} value in argument. The created object is then cached and returned in all 173 * subsequent invocations of this method. 174 * 175 * @return the transformation instance to test. 176 * @throws FactoryException if an error occurred while creating the transformation instance. 177 */ 178 @Override 179 public Transformation getIdentifiedObject() throws FactoryException { 180 if (transformation == null) { 181 assumeNotNull(copAuthorityFactory); 182 final String codeAsString = String.valueOf(code); 183 final CoordinateOperation operation; 184 try { 185 operation = copAuthorityFactory.createCoordinateOperation(codeAsString); 186 } catch (NoSuchIdentifierException e) { 187 /* 188 * Relaxed the exception type from NoSuchAuthorityCodeException because CoordinateOperation creation 189 * will typically use MathTransformFactory under the hood, which throws NoSuchIdentifierException for 190 * non-implemented operation methods (may be identified by their name rather than EPSG code). 191 */ 192 unsupportedCode(Transformation.class, code); 193 throw e; 194 } 195 if (operation != null) { // For consistency with the behavior in other classes. 196 assertInstanceOf(codeAsString, Transformation.class, operation); 197 transformation = (Transformation) operation; 198 } 199 } 200 return transformation; 201 } 202 203 /** 204 * Verifies the properties of the transformation given by {@link #getIdentifiedObject()}. 205 */ 206 private void verifyTransformation() throws FactoryException { 207 final Transformation transformation = getIdentifiedObject(); 208 assertNotNull("Transformation", transformation); 209 validators.validate(transformation); 210 211 // Transformation identifier. 212 assertContainsCode("Transformation.getIdentifiers()", "EPSG", code, transformation.getIdentifiers()); 213 214 // Transformation name. 215 if (isStandardNameSupported) { 216 configurationTip = Configuration.Key.isStandardNameSupported; 217 assertEquals("Transformation.getName()", name, getVerifiableName(transformation)); 218 configurationTip = null; 219 } 220 221 // Operation method. 222 final OperationMethod m = transformation.getMethod(); 223 assertNotNull("Transformation.getMethod()", m); 224 225 // Operation method name. 226 if (isStandardNameSupported) { 227 configurationTip = Configuration.Key.isStandardNameSupported; 228 assertEquals("Transformation.getMethod().getName()", methodName, getVerifiableName(m)); 229 configurationTip = null; 230 } 231 } 232 233 /** 234 * Tests “Baltic depth to AIOC95 depth (1)” transformation creation from the factory. 235 * 236 * <ul> 237 * <li>EPSG transformation code: <b>5445</b></li> 238 * <li>EPSG transformation name: <b>Baltic depth to AIOC95 depth (1)</b></li> 239 * <li>Transformation method: <b>Vertical Offset</b></li> 240 * <li>Particularly important to E&P industry.</li> 241 * </ul> 242 * 243 * @throws FactoryException if an error occurred while creating the transformation from the EPSG code. 244 */ 245 @Test 246 public void testBalticDepth_to_AIOC95() throws FactoryException { 247 important = true; 248 name = "Baltic depth to AIOC95 depth (1)"; 249 methodName = "Vertical Offset"; 250 verifyTransformation(); 251 } 252 253 /** 254 * Tests “Baltic height to AIOC95 height (1)” transformation creation from the factory. 255 * 256 * <ul> 257 * <li>EPSG transformation code: <b>5443</b></li> 258 * <li>EPSG transformation name: <b>Baltic height to AIOC95 height (1)</b></li> 259 * <li>Transformation method: <b>Vertical Offset</b></li> 260 * <li>Particularly important to E&P industry.</li> 261 * </ul> 262 * 263 * @throws FactoryException if an error occurred while creating the transformation from the EPSG code. 264 */ 265 @Test 266 public void testBalticHeight_to_AIOC95() throws FactoryException { 267 important = true; 268 name = "Baltic height to AIOC95 height (1)"; 269 methodName = "Vertical Offset"; 270 verifyTransformation(); 271 } 272 273 /** 274 * Tests “WGS 84 to EGM96 Geoid height (1)” transformation creation from the factory. 275 * 276 * <ul> 277 * <li>EPSG transformation code: <b>10084</b></li> 278 * <li>EPSG transformation name: <b>WGS 84 to EGM96 Geoid height (1)</b></li> 279 * <li>Transformation method: <b>Geographic3D to GravityRelatedHeight (EGM)</b></li> 280 * <li>Specific usage / Remarks: <b>Geoid model.</b></li> 281 * <li>Particularly important to E&P industry.</li> 282 * </ul> 283 * 284 * @throws FactoryException if an error occurred while creating the transformation from the EPSG code. 285 */ 286 @Test 287 public void testWGS84_to_EGM96() throws FactoryException { 288 important = true; 289 name = "WGS 84 to EGM96 Geoid height (1)"; 290 methodName = "Geographic3D to GravityRelatedHeight (EGM)"; 291 verifyTransformation(); 292 } 293}