sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1668905 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ sis-utility/src/main/java/org/apache/sis/util/resources/
Date Tue, 24 Mar 2015 14:24:12 GMT
Author: desruisseaux
Date: Tue Mar 24 14:24:12 2015
New Revision: 1668905

URL: http://svn.apache.org/r1668905
Log:
Referencing: ported code to be needed for assertions in map projections.

Added:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Assertions.java
  (with props)
Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/UnitaryProjection.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties

Added: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Assertions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Assertions.java?rev=1668905&view=auto
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Assertions.java
(added)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Assertions.java
[UTF-8] Tue Mar 24 14:24:12 2015
@@ -0,0 +1,160 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.sis.referencing.operation.projection;
+
+import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.util.Static;
+
+import static java.lang.Math.*;
+
+
+/**
+ * Static methods for assertions. This is used only when Java 1.4 assertions are enabled.
+ * When a point has been projected using spherical formulas, compares with the same point
+ * transformed using spherical formulas and throw an exception if the result differ.
+ *
+ * @author  Martin Desruisseaux (Geomatys)
+ * @author  Rémi Maréchal (Geomatys)
+ * @since   0.6
+ * @version 0.6
+ * @module
+ */
+final class Assertions extends Static {
+    /**
+     * Maximum difference allowed when comparing the result of an inverse projections, in
radians.
+     * A value of 1E-7 radians is approximatively 0.5 kilometres.
+     * Note that inverse projections are typically less accurate than forward projections.
+     * This tolerance is set to such high value for avoiding too intrusive assertion errors.
+     * This is okay only for catching gross programming errors.
+     */
+    private static final double INVERSE_TOLERANCE = 1E-7;
+
+    /**
+     * Maximum difference allowed when comparing the result of forward projections,
+     * in distance on the unit ellipse. A value of 1E-7 is approximatively 0.1 metres.
+     */
+    private static final double FORWARD_TOLERANCE = 1E-7;
+
+    /**
+     * Maximum difference allowed between spherical and ellipsoidal formulas when
+     * comparing derivatives. Units are metres.
+     */
+    private static final double DERIVATIVE_TOLERANCE = 1E-1;
+
+    /**
+     * Do not allows instantiation of this class.
+     */
+    private Assertions() {
+    }
+
+    /**
+     * Checks if transform using spherical formulas produces the same result than ellipsoidal
formulas.
+     * This method is invoked during assertions only.
+     *
+     * @param  expected  The (easting,northing) computed by ellipsoidal formulas.
+     * @param  offset    Index of the coordinate in the {@code expected} array.
+     * @param  x         The easting computed by spherical formulas on the unit sphere.
+     * @param  y         The northing computed by spherical formulas on the unit sphere.
+     * @return Always {@code true}.
+     * @throws ProjectionException if the comparison failed.
+     */
+    static boolean checkTransform(final double[] expected, final int offset, final double
x, final double y)
+            throws ProjectionException
+    {
+        if (expected != null) {
+            compare("x", expected[offset  ], x, FORWARD_TOLERANCE);
+            compare("y", expected[offset+1], y, FORWARD_TOLERANCE);
+        }
+        return true;
+    }
+
+    /**
+     * Checks if inverse transform using spherical formulas produces the same result than
ellipsoidal formulas.
+     * This method is invoked during assertions only.
+     *
+     * @param  expected  The (longitude,latitude) computed by ellipsoidal formulas.
+     * @param  offset    Index of the coordinate in the {@code expected} array.
+     * @param  λ         The longitude computed by spherical formulas, in radians.
+     * @param  φ         The latitude computed by spherical formulas, in radians.
+     * @return Always {@code true}.
+     * @throws ProjectionException if the comparison failed.
+     */
+    static boolean checkInverseTransform(final double[] expected, final int offset, final
double λ, final double φ)
+            throws ProjectionException
+    {
+        compare("latitude",  expected[offset+1], φ, INVERSE_TOLERANCE);
+        compare("longitude", expected[offset  ], λ, INVERSE_TOLERANCE / abs(cos(φ)));
+        return true;
+    }
+
+    /**
+     * Checks if derivatives using spherical formulas produces the same result than ellipsoidal
formulas.
+     * This method is invoked during assertions only. The spherical formulas are used for
the "expected"
+     * results since they are simpler than the ellipsoidal formulas.
+     */
+    @SuppressWarnings("null")
+    static boolean checkDerivative(final Matrix spherical, final Matrix ellipsoidal) throws
ProjectionException {
+        if (spherical != null || ellipsoidal != null) { // NullPointerException is ok if
only one is null.
+            compare("m00", spherical.getElement(0,0), ellipsoidal.getElement(0,0), DERIVATIVE_TOLERANCE);
+            compare("m01", spherical.getElement(0,1), ellipsoidal.getElement(0,1), DERIVATIVE_TOLERANCE);
+            compare("m10", spherical.getElement(1,0), ellipsoidal.getElement(1,0), DERIVATIVE_TOLERANCE);
+            compare("m11", spherical.getElement(1,1), ellipsoidal.getElement(1,1), DERIVATIVE_TOLERANCE);
+        }
+        return true;
+    }
+
+    /**
+     * Compares two value for equality up to some tolerance threshold. This is used during
assertions only.
+     * The comparison does not fail if at least one value to compare is {@link Double#NaN}
or infinity.
+     *
+     * <p><strong>Hack:</strong> if the {@code variable} name starts by
lower-case {@code L}
+     * (as in "longitude" and "latitude"), then the value is assumed to be an angle in radians.
+     * This is used for formatting an error message, if needed.</p>
+     *
+     * @throws ProjectionException if the comparison failed.
+     */
+    private static void compare(final String variable, double expected, double actual, final
double tolerance)
+            throws ProjectionException
+    {
+        final double delta = abs(expected - actual);
+        if (delta > tolerance) {
+            if (variable.charAt(0) == 'l') {
+                actual   = toDegrees(actual);
+                expected = toDegrees(expected);
+            } else if (abs(actual) > 30 && abs(expected) > 30) {
+                /*
+                 * If the projected point tend toward infinity, treats the value as if is
was
+                 * really infinity. Note that 30 is considered as "close to infinity" because
+                 * of the result we get when projecting 90°N using Mercator spherical formula:
+                 *
+                 *     y = log(tan(π/4 + φ/2))
+                 *
+                 * Because there is no exact representation of π/2 in base 2, the tangent
+                 * function gives 1.6E+16 instead of infinity, which leads the logarithmic
+                 * function to give us 37.3.
+                 *
+                 * This behavior is tested in MercatorTest.testSphericalFormulas().
+                 */
+                if (signum(actual) == signum(expected)) {
+                    return;
+                }
+            }
+            throw new ProjectionException("Assertion error: expected " + variable + "= "
+ expected + " but got " +
+                    actual + ". Difference is " + delta + " and comparison threshold was
" + tolerance + '.');
+        }
+    }
+}

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Assertions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/Assertions.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain;charset=UTF-8

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/UnitaryProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/UnitaryProjection.java?rev=1668905&r1=1668904&r2=1668905&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/UnitaryProjection.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/UnitaryProjection.java
[UTF-8] Tue Mar 24 14:24:12 2015
@@ -211,6 +211,18 @@ public abstract class UnitaryProjection
     }
 
     /**
+     * Ensures that this projection is done on a sphere rather than an ellipsoid.
+     * This method is invoked by constructors of classes implementing only spherical formulas.
+     *
+     * @throws IllegalArgumentException If the projection is not done on a sphere.
+     */
+    final void ensureSpherical() throws IllegalArgumentException {
+        if (!isSpherical()) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.EllipticalNotSupported));
+        }
+    }
+
+    /**
      * Converts a single coordinate in {@code srcPts} at the given offset and stores the
result
      * in {@code dstPts} at the given offset. In addition, opportunistically computes the
      * transform derivative if requested.
@@ -270,7 +282,7 @@ public abstract class UnitaryProjection
      * @param dstPts The array into which the converted point coordinate is returned (may
be the same than {@code srcPts}).
      *               Ordinates will be (<var>longitude</var>, <var>latitude</var>)
angles in <strong>radians</strong>.
      * @param dstOff The offset of the location of the converted point that is stored in
the destination array.
-     * @throws ProjectionException if the point can't be converted.
+     * @throws ProjectionException if the point can not be converted.
      */
     protected abstract void inverseTransform(double[] srcPts, int srcOff, double[] dstPts,
int dstOff)
             throws ProjectionException;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java?rev=1668905&r1=1668904&r2=1668905&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.java
