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; 035import javax.measure.Unit; 036import javax.measure.quantity.Angle; 037 038import org.opengis.util.Factory; 039import org.opengis.util.FactoryException; 040import org.opengis.referencing.datum.DatumAuthorityFactory; 041import org.opengis.referencing.NoSuchAuthorityCodeException; 042import org.opengis.referencing.datum.PrimeMeridian; 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.junit.Assert.*; 052 053 054/** 055 * Verifies reference prime meridians bundled with the geoscience software. 056 * 057 * <table class="gigs" summary="Test description"><tr> 058 * <th>Test method:</th> 059 * <td>Compare prime meridian 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_2003_libPrimeMeridian.csv">{@code GIGS_2003_libPrimeMeridian.csv}</a> 063 * and EPSG Dataset.</td> 064 * </tr><tr> 065 * <th>Tested API:</th> 066 * <td>{@link DatumAuthorityFactory#createPrimeMeridian(String)}.</td> 067 * </tr><tr> 068 * <th>Expected result:</th> 069 * <td>Prime meridian definitions bundled with the software should have the same name and Greenwich Longitude 070 * as in the EPSG Dataset. Equivalent alternative units are acceptable but should be reported. 071 * The values of the Greenwich Longitude should be correct to at least 7 decimal places (of degrees or grads). 072 * Meridians 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.GIGS2003; 083 * 084 *@RunWith(JUnit4.class) 085 *public class MyTest extends GIGS2003 { 086 * public MyTest() { 087 * super(new MyDatumAuthorityFactory()); 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 GIGS2003 extends AuthorityFactoryTestCase<PrimeMeridian> { 100 /** 101 * The expected Greenwich longitude in decimal degrees. 102 */ 103 public double greenwichLongitude; 104 105 /** 106 * The prime meridian created by the factory, 107 * or {@code null} if not yet created or if the prime meridian creation failed. 108 * 109 * @see #datumAuthorityFactory 110 */ 111 private PrimeMeridian primeMeridian; 112 113 /** 114 * Factory to use for building {@link PrimeMeridian} instances, or {@code null} if none. 115 * This is the factory used by the {@link #getIdentifiedObject()} method. 116 */ 117 protected final DatumAuthorityFactory datumAuthorityFactory; 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 GIGS2003} constructor. 127 */ 128 @Parameterized.Parameters 129 @SuppressWarnings("unchecked") 130 public static List<Factory[]> factories() { 131 return factories(FactoryFilter.ByAuthority.EPSG, DatumAuthorityFactory.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 datumFactory factory for creating {@link PrimeMeridian} instances. 139 */ 140 public GIGS2003(final DatumAuthorityFactory datumFactory) { 141 super(datumFactory); 142 datumAuthorityFactory = datumFactory; 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 #datumAuthorityFactory}</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.datumAuthorityFactory, datumAuthorityFactory)); 166 return op; 167 } 168 169 /** 170 * Returns the prime meridian instance to be tested. When this method is invoked for the first time, it creates the 171 * prime meridian to test by invoking the {@link DatumAuthorityFactory#createPrimeMeridian(String)} method with the 172 * current {@link #code} value in argument. The created object is then cached and returned in all subsequent 173 * invocations of this method. 174 * 175 * @return the prime meridian instance to test. 176 * @throws FactoryException if an error occurred while creating the prime meridian instance. 177 */ 178 @Override 179 public PrimeMeridian getIdentifiedObject() throws FactoryException { 180 if (primeMeridian == null) { 181 assumeNotNull(datumAuthorityFactory); 182 try { 183 primeMeridian = datumAuthorityFactory.createPrimeMeridian(String.valueOf(code)); 184 } catch (NoSuchAuthorityCodeException e) { 185 unsupportedCode(PrimeMeridian.class, code); 186 throw e; 187 } 188 } 189 return primeMeridian; 190 } 191 192 /** 193 * Verifies the properties of the prime meridian given by {@link #getIdentifiedObject()}. 194 */ 195 private void verifyPrimeMeridian() throws FactoryException { 196 final PrimeMeridian pm = getIdentifiedObject(); 197 assertNotNull("PrimeMeridian", pm); 198 validators.validate(pm); 199 200 // Prime meridian identifiers. 201 assertContainsCode("PrimeMeridian.getIdentifiers()", "EPSG", code, pm.getIdentifiers()); 202 203 // Prime meridian name. 204 if (isStandardNameSupported) { 205 configurationTip = Configuration.Key.isStandardNameSupported; 206 assertEquals("PrimeMeridian.getName()", name, getVerifiableName(pm)); 207 configurationTip = null; 208 } 209 210 // Prime meridian alias. 211 if (isStandardAliasSupported) { 212 configurationTip = Configuration.Key.isStandardAliasSupported; 213 assertContainsAll("PrimeMeridian.getAlias()", aliases, pm.getAlias()); 214 configurationTip = null; 215 } 216 /* 217 * Before to compare the Greenwich longitude, convert the expected angular value from decimal degrees 218 * to the units actually used by the implementation. We do the conversion that way rather than the 219 * opposite way in order to have a more appropriate error message in case of failure. 220 */ 221 final Unit<Angle> unit = pm.getAngularUnit(); 222 double longitude = greenwichLongitude; 223 final Unit<Angle> degree = units.degree(); 224 if (unit != null && !unit.equals(degree)) { 225 longitude = degree.getConverterTo(unit).convert(longitude); 226 } 227 assertEquals("PrimeMeridian.getGreenwichLongitude()", longitude, 228 pm.getGreenwichLongitude(), ANGULAR_TOLERANCE); 229 } 230 231 /** 232 * Tests “Greenwich” prime meridian creation from the factory. 233 * 234 * <ul> 235 * <li>EPSG prime meridian code: <b>8901</b></li> 236 * <li>EPSG prime meridian name: <b>Greenwich</b></li> 237 * <li>Greenwich longitude: <b>0°</b></li> 238 * <li>Particularly important to E&P industry.</li> 239 * </ul> 240 * 241 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 242 * 243 * @see GIGS3003#testGreenwich() 244 */ 245 @Test 246 public void testGreenwich() throws FactoryException { 247 important = true; 248 code = 8901; 249 name = "Greenwich"; 250 aliases = NONE; 251 greenwichLongitude = 0.0; 252 verifyPrimeMeridian(); 253 } 254 255 /** 256 * Tests “Ferro” prime meridian creation from the factory. 257 * 258 * <ul> 259 * <li>EPSG prime meridian code: <b>8909</b></li> 260 * <li>EPSG prime meridian name: <b>Ferro</b></li> 261 * <li>Greenwich longitude: <b>-17°40′</b></li> 262 * <li>Particularly important to E&P industry.</li> 263 * </ul> 264 * 265 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 266 */ 267 @Test 268 public void testFerro() throws FactoryException { 269 important = true; 270 code = 8909; 271 name = "Ferro"; 272 aliases = NONE; 273 greenwichLongitude = -17.666666666666668; 274 verifyPrimeMeridian(); 275 } 276 277 /** 278 * Tests “Jakarta” prime meridian creation from the factory. 279 * 280 * <ul> 281 * <li>EPSG prime meridian code: <b>8908</b></li> 282 * <li>EPSG prime meridian name: <b>Jakarta</b></li> 283 * <li>Greenwich longitude: <b>106°48′27.79″</b></li> 284 * <li>Particularly important to E&P industry.</li> 285 * </ul> 286 * 287 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 288 * 289 * @see GIGS3003#testJakarta() 290 */ 291 @Test 292 public void testJakarta() throws FactoryException { 293 important = true; 294 code = 8908; 295 name = "Jakarta"; 296 aliases = NONE; 297 greenwichLongitude = 106.80771944444444; 298 verifyPrimeMeridian(); 299 } 300 301 /** 302 * Tests “Paris” prime meridian creation from the factory. 303 * 304 * <ul> 305 * <li>EPSG prime meridian code: <b>8903</b></li> 306 * <li>EPSG prime meridian name: <b>Paris</b></li> 307 * <li>Greenwich longitude: <b>2.5969213</b></li> 308 * <li>Specific usage / Remarks: <b>Equivalent to 2°20'14.025\".</b></li> 309 * <li>Particularly important to E&P industry.</li> 310 * </ul> 311 * 312 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 313 * 314 * @see GIGS3003#testParis() 315 */ 316 @Test 317 public void testParis() throws FactoryException { 318 important = true; 319 code = 8903; 320 name = "Paris"; 321 aliases = NONE; 322 greenwichLongitude = 2.33722917; 323 verifyPrimeMeridian(); 324 } 325 326 /** 327 * Tests “Athens” prime meridian creation from the factory. 328 * 329 * <ul> 330 * <li>EPSG prime meridian code: <b>8912</b></li> 331 * <li>EPSG prime meridian name: <b>Athens</b></li> 332 * <li>Greenwich longitude: <b>23°42′58.815″</b></li> 333 * </ul> 334 * 335 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 336 */ 337 @Test 338 public void testAthens() throws FactoryException { 339 code = 8912; 340 name = "Athens"; 341 aliases = NONE; 342 greenwichLongitude = 23.7163375; 343 verifyPrimeMeridian(); 344 } 345 346 /** 347 * Tests “Bern” prime meridian creation from the factory. 348 * 349 * <ul> 350 * <li>EPSG prime meridian code: <b>8907</b></li> 351 * <li>EPSG prime meridian name: <b>Bern</b></li> 352 * <li>Greenwich longitude: <b>7°26′22.5″</b></li> 353 * </ul> 354 * 355 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 356 */ 357 @Test 358 public void testBern() throws FactoryException { 359 code = 8907; 360 name = "Bern"; 361 aliases = NONE; 362 greenwichLongitude = 7.439583333333333; 363 verifyPrimeMeridian(); 364 } 365 366 /** 367 * Tests “Bogota” prime meridian creation from the factory. 368 * 369 * <ul> 370 * <li>EPSG prime meridian code: <b>8904</b></li> 371 * <li>EPSG prime meridian name: <b>Bogota</b></li> 372 * <li>Greenwich longitude: <b>-74°04′51.3″</b></li> 373 * </ul> 374 * 375 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 376 * 377 * @see GIGS3003#testBogota() 378 */ 379 @Test 380 public void testBogota() throws FactoryException { 381 code = 8904; 382 name = "Bogota"; 383 aliases = NONE; 384 greenwichLongitude = -74.08091666666667; 385 verifyPrimeMeridian(); 386 } 387 388 /** 389 * Tests “Brussels” prime meridian creation from the factory. 390 * 391 * <ul> 392 * <li>EPSG prime meridian code: <b>8910</b></li> 393 * <li>EPSG prime meridian name: <b>Brussels</b></li> 394 * <li>Greenwich longitude: <b>4°22′04.71″</b></li> 395 * </ul> 396 * 397 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 398 */ 399 @Test 400 public void testBrussels() throws FactoryException { 401 code = 8910; 402 name = "Brussels"; 403 aliases = NONE; 404 greenwichLongitude = 4.367975; 405 verifyPrimeMeridian(); 406 } 407 408 /** 409 * Tests “Lisbon” prime meridian creation from the factory. 410 * 411 * <ul> 412 * <li>EPSG prime meridian code: <b>8902</b></li> 413 * <li>EPSG prime meridian name: <b>Lisbon</b></li> 414 * <li>Greenwich longitude: <b>-9°07′54.862″</b></li> 415 * </ul> 416 * 417 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 418 */ 419 @Test 420 public void testLisbon() throws FactoryException { 421 code = 8902; 422 name = "Lisbon"; 423 aliases = NONE; 424 greenwichLongitude = -9.13190611111111; 425 verifyPrimeMeridian(); 426 } 427 428 /** 429 * Tests “Madrid” prime meridian creation from the factory. 430 * 431 * <ul> 432 * <li>EPSG prime meridian code: <b>8905</b></li> 433 * <li>EPSG prime meridian name: <b>Madrid</b></li> 434 * <li>Greenwich longitude: <b>-3°41′16.58″</b></li> 435 * </ul> 436 * 437 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 438 */ 439 @Test 440 public void testMadrid() throws FactoryException { 441 code = 8905; 442 name = "Madrid"; 443 aliases = NONE; 444 greenwichLongitude = -3.687938888888889; 445 verifyPrimeMeridian(); 446 } 447 448 /** 449 * Tests “Oslo” prime meridian creation from the factory. 450 * 451 * <ul> 452 * <li>EPSG prime meridian code: <b>8913</b></li> 453 * <li>EPSG prime meridian name: <b>Oslo</b></li> 454 * <li>Alias(es) given by EPSG: <b>Kristiania</b></li> 455 * <li>Greenwich longitude: <b>10°43′22.5″</b></li> 456 * </ul> 457 * 458 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 459 */ 460 @Test 461 public void testOslo() throws FactoryException { 462 code = 8913; 463 name = "Oslo"; 464 aliases = new String[] {"Kristiania"}; 465 greenwichLongitude = 10.722916666666666; 466 verifyPrimeMeridian(); 467 } 468 469 /** 470 * Tests “Paris RGS” prime meridian creation from the factory. 471 * 472 * <ul> 473 * <li>EPSG prime meridian code: <b>8914</b></li> 474 * <li>EPSG prime meridian name: <b>Paris RGS</b></li> 475 * <li>Greenwich longitude: <b>2°20′13.95″</b></li> 476 * </ul> 477 * 478 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 479 */ 480 @Test 481 public void testParisRGS() throws FactoryException { 482 code = 8914; 483 name = "Paris RGS"; 484 aliases = NONE; 485 greenwichLongitude = 2.3372083333333333; 486 verifyPrimeMeridian(); 487 } 488 489 /** 490 * Tests “Rome” prime meridian creation from the factory. 491 * 492 * <ul> 493 * <li>EPSG prime meridian code: <b>8906</b></li> 494 * <li>EPSG prime meridian name: <b>Rome</b></li> 495 * <li>Greenwich longitude: <b>12°27′08.4″</b></li> 496 * </ul> 497 * 498 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 499 */ 500 @Test 501 public void testRome() throws FactoryException { 502 code = 8906; 503 name = "Rome"; 504 aliases = NONE; 505 greenwichLongitude = 12.452333333333334; 506 verifyPrimeMeridian(); 507 } 508 509 /** 510 * Tests “Stockholm” prime meridian creation from the factory. 511 * 512 * <ul> 513 * <li>EPSG prime meridian code: <b>8911</b></li> 514 * <li>EPSG prime meridian name: <b>Stockholm</b></li> 515 * <li>Greenwich longitude: <b>18°03′29.8″</b></li> 516 * </ul> 517 * 518 * @throws FactoryException if an error occurred while creating the prime meridian from the EPSG code. 519 */ 520 @Test 521 public void testStockholm() throws FactoryException { 522 code = 8911; 523 name = "Stockholm"; 524 aliases = NONE; 525 greenwichLongitude = 18.05827777777778; 526 verifyPrimeMeridian(); 527 } 528}