You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2016/07/21 10:17:20 UTC

svn commit: r1753653 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/projection/ test/java/org/apache/sis/referencing/operation/projection/

Author: desruisseaux
Date: Thu Jul 21 10:17:20 2016
New Revision: 1753653

URL: http://svn.apache.org/viewvc?rev=1753653&view=rev
Log:
Take in account the polar cases.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/AlbersEqualArea.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/EqualAreaProjection.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/AlbersEqualAreaTest.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/AlbersEqualArea.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/AlbersEqualArea.java?rev=1753653&r1=1753652&r2=1753653&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/AlbersEqualArea.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/AlbersEqualArea.java [UTF-8] Thu Jul 21 10:17:20 2016
@@ -259,6 +259,11 @@ public class AlbersEqualArea extends Equ
     {
         final double x = srcPts[srcOff  ];
         final double y = srcPts[srcOff+1];
+        /*
+         * Note: Synder suggests to reverse the sign of x, y and \u03c1\u2080 if n is negative. It should not done in Apache SIS
+         * implementation because (x,y) are premultiplied by n (by the normalization affine transform) before to enter
+         * in this method, so if n was negative those values have already their sign reverted.
+         */
         dstPts[dstOff  ] = atan2(x, y);
         dstPts[dstOff+1] = \u03c6((C - (x*x + y*y)) / nm);
         /*

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/EqualAreaProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/EqualAreaProjection.java?rev=1753653&r1=1753652&r2=1753653&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/EqualAreaProjection.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/EqualAreaProjection.java [UTF-8] Thu Jul 21 10:17:20 2016
@@ -250,6 +250,31 @@ abstract class EqualAreaProjection exten
                 return \u03c6;
             }
         }
+        /*
+         * In the Albers Equal Area discussion, Synder said that above algorithm does not converge if
+         *
+         *   q = �(1 - (1-\u212f�)/(2\u212f) \u22c5 ln((1-\u212f)/(1+\u212f)))
+         *
+         * which we rewrite as
+         *
+         *   q = �(1 + (1-\u212f�)\u22c5atanh(\u212f)/\u212f)
+         *
+         * Given that y = q/(1-\u212f�)  (see above comment), we rewrite as
+         *
+         *   y  =  �(1/(1-\u212f�) + atanh(\u212f)/\u212f)  =  �qmPolar
+         *
+         * which implies  sin\u03b2 = �1. This is consistent with Synder discussion of Cylndrical Equal Area
+         * projection, where he said exactly that about the same formula (that it does not converge for
+         * \u03b2 = �90�). In both case, Synder said that the result is \u03c6 = \u03b2, with the same sign.
+         */
+        final double as = abs(sin\u03b2);
+        if (abs(as - 1) < ANGULAR_TOLERANCE) {
+            return copySign(PI/2, y);               // Value is at a pole.
+        }
+        if (as >= 1 || Double.isNaN(y)) {
+            return Double.NaN;                      // Value "after" the pole.
+        }
+        // Value should have converged but did not.
         throw new ProjectionException(Errors.format(Errors.Keys.NoConvergence));
     }
 

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/AlbersEqualAreaTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/AlbersEqualAreaTest.java?rev=1753653&r1=1753652&r2=1753653&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/AlbersEqualAreaTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/AlbersEqualAreaTest.java [UTF-8] Thu Jul 21 10:17:20 2016
@@ -195,6 +195,36 @@ public final strictfp class AlbersEqualA
     }
 
     /**
+     * Tests a few "special" points which need special care in inverse projection algorithm.
+     *
+     * @throws FactoryException if an error occurred while creating the map projection.
+     * @throws TransformException if an error occurred while projecting a point.
+     */
+    @Test
+    @DependsOnMethod("testEllipse")
+    public void testSingularity() throws FactoryException, TransformException {
+        createCompleteProjection(new org.apache.sis.internal.referencing.provider.AlbersEqualArea(),
+                WGS84_A,    // Semi-major axis length
+                WGS84_B,    // Semi-minor axis length
+                0,          // Central meridian
+                0,          // Latitude of origin
+                0,          // Standard parallel 1
+                2,          // Standard parallel 2
+                NaN,        // Scale factor (none)
+                0,          // False easting
+                0);         // False northing
+
+        tolerance = Formulas.LINEAR_TOLERANCE;
+        toleranceModifier = ToleranceModifier.PROJECTION;
+        verifyTransform(new double[] {0,        0,
+                                      0,      +90,
+                                      0,      -90},
+                        new double[] {0,        0,
+                                      0, +6420271.594575703,    // Computed empirically with SIS (not from an external source).
+                                      0, -6309429.217});
+    }
+
+    /**
      * Tests conversion of random points with non-zero central meridian, standard parallel
      * and false easting/northing.
      *
@@ -202,6 +232,7 @@ public final strictfp class AlbersEqualA
      * @throws TransformException if an error occurred while projecting a point.
      */
     @Test
+    @DependsOnMethod("testEllipse")
     public void testRandomPoints() throws FactoryException, TransformException {
         createCompleteProjection(new org.apache.sis.internal.referencing.provider.AlbersEqualArea(),
                 WGS84_A,    // Semi-major axis length