sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] branch geoapi-4.0 updated: Add tests for Cassini-Soldner projection.
Date Tue, 28 Apr 2020 11:24:35 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new c66a77b  Add tests for Cassini-Soldner projection.
c66a77b is described below

commit c66a77ba6cfb374503aed33157fedf96ca11f2cb
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Tue Apr 28 13:02:11 2020 +0200

    Add tests for Cassini-Soldner projection.
---
 .../operation/projection/CassiniSoldner.java       |   6 +-
 .../operation/projection/CassiniSoldnerTest.java   | 162 +++++++++++++++++++++
 .../transform/MathTransformFactoryMock.java        |   2 +-
 .../sis/test/suite/ReferencingTestSuite.java       |   1 +
 4 files changed, 168 insertions(+), 3 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CassiniSoldner.java
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CassiniSoldner.java
index 77fb264..ef40d1e 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CassiniSoldner.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/CassiniSoldner.java
@@ -115,8 +115,10 @@ public class CassiniSoldner extends MeridianArcBased {
         final double T    = tanφ * tanφ;
         final double C    = eccentricitySquared * (cosφ*cosφ) / (1 - eccentricitySquared);
         final double rν   = sqrt(1 - eccentricitySquared*(sinφ*sinφ));
-        dstPts[dstOff  ]  = (A - T*A3/6 - (8 - T + 8*C)*T*(A3*A2) / 120) / rν;
-        dstPts[dstOff+1]  = distance(φ, sinφ, cosφ) + tanφ*(A2/2 + (5 - T + 6*C)*(A2*A2)
/ 24) / rν;
+        if (dstPts != null) {
+            dstPts[dstOff  ]  = (A - T*A3/6 - (8 - T + 8*C)*T*(A3*A2) / 120) / rν;
+            dstPts[dstOff+1]  = distance(φ, sinφ, cosφ) + tanφ*(A2/2 + (5 - T + 6*C)*(A2*A2)
/ 24) / rν;
+        }
         return null;
     }
 
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CassiniSoldnerTest.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CassiniSoldnerTest.java
new file mode 100644
index 0000000..8b87074
--- /dev/null
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/CassiniSoldnerTest.java
@@ -0,0 +1,162 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.projection;
+
+import org.opengis.util.FactoryException;
+import org.opengis.referencing.operation.TransformException;
+import org.apache.sis.internal.referencing.provider.MapProjection;
+import org.apache.sis.internal.referencing.Formulas;
+import org.apache.sis.geometry.DirectPosition2D;
+import org.apache.sis.parameter.Parameters;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static java.lang.Double.NaN;
+import static java.lang.StrictMath.*;
+
+
+/**
+ * Tests the {@link CassiniSoldner} class.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @author  Rémi Maréchal (Geomatys)
+ * @version 1.1
+ * @since   0.8
+ * @module
+ */
+public final strictfp class CassiniSoldnerTest extends MapProjectionTestCase {
+    /**
+     * Returns the operation method for the projection tested in this class.
+     */
+    private static MapProjection method() {
+        return new org.apache.sis.internal.referencing.provider.CassiniSoldner();
+    }
+
+    /**
+     * Creates a new instance of {@link CassiniSoldner}. This instance expects
+     * angles in radians and a φ₀ value of zero; this is not a complete transform.
+     *
+     * @param  ellipse  {@code false} for a sphere, or {@code true} for WGS84 ellipsoid.
+     * @return newly created projection.
+     */
+    private static CassiniSoldner create(final boolean ellipse) {
+        final MapProjection provider = method();
+        final Parameters pg = Parameters.castOrWrap(provider.getParameters().createValue());
+        if (ellipse) {
+            pg.parameter("semi-major").setValue(WGS84_A);
+            pg.parameter("semi-minor").setValue(WGS84_B);
+        } else {
+            pg.parameter("semi-major").setValue(RADIUS);
+            pg.parameter("semi-minor").setValue(RADIUS);
+        }
+        return new CassiniSoldner(provider, pg);
+    }
+
+    /**
+     * Tests some identities related to the {@link CassiniSoldner#distance(double, double,
double)} method.
+     *
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     */
+    @Test
+    public void testSimplePoint() throws TransformException {
+        transform = create(false);
+        /*
+         * Fix φ=45°, which implies tan(φ)=1.
+         * Test using the CassiniSoldner spherical equation.
+         */
+        final DirectPosition2D point = new DirectPosition2D();
+        final double domain = toRadians(5);
+        final double step   = domain / 20;
+        for (double λ = -domain; λ <= domain; λ += step) {
+            final double yFromSimplified = PI/2 - atan(cos(λ));
+            point.x = λ;
+            point.y = PI/4;
+            assertSame(point, transform.transform(point, point));
+            assertEquals("Given excentricity=0 and φ=45°, the spherical equation should
simplify to a "
+                    + "very simple expression, which we are testing here.", yFromSimplified,
point.y, 1E-9);
+        }
+    }
+
+    /**
+     * Tests the point given in EPSG example. This is the same test than {@link #runGeoapiTest()}
+     * but is repeated here for easier debugging.
+     *
+     * @throws FactoryException if an error occurred while creating the map projection.
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     */
+    @Test
+    public void testExampleEPSG() throws FactoryException, TransformException {
+        createCompleteProjection(method(),
+                31706587.88,                            // Semi-major axis (Clarke's links)
+                31706587.88 * (20855233./20926348),     // Semi-minor axis (Clarke's links)
+                -(61 + 20./60),                         // Longitude of natural origin
+                10 + (26 + 30./60)/60,                  // Latitude of natural origin
+                NaN,                                    // Standard parallel 1 (none)
+                NaN,                                    // Standard parallel 2 (none)
+                NaN,                                    // Scale factor (none)
+                430000,                                 // False easting  (Clarke's links)
+                325000);                                // False northing (Clarke's links)
+
+        final DirectPosition2D p = new DirectPosition2D(-62, 10);
+        assertSame(p, transform.transform(p, p));
+        assertEquals(66644.94, p.x, 0.005);
+        assertEquals(82536.22, p.y, 0.005);
+
+        assertSame(p, transform.inverse().transform(p, p));
+        assertEquals(-62, p.x, Formulas.ANGULAR_TOLERANCE);
+        assertEquals(+10, p.y, Formulas.ANGULAR_TOLERANCE);
+    }
+
+    /**
+     * Creates a projection and tests the derivatives at a few points.
+     *
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     */
+//  @Test
+    public void testDerivative() throws TransformException {
+        final double delta = toRadians(100.0 / 60) / 1852;          // Approximately 100
metres.
+        derivativeDeltas = new double[] {delta, delta};
+
+        // Tests spherical formulas
+        tolerance = 1E-9;
+        transform = create(false);
+        validate();
+        verifyDerivative(toRadians(+3), toRadians(-6));
+        verifyDerivative(toRadians(-4), toRadians(40));
+
+        // Tests ellipsoidal formulas
+        tolerance = 1E-8;
+        transform = create(true);
+        validate();
+        verifyDerivative(toRadians(+3), toRadians(-10));
+        verifyDerivative(toRadians(-4), toRadians(+10));
+    }
+
+    /**
+     * Tests the <cite>"Cassini-Soldner"</cite> (EPSG:9806) projection method.
+     * This test is defined in GeoAPI conformance test suite.
+     *
+     * @throws FactoryException if an error occurred while creating the map projection.
+     * @throws TransformException if an error occurred while projecting a coordinate.
+     *
+     * @see org.opengis.test.referencing.ParameterizedTransformTest#testOrthographic()
+     */
+//  @Test
+    public void runGeoapiTest() throws FactoryException, TransformException {
+        createGeoApiTest(method()).testCassiniSoldner();
+    }
+}
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java
index 62ee860..c7d9487 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformFactoryMock.java
@@ -50,7 +50,7 @@ public final strictfp class MathTransformFactoryMock implements MathTransformFac
     /**
      * Creates a new mock for the given operation method.
      *
-     * @param method The operation method to put in this factory.
+     * @param  method  the operation method to put in this factory.
      */
     public MathTransformFactoryMock(final DefaultOperationMethod method) {
         this.method = method;
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
b/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
index 1d86008..eb5fe25 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
@@ -181,6 +181,7 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.projection.LambertConicConformalTest.class,
     org.apache.sis.referencing.operation.projection.TransverseMercatorTest.class,
     org.apache.sis.referencing.operation.projection.ZonedGridSystemTest.class,
+    org.apache.sis.referencing.operation.projection.CassiniSoldnerTest.class,
     org.apache.sis.referencing.operation.projection.PolarStereographicTest.class,
     org.apache.sis.referencing.operation.projection.ObliqueStereographicTest.class,
     org.apache.sis.referencing.operation.projection.ObliqueMercatorTest.class,


Mime
View raw message