[UTF-8] Tue Mar 24 14:24:12 2015
@@ -221,6 +221,11 @@ public final class Errors extends Indexe
         public static final short ElementNotFound_1 = 70;
 
         /**
+         * Elliptical projection not supported.
+         */
+        public static final short EllipticalNotSupported = 182;
+
+        /**
          * Argument ‘{0}’ shall not be empty.
          */
         public static final short EmptyArgument_1 = 20;

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties?rev=1668905&r1=1668904&r2=1668905&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors.properties
[ISO-8859-1] Tue Mar 24 14:24:12 2015
@@ -55,6 +55,7 @@ DuplicatedOption_1                = Opti
 DuplicatedParameterName_4         = Name or alias for parameter \u201c{0}\u201d at index
{1} conflict with name \u201c{2}\u201d at index {3}.
 ElementAlreadyPresent_1           = Element \u201c{0}\u201d is already present.
 ElementNotFound_1                 = Element \u201c{0}\u201d has not been found.
+EllipticalNotSupported            = Elliptical projection not supported.
 EmptyArgument_1                   = Argument \u2018{0}\u2019 shall not be empty.
 EmptyDictionary                   = The dictionary shall contain at least one entry.
 EmptyEnvelope2D                   = Envelope must be at least two-dimensional and non-empty.

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties?rev=1668905&r1=1668904&r2=1668905&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/resources/Errors_fr.properties
[ISO-8859-1] Tue Mar 24 14:24:12 2015
@@ -45,6 +45,7 @@ DuplicatedOption_1                = L\u2
 DuplicatedParameterName_4         = Le nom ou un alias pour le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb
\u00e0 l\u2019index {1} duplique le nom \u00ab\u202f{2}\u202f\u00bb \u00e0 l\u2019index {3}.
 ElementAlreadyPresent_1           = L\u2019\u00e9lement \u00ab\u202f{0}\u202f\u00bb est d\u00e9j\u00e0
pr\u00e9sent.
 ElementNotFound_1                 = L\u2019\u00e9lement \u00ab\u202f{0}\u202f\u00bb n\u2019a
pas \u00e9t\u00e9 trouv\u00e9.
+EllipticalNotSupported            = Projection elliptique non-support\u00e9e.
 EmptyArgument_1                   = L\u2019argument \u2018{0}\u2019 ne doit pas \u00eatre
vide.
 EmptyDictionary                   = Le dictionnaire doit contenir au moins une entr\u00e9e.
 EmptyEnvelope2D                   = L\u2019enveloppe doit avoir au moins deux dimensions
et ne pas \u00eatre vide.



Mime
View raw message