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 2022/01/08 21:08:21 UTC
[sis] branch geoapi-4.0 updated (440c700 -> daf0e36)
This is an automated email from the ASF dual-hosted git repository.
desruisseaux pushed a change to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git.
discard 440c700 Fix a NaN value caused by rounding error in Oblique Mercator inverse projection.
new daf0e36 Fix a NaN value caused by rounding error in Oblique Mercator inverse projection.
This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version. This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:
* -- * -- B -- O -- O -- O (440c700)
\
N -- N -- N refs/heads/geoapi-4.0 (daf0e36)
You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.
Any revisions marked "omit" are not gone; other references still
refer to them. Any revisions marked "discard" are gone forever.
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../sis/referencing/operation/projection/ConformalProjection.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
[sis] 01/01: Fix a NaN value caused by rounding error in Oblique Mercator inverse projection.
Posted by de...@apache.org.
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 daf0e369f9e5fdbc9928d8f1808a8149b5e03f54
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Sat Jan 8 07:22:04 2022 +0100
Fix a NaN value caused by rounding error in Oblique Mercator inverse projection.
https://issues.apache.org/jira/browse/SIS-532
---
.../operation/projection/ConformalProjection.java | 2 +-
.../operation/projection/ObliqueMercator.java | 11 ++++++--
.../operation/projection/ObliqueMercatorTest.java | 31 +++++++++++++++++++++-
3 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
index ba11ca8..e606f9b 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
@@ -176,7 +176,7 @@ abstract class ConformalProjection extends NormalizedProjection {
* <ul>
* <li>φ(0) = π/2</li>
* <li>φ(1) = 0</li>
- * <li>φ(∞) = -π/2.</li>
+ * <li>φ(∞) = -π/2</li>
* </ul>
*
* <b>Note:</b> §1.3.3 in Geomatics Guidance Note number 7 part 2 (April 2015) uses a series expansion
diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueMercator.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueMercator.java
index c4380df..7203e1f 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueMercator.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ObliqueMercator.java
@@ -55,7 +55,7 @@ import static org.apache.sis.internal.referencing.provider.ObliqueMercatorCenter
* @author Rueben Schulz (UBC)
* @author Martin Desruisseaux (Geomatys)
* @author Rémi Maréchal (Geomatys)
- * @version 1.0
+ * @version 1.2
*
* @see Mercator
* @see TransverseMercator
@@ -393,6 +393,13 @@ public class ObliqueMercator extends ConformalProjection {
* + sin(8χ)⋅(e⁸⋅4279/161280)
*
* The calculation of χ and its use in serie expansion is performed by the φ(t) function.
+ *
+ * Note: U shall be in the [−1 … +1] range, otherwise we get φ = NaN. At the limit U = ±1 we get φ = ±π/2
+ * (division by zero is okay: infinite intermediate values produce the correct final result with φ(∞)=-π/2).
+ * Empirical tests suggest that U is inside valid range even with points far outside the projection domain.
+ * We found out-of-range values only at short distances (about 0.01 meter) from pole. In those cases U was
+ * out-of-range only by 1 ULP. The (abs(U) >= 1) check is for handling those cases. Note that if U is NaN,
+ * then we want to use the general formula for propagating the NaN.
*/
final double x = srcPts[srcOff ];
final double y = srcPts[srcOff+1];
@@ -403,7 +410,7 @@ public class ObliqueMercator extends ConformalProjection {
final double V = sin(y);
final double U = (V*cosγ0 + S*sinγ0) / T;
final double λ = -atan2((S*cosγ0 - V*sinγ0), cos(y)) / B;
- final double φ = φ(pow(H / sqrt((1 + U) / (1 - U)), 1/B));
+ final double φ = (abs(U) >= 1) ? copySign(PI/2, U) : φ(pow(H / sqrt((1 + U) / (1 - U)), 1/B));
dstPts[dstOff ] = λ;
dstPts[dstOff+1] = φ;
}
diff --git a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueMercatorTest.java b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueMercatorTest.java
index 67e8d70..a3318ea 100644
--- a/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueMercatorTest.java
+++ b/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ObliqueMercatorTest.java
@@ -16,11 +16,14 @@
*/
package org.apache.sis.referencing.operation.projection;
+import org.opengis.test.ToleranceModifier;
import org.opengis.util.FactoryException;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.referencing.datum.Ellipsoid;
import org.opengis.referencing.operation.TransformException;
+import org.opengis.referencing.operation.MathTransformFactory;
import org.apache.sis.internal.referencing.provider.ObliqueMercatorCenter;
+import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.referencing.CommonCRS;
import org.apache.sis.parameter.Parameters;
import org.apache.sis.test.DependsOn;
@@ -34,7 +37,7 @@ import static java.lang.StrictMath.*;
*
* @author Martin Desruisseaux (Geomatys)
* @author Rémi Maréchal (Geomatys)
- * @version 1.0
+ * @version 1.2
* @since 1.0
* @module
*/
@@ -96,6 +99,32 @@ public final strictfp class ObliqueMercatorTest extends MapProjectionTestCase {
}
/**
+ * Tests with a latitude close to 90°.
+ *
+ * @throws FactoryException if an error occurred while creating the map projection.
+ * @throws TransformException if an error occurred while converting a point.
+ *
+ * <a href="https://issues.apache.org/jira/browse/SIS-532">SIS-532</a>
+ */
+ @Test
+ public void testPole() throws TransformException, FactoryException {
+ tolerance = 0.01;
+ transform = create(179.8, 89.8, -174).createMapProjection(DefaultFactories.forBuildin(MathTransformFactory.class));
+ transform = transform.inverse();
+ validate();
+ /*
+ * The projection of (180, 90) with SIS 1.1 is (+0.004715980030596256, 22338.795490272343).
+ * Empirical cordinates shifted by 0.01 meter: (-0.005463426921067797, 22338.792057282844).
+ * With those shifted coordinated, Apache SIS 1.1 was used to compute φ = NaN because the
+ * U′ value in `ObliqueMercator.inverseTransform(…)` was slightly greater than 1.
+ */
+ isInverseTransformSupported = false;
+ toleranceModifier = ToleranceModifier.GEOGRAPHIC;
+ verifyTransform(new double[] {-0.005464, 22338.792057},
+ new double[] {300, 90});
+ }
+
+ /**
* Tests the <cite>"Hotine Oblique Mercator (variant B)"</cite> (EPSG:9815) projection method.
* This test is defined in GeoAPI conformance test suite.
*