sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1750686 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/projection/ test/java/org/apache/sis/geometry/
Date Wed, 29 Jun 2016 17:52:51 GMT
Author: desruisseaux
Date: Wed Jun 29 17:52:51 2016
New Revision: 1750686

URL: http://svn.apache.org/viewvc?rev=1750686&view=rev
Log:
Check against longitude values too far from the domain of validity in Transverse Mercator
projection (SIS-329).

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ProjectionException.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/geometry/TransformTestCase.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java?rev=1750686&r1=1750685&r2=1750686&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Mercator.java
[UTF-8] Wed Jun 29 17:52:51 2016
@@ -354,8 +354,10 @@ public class Mercator extends ConformalP
                 final double a = abs(φ);
                 if (a < PI/2) {
                     y = log(expOfNorthing(φ, eccentricity * sinφ));     // Snyder (7-7)
+                } else if (a <= (PI/2 + ANGULAR_TOLERANCE)) {
+                    y = copySign(POSITIVE_INFINITY, φ);
                 } else {
-                    y = copySign(a <= (PI/2 + ANGULAR_TOLERANCE) ? POSITIVE_INFINITY :
NaN, φ);
+                    y = NaN;
                 }
             }
             dstPts[dstOff  ] = srcPts[srcOff];   // Scale will be applied by the denormalization
matrix.
@@ -395,8 +397,10 @@ public class Mercator extends ConformalP
                     final double y;
                     if (a < PI/2) {
                         y = log(expOfNorthing(φ, eccentricity * sin(φ)));
+                    } else if (a <= (PI/2 + ANGULAR_TOLERANCE)) {
+                        y = copySign(POSITIVE_INFINITY, φ);
                     } else {
-                        y = copySign(a <= (PI/2 + ANGULAR_TOLERANCE) ? POSITIVE_INFINITY
: NaN, φ);
+                        y = NaN;
                     }
                     dstPts[dstOff] = y;
                 }
@@ -484,8 +488,10 @@ public class Mercator extends ConformalP
                     final double a = abs(φ);
                     if (a < PI/2) {
                         y = log(tan(PI/4 + 0.5*φ));    // Part of Snyder (7-2)
+                    } else if (a <= (PI/2 + ANGULAR_TOLERANCE)) {
+                        y = copySign(POSITIVE_INFINITY, φ);
                     } else {
-                        y = copySign(a <= (PI/2 + ANGULAR_TOLERANCE) ? POSITIVE_INFINITY
: NaN, φ);
+                        y = NaN;
                     }
                 }
                 dstPts[dstOff  ] = srcPts[srcOff];
@@ -518,8 +524,10 @@ public class Mercator extends ConformalP
                         final double y;
                         if (a < PI/2) {
                             y = log(tan(PI/4 + 0.5*φ));     // Part of Snyder (7-2)
+                        } else if (a <= (PI/2 + ANGULAR_TOLERANCE)) {
+                            y = copySign(POSITIVE_INFINITY, φ);
                         } else {
-                            y = copySign(a <= (PI/2 + ANGULAR_TOLERANCE) ? POSITIVE_INFINITY
: NaN, φ);
+                            y = NaN;
                         }
                         dstPts[dstOff] = y;
                     }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ProjectionException.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ProjectionException.java?rev=1750686&r1=1750685&r2=1750686&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ProjectionException.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ProjectionException.java
[UTF-8] Wed Jun 29 17:52:51 2016
@@ -78,14 +78,4 @@ public class ProjectionException extends
     ProjectionException(final short code) {
         this(Errors.format(code));
     }
