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.


Reply via email to