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/06/30 09:54:59 UTC

svn commit: r1750762 - in /sis/branches/JDK8/core/sis-referencing/src: main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java

Author: desruisseaux
Date: Thu Jun 30 09:54:59 2016
New Revision: 1750762

URL: http://svn.apache.org/viewvc?rev=1750762&view=rev
Log:
More conservative threshold for throwing a ProjectionException in TransverseMercator projection.

Modified:
    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/TransverseMercatorTest.java

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=1750762&r1=1750761&r2=1750762&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] Thu Jun 30 09:54:59 2016
@@ -59,7 +59,7 @@ import static org.apache.sis.internal.re
  * @author  Martin Desruisseaux (Geomatys)
  * @author  R�mi Mar�chal (Geomatys)
  * @since   0.6
- * @version 0.7
+ * @version 0.8
  * @module
  *
  * @see Mercator
@@ -314,19 +314,24 @@ public class TransverseMercator extends
                             final boolean derivate) throws ProjectionException
     {
         final double \u03bb = srcPts[srcOff];
-        if (abs(\u03bb) > PI/2) {
+        if (abs(\u03bb) >= (0.9*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 projection is conceptually a Mercator projection rotated by 90�.
+             * In Mercator projection, y values tend toward infinity for latitudes close to �90�.
+             * In Transverse Mercator, x values tend toward infinity for longitudes close to �90�
+             * at equator and after subtraction of central meridian. After we pass the 90� limit,
              * the Transverse Mercator results at (90� + \u0394) are the same as for (90� - \u0394).
              *
              * Problem is that 90� is an ordinary longitude value, not even close to the limit of longitude
-             * values range (�180�). So having f(90�+\u0394, \u03c6) = f(90�-\u0394, \u03c6) 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.
+             * values range (�180�). So having f(\u03c0/2+\u0394, \u03c6) = f(\u03c0/2-\u0394, \u03c6) results in wrong behavior in some
+             * algorithms like the one used by Envelopes.transform(CoordinateOperation, Envelope).
+             * Since a distance of 90� from central meridian is far outside the Transverse Mercator
+             * domain of validity anyway, we do not let the user go further.
+             *
+             * In the particular case of ellipsoidal formulas, we put a limit of 81� instead of 90�
+             * because experience shows that results close to equator become chaotic after 85� when
+             * using WGS84 ellipsoid. We do not need to reduce the limit for the spherical formulas,
+             * because the mathematic are simpler and the function still smooth until 90�.
              */
             throw new ProjectionException(Errors.Keys.OutsideDomainOfValidity);
         }
@@ -611,7 +616,11 @@ public class TransverseMercator extends
                                 final double[] dstPts, final int dstOff,
                                 final boolean derivate) throws ProjectionException
         {
-            final double \u03bb    = srcPts[srcOff  ];
+            final double \u03bb = srcPts[srcOff  ];
+            if (abs(\u03bb) > PI/2) {
+                // See comment in the overridden class.
+                throw new ProjectionException(Errors.Keys.OutsideDomainOfValidity);
+            }
             final double \u03c6    = srcPts[srcOff+1];
             final double sin\u03bb = sin(\u03bb);
             final double cos\u03bb = cos(\u03bb);

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java?rev=1750762&r1=1750761&r2=1750762&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/TransverseMercatorTest.java [UTF-8] Thu Jun 30 09:54:59 2016
@@ -158,6 +158,10 @@ public final strictfp class TransverseMe
          */
         final double[] source = CoordinateDomain.GEOGRAPHIC_RADIANS_HALF_\u03bb.generateRandomInput(new Random(5346144739450824145L), 2, 10);
         final double[] target = new double[source.length];
+        for (int i=0; i<source.length; i+=2) {
+            // A longitude range of [-90 \u2026 +90]� is still too wide for Transverse Mercator. Reduce to [-45 \u2026 +45]�.
+            source[i] /= 2;
+        }
         transform.transform(source, 0, target, 0, 10);
         transform = assertSerializedEquals(transform);
         tolerance = Formulas.LINEAR_TOLERANCE;