sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject 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
Date Thu, 30 Jun 2016 09:54:59 GMT
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 λ = srcPts[srcOff];
-        if (abs(λ) > PI/2) {
+        if (abs(λ) >= (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° + Δ) 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.
+             * values range (±180°). So having f(π/2+Δ, φ) = f(π/2-Δ, φ) 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 λ    = srcPts[srcOff  ];
+            final double λ = srcPts[srcOff  ];
+            if (abs(λ) > PI/2) {
+                // See comment in the overridden class.
+                throw new ProjectionException(Errors.Keys.OutsideDomainOfValidity);
+            }
             final double φ    = srcPts[srcOff+1];
             final double sinλ = sin(λ);
             final double cosλ = cos(λ);

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_λ.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 … +90]° is still too wide for Transverse Mercator.
Reduce to [-45 … +45]°.
+            source[i] /= 2;
+        }
         transform.transform(source, 0, target, 0, 10);
         transform = assertSerializedEquals(transform);
         tolerance = Formulas.LINEAR_TOLERANCE;



Mime
View raw message