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 2015/03/24 15:24:12 UTC
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/
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.