sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1709179 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/projection/ test/java/org/apache/sis/referencing/operation/projection/
Date Sat, 17 Oct 2015 14:22:58 GMT
Author: desruisseaux
Date: Sat Oct 17 14:22:57 2015
New Revision: 1709179

URL: http://svn.apache.org/viewvc?rev=1709179&view=rev
Log:
Rearrange oblique stereographic tests for more uniformity with other tests.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/InitializerTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java?rev=1709179&r1=1709178&r2=1709179&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Initializer.java
[UTF-8] Sat Oct 17 14:22:57 2015
@@ -321,9 +321,9 @@ final class Initializer {
      */
     final double radiusOfConformalSphere(final double sinφ) {
         final DoubleDouble Rc = verbatim(1);
-        Rc.subtract(excentricitySquared);   //-- 1 - ℯ²
-        Rc.sqrt();                          //-- √(1 - ℯ²)
-        Rc.divide(rν2(sinφ));               //-- √(1 - ℯ²) / (1 - ℯ²sin²φ)
+        Rc.subtract(excentricitySquared);       //  1 - ℯ²
+        Rc.sqrt();                              //  √(1 - ℯ²)
+        Rc.divide(rν2(sinφ));                   //  √(1 - ℯ²) / (1 - ℯ²sin²φ)
         return Rc.value;
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java?rev=1709179&r1=1709178&r2=1709179&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
[UTF-8] Sat Oct 17 14:22:57 2015
@@ -40,15 +40,12 @@ import static org.apache.sis.internal.re
  *
  * <div class="section">References</div>
  * <ul>
- *   <li>{@code libproj4} is available at
- *       <a href = http://www.iogp.org/pubs/373-07-2.pdf>EPSG guide</a>.<br>
- *        Relevant files are: {@code PJ_sterea.c}, {@code pj_gauss.c},
- *        {@code pj_fwd.c}, {@code pj_inv.c} and {@code lib_proj.h}</li>
+ *   <li><a href = http://www.iogp.org/pubs/373-07-2.pdf>EPSG guide</a>.</li>
  * </ul>
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @since   0.6
+ * @since   0.7
  * @version 0.7
  * @module
  */
@@ -67,7 +64,7 @@ public class ObliqueStereographic extend
      * Conformal latitude of origin only use
      * into {@link #inverseTransform(double[], int, double[], int) }.
      */
-    protected final double χ0;
+    final double χ0;
 
     /**
      * Value of sin(χ0) only use
@@ -75,7 +72,7 @@ public class ObliqueStereographic extend
      *
      * @see #χ0
      */
-    protected final double sinχ0;
+    final double sinχ0;
 
     /**
      * Value of cos(χ0) only use
@@ -83,7 +80,7 @@ public class ObliqueStereographic extend
      *
      * @see #χ0
      */
-    protected final double cosχ0;
+    final double cosχ0;
 
     /**
      * c, internaly parameter used to define conformal sphere, used

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java?rev=1709179&r1=1709178&r2=1709179&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
[UTF-8] Sat Oct 17 14:22:57 2015
@@ -34,6 +34,7 @@ import org.apache.sis.util.Workaround;
 import static java.lang.Math.*;
 import static org.apache.sis.math.MathFunctions.asinh;
 import static org.apache.sis.math.MathFunctions.atanh;
+import static org.apache.sis.internal.referencing.provider.TransverseMercator.*;
 
 
 /**
@@ -115,10 +116,10 @@ public class TransverseMercator extends
             xOffset = ParameterRole.FALSE_WESTING;
             yOffset = ParameterRole.FALSE_SOUTHING;
         }
-        roles.put(ParameterRole.CENTRAL_MERIDIAN, org.apache.sis.internal.referencing.provider.TransverseMercator.LONGITUDE_OF_ORIGIN);
-        roles.put(ParameterRole.SCALE_FACTOR,     org.apache.sis.internal.referencing.provider.TransverseMercator.SCALE_FACTOR);
-        roles.put(xOffset,                        org.apache.sis.internal.referencing.provider.TransverseMercator.FALSE_EASTING);
-        roles.put(yOffset,                        org.apache.sis.internal.referencing.provider.TransverseMercator.FALSE_NORTHING);
+        roles.put(ParameterRole.CENTRAL_MERIDIAN, LONGITUDE_OF_ORIGIN);
+        roles.put(ParameterRole.SCALE_FACTOR, SCALE_FACTOR);
+        roles.put(xOffset, FALSE_EASTING);
+        roles.put(yOffset, FALSE_NORTHING);
         return new Initializer(method, parameters, roles, isSouth ? (byte) 1 : (byte) 0);
     }
 
@@ -129,8 +130,7 @@ public class TransverseMercator extends
     @Workaround(library="JDK", version="1.7")
     private TransverseMercator(final Initializer initializer) {
         super(initializer);
-        final double φ0 = toRadians(initializer.getAndStore(
-                org.apache.sis.internal.referencing.provider.TransverseMercator.LATITUDE_OF_ORIGIN));
+        final double φ0 = toRadians(initializer.getAndStore(LATITUDE_OF_ORIGIN));
         /*
          * Opportunistically use double-double arithmetic for computation of B since we will
store
          * it in the denormalization matrix, and there is no sine/cosine functions involved
here.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/InitializerTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/InitializerTest.java?rev=1709179&r1=1709178&r2=1709179&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/InitializerTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/InitializerTest.java
[UTF-8] Sat Oct 17 14:22:57 2015
@@ -17,19 +17,17 @@
 package org.apache.sis.referencing.operation.projection;
 
 import java.util.EnumMap;
-
 import org.opengis.parameter.ParameterDescriptor;
 import org.opengis.parameter.ParameterValueGroup;
 import org.opengis.referencing.operation.OperationMethod;
-
 import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.internal.referencing.provider.ObliqueStereographic;
 import org.apache.sis.parameter.Parameters;
+import org.opengis.test.TestCase;
 import org.junit.Test;
 
-import static org.apache.sis.internal.referencing.provider.ObliqueStereographic.*;
+import static java.lang.StrictMath.*;
 import static org.opengis.test.Assert.*;
-import org.opengis.test.TestCase;
 
 
 /**
@@ -41,40 +39,52 @@ import org.opengis.test.TestCase;
  * @version 0.7
  * @module
  */
-public strictfp class InitializerTest extends TestCase{
+public final strictfp class InitializerTest extends TestCase{
     /**
      * Tests the {@link Initializer#radiusOfConformalSphere(double)} method.
-     * This test compute the Radius of conformal Sphere using the values given by the
-     * <a href = http://www.iogp.org/pubs/373-07-2.pdf>EPSG guide</a> for the
Stereographic projection.
-     *
-     * @see Initializer#radiusOfConformalSphere(double)
+     * This test computes the Radius of Conformal Sphere using the values given
+     * by the <a href="http://www.iogp.org/pubs/373-07-2.pdf">EPSG guide</a>
for
+     * the <cite>Amersfoort / RD New</cite> projection (a Stereographic one).
      */
     @Test
     public void testRadiusOfConformalSphere() {
-        final EnumMap<NormalizedProjection.ParameterRole, ParameterDescriptor<Double>>
roles =
-                new EnumMap<>(NormalizedProjection.ParameterRole.class);
-        roles.put(NormalizedProjection.ParameterRole.CENTRAL_MERIDIAN, LONGITUDE_OF_ORIGIN);
-        roles.put(NormalizedProjection.ParameterRole.SCALE_FACTOR,     SCALE_FACTOR);
-        roles.put(NormalizedProjection.ParameterRole.FALSE_EASTING,    FALSE_EASTING);
-        roles.put(NormalizedProjection.ParameterRole.FALSE_NORTHING,   FALSE_NORTHING);
-
         final OperationMethod op = new ObliqueStereographic();
         final ParameterValueGroup p = op.getParameters().createValue();
-
-        //-- Implicit parameters (OGC names).
+        /*
+         * Following parameters are not given explicitely by EPSG definitions since they
are
+         * usually inferred from the datum.  However in the particular case of this test,
we
+         * need to provide them. The names used below are either OGC names or SIS extensions.
+         */
         p.parameter("semi_major").setValue(6377397.155);
         p.parameter("inverse_flattening").setValue(299.15281);
-
-        //-- Explicit parameters from EPSG registry
+        /*
+         * Following parameters are reproduced verbatim from EPSG registry and EPSG guide.
+         */
         p.parameter("Latitude of natural origin").setValue(52.156160556);
         p.parameter("Longitude of natural origin").setValue(5.387638889);
         p.parameter("Scale factor at natural origin").setValue(0.9999079);
         p.parameter("False easting").setValue(155000.00);
         p.parameter("False northing").setValue(463000.00);
-
+        /*
+         * The following lines are a typical way to create an Initializer instance.
+         * The EnumMap tells to the Initializer constructor which parameters to look for.
+         * We construct this map here for testing purpose, but users normally do not have
+         * to do that since this map is provided by the ObliqueStereographic class itself.
+         */
+        final EnumMap<NormalizedProjection.ParameterRole, ParameterDescriptor<Double>>
roles =
+                new EnumMap<>(NormalizedProjection.ParameterRole.class);
+        roles.put(NormalizedProjection.ParameterRole.CENTRAL_MERIDIAN, ObliqueStereographic.LONGITUDE_OF_ORIGIN);
+        roles.put(NormalizedProjection.ParameterRole.SCALE_FACTOR,     ObliqueStereographic.SCALE_FACTOR);
+        roles.put(NormalizedProjection.ParameterRole.FALSE_EASTING,    ObliqueStereographic.FALSE_EASTING);
+        roles.put(NormalizedProjection.ParameterRole.FALSE_NORTHING,   ObliqueStereographic.FALSE_NORTHING);
         final Initializer initializer = new Initializer(op, (Parameters) p, roles, (byte)
0);
-
+        /*
+         * The following lines give an example of how Apache SIS projection constructors
+         * use the Initializer class.
+         */
+        final double φ0 = toRadians(initializer.getAndStore(ObliqueStereographic.LATITUDE_OF_ORIGIN));
+        assertTrue(φ0 > 0);
         assertEquals("Conformal Sphere Radius", 6382644.571, 6377397.155 *
-                initializer.radiusOfConformalSphere(Math.sin(Math.toRadians(52.156160556))),
Formulas.LINEAR_TOLERANCE);
+                initializer.radiusOfConformalSphere(sin(φ0)), Formulas.LINEAR_TOLERANCE);
     }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java?rev=1709179&r1=1709178&r2=1709179&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
[UTF-8] Sat Oct 17 14:22:57 2015
@@ -50,6 +50,7 @@ import static org.apache.sis.referencing
 public final strictfp class MercatorTest extends MapProjectionTestCase {
     /**
      * Creates a new instance of {@link Mercator} for a sphere or an ellipsoid.
+     * The new instance is stored in the inherited {@link #transform} field.
      *
      * @param ellipse {@code false} for a sphere, or {@code true} for WGS84 ellipsoid.
      */

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java?rev=1709179&r1=1709178&r2=1709179&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/NormalizedProjectionTest.java
[UTF-8] Sat Oct 17 14:22:57 2015
@@ -36,7 +36,8 @@ import static org.junit.Assert.*;
 @DependsOn({
     // Following dependency is where the basic parameters (e.g. SEMI_MAJOR) are tested.
     // Those parameters are needed by NoOp pseudo-projection, which is used in this package.
-    org.apache.sis.internal.referencing.provider.MapProjectionTest.class
+    org.apache.sis.internal.referencing.provider.MapProjectionTest.class,
+    InitializerTest.class
 })
 public final strictfp class NormalizedProjectionTest extends TransformTestCase {
     /**

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java?rev=1709179&r1=1709178&r2=1709179&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java
[UTF-8] Sat Oct 17 14:22:57 2015
@@ -16,28 +16,26 @@
  */
 package org.apache.sis.referencing.operation.projection;
 
+import javax.measure.unit.SI;
 import org.opengis.parameter.ParameterValueGroup;
-import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.Matrix;
 import org.opengis.referencing.operation.OperationMethod;
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.util.FactoryException;
-
-import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.parameter.Parameters;
 import org.apache.sis.referencing.operation.transform.ContextualParameters;
-
-import org.junit.Assert;
-import org.junit.Test;
-
-import static java.lang.Math.sqrt;
-import static java.lang.StrictMath.toRadians;
 import org.apache.sis.referencing.operation.matrix.Matrix2;
+import org.apache.sis.internal.referencing.Formulas;
 import org.apache.sis.test.DependsOnMethod;
-import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.test.DependsOn;
+import org.junit.Test;
+
+import static java.lang.StrictMath.*;
+import static org.junit.Assert.*;
 
 
 /**
- * Tests {@link ObliqueStereographic} projection.
+ * Tests the {@link ObliqueStereographic} class.
  *
  * @author  Rémi Marechal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
@@ -45,161 +43,169 @@ import org.opengis.referencing.operation
  * @version 0.7
  * @module
  */
+@DependsOn({
+    InitializerTest.class,
+    NormalizedProjectionTest.class
+})
 public final strictfp class ObliqueStereographicTest extends MapProjectionTestCase {
     /**
-     * Tolerance used to compare spherical and oblique formula
-     * into same parameters context.
-     */
-    private final static double EPSG_SPHERICAL_TOLERANCE = 1E-15;
-
-    /**
-     * Parameter values provided by the <a href = http://www.iogp.org/pubs/373-07-2.pdf>EPSG
guide</a>
-     * for testing {@link ObliqueStereographic} transform conformity.
+     * Parameter values provided by the <a href="http://www.iogp.org/pubs/373-07-2.pdf">EPSG
guide</a>
+     * for testing {@link ObliqueStereographic} transform conformity. The test uses the parameters
for
+     * the <cite>Amersfoort / RD New</cite> projection:
      *
-     * @see ContextualParameters#getMatrix(boolean) where boolean is true for value n.
-     * @see ContextualParameters#getMatrix(boolean) where boolean is false for k0, a, FE,
FN and R.
-     * @see Initializer#radiusOfConformalSphere(double) for value R
+     * <ul>
+     *   <li>Semi-major axis length:            <var>a</var>  = 6377397.155
metres</li>
+     *   <li>Inverse flattening:              1/<var>f</var>  = 299.15281</li>
+     *   <li>Latitude of natural origin:        <var>φ₀</var> = 52°09'22.178"N</li>
+     *   <li>Longitude of natural origin:       <var>λ₀</var> =  5°23'15.500"E</li>
+     *   <li>Scale factor at natural origin:    <var>k₀</var> = 0.9999079</li>
+     *   <li>False easting:                     <var>FE</var> = 155000.00
metres</li>
+     *   <li>False northing:                    <var>FN</var> = 463000.00
metres</li>
+     * </ul>
      *
+     * Other parameters (<var>n</var>, <var>R</var>, <var>g</var>,
<var>h</var>) are computed from the above.
+     * Those parameters fall in three groups:
+     *
+     * <ul>
+     *   <li>Parameters used in linear operations (additions or multiplications) performed
<strong>before</strong> the
+     *       non-linear part (the "kernel") of the map projection. Those parameters are <var>λ₀</var>
and <var>n</var>
+     *       and their values are stored in the normalization matrix given by
+     *       <code>{@linkplain ContextualParameters#getMatrix(boolean) ContextualParameters.getMatrix}(true)</code>.</li>
+     *
+     *   <li>Parameters used in linear operations (additions or multiplications) performed
<strong>after</strong> the
+     *       non-linear part (the "kernel") of the map projection. Those parameters are <var>k₀</var>,
<var>R</var>,
+     *       <var>FE</var> and <var>FN</var> and their values are
stored in the denormalization matrix given by
+     *       <code>{@linkplain ContextualParameters#getMatrix(boolean) ContextualParameters.getMatrix}(false)</code>.</li>
+     *
+     *   <li>Other parameters are either used in the non-linear "kernel" of the map
projection or used for computing the
+     *       above-cited parameters.</li>
+     * </ul>
+     *
+     * <p><b>Note 1:</b> value of <var>R</var> is computed
by {@link Initializer#radiusOfConformalSphere(double)}.</p>
+     *
+     * <p><b>Note 2:</b> we do not follow the Java naming convention here
(constants in upper cases) in order to use
+     * as much as possible the exact same symbols as in the EPSG guide.</p>
      */
-    private final static double eSQUARED = 0.08169683 * 0.08169683,     // Excentricity squared.
-                                φ0       = 0.910296727,                 // Latitude of natural
origin (rad)
-
-                                //-- Some attributs are considered as linear and put into
normalize matrix and apply before transform
-                                n        = sqrt(1 + (eSQUARED * Math.pow(Math.cos(φ0), 4))
/ (1 - eSQUARED)),
-
-                                //-- Some attributs are considered as linear and put into
denormalize matrix and apply just after
-                                k0       = 0.9999079,
-                                a        = 6377397.155,
-                                FE       = 155000.00,
-                                FN       = 463000.00,
-                                R        = 6382644.571 / a;
-
-    /**
-     * Tested {@link ObliqueStereographic} projection.
-     */
-    private final ObliqueStereographic obliqueStereographic;
-
-    /**
-     * {@link ObliqueStereographic} projection define into spherical particularity case.
-     * Used to compute the expected transform, invert transform and derivative values
-     * when the projection is spherical.
-     */
-    private final ObliqueStereographic obliqueReference;
+    private static final double φ0  = 0.910296727,      // Latitude of natural origin (rad)
+        /* Before kernel */     λ0  = 0.094032038,      // Longitude of natural origin (rad)
+        /*  After kernel */     R   = 6382644.571,      // Radius of conformal sphere (m)
+                                a   = 6377397.155,      // Semi-major axis length (m)
+                                ivf = 299.15281,        // Inverse flattening factor
+                                e   = 0.08169683,       // Excentricity
+        /* Before kernel */     n   = 1.000475857,      // Coefficient computed from excentricity
and φ₀.
+        /*  After kernel */     k0  = 0.9999079,        // Scale factor
+        /*  After kernel */     FE  = 155000.00,        // False Easting (m)
+        /*  After kernel */     FN  = 463000.00;        // False Northing (m)
 
     /**
-     * Tested {@link ObliqueStereographic} projection into spherical particularity case.
+     * Compares the <var>n</var> value given in the EPSG guide with the value
computed from the formula.
      */
-    private final ObliqueStereographic.Spherical sphericalObliqueStereographic;
+    @Test
+    public void testN() {
+        assertEquals(n, sqrt(1 + (e*e * pow(cos(φ0), 4)) / (1 - e*e)), 0.5E-9);
+    }
 
     /**
-     * Buid tested {@link ObliqueStereographic} {@link MathTransform}.
+     * Creates a new instance of {@link ObliqueStereographic} for a sphere or an ellipsoid.
+     * The new instance is stored in the inherited {@link #transform} field.
+     *
+     * @param ellipse {@code false} for the spherical case, or {@code true} for the ellipsoidal
case.
      */
-    public ObliqueStereographicTest() {
-
-        //-- oblique EPSG case
+    private void createNormalizedProjection(final boolean ellipse) {
         final OperationMethod op = new org.apache.sis.internal.referencing.provider.ObliqueStereographic();
+        final ParameterValueGroup p = op.getParameters().createValue();
+        /*
+         * Following parameters are not given explicitely by EPSG definitions since they
are
+         * usually inferred from the datum.  However in the particular case of this test,
we
+         * need to provide them. The names used below are either OGC names or SIS extensions.
+         */
+        if (!ellipse) {
+            p.parameter("semi_major").setValue(R);
+            p.parameter("semi_minor").setValue(R);
+        } else {
+            p.parameter("semi_major").setValue(a);
+            p.parameter("inverse_flattening").setValue(ivf);
+        }
+        /*
+         * Following parameters are reproduced verbatim from EPSG registry and EPSG guide.
+         */
+        p.parameter("Latitude of natural origin")    .setValue(φ0, SI.RADIAN);
+        p.parameter("Longitude of natural origin")   .setValue(λ0, SI.RADIAN);
+        p.parameter("Scale factor at natural origin").setValue(k0);
+        p.parameter("False easting")                 .setValue(FE, SI.METRE);
+        p.parameter("False northing")                .setValue(FN, SI.METRE);
 
-        final ParameterValueGroup obliqueParameters = op.getParameters().createValue();
-
-        //-- implicit names from OGC.
-        obliqueParameters.parameter("semi_major").setValue(6377397.155);
-        obliqueParameters.parameter("inverse_flattening").setValue(299.15281);
-
-        //-- Name parameters from Epsg registry
-        obliqueParameters.parameter("Latitude of natural origin").setValue(52.156160556);
-        obliqueParameters.parameter("Longitude of natural origin").setValue(5.387638889);
-        obliqueParameters.parameter("Scale factor at natural origin").setValue(0.9999079);
-        obliqueParameters.parameter("False easting").setValue(155000.00);
-        obliqueParameters.parameter("False northing").setValue(463000.00);
-
-        obliqueStereographic = new ObliqueStereographic(op, (Parameters) obliqueParameters);
-
-
-        //-- spherical case
-        final ParameterValueGroup sphericalParameters = op.getParameters().createValue();
-
-        //-- implicit names from OGC.
-        sphericalParameters.parameter("semi_major").setValue(6377397.155);
-        sphericalParameters.parameter("semi_minor").setValue(6377397.155);
-
-        //-- Name parameters from Epsg registry
-        sphericalParameters.parameter("Latitude of natural origin").setValue(52.156160556);
-        sphericalParameters.parameter("Longitude of natural origin").setValue(5.387638889);
-        sphericalParameters.parameter("Scale factor at natural origin").setValue(0.9999079);
-        sphericalParameters.parameter("False easting").setValue(155000.00);
-        sphericalParameters.parameter("False northing").setValue(463000.00);
-
-        obliqueReference              = new ObliqueStereographic(op, (Parameters) sphericalParameters);
-        sphericalObliqueStereographic = new ObliqueStereographic.Spherical(obliqueReference);
+        transform = new ObliqueStereographic(op, (Parameters) p);
     }
 
     /**
-     * {@link MathTransform#transform(org.opengis.geometry.DirectPosition, org.opengis.geometry.DirectPosition)
}
-     * test with expected values from
-     * <a href = http://www.iogp.org/pubs/373-07-2.pdf> EPSG guide</a>
+     * The point given in the EPSG guide for testing the map projection.
+     * (φ<sub>t</sub>, λ<sub>t</sub>) is the source geographic
coordinate in degrees and
+     * (x<sub>t</sub>, y<sub>t</sub>) is the target projected coordinate
in metres.
+     */
+    private static final double φt = 53,                // Latitude in degrees
+                                λt = 6,                 // Longitude in degrees
+                                Et = 196105.283,        // Easting in metres
+                                Nt = 557057.739;        // Northing in metres
+
+    /**
+     * Tests {@link ObliqueStereographic#transform(double[], int, double[], int, boolean)}
+     * with the values given by the EPSG guide.
      *
-     * @throws FactoryException if an error occurred while creating the map projection.
-     * @throws TransformException if an error occurred while projecting a coordinate.
+     * @throws TransformException if an error occurred while projecting the coordinate.
      */
     @Test
-    public void testEPSGTransform() throws FactoryException, TransformException {
-
-        final double[] srcPts = new double[]{6, 53}; //-- deg
-        srcPts[0] = Math.toRadians(srcPts[0] - 5.387638889) ;
-        srcPts[1] = Math.toRadians(srcPts[1]);
-
+    public void testTransform() throws TransformException {
+        final double[] srcPts = new double[] {λt, φt};   // in degrees
         final double[] dstPts = new double[2];
 
-        srcPts[0] = srcPts[0] * n;
-
-        obliqueStereographic.transform(srcPts, 0, dstPts, 0, 1);
+        // Linear operations (normalization) applied by NormalizedTransform.
+        srcPts[0] = toRadians(srcPts[0]) - λ0;
+        srcPts[1] = toRadians(srcPts[1]);
+        srcPts[0] *= n;
+
+        // The non-linear part of map projection (the "kernel").
+        createNormalizedProjection(true);
+        transform.transform(srcPts, 0, dstPts, 0, 1);
+
+        // Linear operations (denormalization) applied by NormalizedTransform.
+        dstPts[0] *= (k0 * 2*R);
+        dstPts[1] *= (k0 * 2*R);
+        dstPts[0] += FE;
+        dstPts[1] += FN;
 
-        final double destE = dstPts[0] * k0 * a * 2 * R + FE;
-        final double destN = dstPts[1] * k0 * a * 2 * R + FN;
-
-        Assert.assertEquals("destination East coordinate",  196105.283, destE, Formulas.LINEAR_TOLERANCE);
-        Assert.assertEquals("destination North coordinate", 557057.739, destN, Formulas.LINEAR_TOLERANCE);
+        assertEquals("Easting",  Et, dstPts[0], Formulas.LINEAR_TOLERANCE);
+        assertEquals("Northing", Nt, dstPts[1], Formulas.LINEAR_TOLERANCE);
     }
 
-
-   /**
-     * Test method {@link ObliqueStereographic#inverseTransform(double[], int, double[],
int)}
-     * test with expected values from
-     * <a href = http://www.iogp.org/pubs/373-07-2.pdf> EPSG guide</a>
+    /**
+     * Tests {@link ObliqueStereographic#inverseTransform(double[], int, double[], int)}
+     * with the values given by the EPSG guide.
      *
-     * @throws org.apache.sis.referencing.operation.projection.ProjectionException
+     * @throws TransformException if an error occurred while projecting the coordinate.
      */
     @Test
-    public void testEPSGinvertTransform() throws ProjectionException {
-
-        double srcEast  = 196105.28;
-        double srcNorth = 557057.74;
-
-        srcEast  -= FE;
-        srcNorth -= FN;
-        srcEast  /= k0;
-        srcNorth /= k0;
-        srcEast  /= a;
-        srcNorth /= a;
-        srcEast  /= (2 * R);
-        srcNorth /= (2 * R);
-
-        //-- tcheck transform
-        final double[] srcPts = new double[]{srcEast, srcNorth}; //-- meter
-
+    public void testInverseTransform() throws TransformException {
+        final double[] srcPts = new double[] {Et, Nt};  // in metres
         final double[] dstPts = new double[2];
-        obliqueStereographic.inverseTransform(srcPts, 0, dstPts, 0);
-
-        final double λO = 0.094032038;
 
-        double destλ = dstPts[0] / n + λO;
-        double destφ = dstPts[1];
+        // Linear operations (normalization) applied by NormalizedTransform.
+        srcPts[0] -= FE;
+        srcPts[1] -= FN;
+        srcPts[0] /= (k0 * 2*R);
+        srcPts[1] /= (k0 * 2*R);
+
+        // The non-linear part of map projection (the "kernel").
+        createNormalizedProjection(true);
+        ((NormalizedProjection) transform).inverseTransform(srcPts, 0, dstPts, 0);
+
+        // Linear operations (denormalization) applied by NormalizedTransform.
+        dstPts[0] /= n;
+        dstPts[0] = toDegrees(dstPts[0] + λ0);
+        dstPts[1] = toDegrees(dstPts[1]);
 
-        destλ = Math.toDegrees(destλ);
-        destφ = Math.toDegrees(destφ);
-
-        Assert.assertEquals("destination East coordinate",  6, destλ, Formulas.ANGULAR_TOLERANCE);
-        Assert.assertEquals("destination North coordinate", 53, destφ, Formulas.ANGULAR_TOLERANCE);
+        assertEquals("Longitude", λt, dstPts[0], Formulas.ANGULAR_TOLERANCE);
+        assertEquals("Latitude",  φt, dstPts[1], Formulas.ANGULAR_TOLERANCE);
     }
 
     /**
@@ -212,113 +218,124 @@ public final strictfp class ObliqueStere
      * @see org.opengis.test.referencing.ParameterizedTransformTest#testObliqueStereographic()
      */
     @Test
+    @DependsOnMethod({"testTransform", "testInverseTransform"})
     public void testObliqueStereographic() throws FactoryException, TransformException {
         createGeoApiTest(new org.apache.sis.internal.referencing.provider.ObliqueStereographic()).testObliqueStereographic();
     }
 
     /**
-     * Verifies the consistency of elliptical formulas with the spherical formulas.
-     * This test compares the results between elliptical and spherical transform formulas
-     * from the particularity case stipulated into EPSG guide.
+     * Verifies the consistency of spherical formulas with the elliptical formulas.
+     * This test transforms the point given in the EPSG guide and takes the result
+     * of the elliptical implementation as a reference.
      *
-     * @see ObliqueStereographic.Spherical#transform(double[], int, double[], int, boolean)
-     * with boolean setted to {@code false}
-     * @throws TransformException if an error occurred while projecting a coordinate.
+     * @throws TransformException if an error occurred while projecting the coordinate.
      */
     @Test
-    @DependsOnMethod("testObliqueStereographic")
-    public void EPSGEllipticalWithSphericalTransform() throws TransformException {
-
-        final double[] srcPts = new double[]{6, 53}; //-- deg
-        srcPts[0] = Math.toRadians(srcPts[0] - 5.387638889) ;
-        srcPts[1] = Math.toRadians(srcPts[1]);
-
+    @DependsOnMethod("testTransform")
+    public void testSphericalTransform() throws TransformException {
+        final double[] srcPts = new double[] {λt, φt};  // in degrees
         final double[] dstPts = new double[2];
+        final double[] refPts = new double[2];
 
-        srcPts[0] = srcPts[0] * n;
-
-        obliqueReference.transform(srcPts, 0, dstPts, 0, 1);
-
-        final double destE = dstPts[0] * k0 * a * 2 * R + FE;
-        final double destN = dstPts[1] * k0 * a * 2 * R + FN;
+        // Linear operations (normalization) applied by NormalizedTransform.
+        srcPts[0] = toRadians(srcPts[0]) - λ0;
+        srcPts[1] = toRadians(srcPts[1]);
+        srcPts[0] *= n;
+
+        // The non-linear part of map projection (the "kernel").
+        createNormalizedProjection(false);
+        transform.transform(srcPts, 0, refPts, 0, 1);
+
+        // Linear operations (denormalization) applied by NormalizedTransform.
+        refPts[0] *= (k0 * 2*R);
+        refPts[1] *= (k0 * 2*R);
+        refPts[0] += FE;
+        refPts[1] += FN;
+
+        // Transform the same point, now using the spherical implementation.
+        ObliqueStereographic spherical = (ObliqueStereographic) transform;
+        spherical = new ObliqueStereographic.Spherical(spherical);
+        spherical.transform(srcPts, 0, dstPts, 0, 1);
+
+        // Linear operations (denormalization) applied by NormalizedTransform.
+        dstPts[0] *= (k0 * 2*R);
+        dstPts[1] *= (k0 * 2*R);
+        dstPts[0] += FE;
+        dstPts[1] += FN;
 
-        sphericalObliqueStereographic.transform(srcPts, 0, dstPts, 0, 1);
-
-        final double destSphereE = dstPts[0] * k0 * a * 2 * R + FE;
-        final double destSphereN = dstPts[1] * k0 * a * 2 * R + FN;
-
-        Assert.assertEquals("destination East coordinate",  destE, destSphereE, EPSG_SPHERICAL_TOLERANCE);
-        Assert.assertEquals("destination North coordinate", destN, destSphereN, EPSG_SPHERICAL_TOLERANCE);
+        assertArrayEquals("Spherical projection", refPts, dstPts, Formulas.LINEAR_TOLERANCE);
     }
 
     /**
-     * Verifies the consistency of elliptical formulas with the spherical formulas.
-     * This test compares the results between elliptical and spherical invert transform formulas
-     * from the particularity case stipulated into EPSG guide.
+     * Verifies the consistency of spherical formulas with the elliptical formulas.
+     * This test computes the inverse transform of the point given in the EPSG guide
+     * and takes the result of the elliptical implementation as a reference.
      *
-     * @see ObliqueStereographic.Spherical#inverseTransform(double[], int, double[], int)
-     * @throws ProjectionException if an error occurred while invert transformation computing.
+     * @throws TransformException if an error occurred while projecting the coordinate.
      */
     @Test
-    @DependsOnMethod("testObliqueStereographic")
-    public void EPSGEllipticalWithSphericalInvertTransform() throws ProjectionException {
-        double srcEast  = 196105.28;
-        double srcNorth = 557057.74;
-
-        srcEast  -= FE;
-        srcNorth -= FN;
-        srcEast  /= k0;
-        srcNorth /= k0;
-        srcEast  /= a;
-        srcNorth /= a;
-        srcEast  /= (2 * R);
-        srcNorth /= (2 * R);
-
-        //-- tcheck transform
-        final double[] srcProjPts = new double[]{srcEast, srcNorth}; //-- meter
-
+    @DependsOnMethod("testInverseTransform")
+    public void testSphericalInverseTransform() throws TransformException {
+        final double[] srcPts = new double[] {Et, Nt};  // in metres
         final double[] dstPts = new double[2];
+        final double[] refPts = new double[2];
 
-        obliqueReference.inverseTransform(srcProjPts, 0, dstPts, 0);
+        // Linear operations (normalization) applied by NormalizedTransform.
+        srcPts[0] -= FE;
+        srcPts[1] -= FN;
+        srcPts[0] /= (k0 * 2*R);
+        srcPts[1] /= (k0 * 2*R);
+
+        // The non-linear part of map projection (the "kernel").
+        createNormalizedProjection(false);
+        ((NormalizedProjection) transform).inverseTransform(srcPts, 0, refPts, 0);
+
+        // Linear operations (denormalization) applied by NormalizedTransform.
+        refPts[0] /= n;
+        refPts[0] = toDegrees(refPts[0] + λ0);
+        refPts[1] = toDegrees(refPts[1]);
+
+        // Transform the same point, now using the spherical implementation.
+        ObliqueStereographic spherical = (ObliqueStereographic) transform;
+        spherical = new ObliqueStereographic.Spherical(spherical);
+        spherical.inverseTransform(srcPts, 0, dstPts, 0);
+
+        // Linear operations (denormalization) applied by NormalizedTransform.
+        dstPts[0] /= n;
+        dstPts[0] = toDegrees(dstPts[0] + λ0);
+        dstPts[1] = toDegrees(dstPts[1]);
 
-        final double destλ = dstPts[0];
-        final double destφ = dstPts[1];
-
-        sphericalObliqueStereographic.inverseTransform(srcProjPts, 0, dstPts, 0);
-
-        final double destSphereλ = dstPts[0];
-        final double destSphereφ = dstPts[1];
-
-        Assert.assertEquals("destination East coordinate",  destλ, destSphereλ, EPSG_SPHERICAL_TOLERANCE);
-        Assert.assertEquals("destination North coordinate", destφ, destSphereφ, EPSG_SPHERICAL_TOLERANCE);
+        assertArrayEquals("Spherical inverse projection", refPts, dstPts, Formulas.ANGULAR_TOLERANCE);
     }
 
     /**
-     * Verifies the consistency of elliptical formulas with the spherical formulas.
-     * This test compares the results between elliptical and spherical derivative formulas
-     * from the particularity case stipulated into EPSG guide.
-     *
-     * @see ObliqueStereographic.Spherical#transform(double[], int, double[], int, boolean)
-     * with boolean setted to {@code true}
-     * @throws ProjectionException if an error occurred while derivative computing.
+     * Verifies the consistency of spherical formulas with the elliptical formulas.
+     * This test computes the derivative at a point and takes the result of the elliptical
+     * implementation as a reference.
+     *
+     * @throws TransformException if an error occurred while computing the derivative.
      */
     @Test
-    @DependsOnMethod("testObliqueStereographic")
-    public void EPSGEllipticalWithSphericalDerivative() throws ProjectionException {
-
-        final Matrix2 derivativeTolerance = new Matrix2(EPSG_SPHERICAL_TOLERANCE, EPSG_SPHERICAL_TOLERANCE,
-                                                                                   EPSG_SPHERICAL_TOLERANCE,
EPSG_SPHERICAL_TOLERANCE);
-        final double[] srcPts = new double[]{6, 53}; //-- deg
-        srcPts[0] = Math.toRadians(srcPts[0] - 5.387638889) ;
-        srcPts[1] = Math.toRadians(srcPts[1]);
-
-        srcPts[0] = srcPts[0] * n;
-
-        //-- Derivative
-        final Matrix expectedDerivative = obliqueReference.transform(srcPts, 0, null, 0,
true);
-        final Matrix testedDerivative   = sphericalObliqueStereographic.transform(srcPts,
0, null, 0, true);
-
-        assertMatrixEquals("derivative spherical", expectedDerivative, testedDerivative,
derivativeTolerance);
+    @DependsOnMethod("testDerivative")
+    public void testSphericalDerivative() throws TransformException {
+        final double[] srcPts = new double[] {λt, φt};  // in degrees
+        srcPts[0] = toRadians(srcPts[0]) - λ0;
+        srcPts[1] = toRadians(srcPts[1]);
+        srcPts[0] *= n;
+
+        // Using elliptical implementation.
+        createNormalizedProjection(false);
+        final Matrix reference = ((NormalizedProjection) transform).transform(srcPts, 0,
null, 0, true);
+
+        // Using spherical implementation.
+        ObliqueStereographic spherical = (ObliqueStereographic) transform;
+        spherical = new ObliqueStereographic.Spherical(spherical);
+        final Matrix derivative = spherical.transform(srcPts, 0, null, 0, true);
+
+        tolerance = 1E-12;
+        assertMatrixEquals("Spherical derivative", reference, derivative,
+                new Matrix2(tolerance, tolerance,
+                            tolerance, tolerance));
     }
 
     /**
@@ -327,8 +344,8 @@ public final strictfp class ObliqueStere
      * @throws TransformException Should never happen.
      */
     @Test
-    public void testSphericalDerivative() throws TransformException {
-        transform = obliqueStereographic;
+    public void testDerivative() throws TransformException {
+        createNormalizedProjection(true);
         tolerance = 1E-9;
 
         final double delta = toRadians(100.0 / 60) / 1852; // Approximatively 100 metres.




Mime
View raw message