Author: desruisseaux
Date: Tue Jul 28 17:18:30 2015
New Revision: 1693133
URL: http://svn.apache.org/r1693133
Log:
WKT: Convention.INTERNAL should display the real internal parameters used by a
map projection implementation.
Those internal parameters are very different than the public parameters, but
are sometime needed for debugging.
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.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/LambertConformalTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/ISOMetadata.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -32,6 +32,7 @@ import org.apache.sis.metadata.MetadataS
import org.apache.sis.metadata.ModifiableMetadata;
import org.apache.sis.internal.jaxb.IdentifierMapWithSpecialCases;
import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.util.Utilities;
import org.apache.sis.util.collection.Containers;
import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.CharSequences;
@@ -107,7 +108,7 @@ public class ISOMetadata extends Modifia
* without invoking super.getIdentifiers(), in which case
their identifiers will not be copied.
* For safety, we will do this optimization only if the
implementation is an Apache SIS one.
*/
- if (object.getClass().getName().startsWith("org.apache.sis."))
{
+ if (Utilities.isSIS(object.getClass())) {
return;
}
}
Modified:
sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-metadata/src/test/java/org/apache/sis/test/MetadataAssert.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -30,7 +30,7 @@ import org.apache.sis.io.wkt.Convention;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
- * @version 0.5
+ * @version 0.6
* @module
*/
public strictfp class MetadataAssert extends Assert {
@@ -109,4 +109,31 @@ public strictfp class MetadataAssert ext
((IdentifiedObject) object).getName().getCode() :
object.getClass().getSimpleName(), expected, wkt);
}
}
+
+ /**
+ * Asserts that the WKT of the given object according the given convention
is equal to the given regular expression.
+ * This method is like {@link #assertWktEquals(String, Object)}, but the
use of regular expression allows some
+ * tolerance for example on numerical parameter values that may be subject
to a limited form of rounding errors.
+ *
+ * @param convention The WKT convention to use.
+ * @param expected The expected regular expression, or {@code null} if
{@code object} is expected to be null.
+ * @param object The object to format in <cite>Well Known Text</cite>
format, or {@code null}.
+ *
+ * @since 0.6
+ */
+ public static void assertWktEqualsRegex(final Convention convention, final
String expected, final Object object) {
+ if (expected == null) {
+ assertNull(object);
+ } else {
+ assertNotNull(object);
+ final String wkt;
+ synchronized (WKT_FORMAT) {
+ WKT_FORMAT.setConvention(convention);
+ wkt = WKT_FORMAT.format(object);
+ }
+ if (!wkt.matches(expected)) {
+ fail("WKT does not match the expected regular expression. The
WKT that we got is:\n" + wkt);
+ }
+ }
+ }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -32,6 +32,7 @@ import org.apache.sis.internal.referenci
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.internal.util.Utilities;
import
org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
import org.apache.sis.util.collection.WeakHashSet;
import org.apache.sis.util.collection.Containers;
@@ -569,7 +570,7 @@ public class DefaultCoordinateOperationF
return delegate;
}
for (final CoordinateOperationFactory factory :
java.util.ServiceLoader.load(CoordinateOperationFactory.class)) {
- if (!factory.getClass().getName().startsWith("org.apache.sis.")) {
+ if (!Utilities.isSIS(factory.getClass())) {
delegate = factory;
return factory;
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ConformalProjection.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -45,6 +45,12 @@ import static java.lang.Math.*;
* appear to be the same with the <var>n</var> factor fixed to 1 or -1, so we
leverage the code provided by
* this base class. This class hierarchy is only an implementation convenience
and not part of public API.</p>
*
+ * <div class="note"><b>Reference:</b>
+ * “Lambert developed the regular Conformal Conic as the oblique aspect of a
family containing the previously
+ * known polar Stereographic and regular Mercator projections. (…) If the
standard parallels are symmetrical
+ * about the Equator, the regular Mercator results (although formulas must be
revised). If the only standard
+ * parallel is a pole, the polar Stereographic results.” (Snyder, page
105)</div>
+ *
* @author Martin Desruisseaux (Geomatys)
* @since 0.6
* @version 0.6
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/LambertConformal.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -19,7 +19,6 @@ package org.apache.sis.referencing.opera
import java.util.Map;
import java.util.EnumMap;
import org.opengis.util.FactoryException;
-import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransformFactory;
@@ -36,12 +35,8 @@ import org.apache.sis.internal.referenci
import org.apache.sis.internal.referencing.provider.LambertConformalMichigan;
import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.internal.util.DoubleDouble;
-import org.apache.sis.internal.util.Constants;
-import org.apache.sis.internal.util.Numerics;
import org.apache.sis.util.resources.Errors;
-import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.Workaround;
-import org.apache.sis.util.Debug;
import static java.lang.Math.*;
import static java.lang.Double.*;
@@ -118,6 +113,11 @@ public class LambertConformal extends Co
* <li>If φ1 = φ2 = ±90°, then this {@code n} value become ±1. The
formulas in the transform and
* inverse transform methods become basically the same than the ones
in {@link PolarStereographic},
* (de)normalization matrices contain NaN values.</li>
+ * <li>Depending on how the formulas are written, <var>n</var> may be
positive in the South hemisphere and
+ * negative in the North hemisphere (or conversely). However Apache
SIS adjusts the coefficients of the
+ * (de)normalization matrices in order to keep <var>n</var>
positive, because the formulas are slightly
+ * more accurate for positive <var>n</var> values. However this
adjustment is optional and can be disabled
+ * in the constructor.</li>
* </ul>
*/
final double n;
@@ -329,6 +329,24 @@ public class LambertConformal extends Co
}
/**
+ * Returns the names of additional internal parameters which need to be
taken in account when
+ * comparing two {@code LambertConformal} projections or formatting them
in debug mode.
+ */
+ @Override
+ String[] getInternalParameterNames() {
+ return new String[] {"n"};
+ }
+
+ /**
+ * Returns the values of additional internal parameters which need to be
taken in account when
+ * comparing two {@code LambertConformal} projections or formatting them
in debug mode.
+ */
+ @Override
+ double[] getInternalParameterValues() {
+ return new double[] {n};
+ }
+
+ /**
* Returns the sequence of <cite>normalization</cite> → {@code this} →
<cite>denormalization</cite> transforms
* as a whole. The transform returned by this method except
(<var>longitude</var>, <var>latitude</var>)
* coordinates in <em>degrees</em> and returns (<var>x</var>,<var>y</var>)
coordinates in <em>metres</em>.
@@ -350,48 +368,6 @@ public class LambertConformal extends Co
}
/**
- * Returns a copy of the parameter values for this projection.
- * This method supplies a value only for the following parameters:
- *
- * <ul>
- * <li>Semi-major axis length of 1</li>
- * <li>Semi-minor axis length of <code>sqrt(1 - {@linkplain
#excentricitySquared ℯ²})</code></li>
- * <li>Only one of the following:
- * <ul>
- * <li>Natural origin (1SP case)</li>
- * </ul>
- * or, in the 2SP case:
- * <ul>
- * <li>Standard parallel 1</li>
- * <li>Standard parallel 2</li>
- * </ul>
- * </li>
- * </ul>
- *
- * No other parameters are set because only the above-cited ones are
significant for the non-linear part
- * of this projection.
- *
- * <div class="note"><b>Note:</b>
- * This method is mostly for {@linkplain
org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
- * since the isolation of non-linear parameters in this class is highly
implementation dependent.
- * Most GIS applications will instead be interested in the {@linkplain
#getContextualParameters()
- * contextual parameters}.</div>
- *
- * @return A copy of the parameter values for this normalized projection.
- */
- @Debug
- @Override
- public ParameterValueGroup getParameterValues() {
- return getParameterValues(new String[] {
- Constants.SEMI_MAJOR,
- Constants.SEMI_MINOR,
- Constants.STANDARD_PARALLEL_1,
- Constants.STANDARD_PARALLEL_2,
- "latitude_of_origin"
- });
- }
-
- /**
* Converts the specified (θ,φ) coordinate (units in radians) and stores
the result in {@code dstPts}.
* In addition, opportunistically computes the projection derivative if
{@code derivate} is {@code true}.
*
@@ -567,17 +543,4 @@ public class LambertConformal extends Co
dstPts[dstOff+1] = PI/2 - 2*atan(pow(1/ρ, 1/n));
}
}
-
- /**
- * Compares the given object with this transform for equivalence.
- *
- * @return {@code true} if the given object is equivalent to this map
projection.
- */
- @Override
- public boolean equals(final Object object, final ComparisonMode mode) {
- if (super.equals(object, mode)) {
- return Numerics.epsilonEqual(n, ((LambertConformal) object).n,
mode);
- }
- return false;
- }
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -16,16 +16,14 @@
*/
package org.apache.sis.referencing.operation.projection;
-import java.util.List;
-import java.util.ArrayList;
import java.util.Map;
+import java.util.HashMap;
import java.io.Serializable;
+import java.lang.reflect.Modifier;
import org.opengis.metadata.Identifier;
-import org.opengis.parameter.ParameterValue;
import org.opengis.parameter.ParameterValueGroup;
import org.opengis.parameter.ParameterDescriptor;
import org.opengis.parameter.ParameterDescriptorGroup;
-import org.opengis.parameter.GeneralParameterDescriptor;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.MathTransform2D;
@@ -34,18 +32,21 @@ import org.opengis.referencing.operation
import org.opengis.referencing.operation.MathTransformFactory;
import org.opengis.util.FactoryException;
import org.apache.sis.util.Debug;
+import org.apache.sis.util.CharSequences;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.parameter.Parameters;
-import org.apache.sis.parameter.DefaultParameterDescriptorGroup;
-import org.apache.sis.referencing.IdentifiedObjects;
+import org.apache.sis.parameter.ParameterBuilder;
+import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
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.referencing.Formulas;
+import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.util.DoubleDouble;
import org.apache.sis.internal.util.Constants;
+import org.apache.sis.internal.util.Utilities;
import org.apache.sis.internal.util.Numerics;
import static java.lang.Math.*;
@@ -160,6 +161,17 @@ public abstract class NormalizedProjecti
static final int MAXIMUM_ITERATIONS = 15;
/**
+ * The internal parameter descriptors. Keys are implementation classes.
Values are parameter descriptor groups
+ * containing at least a parameter for the {@link #excentricity} value,
and optionally other internal parameter
+ * added by some subclasses.
+ *
+ * <p>Entries are created only when first needed. Those descriptors are
usually never created since they are
+ * used only by {@link #getParameterDescriptors()}, which is itself
invoked mostly for debugging purpose.</p>
+ */
+ @Debug
+ private static final Map<Class<?>,ParameterDescriptorGroup> DESCRIPTORS =
new HashMap<>();
+
+ /**
* The parameters used for creating this projection. They are used for
formatting <cite>Well Known Text</cite> (WKT)
* and error messages. Subclasses shall not use the values defined in this
object for computation purpose, except at
* construction time.
@@ -566,18 +578,11 @@ public abstract class NormalizedProjecti
}
/**
- * Returns a copy of the parameter values for this projection.
- * This base class supplies a value only 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 if needed. Many projections will not need to
complete,
- * because most parameters like the scale factor or the false
easting/northing can
- * be handled by the (de)normalization affine transforms.
+ * Returns a copy of non-linear internal parameter values of this {@code
NormalizedProjection}.
+ * The returned group contained at least the {@link #excentricity}
parameter value.
+ * Some subclasses add more non-linear parameters, but most of them do not
because many parameters
+ * like the <cite>scale factor</cite> or the <cite>false
easting/northing</cite> are handled by the
+ * {@linkplain ContextualParameters#getMatrix(boolean) (de)normalization
affine transforms} instead.
*
* <div class="note"><b>Note:</b>
* This method is mostly for {@linkplain
org.apache.sis.io.wkt.Convention#INTERNAL debugging purposes}
@@ -585,56 +590,85 @@ public abstract class NormalizedProjecti
* Most GIS applications will instead be interested in the {@linkplain
#getContextualParameters()
* contextual parameters}.</div>
*
- * @return A copy of the parameter values for this normalized projection.
+ * @return A copy of the internal parameter values for this normalized
projection.
*/
@Debug
@Override
public ParameterValueGroup getParameterValues() {
- return getParameterValues(new String[] {
- Constants.SEMI_MAJOR,
- Constants.SEMI_MINOR
- });
+ final ParameterValueGroup group =
getParameterDescriptors().createValue();
+ group.parameter("excentricity").setValue(excentricity);
+ final String[] names = getInternalParameterNames();
+ final double[] values = getInternalParameterValues();
+ for (int i=0; i<names.length; i++) {
+ group.parameter(names[i]).setValue(values[i]);
+ }
+ return group;
}
/**
- * Filters the parameter descriptor in order to retain only the parameters
of the given names, and
- * sets the semi-major and semi-minor axis lengths. The specified
parameters list should contains at
- * least the {@code "semi_major"} and {@code "semi_minor"} strings.
+ * Returns a description of the non-linear internal parameters of this
{@code NormalizedProjection}.
+ * The returned group contained at least a descriptor for the {@link
#excentricity} parameter.
+ * Subclasses may add more parameters.
+ *
+ * <p>This method is for inspecting the parameter values of this
non-linear kernel only,
+ * not for inspecting the {@linkplain #getContextualParameters()
contextual parameters}.
+ * Inspecting the kernel parameter values is usually for debugging purpose
only.</p>
*
- * <p>This filtered descriptor is used for displaying the parameter values
of this non-linear kernel only,
- * not for displaying the {@linkplain #getContextualParameters()
contextual parameters}. Since displaying
- * the kernel parameter values is for debugging purpose only, it is not
worth to cache this descriptor.</p>
+ * @return A description of the internal parameters.
*/
@Debug
- final ParameterValueGroup getParameterValues(final String[]
nonLinearParameters) {
- ParameterDescriptorGroup descriptor = getParameterDescriptors();
- final List<GeneralParameterDescriptor> filtered = new
ArrayList<>(nonLinearParameters.length);
- for (final GeneralParameterDescriptor p : descriptor.descriptors()) {
- for (final String name : nonLinearParameters) {
- if (IdentifiedObjects.isHeuristicMatchForName(p, name)) {
- filtered.add(p);
- break;
+ @Override
+ public ParameterDescriptorGroup getParameterDescriptors() {
+ Class<?> type = getClass();
+ while (!Modifier.isPublic(type.getModifiers())) {
+ type = type.getSuperclass();
+ }
+ ParameterDescriptorGroup group;
+ synchronized (DESCRIPTORS) {
+ group = DESCRIPTORS.get(type);
+ if (group == null) {
+ final ParameterBuilder builder = new
ParameterBuilder().setRequired(true);
+ if (Utilities.isSIS(type)) {
+ builder.setCodeSpace(Citations.SIS, "SIS");
}
+ final String[] names = getInternalParameterNames();
+ final ParameterDescriptor<?>[] parameters = new
ParameterDescriptor<?>[names.length + 1];
+ for (int i=0; i<parameters.length; i++) {
+ final ParameterDescriptor<?> p;
+ if (i == 0) {
+ final ParameterDescriptorGroup existing =
CollectionsExt.first(DESCRIPTORS.values());
+ if (existing != null) {
+ p = (ParameterDescriptor<?>)
existing.descriptor("excentricity");
+ } else {
+ p = builder.addName(Citations.SIS,
"excentricity").createBounded(0, 1, Double.NaN, null);
+ }
+ } else {
+ p = builder.addName(names[i-1]).create(Double.class,
null);
+ }
+ parameters[i] = p;
+ }
+ group =
builder.addName(CharSequences.camelCaseToSentence(type.getSimpleName())).createGroup(1,
1, parameters);
+ DESCRIPTORS.put(type, group);
}
}
- descriptor = new
DefaultParameterDescriptorGroup(IdentifiedObjects.getProperties(descriptor),
- 1, 1, filtered.toArray(new
GeneralParameterDescriptor[filtered.size()]));
- /*
- * Parameter values for the ellipsoid semi-major and semi-minor axis
lengths are 1 and <= 1
- * respectively because the denormalization (e.g. multiplication by a
scale factor) will be
- * applied by an affine transform after this NormalizedProjection.
- */
- final ParameterValueGroup values = descriptor.createValue();
- for (final GeneralParameterDescriptor desc : filtered) {
- final String name = desc.getName().getCode();
- final ParameterValue<?> p = values.parameter(name);
- switch (name) {
- case Constants.SEMI_MAJOR: p.setValue(1.0); break;
- case Constants.SEMI_MINOR: p.setValue(sqrt(1 -
excentricitySquared)); break;
- default: p.setValue(context.parameter(name).getValue());
- }
- }
- return values;
+ return group;
+ }
+
+ /**
+ * Returns the names of any additional internal parameters (other than
{@link #excentricity})
+ * that this projection has. The length of this array must be the same
than the length of the
+ * {@link #getInternalParameterValues()} array, if the later is non-null.
+ */
+ String[] getInternalParameterNames() {
+ return CharSequences.EMPTY_ARRAY;
+ }
+
+ /**
+ * Returns the values of any additional internal parameters (other than
{@link #excentricity}) that
+ * this projection has. Those values are also compared by {@link
#equals(Object, ComparisonMode)}.
+ */
+ double[] getInternalParameterValues() {
+ return null;
}
/**
@@ -760,14 +794,20 @@ public abstract class NormalizedProjecti
}
/**
- * Computes a hash code value for this map projection.
- * The default implementation computes a value from the parameters given
at construction time.
+ * Computes a hash code value for this {@code NormalizedProjection}.
*
* @return The hash code value.
*/
@Override
protected int computeHashCode() {
- return context.hashCode() + 31 * super.computeHashCode();
+ long c = Double.doubleToLongBits(excentricity);
+ final double[] parameters = getInternalParameterValues();
+ if (parameters != null) {
+ for (int i=0; i<parameters.length; i++) {
+ c = c*31 + Double.doubleToLongBits(parameters[i]);
+ }
+ }
+ return super.computeHashCode() ^ Numerics.hashCode(c);
}
/**
@@ -817,7 +857,23 @@ public abstract class NormalizedProjecti
* 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);
+ if (Numerics.epsilonEqual(e1, e2, mode)) {
+ final double[] parameters = getInternalParameterValues();
+ if (parameters != null) {
+ /*
+ * super.equals(…) guarantees that the two objects are of
the same class.
+ * So in SIS implementation, this implies that the arrays
have the same length.
+ */
+ final double[] others = that.getInternalParameterValues();
+ assert others.length == parameters.length;
+ for (int i=0; i<parameters.length; i++) {
+ if (!Numerics.epsilonEqual(parameters[i], others[i],
mode)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
}
return false;
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -874,14 +874,13 @@ public abstract class AbstractMathTransf
* <p>The default implementation returns {@code true} if the following
conditions are meet:</p>
* <ul>
* <li>{@code object} is an instance of the same class than {@code
this}. We require the
- * same class because there is no interface for the various kinds
of transform.</li>
- * <li>The {@linkplain #getParameterDescriptors() parameter descriptors}
are equal according
+ * same class because there is no interface for the various kinds of
transform.</li>
+ * <li>If the hash code value has already been {@linkplain
#computeHashCode() computed} for both
+ * instances, their values are the same <i>(opportunist performance
enhancement)</i>.</li>
+ * <li>The {@linkplain #getContextualParameters() contextual parameters}
are equal according
* the given comparison mode.</li>
* </ul>
*
- * The {@linkplain #getParameterValues() parameter values} are
<strong>not</strong> compared because
- * subclasses can typically compare those values more efficiently by
accessing to their member fields.
- *
* @param object The object to compare with this transform.
* @param mode The strictness level of the comparison. Default to {@link
ComparisonMode#STRICT STRICT}.
* @return {@code true} if the given object is considered equals to this
math transform.
@@ -909,8 +908,8 @@ public abstract class AbstractMathTransf
if (mode.ordinal() >= ComparisonMode.IGNORE_METADATA.ordinal()) {
return true;
}
- return Utilities.deepEquals(this.getParameterDescriptors(),
- that.getParameterDescriptors(), mode);
+ return Utilities.deepEquals(this.getContextualParameters(),
+ that.getContextualParameters(), 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=1693133&r1=1693132&r2=1693133&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] Tue Jul 28 17:18:30 2015
@@ -562,7 +562,7 @@ public class ContextualParameters extend
*/
@Override
public int hashCode() {
- return (normalize.hashCode() + 31*denormalize.hashCode()) ^ (int)
serialVersionUID;
+ return (normalize.hashCode() + 31*denormalize.hashCode()) ^
Arrays.hashCode(values) ^ (int) serialVersionUID;
}
/**
@@ -575,9 +575,10 @@ public class ContextualParameters extend
public boolean equals(final Object object) {
if (object != null && object.getClass() == getClass()) {
final ContextualParameters that = (ContextualParameters) object;
- return Objects.equals(descriptor, that.descriptor) &&
- Objects.equals(normalize, that.normalize) &&
- Objects.equals(denormalize, that.denormalize);
+ return Objects.equals(descriptor, that.descriptor) &&
+ Objects.equals(normalize, that.normalize) &&
+ Objects.equals(denormalize, that.denormalize) &&
+ Arrays.equals(values, that.values);
}
return false;
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/LambertConformalTest.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -73,16 +73,22 @@ public final strictfp class LambertConfo
/**
* Tests the WKT formatting of {@link NormalizedProjection}. For the
Lambert Conformal projection, we expect
- * the standard parallels or the latitude of origin in addition to the
semi-major and semi-minor axis length.
+ * the internal {@code n} parameter in addition to the excentricity.
+ *
+ * <div class="section">Note on accuracy</div>
+ * The value of the excentricity parameter should be fully accurate
because it is calculated using only the
+ * {@link Math#sqrt(double)} function (ignoring basic algebraic
operations) which, according javadoc, must
+ * give the result closest to the true mathematical result. But the
functions involved in the calculation of
+ * <var>n</var> do not have such strong guarantees. So we use a regular
expression in this test for ignoring
+ * the 2 last digits of <var>n</var>.
*/
@Test
public void testNormalizedWKT() {
createNormalizedProjection(true, 40);
- assertWktEquals(
- "PARAM_MT[“Lambert_Conformal_Conic_1SP”,\n" +
- " PARAMETER[“semi_major”, 1.0],\n" +
- " PARAMETER[“semi_minor”, 0.9966471893352525],\n" +
- " PARAMETER[“latitude_of_origin”, 40.0]]");
+ assertWktEqualsRegex("\\Q" +
+ "PARAM_MT[“Lambert conformal”,\n" +
+ " PARAMETER[“excentricity”, 0.08181919084262157],\n" +
+ " PARAMETER[“n”, 0.64278760968653\\E\\d*\\]\\]"); //
0.6427876096865393 in the original test.
}
/**
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -65,16 +65,17 @@ public final strictfp class MercatorTest
/**
* Tests the WKT formatting of {@link NormalizedProjection}. For the
Mercator projection, we expect only
- * the semi-major and semi-minor axis length. We expect nothing else
because all other parameters are used
+ * the ellipsoid excentricity. We expect nothing else because all other
parameters are used
* by the (de)normalization affine transforms instead than the {@link
Mercator} class itself.
+ *
+ * @see LambertConformalTest#testNormalizedWKT()
*/
@Test
public void testNormalizedWKT() {
createNormalizedProjection(true);
assertWktEquals(
- "PARAM_MT[“Mercator_2SP”,\n" +
- " PARAMETER[“semi_major”, 1.0],\n" +
- " PARAMETER[“semi_minor”, 0.9966471893352525]]");
+ "PARAM_MT[“Mercator”,\n" +
+ " PARAMETER[“excentricity”, 0.08181919084262157]]");
}
/**
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/ProjectionResultComparator.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera
import java.util.Arrays;
import java.util.List;
import org.opengis.parameter.ParameterValueGroup;
+import org.opengis.parameter.ParameterDescriptorGroup;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.internal.referencing.Formulas;
@@ -170,6 +171,15 @@ final strictfp class ProjectionResultCom
}
/**
+ * Delegates to the {@link #tested} implementation.
+ */
+ @Debug
+ @Override
+ public ParameterDescriptorGroup getParameterDescriptors() {
+ return tested.getParameterDescriptors();
+ }
+
+ /**
* Delegates to the {@link #tested} implementation.
*/
@Debug
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/transform/MathTransformTestCase.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -366,6 +366,20 @@ public abstract strictfp class MathTrans
}
/**
+ * Asserts that the current {@linkplain #transform transform} produces a
WKT matching the given regular expression.
+ *
+ * @param expected A regular expression for the expected WKT.
+ *
+ * @see #printInternalWKT()
+ *
+ * @since 0.6
+ */
+ protected final void assertWktEqualsRegex(final String expected) {
+ assertNotNull("The 'transform' field shall be assigned a value.",
transform);
+ ReferencingAssert.assertWktEqualsRegex(Convention.WKT1, expected,
transform);
+ }
+
+ /**
* Prints the current {@linkplain #transform transform} as normal and
internal WKT.
* This method is for debugging purpose only.
*
@@ -373,6 +387,7 @@ public abstract strictfp class MathTrans
*/
@Debug
protected final void printInternalWKT() {
+ @SuppressWarnings("UseOfSystemOutOrSystemErr")
final TableAppender table = new TableAppender(System.out);
table.setMultiLinesCells(true);
table.appendHorizontalSeparator();
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -20,6 +20,7 @@ import java.util.Map;
import java.util.IdentityHashMap;
import java.util.ServiceLoader;
import java.util.ServiceConfigurationError;
+import org.apache.sis.internal.util.Utilities;
/**
@@ -86,8 +87,7 @@ public final class DefaultFactories exte
if (factory == null && !FACTORIES.containsKey(type)) {
T fallback = null;
for (final T candidate : ServiceLoader.load(type)) {
- final Class<?> ct = candidate.getClass();
- if (ct.getName().startsWith("org.apache.sis.")) {
+ if (Utilities.isSIS(candidate.getClass())) {
if (factory != null) {
throw new ServiceConfigurationError("Found two
implementations of " + type);
}
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java?rev=1693133&r1=1693132&r2=1693133&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Utilities.java
[UTF-8] Tue Jul 28 17:18:30 2015
@@ -39,6 +39,16 @@ public final class Utilities extends Sta
}
/**
+ * Returns {@code true} if the given class is an Apache SIS class.
+ *
+ * @param type The class to verify.
+ * @return {@code true} if the given class is an Apache SIS class.
+ */
+ public static boolean isSIS(final Class<?> type) {
+ return type.getName().startsWith("org.apache.sis.");
+ }
+
+ /**
* Appends to the given buffer only the characters that are valid for a
Unicode identifier.
* The given separator character is append before the given {@code text}
only if the buffer
* is not empty and at least one {@code text} character is valid.