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;
037import javax.measure.quantity.Length;
038
039import org.opengis.util.Factory;
040import org.opengis.util.FactoryException;
041import org.opengis.util.NoSuchIdentifierException;
042import org.opengis.parameter.ParameterValue;
043import org.opengis.parameter.ParameterValueGroup;
044import org.opengis.parameter.GeneralParameterValue;
045import org.opengis.referencing.operation.Conversion;
046import org.opengis.referencing.operation.CoordinateOperation;
047import org.opengis.referencing.operation.CoordinateOperationFactory;
048import org.opengis.referencing.operation.OperationMethod;
049import org.opengis.test.Configuration;
050
051import org.junit.Test;
052import org.junit.runner.RunWith;
053import org.junit.runners.Parameterized;
054
055import static org.junit.Assume.*;
056import static org.opengis.test.Assert.*;
057
058
059/**
060 * Verifies that the software allows correct definition of a user-defined map projection.
061 *
062 * <table class="gigs" summary="Test description"><tr>
063 *   <th>Test method:</th>
064 *   <td>Create user-defined projection for each of several different map projections.</td>
065 * </tr><tr>
066 *   <th>Test data:</th>
067 *   <td><a href="doc-files/GIGS_3005_userProjection.csv">{@code GIGS_3005_userProjection.csv}</a>.</td>
068 * </tr><tr>
069 *   <th>Tested API:</th>
070 *   <td>{@link CoordinateOperationFactory#getOperationMethod(String)} and<br>
071 *       {@link CoordinateOperationFactory#createDefiningConversion(Map, OperationMethod, ParameterValueGroup)}.</td>
072 * </tr><tr>
073 *   <th>Expected result:</th>
074 *   <td>The geoscience software should accept the test data. The order in which the projection parameters
075 *       are entered is not critical, although that given in the test dataset is recommended.</td>
076 * </tr></table>
077 *
078 *
079 * <div class="note"><b>Usage example:</b>
080 * in order to specify their factories and run the tests in a JUnit framework, implementors can
081 * define a subclass in their own test suite as in the example below:
082 *
083 * <blockquote><pre>import org.junit.runner.RunWith;
084 *import org.junit.runners.JUnit4;
085 *import org.opengis.test.referencing.gigs.GIGS300(;
086 *
087 *&#64;RunWith(JUnit4.class)
088 *public class MyTest extends GIGS3005 {
089 *    public MyTest() {
090 *        super(new MyCoordinateOperationFactory());
091 *    }
092 *}</pre></blockquote>
093 * </div>
094 *
095 * @author  GIGS (IOGP)
096 * @author  Martin Desruisseaux (Geomatys)
097 * @author  Alexis Manin (Geomatys)
098 * @version 3.1
099 * @since   3.1
100 */
101@RunWith(Parameterized.class)
102public strictfp class GIGS3005 extends UserObjectFactoryTestCase<Conversion> {
103    /**
104     * The name of the operation method to use.
105     */
106    public String methodName;
107
108    /**
109     * The parameters of the conversion to create.
110     */
111    public ParameterValueGroup definition;
112
113    /**
114     * The coordinate operation method.
115     */
116    private OperationMethod method;
117
118    /**
119     * The coordinate conversion created by the factory,
120     * or {@code null} if not yet created or if the conversion creation failed.
121     *
122     * @see #copAuthorityFactory
123     */
124    private Conversion conversion;
125
126    /**
127     * Factory to use for building {@link Conversion} instances, or {@code null} if none.
128     * This is the factory used by the {@link #getIdentifiedObject()} method.
129     */
130    protected final CoordinateOperationFactory copFactory;
131
132    /**
133     * Returns a default set of factories to use for running the tests. Those factories are given
134     * in arguments to the constructor when this test class is instantiated directly by JUnit (for
135     * example as a {@linkplain org.junit.runners.Suite.SuiteClasses suite} element), instead than
136     * subclassed by the implementor. The factories are fetched as documented in the
137     * {@link #factories(Class[])} javadoc.
138     *
139     * @return the default set of arguments to be given to the {@code GIGS3004} constructor.
140     */
141    @Parameterized.Parameters
142    @SuppressWarnings("unchecked")
143    public static List<Factory[]> factories() {
144        return factories(CoordinateOperationFactory.class);
145    }
146
147    /**
148     * Creates a new test using the given factory. If a given factory is {@code null},
149     * then the tests which depend on it will be skipped.
150     *
151     * @param copFactory  factory for creating {@link Conversion} instances.
152     */
153    public GIGS3005(final CoordinateOperationFactory copFactory) {
154        super(copFactory);
155        this.copFactory = copFactory;
156    }
157
158    /**
159     * Returns information about the configuration of the test which has been run.
160     * This method returns a map containing:
161     *
162     * <ul>
163     *   <li>All the following values associated to the {@link org.opengis.test.Configuration.Key} of the same name:
164     *     <ul>
165     *       <li>{@link #isFactoryPreservingUserValues}</li>
166     *       <li>{@linkplain #copFactory}</li>
167     *     </ul>
168     *   </li>
169     * </ul>
170     *
171     * @return the configuration of the test being run.
172     */
173    @Override
174    public Configuration configuration() {
175        final Configuration op = super.configuration();
176        assertNull(op.put(Configuration.Key.copFactory, copFactory));
177        return op;
178    }
179
180    /**
181     * Instantiates the {@link #definition} field.
182     * It is caller's responsibility to set the parameter values.
183     *
184     * @throws FactoryException if an error occurred while creating the parameters.
185     */
186    @SuppressWarnings("null")
187    private void createDefaultParameters() throws FactoryException {
188        assumeNotNull(copFactory);
189        /*
190         * Get the OperationMethod defined by the library. Libraries are not required
191         * to implement every possible operation methods, in which case unimplemented
192         * methods will be reported. If the method is supported, then this method will
193         * verify the following properties:
194         *
195         *  - The number of source dimensions
196         *  - The number of target dimensions
197         *
198         * We currently do not verify the name because libraries often have their own
199         * hard-coded implementations of operation methods instead than creating new
200         * instances from the given properties.
201         */
202        try {
203            method = copFactory.getOperationMethod(methodName);
204        } catch (NoSuchIdentifierException e) {
205            unsupportedCode(OperationMethod.class, methodName);
206            throw e;
207        }
208        if (method == null) {
209            fail("CoordinateOperationFactory.getOperationMethod(\"" + methodName + "\") shall not return null.");
210        }
211        validators.validate(method);
212        assertEquals("OperationMethod.getSourceDimensions()", Integer.valueOf(2), method.getSourceDimensions());
213        assertEquals("OperationMethod.getTargetDimensions()", Integer.valueOf(2), method.getTargetDimensions());
214        definition = method.getParameters().createValue();
215    }
216
217    /**
218     * Returns the coordinate operation instance to be tested. When this method is invoked for the first time,
219     * it creates the coordinate operation to test by invoking the corresponding method from
220     * {@link CoordinateOperationFactory} with the current {@link #properties properties} map in argument.
221     * The created object is then cached and returned in all subsequent invocations of this method.
222     *
223     * @return the geodetic datum instance to test.
224     * @throws FactoryException if an error occurred while creating the coordinate operation instance.
225     */
226    @Override
227    @SuppressWarnings("null")
228    public Conversion getIdentifiedObject() throws FactoryException {
229        if (conversion == null) {
230            validators.validate(definition);
231            final CoordinateOperation operation = copFactory.createDefiningConversion(properties, method, definition);
232            if (operation != null) {  // For consistency with the behavior in other classes.
233                assertInstanceOf(getName(), Conversion.class, operation);
234                conversion = (Conversion) operation;
235            }
236        }
237        return conversion;
238    }
239
240    /**
241     * Verifies the properties of the conversion given by {@link #getIdentifiedObject()}.
242     */
243    final void verifyConversion() throws FactoryException {
244        if (skipTests) {
245            return;
246        }
247        final String name = getName();
248        final String code = getCode();
249        final Conversion conversion = getIdentifiedObject();
250        assertNotNull("Conversion", conversion);
251        validators.validate(conversion);
252        verifyIdentification(conversion, name, code);
253        /*
254         * Now verify the properties of the projection we just created. We require the parameter
255         * group to contain at least the values that we gave to it. If the library defines some
256         * additional parameters, then those extra parameters will be ignored.
257         */
258        final ParameterValueGroup projectionParameters = conversion.getParameterValues();
259        assertNotNull("Conversion.getParameterValues()", projectionParameters);
260        if (isFactoryPreservingUserValues) {
261            for (final GeneralParameterValue info : definition.values()) {
262                final String paramName = getName(info.getDescriptor());
263                if ("semi_major".equalsIgnoreCase(paramName) ||
264                    "semi_minor".equalsIgnoreCase(paramName))
265                {
266                    /*
267                     * Semi-major and semi-minor parameters were part of OGC 01-009 specification.
268                     * Since ISO 19111 they are not anymore explicit part of projection parameters.
269                     * However some implementations may still use them, so we make this test tolerant.
270                     */
271                    continue;
272                }
273                if (info instanceof ParameterValue<?>) {
274                    final ParameterValue<?> expected = (ParameterValue<?>) info;
275                    final ParameterValue<?> param = projectionParameters.parameter(paramName);
276                    assertNotNull(paramName, param);
277                    final double value = expected.doubleValue();
278                    assertEquals(paramName, value, param.doubleValue(expected.getUnit()), StrictMath.abs(TOLERANCE * value));
279                }
280            }
281        }
282    }
283
284    /**
285     * Tests “GIGS projection 1” conversion creation from the factory.
286     *
287     * <ul>
288     *   <li>GIGS conversion code: <b>65001</b></li>
289     *   <li>GIGS conversion name: <b>GIGS projection 1</b></li>
290     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
291     *   <li>EPSG equivalence: <b>16031 – UTM zone 31N</b></li>
292     * </ul>
293     * <table class="ogc">
294     *   <caption>Conversion parameters</caption>
295     *   <tr><th>Parameter name</th><th>Value</th></tr>
296     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
297     *   <tr><td>Longitude of natural origin</td><td>3°</td></tr>
298     *   <tr><td>Scale factor at natural origin</td><td>0.9996</td></tr>
299     *   <tr><td>False easting</td><td>500000 metres</td></tr>
300     *   <tr><td>False northing</td><td>0 metre</td></tr>
301     * </table>
302     *
303     * @throws FactoryException if an error occurred while creating the conversion from the properties.
304     *
305     * @see GIGS2005#testUTM()
306     */
307    @Test
308    public void testUTM_zone31N() throws FactoryException {
309        setCodeAndName(65001, "GIGS projection 1");
310        methodName = "Transverse Mercator";
311        createDefaultParameters();
312        final Unit<Angle> degree = units.degree();
313        final Unit<Length> metre = units.metre();
314        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
315        definition.parameter("Longitude of natural origin").setValue(3.0, degree);
316        definition.parameter("Scale factor at natural origin").setValue(0.9996, units.one());
317        definition.parameter("False easting").setValue(500000.0, metre);
318        definition.parameter("False northing").setValue(0.0, metre);
319        verifyConversion();
320    }
321
322    /**
323     * Tests “GIGS projection 2” conversion creation from the factory.
324     *
325     * <ul>
326     *   <li>GIGS conversion code: <b>65002</b></li>
327     *   <li>GIGS conversion name: <b>GIGS projection 2</b></li>
328     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
329     *   <li>EPSG equivalence: <b>19916 – British National Grid</b></li>
330     * </ul>
331     * <table class="ogc">
332     *   <caption>Conversion parameters</caption>
333     *   <tr><th>Parameter name</th><th>Value</th></tr>
334     *   <tr><td>Latitude of natural origin</td><td>49°</td></tr>
335     *   <tr><td>Longitude of natural origin</td><td>-2°</td></tr>
336     *   <tr><td>Scale factor at natural origin</td><td>0.999601272</td></tr>
337     *   <tr><td>False easting</td><td>400000 metres</td></tr>
338     *   <tr><td>False northing</td><td>-100000 metres</td></tr>
339     * </table>
340     *
341     * @throws FactoryException if an error occurred while creating the conversion from the properties.
342     *
343     * @see GIGS2005#testBritishNationalGrid()
344     */
345    @Test
346    public void testBritishNationalGrid() throws FactoryException {
347        setCodeAndName(65002, "GIGS projection 2");
348        methodName = "Transverse Mercator";
349        createDefaultParameters();
350        final Unit<Angle> degree = units.degree();
351        final Unit<Length> metre = units.metre();
352        definition.parameter("Latitude of natural origin").setValue(49.0, degree);
353        definition.parameter("Longitude of natural origin").setValue(-2.0, degree);
354        definition.parameter("Scale factor at natural origin").setValue(0.999601272, units.one());
355        definition.parameter("False easting").setValue(400000.0, metre);
356        definition.parameter("False northing").setValue(-100000.0, metre);
357        verifyConversion();
358    }
359
360    /**
361     * Tests “GIGS projection 2 alt A” conversion creation from the factory.
362     *
363     * <ul>
364     *   <li>GIGS conversion code: <b>65021</b></li>
365     *   <li>GIGS conversion name: <b>GIGS projection 2 alt A</b></li>
366     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
367     * </ul>
368     * <table class="ogc">
369     *   <caption>Conversion parameters</caption>
370     *   <tr><th>Parameter name</th><th>Value</th></tr>
371     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
372     *   <tr><td>Longitude of natural origin</td><td>-2°</td></tr>
373     *   <tr><td>Scale factor at natural origin</td><td>0.999601272</td></tr>
374     *   <tr><td>False easting</td><td>400000 metres</td></tr>
375     *   <tr><td>False northing</td><td>-5527462.688 metres</td></tr>
376     * </table>
377     *
378     * @throws FactoryException if an error occurred while creating the conversion from the properties.
379     */
380    @Test
381    public void testBritishNationalGrid_altA() throws FactoryException {
382        setCodeAndName(65021, "GIGS projection 2 alt A");
383        methodName = "Transverse Mercator";
384        createDefaultParameters();
385        final Unit<Angle> degree = units.degree();
386        final Unit<Length> metre = units.metre();
387        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
388        definition.parameter("Longitude of natural origin").setValue(-2.0, degree);
389        definition.parameter("Scale factor at natural origin").setValue(0.999601272, units.one());
390        definition.parameter("False easting").setValue(400000.0, metre);
391        definition.parameter("False northing").setValue(-5527462.688, metre);
392        verifyConversion();
393    }
394
395    /**
396     * Tests “GIGS projection 2 alt B” conversion creation from the factory.
397     *
398     * <ul>
399     *   <li>GIGS conversion code: <b>65022</b></li>
400     *   <li>GIGS conversion name: <b>GIGS projection 2 alt B</b></li>
401     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
402     * </ul>
403     * <table class="ogc">
404     *   <caption>Conversion parameters</caption>
405     *   <tr><th>Parameter name</th><th>Value</th></tr>
406     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
407     *   <tr><td>Longitude of natural origin</td><td>-2°</td></tr>
408     *   <tr><td>Scale factor at natural origin</td><td>0.999601272</td></tr>
409     *   <tr><td>False easting</td><td>400000 metres</td></tr>
410     *   <tr><td>False northing</td><td>-5527063.816 metres</td></tr>
411     * </table>
412     *
413     * @throws FactoryException if an error occurred while creating the conversion from the properties.
414     */
415    @Test
416    public void testBritishNationalGrid_altB() throws FactoryException {
417        setCodeAndName(65022, "GIGS projection 2 alt B");
418        methodName = "Transverse Mercator";
419        createDefaultParameters();
420        final Unit<Angle> degree = units.degree();
421        final Unit<Length> metre = units.metre();
422        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
423        definition.parameter("Longitude of natural origin").setValue(-2.0, degree);
424        definition.parameter("Scale factor at natural origin").setValue(0.999601272, units.one());
425        definition.parameter("False easting").setValue(400000.0, metre);
426        definition.parameter("False northing").setValue(-5527063.816, metre);
427        verifyConversion();
428    }
429
430    /**
431     * Tests “GIGS projection 4” conversion creation from the factory.
432     *
433     * <ul>
434     *   <li>GIGS conversion code: <b>65004</b></li>
435     *   <li>GIGS conversion name: <b>GIGS projection 4</b></li>
436     *   <li>EPSG operation method: <b>Oblique Stereographic</b></li>
437     *   <li>EPSG equivalence: <b>19914 – RD New</b></li>
438     * </ul>
439     * <table class="ogc">
440     *   <caption>Conversion parameters</caption>
441     *   <tr><th>Parameter name</th><th>Value</th></tr>
442     *   <tr><td>Latitude of natural origin</td><td>52°09'22.178N</td></tr>
443     *   <tr><td>Longitude of natural origin</td><td>5°23'15.5E</td></tr>
444     *   <tr><td>Scale factor at natural origin</td><td>0.9999079</td></tr>
445     *   <tr><td>False easting</td><td>155000 metres</td></tr>
446     *   <tr><td>False northing</td><td>463000 metres</td></tr>
447     * </table>
448     *
449     * @throws FactoryException if an error occurred while creating the conversion from the properties.
450     *
451     * @see GIGS2005#testRDNew()
452     */
453    @Test
454    public void testRDNew() throws FactoryException {
455        setCodeAndName(65004, "GIGS projection 4");
456        methodName = "Oblique Stereographic";
457        createDefaultParameters();
458        final Unit<Angle> degree = units.degree();
459        final Unit<Length> metre = units.metre();
460        definition.parameter("Latitude of natural origin").setValue(52.1561606, degree);
461        definition.parameter("Longitude of natural origin").setValue(5.3876389, degree);
462        definition.parameter("Scale factor at natural origin").setValue(0.9999079, units.one());
463        definition.parameter("False easting").setValue(155000.0, metre);
464        definition.parameter("False northing").setValue(463000.0, metre);
465        verifyConversion();
466    }
467
468    /**
469     * Tests “GIGS projection 5” conversion creation from the factory.
470     *
471     * <ul>
472     *   <li>GIGS conversion code: <b>65005</b></li>
473     *   <li>GIGS conversion name: <b>GIGS projection 5</b></li>
474     *   <li>EPSG operation method: <b>Mercator (1SP)</b></li>
475     * </ul>
476     * <table class="ogc">
477     *   <caption>Conversion parameters</caption>
478     *   <tr><th>Parameter name</th><th>Value</th></tr>
479     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
480     *   <tr><td>Longitude of natural origin</td><td>3°11'32.21E</td></tr>
481     *   <tr><td>Scale factor at natural origin</td><td>0.997</td></tr>
482     *   <tr><td>False easting</td><td>3900000 metres</td></tr>
483     *   <tr><td>False northing</td><td>900000 metres</td></tr>
484     * </table>
485     *
486     * @throws FactoryException if an error occurred while creating the conversion from the properties.
487     */
488    @Test
489    public void testGIGSProjection5() throws FactoryException {
490        setCodeAndName(65005, "GIGS projection 5");
491        methodName = "Mercator (1SP)";
492        createDefaultParameters();
493        final Unit<Angle> degree = units.degree();
494        final Unit<Length> metre = units.metre();
495        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
496        definition.parameter("Longitude of natural origin").setValue(3.1922806, degree);
497        definition.parameter("Scale factor at natural origin").setValue(0.997, units.one());
498        definition.parameter("False easting").setValue(3900000.0, metre);
499        definition.parameter("False northing").setValue(900000.0, metre);
500        verifyConversion();
501    }
502
503    /**
504     * Tests “GIGS projection 6” conversion creation from the factory.
505     *
506     * <ul>
507     *   <li>GIGS conversion code: <b>65006</b></li>
508     *   <li>GIGS conversion name: <b>GIGS projection 6</b></li>
509     *   <li>EPSG operation method: <b>Lambert Conic Conformal (2SP)</b></li>
510     *   <li>EPSG equivalence: <b>19961 – Belgian Lambert 72</b></li>
511     * </ul>
512     * <table class="ogc">
513     *   <caption>Conversion parameters</caption>
514     *   <tr><th>Parameter name</th><th>Value</th></tr>
515     *   <tr><td>Latitude of false origin</td><td>90°</td></tr>
516     *   <tr><td>Longitude of false origin</td><td>4°22'02.952E</td></tr>
517     *   <tr><td>Latitude of 1st standard parallel</td><td>51°10'00.00204N</td></tr>
518     *   <tr><td>Latitude of 2nd standard parallel</td><td>49°50'00.00204N</td></tr>
519     *   <tr><td>Easting at false origin</td><td>150000.013 metres</td></tr>
520     *   <tr><td>Northing at false origin</td><td>5400088.438 metres</td></tr>
521     * </table>
522     *
523     * @throws FactoryException if an error occurred while creating the conversion from the properties.
524     */
525    @Test
526    public void testBelgianLambert72() throws FactoryException {
527        setCodeAndName(65006, "GIGS projection 6");
528        methodName = "Lambert Conic Conformal (2SP)";
529        createDefaultParameters();
530        final Unit<Angle> degree = units.degree();
531        final Unit<Length> metre = units.metre();
532        definition.parameter("Latitude of false origin").setValue(90.0, degree);
533        definition.parameter("Longitude of false origin").setValue(4.3674867, degree);
534        definition.parameter("Latitude of 1st standard parallel").setValue(51.1666672, degree);
535        definition.parameter("Latitude of 2nd standard parallel").setValue(49.8333339, degree);
536        definition.parameter("Easting at false origin").setValue(150000.013, metre);
537        definition.parameter("Northing at false origin").setValue(5400088.438, metre);
538        verifyConversion();
539    }
540
541    /**
542     * Tests “GIGS projection 7” conversion creation from the factory.
543     *
544     * <ul>
545     *   <li>GIGS conversion code: <b>65007</b></li>
546     *   <li>GIGS conversion name: <b>GIGS projection 7</b></li>
547     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
548     *   <li>EPSG equivalence: <b>17454 – Australian Map Grid zone 54</b></li>
549     * </ul>
550     * <table class="ogc">
551     *   <caption>Conversion parameters</caption>
552     *   <tr><th>Parameter name</th><th>Value</th></tr>
553     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
554     *   <tr><td>Longitude of natural origin</td><td>141°</td></tr>
555     *   <tr><td>Scale factor at natural origin</td><td>0.9996</td></tr>
556     *   <tr><td>False easting</td><td>500000 metres</td></tr>
557     *   <tr><td>False northing</td><td>10000000 metres</td></tr>
558     * </table>
559     *
560     * @throws FactoryException if an error occurred while creating the conversion from the properties.
561     *
562     * @see GIGS2005#testAustralianMapGridZones()
563     */
564    @Test
565    public void testAustralianMapGridZone54() throws FactoryException {
566        setCodeAndName(65007, "GIGS projection 7");
567        methodName = "Transverse Mercator";
568        createDefaultParameters();
569        final Unit<Angle> degree = units.degree();
570        final Unit<Length> metre = units.metre();
571        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
572        definition.parameter("Longitude of natural origin").setValue(141.0, degree);
573        definition.parameter("Scale factor at natural origin").setValue(0.9996, units.one());
574        definition.parameter("False easting").setValue(500000.0, metre);
575        definition.parameter("False northing").setValue(1.0E7, metre);
576        verifyConversion();
577    }
578
579    /**
580     * Tests “GIGS projection 8” conversion creation from the factory.
581     *
582     * <ul>
583     *   <li>GIGS conversion code: <b>65008</b></li>
584     *   <li>GIGS conversion name: <b>GIGS projection 8</b></li>
585     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
586     *   <li>EPSG equivalence: <b>17455 – Australian Map Grid zone 55</b></li>
587     * </ul>
588     * <table class="ogc">
589     *   <caption>Conversion parameters</caption>
590     *   <tr><th>Parameter name</th><th>Value</th></tr>
591     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
592     *   <tr><td>Longitude of natural origin</td><td>147°</td></tr>
593     *   <tr><td>Scale factor at natural origin</td><td>0.9996</td></tr>
594     *   <tr><td>False easting</td><td>500000 metres</td></tr>
595     *   <tr><td>False northing</td><td>10000000 metres</td></tr>
596     * </table>
597     *
598     * @throws FactoryException if an error occurred while creating the conversion from the properties.
599     *
600     * @see GIGS2005#testAustralianMapGridZones()
601     */
602    @Test
603    public void testAustralianMapGridZone55() throws FactoryException {
604        setCodeAndName(65008, "GIGS projection 8");
605        methodName = "Transverse Mercator";
606        createDefaultParameters();
607        final Unit<Angle> degree = units.degree();
608        final Unit<Length> metre = units.metre();
609        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
610        definition.parameter("Longitude of natural origin").setValue(147.0, degree);
611        definition.parameter("Scale factor at natural origin").setValue(0.9996, units.one());
612        definition.parameter("False easting").setValue(500000.0, metre);
613        definition.parameter("False northing").setValue(1.0E7, metre);
614        verifyConversion();
615    }
616
617    /**
618     * Tests “GIGS projection 9” conversion creation from the factory.
619     *
620     * <ul>
621     *   <li>GIGS conversion code: <b>65009</b></li>
622     *   <li>GIGS conversion name: <b>GIGS projection 9</b></li>
623     *   <li>EPSG operation method: <b>Albers Equal Area</b></li>
624     *   <li>EPSG equivalence: <b>17365 – Australian Albers</b></li>
625     * </ul>
626     * <table class="ogc">
627     *   <caption>Conversion parameters</caption>
628     *   <tr><th>Parameter name</th><th>Value</th></tr>
629     *   <tr><td>Latitude of false origin</td><td>0°</td></tr>
630     *   <tr><td>Longitude of false origin</td><td>132°</td></tr>
631     *   <tr><td>Latitude of 1st standard parallel</td><td>-18°</td></tr>
632     *   <tr><td>Latitude of 2nd standard parallel</td><td>-36°</td></tr>
633     *   <tr><td>Easting at false origin</td><td>0 metre</td></tr>
634     *   <tr><td>Northing at false origin</td><td>0 metre</td></tr>
635     * </table>
636     *
637     * @throws FactoryException if an error occurred while creating the conversion from the properties.
638     */
639    @Test
640    public void testAustralianAlbers() throws FactoryException {
641        setCodeAndName(65009, "GIGS projection 9");
642        methodName = "Albers Equal Area";
643        createDefaultParameters();
644        final Unit<Angle> degree = units.degree();
645        final Unit<Length> metre = units.metre();
646        definition.parameter("Latitude of false origin").setValue(0.0, degree);
647        definition.parameter("Longitude of false origin").setValue(132.0, degree);
648        definition.parameter("Latitude of 1st standard parallel").setValue(-18.0, degree);
649        definition.parameter("Latitude of 2nd standard parallel").setValue(-36.0, degree);
650        definition.parameter("Easting at false origin").setValue(0.0, metre);
651        definition.parameter("Northing at false origin").setValue(0.0, metre);
652        verifyConversion();
653    }
654
655    /**
656     * Tests “GIGS projection 10” conversion creation from the factory.
657     *
658     * <ul>
659     *   <li>GIGS conversion code: <b>65010</b></li>
660     *   <li>GIGS conversion name: <b>GIGS projection 10</b></li>
661     *   <li>EPSG operation method: <b>Transverse Mercator (South Orientated)</b></li>
662     *   <li>EPSG equivalence: <b>17521 – South African Survey Grid zone 21</b></li>
663     * </ul>
664     * <table class="ogc">
665     *   <caption>Conversion parameters</caption>
666     *   <tr><th>Parameter name</th><th>Value</th></tr>
667     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
668     *   <tr><td>Longitude of natural origin</td><td>21°</td></tr>
669     *   <tr><td>Scale factor at natural origin</td><td>1</td></tr>
670     *   <tr><td>False easting</td><td>0 metre</td></tr>
671     *   <tr><td>False northing</td><td>0 metre</td></tr>
672     * </table>
673     *
674     * @throws FactoryException if an error occurred while creating the conversion from the properties.
675     */
676    @Test
677    public void testSouthAfricanSurveyGridZone21() throws FactoryException {
678        setCodeAndName(65010, "GIGS projection 10");
679        methodName = "Transverse Mercator (South Orientated)";
680        createDefaultParameters();
681        final Unit<Angle> degree = units.degree();
682        final Unit<Length> metre = units.metre();
683        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
684        definition.parameter("Longitude of natural origin").setValue(21.0, degree);
685        definition.parameter("Scale factor at natural origin").setValue(1.0, units.one());
686        definition.parameter("False easting").setValue(0.0, metre);
687        definition.parameter("False northing").setValue(0.0, metre);
688        verifyConversion();
689    }
690
691    /**
692     * Tests “GIGS projection 11” conversion creation from the factory.
693     *
694     * <ul>
695     *   <li>GIGS conversion code: <b>65011</b></li>
696     *   <li>GIGS conversion name: <b>GIGS projection 11</b></li>
697     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
698     *   <li>EPSG equivalence: <b>18035 – Argentina zone 5</b></li>
699     * </ul>
700     * <table class="ogc">
701     *   <caption>Conversion parameters</caption>
702     *   <tr><th>Parameter name</th><th>Value</th></tr>
703     *   <tr><td>Latitude of natural origin</td><td>-90°</td></tr>
704     *   <tr><td>Longitude of natural origin</td><td>-60°</td></tr>
705     *   <tr><td>Scale factor at natural origin</td><td>1</td></tr>
706     *   <tr><td>False easting</td><td>5500000 metres</td></tr>
707     *   <tr><td>False northing</td><td>0 metre</td></tr>
708     * </table>
709     *
710     * @throws FactoryException if an error occurred while creating the conversion from the properties.
711     *
712     * @see GIGS2005#testArgentinaZones()
713     */
714    @Test
715    public void testArgentinaZone5() throws FactoryException {
716        setCodeAndName(65011, "GIGS projection 11");
717        methodName = "Transverse Mercator";
718        createDefaultParameters();
719        final Unit<Angle> degree = units.degree();
720        final Unit<Length> metre = units.metre();
721        definition.parameter("Latitude of natural origin").setValue(-90.0, degree);
722        definition.parameter("Longitude of natural origin").setValue(-60.0, degree);
723        definition.parameter("Scale factor at natural origin").setValue(1.0, units.one());
724        definition.parameter("False easting").setValue(5500000.0, metre);
725        definition.parameter("False northing").setValue(0.0, metre);
726        verifyConversion();
727    }
728
729    /**
730     * Tests “GIGS projection 12” conversion creation from the factory.
731     *
732     * <ul>
733     *   <li>GIGS conversion code: <b>65012</b></li>
734     *   <li>GIGS conversion name: <b>GIGS projection 12</b></li>
735     *   <li>EPSG operation method: <b>American Polyconic</b></li>
736     *   <li>EPSG equivalence: <b>19941 – Brazil Polyconic</b></li>
737     * </ul>
738     * <table class="ogc">
739     *   <caption>Conversion parameters</caption>
740     *   <tr><th>Parameter name</th><th>Value</th></tr>
741     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
742     *   <tr><td>Longitude of natural origin</td><td>-54°</td></tr>
743     *   <tr><td>False easting</td><td>5000000 metres</td></tr>
744     *   <tr><td>False northing</td><td>10000000 metres</td></tr>
745     * </table>
746     *
747     * @throws FactoryException if an error occurred while creating the conversion from the properties.
748     *
749     * @see GIGS2005#testBrazilPolyconic()
750     */
751    @Test
752    public void testBrazilPolyconic() throws FactoryException {
753        setCodeAndName(65012, "GIGS projection 12");
754        methodName = "American Polyconic";
755        createDefaultParameters();
756        final Unit<Angle> degree = units.degree();
757        final Unit<Length> metre = units.metre();
758        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
759        definition.parameter("Longitude of natural origin").setValue(-54.0, degree);
760        definition.parameter("False easting").setValue(5000000.0, metre);
761        definition.parameter("False northing").setValue(1.0E7, metre);
762        verifyConversion();
763    }
764
765    /**
766     * Tests “GIGS projection 13” conversion creation from the factory.
767     *
768     * <ul>
769     *   <li>GIGS conversion code: <b>65013</b></li>
770     *   <li>GIGS conversion name: <b>GIGS projection 13</b></li>
771     *   <li>EPSG operation method: <b>Hotine Oblique Mercator (variant B)</b></li>
772     *   <li>Specific usage / Remarks: <b>metre</b></li>
773     * </ul>
774     * <table class="ogc">
775     *   <caption>Conversion parameters</caption>
776     *   <tr><th>Parameter name</th><th>Value</th></tr>
777     *   <tr><td>Latitude of projection centre</td><td>4°</td></tr>
778     *   <tr><td>Longitude of projection centre</td><td>115°</td></tr>
779     *   <tr><td>Azimuth of initial line</td><td>53°18'56.9158</td></tr>
780     *   <tr><td>Angle from Rectified to Skew Grid</td><td>53°07'48.3685</td></tr>
781     *   <tr><td>Scale factor on initial line</td><td>0.99984</td></tr>
782     *   <tr><td>Easting at projection centre</td><td>590521.147 metres</td></tr>
783     *   <tr><td>Northing at projection centre</td><td>442890.861 metres</td></tr>
784     * </table>
785     *
786     * @throws FactoryException if an error occurred while creating the conversion from the properties.
787     */
788    @Test
789    public void testGIGSProjection13() throws FactoryException {
790        setCodeAndName(65013, "GIGS projection 13");
791        methodName = "Hotine Oblique Mercator (variant B)";
792        createDefaultParameters();
793        final Unit<Angle> degree = units.degree();
794        final Unit<Length> metre = units.metre();
795        definition.parameter("Latitude of projection centre").setValue(4.0, degree);
796        definition.parameter("Longitude of projection centre").setValue(115.0, degree);
797        definition.parameter("Azimuth of initial line").setValue(53.3158099, degree);
798        definition.parameter("Angle from Rectified to Skew Grid").setValue(53.1301024, degree);
799        definition.parameter("Scale factor on initial line").setValue(0.99984, units.one());
800        definition.parameter("Easting at projection centre").setValue(590521.147, metre);
801        definition.parameter("Northing at projection centre").setValue(442890.861, metre);
802        verifyConversion();
803    }
804
805    /**
806     * Tests “GIGS projection 14” conversion creation from the factory.
807     *
808     * <ul>
809     *   <li>GIGS conversion code: <b>65014</b></li>
810     *   <li>GIGS conversion name: <b>GIGS projection 14</b></li>
811     *   <li>EPSG operation method: <b>Hotine Oblique Mercator (variant A)</b></li>
812     *   <li>EPSG equivalence: <b>19894 – East Malaysia BRSO</b></li>
813     *   <li>Specific usage / Remarks: <b>metre</b></li>
814     * </ul>
815     * <table class="ogc">
816     *   <caption>Conversion parameters</caption>
817     *   <tr><th>Parameter name</th><th>Value</th></tr>
818     *   <tr><td>Latitude of projection centre</td><td>4°</td></tr>
819     *   <tr><td>Longitude of projection centre</td><td>115°</td></tr>
820     *   <tr><td>Azimuth of initial line</td><td>53°18'56.9158</td></tr>
821     *   <tr><td>Angle from Rectified to Skew Grid</td><td>53°07'48.3685</td></tr>
822     *   <tr><td>Scale factor on initial line</td><td>0.99984</td></tr>
823     *   <tr><td>False easting</td><td>0 metre</td></tr>
824     *   <tr><td>False northing</td><td>0 metre</td></tr>
825     * </table>
826     *
827     * @throws FactoryException if an error occurred while creating the conversion from the properties.
828     */
829    @Test
830    public void testEastMalaysia() throws FactoryException {
831        setCodeAndName(65014, "GIGS projection 14");
832        methodName = "Hotine Oblique Mercator (variant A)";
833        createDefaultParameters();
834        final Unit<Angle> degree = units.degree();
835        final Unit<Length> metre = units.metre();
836        definition.parameter("Latitude of projection centre").setValue(4.0, degree);
837        definition.parameter("Longitude of projection centre").setValue(115.0, degree);
838        definition.parameter("Azimuth of initial line").setValue(53.3158099, degree);
839        definition.parameter("Angle from Rectified to Skew Grid").setValue(53.1301024, degree);
840        definition.parameter("Scale factor on initial line").setValue(0.99984, units.one());
841        definition.parameter("False easting").setValue(0.0, metre);
842        definition.parameter("False northing").setValue(0.0, metre);
843        verifyConversion();
844    }
845
846    /**
847     * Tests “GIGS projection 15” conversion creation from the factory.
848     *
849     * <ul>
850     *   <li>GIGS conversion code: <b>65015</b></li>
851     *   <li>GIGS conversion name: <b>GIGS projection 15</b></li>
852     *   <li>EPSG operation method: <b>Cassini-Soldner</b></li>
853     *   <li>EPSG equivalence: <b>19893 – Johor Grid</b></li>
854     * </ul>
855     * <table class="ogc">
856     *   <caption>Conversion parameters</caption>
857     *   <tr><th>Parameter name</th><th>Value</th></tr>
858     *   <tr><td>Latitude of natural origin</td><td>2°07'18.0471N</td></tr>
859     *   <tr><td>Longitude of natural origin</td><td>103°25'40.5704E</td></tr>
860     *   <tr><td>False easting</td><td>-14810.562 metres</td></tr>
861     *   <tr><td>False northing</td><td>8758.32 metres</td></tr>
862     * </table>
863     *
864     * @throws FactoryException if an error occurred while creating the conversion from the properties.
865     */
866    @Test
867    public void testJohorGrid() throws FactoryException {
868        setCodeAndName(65015, "GIGS projection 15");
869        methodName = "Cassini-Soldner";
870        createDefaultParameters();
871        final Unit<Angle> degree = units.degree();
872        final Unit<Length> metre = units.metre();
873        definition.parameter("Latitude of natural origin").setValue(2.1216797, degree);
874        definition.parameter("Longitude of natural origin").setValue(103.4279361, degree);
875        definition.parameter("False easting").setValue(-14810.562, metre);
876        definition.parameter("False northing").setValue(8758.32, metre);
877        verifyConversion();
878    }
879
880    /**
881     * Tests “GIGS projection 16” conversion creation from the factory.
882     *
883     * <ul>
884     *   <li>GIGS conversion code: <b>65016</b></li>
885     *   <li>GIGS conversion name: <b>GIGS projection 16</b></li>
886     *   <li>EPSG operation method: <b>Lambert Azimuthal Equal Area</b></li>
887     *   <li>EPSG equivalence: <b>19986 – Europe Equal Area 2001</b></li>
888     * </ul>
889     * <table class="ogc">
890     *   <caption>Conversion parameters</caption>
891     *   <tr><th>Parameter name</th><th>Value</th></tr>
892     *   <tr><td>Latitude of natural origin</td><td>52°</td></tr>
893     *   <tr><td>Longitude of natural origin</td><td>10°</td></tr>
894     *   <tr><td>False easting</td><td>4321000 metres</td></tr>
895     *   <tr><td>False northing</td><td>3210000 metres</td></tr>
896     * </table>
897     *
898     * @throws FactoryException if an error occurred while creating the conversion from the properties.
899     */
900    @Test
901    public void testEuropeEqualArea() throws FactoryException {
902        setCodeAndName(65016, "GIGS projection 16");
903        methodName = "Lambert Azimuthal Equal Area";
904        createDefaultParameters();
905        final Unit<Angle> degree = units.degree();
906        final Unit<Length> metre = units.metre();
907        definition.parameter("Latitude of natural origin").setValue(52.0, degree);
908        definition.parameter("Longitude of natural origin").setValue(10.0, degree);
909        definition.parameter("False easting").setValue(4321000.0, metre);
910        definition.parameter("False northing").setValue(3210000.0, metre);
911        verifyConversion();
912    }
913
914    /**
915     * Tests “GIGS projection 17” conversion creation from the factory.
916     *
917     * <ul>
918     *   <li>GIGS conversion code: <b>65017</b></li>
919     *   <li>GIGS conversion name: <b>GIGS projection 17</b></li>
920     *   <li>EPSG operation method: <b>Lambert Conic Conformal (2SP)</b></li>
921     *   <li>EPSG equivalence: <b>15262 – Utah North (ft)</b></li>
922     * </ul>
923     * <table class="ogc">
924     *   <caption>Conversion parameters</caption>
925     *   <tr><th>Parameter name</th><th>Value</th></tr>
926     *   <tr><td>Latitude of false origin</td><td>40°20'N</td></tr>
927     *   <tr><td>Longitude of false origin</td><td>111°30'W</td></tr>
928     *   <tr><td>Latitude of 1st standard parallel</td><td>41°47'N</td></tr>
929     *   <tr><td>Latitude of 2nd standard parallel</td><td>40°43'N</td></tr>
930     *   <tr><td>Easting at false origin</td><td>1640419.948 foots</td></tr>
931     *   <tr><td>Northing at false origin</td><td>3280839.895 foots</td></tr>
932     * </table>
933     *
934     * @throws FactoryException if an error occurred while creating the conversion from the properties.
935     */
936    @Test
937    public void testUtahNorth() throws FactoryException {
938        setCodeAndName(65017, "GIGS projection 17");
939        methodName = "Lambert Conic Conformal (2SP)";
940        createDefaultParameters();
941        final Unit<Angle> degree = units.degree();
942        final Unit<Length> foot = units.foot();
943        definition.parameter("Latitude of false origin").setValue(40.3333333, degree);
944        definition.parameter("Longitude of false origin").setValue(-111.5, degree);
945        definition.parameter("Latitude of 1st standard parallel").setValue(41.7833333, degree);
946        definition.parameter("Latitude of 2nd standard parallel").setValue(40.7166667, degree);
947        definition.parameter("Easting at false origin").setValue(1640419.948, foot);
948        definition.parameter("Northing at false origin").setValue(3280839.895, foot);
949        verifyConversion();
950    }
951
952    /**
953     * Tests “GIGS projection 18” conversion creation from the factory.
954     *
955     * <ul>
956     *   <li>GIGS conversion code: <b>65018</b></li>
957     *   <li>GIGS conversion name: <b>GIGS projection 18</b></li>
958     *   <li>EPSG operation method: <b>Lambert Conic Conformal (2SP)</b></li>
959     *   <li>EPSG equivalence: <b>15297 – Utah North (ftUS)</b></li>
960     * </ul>
961     * <table class="ogc">
962     *   <caption>Conversion parameters</caption>
963     *   <tr><th>Parameter name</th><th>Value</th></tr>
964     *   <tr><td>Latitude of false origin</td><td>40°20'N</td></tr>
965     *   <tr><td>Longitude of false origin</td><td>111°30'W</td></tr>
966     *   <tr><td>Latitude of 1st standard parallel</td><td>41°47'N</td></tr>
967     *   <tr><td>Latitude of 2nd standard parallel</td><td>40°43'N</td></tr>
968     *   <tr><td>Easting at false origin</td><td>1640416.667 US survey foots</td></tr>
969     *   <tr><td>Northing at false origin</td><td>3280833.333 US survey foots</td></tr>
970     * </table>
971     *
972     * @throws FactoryException if an error occurred while creating the conversion from the properties.
973     */
974    @Test
975    public void testUtahNorth_ftUS() throws FactoryException {
976        setCodeAndName(65018, "GIGS projection 18");
977        methodName = "Lambert Conic Conformal (2SP)";
978        createDefaultParameters();
979        final Unit<Angle> degree = units.degree();
980        final Unit<Length> footSurveyUS = units.footSurveyUS();
981        definition.parameter("Latitude of false origin").setValue(40.3333333, degree);
982        definition.parameter("Longitude of false origin").setValue(-111.5, degree);
983        definition.parameter("Latitude of 1st standard parallel").setValue(41.7833333, degree);
984        definition.parameter("Latitude of 2nd standard parallel").setValue(40.7166667, degree);
985        definition.parameter("Easting at false origin").setValue(1640416.667, footSurveyUS);
986        definition.parameter("Northing at false origin").setValue(3280833.333, footSurveyUS);
987        verifyConversion();
988    }
989
990    /**
991     * Tests “GIGS projection 19” conversion creation from the factory.
992     *
993     * <ul>
994     *   <li>GIGS conversion code: <b>65019</b></li>
995     *   <li>GIGS conversion name: <b>GIGS projection 19</b></li>
996     *   <li>EPSG operation method: <b>Lambert Conic Conformal (1SP)</b></li>
997     *   <li>EPSG equivalence: <b>18082 – Lambert zone II</b></li>
998     * </ul>
999     * <table class="ogc">
1000     *   <caption>Conversion parameters</caption>
1001     *   <tr><th>Parameter name</th><th>Value</th></tr>
1002     *   <tr><td>Latitude of natural origin</td><td>52 grads</td></tr>
1003     *   <tr><td>Longitude of natural origin</td><td>0 grad</td></tr>
1004     *   <tr><td>Scale factor at natural origin</td><td>0.99987742</td></tr>
1005     *   <tr><td>False easting</td><td>600000 metres</td></tr>
1006     *   <tr><td>False northing</td><td>2200000 metres</td></tr>
1007     * </table>
1008     *
1009     * @throws FactoryException if an error occurred while creating the conversion from the properties.
1010     */
1011    @Test
1012    public void testLambertZoneII() throws FactoryException {
1013        setCodeAndName(65019, "GIGS projection 19");
1014        methodName = "Lambert Conic Conformal (1SP)";
1015        createDefaultParameters();
1016        final Unit<Angle>  grad  = units.grad();
1017        final Unit<Length> metre = units.metre();
1018        definition.parameter("Latitude of natural origin").setValue(52.0, grad);
1019        definition.parameter("Longitude of natural origin").setValue(0.0, grad);
1020        definition.parameter("Scale factor at natural origin").setValue(0.99987742, units.one());
1021        definition.parameter("False easting").setValue(600000.0, metre);
1022        definition.parameter("False northing").setValue(2200000.0, metre);
1023        verifyConversion();
1024    }
1025
1026    /**
1027     * Tests “GIGS projection 23” conversion creation from the factory.
1028     *
1029     * <ul>
1030     *   <li>GIGS conversion code: <b>65023</b></li>
1031     *   <li>GIGS conversion name: <b>GIGS projection 23</b></li>
1032     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
1033     *   <li>EPSG equivalence: <b>No direct equivalent</b></li>
1034     * </ul>
1035     * <table class="ogc">
1036     *   <caption>Conversion parameters</caption>
1037     *   <tr><th>Parameter name</th><th>Value</th></tr>
1038     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
1039     *   <tr><td>Longitude of natural origin</td><td>3°</td></tr>
1040     *   <tr><td>Scale factor at natural origin</td><td>0.9996</td></tr>
1041     *   <tr><td>False easting</td><td>1640416.667 US survey foots</td></tr>
1042     *   <tr><td>False northing</td><td>0 US survey foot</td></tr>
1043     * </table>
1044     *
1045     * @throws FactoryException if an error occurred while creating the conversion from the properties.
1046     */
1047    @Test
1048    public void testGIGSProjection23() throws FactoryException {
1049        setCodeAndName(65023, "GIGS projection 23");
1050        methodName = "Transverse Mercator";
1051        createDefaultParameters();
1052        final Unit<Angle> degree = units.degree();
1053        final Unit<Length> footSurveyUS = units.footSurveyUS();
1054        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
1055        definition.parameter("Longitude of natural origin").setValue(3.0, degree);
1056        definition.parameter("Scale factor at natural origin").setValue(0.9996, units.one());
1057        definition.parameter("False easting").setValue(1640416.667, footSurveyUS);
1058        definition.parameter("False northing").setValue(0.0, footSurveyUS);
1059        verifyConversion();
1060    }
1061
1062    /**
1063     * Tests “GIGS projection 24” conversion creation from the factory.
1064     *
1065     * <ul>
1066     *   <li>GIGS conversion code: <b>65024</b></li>
1067     *   <li>GIGS conversion name: <b>GIGS projection 24</b></li>
1068     *   <li>EPSG operation method: <b>Mercator (Variant B)</b></li>
1069     *   <li>EPSG equivalence: <b>19884 – Caspian Sea Mercator</b></li>
1070     * </ul>
1071     * <table class="ogc">
1072     *   <caption>Conversion parameters</caption>
1073     *   <tr><th>Parameter name</th><th>Value</th></tr>
1074     *   <tr><td>Latitude of 1st standard parallel</td><td>42°</td></tr>
1075     *   <tr><td>Longitude of natural origin</td><td>51°</td></tr>
1076     *   <tr><td>False easting</td><td>0 metre</td></tr>
1077     *   <tr><td>False northing</td><td>0 metre</td></tr>
1078     * </table>
1079     *
1080     * @throws FactoryException if an error occurred while creating the conversion from the properties.
1081     */
1082    @Test
1083    public void testCaspianSeaMercator() throws FactoryException {
1084        setCodeAndName(65024, "GIGS projection 24");
1085        methodName = "Mercator (Variant B)";
1086        createDefaultParameters();
1087        final Unit<Angle> degree = units.degree();
1088        final Unit<Length> metre = units.metre();
1089        definition.parameter("Latitude of 1st standard parallel").setValue(42.0, degree);
1090        definition.parameter("Longitude of natural origin").setValue(51.0, degree);
1091        definition.parameter("False easting").setValue(0.0, metre);
1092        definition.parameter("False northing").setValue(0.0, metre);
1093        verifyConversion();
1094    }
1095
1096    /**
1097     * Tests “GIGS projection 25” conversion creation from the factory.
1098     *
1099     * <ul>
1100     *   <li>GIGS conversion code: <b>65025</b></li>
1101     *   <li>GIGS conversion name: <b>GIGS projection 25</b></li>
1102     *   <li>EPSG operation method: <b>Lambert Conic Conformal (1SP)</b></li>
1103     *   <li>EPSG equivalence: <b>18086 – France EuroLambert</b></li>
1104     * </ul>
1105     * <table class="ogc">
1106     *   <caption>Conversion parameters</caption>
1107     *   <tr><th>Parameter name</th><th>Value</th></tr>
1108     *   <tr><td>Latitude of natural origin</td><td>46°48'N</td></tr>
1109     *   <tr><td>Longitude of natural origin</td><td>2°20'14.025E</td></tr>
1110     *   <tr><td>Scale factor at natural origin</td><td>0.99987742</td></tr>
1111     *   <tr><td>False easting</td><td>600000 metres</td></tr>
1112     *   <tr><td>False northing</td><td>2200000 metres</td></tr>
1113     * </table>
1114     *
1115     * @throws FactoryException if an error occurred while creating the conversion from the properties.
1116     */
1117    @Test
1118    public void testFranceEuroLambert() throws FactoryException {
1119        setCodeAndName(65025, "GIGS projection 25");
1120        methodName = "Lambert Conic Conformal (1SP)";
1121        createDefaultParameters();
1122        final Unit<Angle> degree = units.degree();
1123        final Unit<Length> metre = units.metre();
1124        definition.parameter("Latitude of natural origin").setValue(46.8, degree);
1125        definition.parameter("Longitude of natural origin").setValue(2.3372292, degree);
1126        definition.parameter("Scale factor at natural origin").setValue(0.99987742, units.one());
1127        definition.parameter("False easting").setValue(600000.0, metre);
1128        definition.parameter("False northing").setValue(2200000.0, metre);
1129        verifyConversion();
1130    }
1131
1132    /**
1133     * Tests “GIGS projection 26” conversion creation from the factory.
1134     *
1135     * <ul>
1136     *   <li>GIGS conversion code: <b>65026</b></li>
1137     *   <li>GIGS conversion name: <b>GIGS projection 26</b></li>
1138     *   <li>EPSG operation method: <b>Hotine Oblique Mercator (variant B)</b></li>
1139     *   <li>EPSG equivalence: <b>19931 – EOV</b></li>
1140     *   <li>Specific usage / Remarks: <b>metre</b></li>
1141     * </ul>
1142     * <table class="ogc">
1143     *   <caption>Conversion parameters</caption>
1144     *   <tr><th>Parameter name</th><th>Value</th></tr>
1145     *   <tr><td>Latitude of projection centre</td><td>47°08'39.8174N</td></tr>
1146     *   <tr><td>Longitude of projection centre</td><td>19°02'54.8584E</td></tr>
1147     *   <tr><td>Azimuth of initial line</td><td>90°</td></tr>
1148     *   <tr><td>Angle from Rectified to Skew Grid</td><td>90°</td></tr>
1149     *   <tr><td>Scale factor on initial line</td><td>0.99993</td></tr>
1150     *   <tr><td>Easting at projection centre</td><td>650000 metres</td></tr>
1151     *   <tr><td>Northing at projection centre</td><td>200000 metres</td></tr>
1152     * </table>
1153     *
1154     * @throws FactoryException if an error occurred while creating the conversion from the properties.
1155     *
1156     * @see GIGS2005#testEOV()
1157     */
1158    @Test
1159    public void testEOV() throws FactoryException {
1160        setCodeAndName(65026, "GIGS projection 26");
1161        methodName = "Hotine Oblique Mercator (variant B)";
1162        createDefaultParameters();
1163        final Unit<Angle> degree = units.degree();
1164        final Unit<Length> metre = units.metre();
1165        definition.parameter("Latitude of projection centre").setValue(47.14439372222222, degree);
1166        definition.parameter("Longitude of projection centre").setValue(19.048571777777777, degree);
1167        definition.parameter("Azimuth of initial line").setValue(90.0, degree);
1168        definition.parameter("Angle from Rectified to Skew Grid").setValue(90.0, degree);
1169        definition.parameter("Scale factor on initial line").setValue(0.99993, units.one());
1170        definition.parameter("Easting at projection centre").setValue(650000.0, metre);
1171        definition.parameter("Northing at projection centre").setValue(200000.0, metre);
1172        verifyConversion();
1173    }
1174
1175    /**
1176     * Tests “GIGS projection 27” conversion creation from the factory.
1177     *
1178     * <ul>
1179     *   <li>GIGS conversion code: <b>65027</b></li>
1180     *   <li>GIGS conversion name: <b>GIGS projection 27</b></li>
1181     *   <li>EPSG operation method: <b>Mercator (variant A)</b></li>
1182     *   <li>EPSG equivalence: <b>19905 – NEIEZ</b></li>
1183     * </ul>
1184     * <table class="ogc">
1185     *   <caption>Conversion parameters</caption>
1186     *   <tr><th>Parameter name</th><th>Value</th></tr>
1187     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
1188     *   <tr><td>Longitude of natural origin</td><td>110°</td></tr>
1189     *   <tr><td>Scale factor at natural origin</td><td>0.997</td></tr>
1190     *   <tr><td>False easting</td><td>3900000 metres</td></tr>
1191     *   <tr><td>False northing</td><td>900000 metres</td></tr>
1192     * </table>
1193     *
1194     * @throws FactoryException if an error occurred while creating the conversion from the properties.
1195     *
1196     * @see GIGS2005#testNEIEZ()
1197     */
1198    @Test
1199    public void testNEIEZ() throws FactoryException {
1200        setCodeAndName(65027, "GIGS projection 27");
1201        methodName = "Mercator (variant A)";
1202        createDefaultParameters();
1203        final Unit<Angle> degree = units.degree();
1204        final Unit<Length> metre = units.metre();
1205        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
1206        definition.parameter("Longitude of natural origin").setValue(110.0, degree);
1207        definition.parameter("Scale factor at natural origin").setValue(0.997, units.one());
1208        definition.parameter("False easting").setValue(3900000.0, metre);
1209        definition.parameter("False northing").setValue(900000.0, metre);
1210        verifyConversion();
1211    }
1212
1213    /**
1214     * Tests “GIGS projection 28” conversion creation from the factory.
1215     *
1216     * <ul>
1217     *   <li>GIGS conversion code: <b>65028</b></li>
1218     *   <li>GIGS conversion name: <b>GIGS projection 28</b></li>
1219     *   <li>EPSG operation method: <b>Transverse Mercator</b></li>
1220     *   <li>EPSG equivalence: <b>16008 – UTM zone 8N</b></li>
1221     * </ul>
1222     * <table class="ogc">
1223     *   <caption>Conversion parameters</caption>
1224     *   <tr><th>Parameter name</th><th>Value</th></tr>
1225     *   <tr><td>Latitude of natural origin</td><td>0°</td></tr>
1226     *   <tr><td>Longitude of natural origin</td><td>-135°</td></tr>
1227     *   <tr><td>Scale factor at natural origin</td><td>0.9996</td></tr>
1228     *   <tr><td>False easting</td><td>500000 metres</td></tr>
1229     *   <tr><td>False northing</td><td>0 metre</td></tr>
1230     * </table>
1231     *
1232     * @throws FactoryException if an error occurred while creating the conversion from the properties.
1233     *
1234     * @see GIGS2005#testUTM()
1235     */
1236    @Test
1237    public void testUTM_zone8N() throws FactoryException {
1238        setCodeAndName(65028, "GIGS projection 28");
1239        methodName = "Transverse Mercator";
1240        createDefaultParameters();
1241        final Unit<Angle> degree = units.degree();
1242        final Unit<Length> metre = units.metre();
1243        definition.parameter("Latitude of natural origin").setValue(0.0, degree);
1244        definition.parameter("Longitude of natural origin").setValue(-135.0, degree);
1245        definition.parameter("Scale factor at natural origin").setValue(0.9996, units.one());
1246        definition.parameter("False easting").setValue(500000.0, metre);
1247        definition.parameter("False northing").setValue(0.0, metre);
1248        verifyConversion();
1249    }
1250}