-
-    /**
-     * Constructs a new exception with the specified detail message.
-     *
-     * @param code One of the constants suitable for {@link Errors#format(short)}.
-     * @param value An argument value to be formatted.
-     */
-    ProjectionException(final short code, final Object value) {
-        this(Errors.format(code, value));
-    }
 }

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=1750686&r1=1750685&r2=1750686&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] Wed Jun 29 17:52:51 2016
@@ -313,13 +313,29 @@ public class TransverseMercator extends
                             final double[] dstPts, final int dstOff,
                             final boolean derivate) throws ProjectionException
     {
-        final double λ     = srcPts[srcOff  ];
+        final double λ = srcPts[srcOff];
+        if (abs(λ) > PI/2) {
+            /*
+             * The Transverse Mercator projection is conceptually a Mercator projection rotated
by ±90°.
+             * In the Mercator projection, the y values tend toward infinity for latitudes
close to ±90°.
+             * Likewise in the Transverse Mercator, x values tend toward infinity for longitudes
close ±90°
+             * (at equator and after subtraction of central meridian). After we pass the
90° limit,
+             * the Transverse Mercator results at (90° + Δ) are the same as for (90° -
Δ).
+             *
+             * Problem is that 90° is an ordinary longitude value, not even close to the
limit of longitude
+             * values range (±180°). So having f(90°+Δ, φ) = f(90°-Δ, φ) results
in wrong behavior in some
+             * algorithm likes the one used by Envelopes.transform(CoordinateOperation, Envelope).
+             * Since a distance of 90° from central meridian is way outside the Transverse
Mercator domain
+             * of validity anyway, we do not let the user go further.
+             */
+            throw new ProjectionException(Errors.Keys.OutsideDomainOfValidity);
+        }
         final double φ     = srcPts[srcOff+1];
         final double sinλ  = sin(λ);
         final double ℯsinφ = sin(φ) * eccentricity;
         final double Q     = asinh(tan(φ)) - atanh(ℯsinφ) * eccentricity;
-        final double coshQ = cosh(Q);
-        final double η0    = atanh(sinλ / coshQ);
+        final double coshQ = cosh(Q);                                       // Can not be
smaller than 1.
+        final double η0    = atanh(sinλ / coshQ);                           // Tends toward
±∞ if λ → ±90°.
         /*
          * Original formula: η0 = atanh(sin(λ) * cos(β)) where
          * cos(β) = cos(atan(sinh(Q)))

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java?rev=1750686&r1=1750685&r2=1750686&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/geometry/TransformTestCase.java
[UTF-8] Wed Jun 29 17:52:51 2016
@@ -188,6 +188,29 @@ public abstract strictfp class Transform
     }
 
     /**
+     * Tests conversions of an envelope or rectangle which is <strong>not</strong>
over a pole,
+     * but was wrongly considered as over a pole before SIS-329 fix.
+     *
+     * @throws FactoryException if an error occurred while creating the operation.
+     * @throws TransformException if an error occurred while transforming the envelope.
+     *
+     * @see <a href="https://issues.apache.org/jira/browse/SIS-329">SIS-329</a>
+     */
+    @Test
+    @DependsOnMethod("testTransform")
+    public final void testTransformNotOverPole() throws FactoryException, TransformException
{
+        final ProjectedCRS  sourceCRS  = CommonCRS.WGS84.UTM(10, -3.5);
+        final GeographicCRS targetCRS  = sourceCRS.getBaseCRS();
+        final Conversion    conversion = inverse(sourceCRS.getConversionFromBase());
+        final G rectangle = createFromExtremums(sourceCRS, 199980, 4490220, 309780, 4600020);
+        final G expected  = createFromExtremums(targetCRS,
+                40.50846282536367, -6.594124551832373,          // Computed by SIS (not validated
by external authority).
+                41.52923550023067, -5.246186118392847);
+        final G actual = transform(conversion, rectangle);
+        assertGeometryEquals(expected, actual, ANGULAR_TOLERANCE, ANGULAR_TOLERANCE);
+    }
+
+    /**
      * Returns the inverse of the given conversion. This method is not strictly correct
      * since we reuse the properties (name, aliases, etc.) from the given conversion.
      * However those properties are not significant for the purpose of this test.



Mime
View raw message