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

commit b718383130431e75d10490d604a1a3c612566321
Author: Martin Desruisseaux <martin.desruisse...@geomatys.com>
AuthorDate: Mon Feb 21 12:44:29 2022 +0100

    Fix wrong coordinates in inverse Oblique Stereographic projection.
    https://issues.apache.org/jira/browse/SIS-537 (contribution by Emmanuel 
Giasson).
---
 .../operation/projection/ObliqueStereographic.java |  9 ++---
 .../projection/ObliqueStereographicTest.java       | 38 +++++++++++++++++++---
 2 files changed, 39 insertions(+), 8 deletions(-)

diff --git 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
index 8a96322..b926b91 100644
--- 
a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
+++ 
b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueStereographic.java
@@ -62,7 +62,8 @@ import static 
org.apache.sis.internal.referencing.provider.ObliqueStereographic.
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @author  Emmanuel Giasson (Thales)
+ * @version 1.2
  * @since   0.7
  * @module
  */
@@ -355,8 +356,8 @@ public class ObliqueStereographic extends 
NormalizedProjection {
     {
         final double x = srcPts[srcOff  ];
         final double y = srcPts[srcOff+1];
-        final double i = atan(x / (h + y));
-        final double j = atan(x / (g - y)) - i;
+        final double i = atan2(x, h + y);
+        final double j = atan2(x, g - y) - i;
         /*
          * The conformal longitude is  Λ = j + 2i + Λ₀.  In the particular 
case of stereographic projection,
          * the geodetic longitude λ is equals to Λ. Furthermore in Apache SIS 
implementation, Λ₀ is added by
@@ -377,7 +378,7 @@ public class ObliqueStereographic extends 
NormalizedProjection {
             final double ψi = log(tan(φ/2 + PI/4) * pow((1 - ℯsinφ) / (1 + 
ℯsinφ), he));
             final double Δφ = (ψ - ψi) * cos(φ) * (1 - ℯsinφ*ℯsinφ) / ome;
             φ += Δφ;
-            if (!(abs(Δφ) > ITERATION_TOLERANCE)) {     // Use '!' for 
accepting NaN.
+            if (!(abs(Δφ) > ITERATION_TOLERANCE)) {     // Use `!` for 
accepting NaN.
                 dstPts[dstOff  ] = λ;
                 dstPts[dstOff+1] = φ;
                 return;
diff --git 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java
 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java
index 0e178f5..f705115 100644
--- 
a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java
+++ 
b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueStereographicTest.java
@@ -41,7 +41,8 @@ import static org.junit.Assert.*;
  *
  * @author  Rémi Maréchal (Geomatys)
  * @author  Martin Desruisseaux (Geomatys)
- * @version 1.1
+ * @author  Emmanuel Giasson (Thales)
+ * @version 1.2
  * @since   0.7
  * @module
  */
@@ -142,6 +143,16 @@ public final strictfp class ObliqueStereographicTest 
extends MapProjectionTestCa
     }
 
     /**
+     * Creates the complete transform from the given parameter values.
+     * Input and output coordinates will be in degrees, contrarily to the 
transform
+     * created by above {@link #createNormalizedProjection(boolean)} method.
+     */
+    private void createCompleteTransform(final OperationMethod op, final 
ParameterValueGroup p) throws FactoryException {
+        transform = new ObliqueStereographic(op, (Parameters) 
p).createMapProjection(
+                DefaultFactories.forBuildin(MathTransformFactory.class));
+    }
+
+    /**
      * 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.
@@ -227,6 +238,27 @@ public final strictfp class ObliqueStereographicTest 
extends MapProjectionTestCa
     }
 
     /**
+     * Tests consistency between forward and inverse projection using a point 
that was known to fail.
+     *
+     * @throws FactoryException if an error occurred while creating the map 
projection.
+     * @throws TransformException if an error occurred while projecting a 
coordinate.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-537";>SIS-537</a>
+     */
+    @Test
+    public void testObliqueStereographicConsistency() throws FactoryException, 
TransformException {
+        final OperationMethod op = new 
org.apache.sis.internal.referencing.provider.ObliqueStereographic();
+        final ParameterValueGroup p = op.getParameters().createValue();
+        p.parameter("semi_major").setValue(WGS84_A);
+        p.parameter("semi_minor").setValue(WGS84_B);
+        p.parameter("Latitude of natural origin") .setValue( 45, Units.DEGREE);
+        p.parameter("Longitude of natural origin").setValue(-70, Units.DEGREE);
+        createCompleteTransform(op, p);
+        tolerance = Formulas.ANGULAR_TOLERANCE;
+        verifyInverse(30, 45);
+    }
+
+    /**
      * 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.
@@ -376,9 +408,7 @@ public final strictfp class ObliqueStereographicTest 
extends MapProjectionTestCa
         p.parameter("Scale factor at natural origin").setValue(0.994);
         p.parameter("False easting")                 .setValue(2000000);
         p.parameter("False northing")                .setValue(2000000);
-
-        transform = new ObliqueStereographic(op, (Parameters) 
p).createMapProjection(
-                DefaultFactories.forBuildin(MathTransformFactory.class));
+        createCompleteTransform(op, p);
         tolerance = 0.01;
         verifyTransform(new double[] {44, 73}, new double[] {3320416.75, 
632668.43});
     }

Reply via email to