Author: desruisseaux
Date: Mon Mar 23 10:00:12 2015
New Revision: 1668581
URL: http://svn.apache.org/r1668581
Log:
Referencing: documentation fix, and added missing methods in UnitaryProjection.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/UnitaryProjection.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/UnitaryProjectionTest.java
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=1668581&r1=1668580&r2=1668581&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] Mon Mar 23 10:00:12 2015
@@ -17,6 +17,8 @@
package org.apache.sis.referencing.operation.projection;
import java.io.Serializable;
+import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.MathTransform2D;
@@ -28,11 +30,16 @@ import org.apache.sis.referencing.operat
import org.apache.sis.referencing.operation.transform.AbstractMathTransform2D;
import org.apache.sis.referencing.operation.transform.ContextualParameters;
import org.apache.sis.internal.referencing.provider.MapProjection;
+import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.util.Numerics;
import static java.lang.Math.*;
import static java.lang.Double.*;
import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+// Branch-dependent imports
+import java.util.Objects;
+
/**
* Base class for conversion services between ellipsoidal and cartographic
projections.
@@ -40,13 +47,13 @@ import static org.apache.sis.util.Argume
* computations are performed for a sphere having a semi-major axis of 1. More
specifically:
*
* <ul class="verbose">
- * <li>On input, the {@link #transform(double[], int, double[], int,
boolean) transform} method
+ * <li>On input, the {@link #transform(double[], int, double[], int,
boolean) transform(…)} method
* expects (<var>longitude</var>, <var>latitude</var>) angles in
<strong>radians</strong>.
* Longitudes have the <cite>central meridian</cite> removed before the
transform method is invoked.
* The conversion from degrees to radians and the longitude rotation are
applied by the
* {@linkplain ContextualParameters#normalization(boolean) normalize} affine
transform.</li>
*
- * <li>On output, the {@link #transform(double[],int,double[],int,boolean)
transform} method returns
+ * <li>On output, the {@link #transform(double[],int,double[],int,boolean)
transform(…)} method returns
* (<var>easting</var>, <var>northing</var>) values on a sphere or ellipse
having a semi-major axis length of 1.
* The multiplication by the scale factor and the false easting/northing
offsets are applied by the
* {@linkplain ContextualParameters#normalization(boolean) denormalize}
affine transform.</li>
@@ -59,7 +66,8 @@ import static org.apache.sis.util.Argume
* (typically some combinations of inverse projection followed by a direct
projection).
*
* <p>All angles (either fields, method parameters or return values) in this
class and subclasses are
- * in radians. This is the opposite of {@link Parameters} where all angles are
in decimal degrees.</p>
+ * in radians. This is the opposite of {@link Parameters} where all angles are
in CRS-dependent units,
+ * typically decimal degrees.</p>
*
* <div class="section">Serialization</div>
* Serialization of this class is appropriate for short-term storage or RMI
use, but may not be compatible
@@ -127,8 +135,8 @@ public abstract class UnitaryProjection
protected final double excentricity;
/**
- * The square of excentricity: e² = (a²-b²)/a² where
- * <var>e</var> is the {@linkplain #excentricity excentricity},
+ * The square of excentricity: ℯ² = (a²-b²)/a² where
+ * <var>ℯ</var> is the {@linkplain #excentricity excentricity},
* <var>a</var> is the <cite>semi-major</cite> axis length and
* <var>b</var> is the <cite>semi-minor</cite> axis length.
*/
@@ -156,19 +164,56 @@ public abstract class UnitaryProjection
}
/**
+ * Returns the parameters used for creating the complete map projection.
Those parameters describe a sequence
+ * of <cite>normalize</cite> → {@code this} → <cite>denormalize</cite>
transforms. They are used for formatting
+ * <cite>Well Known Text</cite> (WKT) and error messages. Subclasses shall
not use the values defined in the
+ * returned object for computation purpose, except at construction time.
+ *
+ * @return The parameters values for the sequence of
<cite>normalize</cite> → {@code this} → <cite>denormalize</cite>
+ * transforms, or {@code null} if unspecified.
+ */
+ @Override
+ protected final ContextualParameters getContextualParameters() {
+ return parameters;
+ }
+
+ /**
+ * Returns a copy of the parameter values for this projection.
+ * This base class supplies a value for the following parameters:
+ *
+ * <ul>
+ * <li>Semi-major axis length, which is set to 1.</li>
+ * <li>Semi-minor axis length, which is set to
+ * <code>sqrt(1 - {@linkplain #excentricitySquared ℯ²})</code>.</li>
+ * </ul>
+ *
+ * Subclasses must complete.
+ *
+ * @return A copy of the parameter values for this unitary projection.
+ */
+ @Override
+ public ParameterValueGroup getParameterValues() {
+ final ParameterDescriptorGroup descriptor =
super.getParameterDescriptors();
+ final ParameterValueGroup values = descriptor.createValue();
+ values.parameter(Constants.SEMI_MAJOR).setValue(1.0);
+ values.parameter(Constants.SEMI_MINOR).setValue(sqrt(1 -
excentricitySquared));
+ return values;
+ }
+
+ /**
* 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.
*
* <div class="section">Normalization</div>
- * <p>The input ordinates are (<var>λ</var>,<var>φ</var>) (the variable
names for <var>longitude</var> and
+ * The input ordinates are (<var>λ</var>,<var>φ</var>) (the variable names
for <var>longitude</var> and
* <var>latitude</var> respectively) angles in radians.
* Input coordinate shall have the <cite>central meridian</cite> removed
from the longitude by the caller
* before this method is invoked. After this method is invoked, the caller
will need to multiply the output
* coordinate by the global <cite>scale factor</cite>
* and apply the (<cite>false easting</cite>, <cite>false northing</cite>)
offset.
* This means that projections that implement this method are performed on
a sphere or ellipse
- * having a semi-major axis length of 1.</p>
+ * having a semi-major axis length of 1.
*
* <div class="note"><b>Note:</b> in <a
href="http://trac.osgeo.org/proj/">PROJ.4</a>, the same standardization,
* described above, is handled by {@code pj_fwd.c}.</div>
@@ -201,11 +246,11 @@ public abstract class UnitaryProjection
* angles in radians, usually (but not necessarily) in the range [-π … π]
and [-π/2 … π/2] respectively.
*
* <div class="section">Normalization</div>
- * <p>Input coordinate shall have the (<cite>false easting</cite>,
<cite>false northing</cite>) removed
+ * Input coordinate shall have the (<cite>false easting</cite>,
<cite>false northing</cite>) removed
* by the caller and the result divided by the global <cite>scale
factor</cite> before this method is invoked.
* After this method is invoked, the caller will need to add the
<cite>central meridian</cite> to the longitude
* in the output coordinate. This means that projections that implement
this method are performed on a sphere
- * or ellipse having a semi-major axis of 1.</p>
+ * or ellipse having a semi-major axis of 1.
*
* <div class="note"><b>Note:</b> in <a
href="http://trac.osgeo.org/proj/">PROJ.4</a>, the same standardization,
* described above, is handled by {@code pj_inv.c}.</div>
@@ -277,6 +322,79 @@ public abstract class UnitaryProjection
}
}
+ /**
+ * Returns {@code true} if this class is a {@code Spherical} nested class.
+ * This information is used sometime for selecting formulas, and for
testing purpose.
+ *
+ * This method is not public because the usage of those nested classes is
specific to Apache SIS implementation.
+ */
+ boolean isSpherical() {
+ return false;
+ }
+
+ /**
+ * Computes a hash code value for this unitary projection.
+ * The default implementation computes a value from the parameters given
at construction time.
+ *
+ * @return The hash code value.
+ */
+ @Override
+ protected int computeHashCode() {
+ return parameters.hashCode() + 31 * super.computeHashCode();
+ }
+
+ /**
+ * Compares the given object with this transform for equivalence. The
default implementation checks if
+ * {@code object} is an instance of the same class than {@code this}, then
compares the excentricity.
+ *
+ * <p>If this method returns {@code true}, then for any given identical
source position, the two compared
+ * unitary projections shall compute the same target position. Many of the
{@linkplain Parameters projection
+ * parameters} used for creating the unitary projections are irrelevant
and don not need to be known.
+ * Those projection parameters will be compared only if the comparison
mode is {@link ComparisonMode#STRICT}
+ * or {@link ComparisonMode#BY_CONTRACT BY_CONTRACT}.</p>
+ *
+ * <div class="note"><b>Example:</b>
+ * a {@linkplain Mercator Mercator} projection can be created in the 2SP
case with a <cite>standard parallel</cite>
+ * value of 60°. The same projection can also be created in the 1SP case
with a <cite>scale factor</cite> of 0.5.
+ * Nevertheless those two unitary projections applied on a sphere gives
identical results. Considering them as
+ * equivalent allows the referencing module to transform coordinates
between those two projections more efficiently.
+ * </div>
+ *
+ * @param object The object to compare with this unitary projection for
equivalence.
+ * @param mode The strictness level of the comparison. Default to {@link
ComparisonMode#STRICT}.
+ * @return {@code true} if the given object is equivalent to this unitary
projection.
+ */
+ @Override
+ public boolean equals(final Object object, final ComparisonMode mode) {
+ if (object == this) {
+ return true;
+ }
+ if (super.equals(object, mode)) {
+ final double e1, e2;
+ final UnitaryProjection that = (UnitaryProjection) object;
+ if (mode.ordinal() < ComparisonMode.IGNORE_METADATA.ordinal()) {
+ if (!Objects.equals(parameters, that.parameters)) {
+ return false;
+ }
+ e1 = this.excentricitySquared;
+ e2 = that.excentricitySquared;
+ } else {
+ e1 = this.excentricity;
+ e2 = that.excentricity;
+ }
+ /*
+ * There is no need to compare both 'excentricity' and
'excentricitySquared' since
+ * the former is computed from the later. In strict comparison
mode, we are better
+ * to compare the 'excentricitySquared' since it is the original
value from which
+ * the other value is derived. However in approximative comparison
mode, we need
+ * to use the 'excentricity', otherwise we would need to take the
square of the
+ * tolerance factor before comparing 'excentricitySquared'.
+ */
+ return Numerics.epsilonEqual(e1, e2, mode);
+ }
+ return false;
+ }
+
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java?rev=1668581&r1=1668580&r2=1668581&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/ContextualParameters.java
[UTF-8] Mon Mar 23 10:00:12 2015
@@ -117,10 +117,10 @@ public class ContextualParameters extend
/**
* The affine transform to be applied before (<cite>normalize</cite>) and
after (<cite>denormalize</cite>)
- the kernel operation.On {@code ContextualParameters} construction, those
affines are initially identity
- transforms, to be modified in-place by callers of {@link
#normalization(boolean)}.
- After {@link #createConcatenatedTransform(MathTransformFactory,
MathTransform)} has been invoked,
- they are typically (but not necessarily) replaced by the {@link
LinearTransform} instance itself.
+ * the kernel operation.On {@code ContextualParameters} construction,
those affines are initially identity
+ * transforms, to be modified in-place by callers of {@link
#normalization(boolean)}.
+ * After {@link #createConcatenatedTransform(MathTransformFactory,
MathTransform)} has been invoked,
+ * they are typically (but not necessarily) replaced by the {@link
LinearTransform} instance itself.
* @see #normalization(boolean)
*/
denormalize;
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/UnitaryProjectionTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/UnitaryProjectionTest.java?rev=1668581&r1=1668580&r2=1668581&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/UnitaryProjectionTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/UnitaryProjectionTest.java
[UTF-8] Mon Mar 23 10:00:12 2015
@@ -119,7 +119,6 @@ public final strictfp class UnitaryProje
/**
* Tests the {@link UnitaryProjection#t(double, double)} function.
- * This is also a test of the forward Mercator projection in the
ellipsoidal case.
*
* {@preformat text
* Forward: y = -log(tsfn(φ))
@@ -152,6 +151,10 @@ public final strictfp class UnitaryProje
assertTrue ("Out of bounds", t(PI*3/2) <
-1E+16);
assertEquals("Function periodicity", 1, t(2*PI),
TOLERANCE);
assertEquals("Function periodicity", 0, t(PI*5/2),
TOLERANCE);
+ /*
+ * Use in a way close to (but not identical)
+ * to the way the Mercator projection need it.
+ */
assertEquals("Forward 0°N", 0, -log(t(0)),
TOLERANCE);
assertEquals("Forward 90°N", POSITIVE_INFINITY, -log(t(+PI/2)),
TOLERANCE);
assertTrue ("Forward 90°S", -LN_INFINITY > -log(t(-PI/2)));