Author: desruisseaux
Date: Wed Jul 29 14:55:12 2015
New Revision: 1693283
URL: http://svn.apache.org/r1693283
Log:
Consolidation of the tolerance threshold when comparing objects: try to use
thresholds having a physical meaning:
- LINEAR_THRESHOLD (1 cm) when comparing the Ellipsoid axis length,
- ANGULAR_THRESHOLD (equivalent to about 1 cm on Earth) when comparing the
PrimeMeridian Greenwich longitude,
- A threshold computed in a way that describe an error of about 1 cm on Earth
when comparing map projection excentricity.
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ReferenceSystemMetadata.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ServiceParameter.java
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.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/AbstractLinearTransform.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/test/java/org/apache/sis/internal/referencing/ReferencingUtilitiesTest.java
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/projection/MercatorTest.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ReferenceSystemMetadata.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ReferenceSystemMetadata.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ReferenceSystemMetadata.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ReferenceSystemMetadata.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -108,7 +108,7 @@ public class ReferenceSystemMetadata ext
public boolean equals(final Object object, final ComparisonMode mode) {
if (super.equals(object, mode) && (object instanceof ReferenceSystem))
{
final ReferenceSystem that = (ReferenceSystem) object;
- if (mode.ordinal() >= ComparisonMode.IGNORE_METADATA.ordinal()) {
+ if (mode.isIgnoringMetadata()) {
// Compare the name because it was ignored by super.equals(…)
in "ignore metadata" mode.
return Objects.equals(getName(), that.getName());
}
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ServiceParameter.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ServiceParameter.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ServiceParameter.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/internal/jaxb/metadata/replace/ServiceParameter.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -346,16 +346,17 @@ public final class ServiceParameter exte
that.getDefaultValue() == null &&
that.getValueClass() == getValueClass())
{
- if (mode.ordinal() >=
ComparisonMode.IGNORE_METADATA.ordinal()) {
+ if (mode.isIgnoringMetadata()) {
return Objects.equals(toString(getName()),
toString(that.getName()));
+ // super.equals(…) already compared 'getName()' in others
mode.
}
return deepEquals(that.getDescription(), getDescription(),
mode) &&
- that.getDirection() == getDirection() &&
- that.getMinimumOccurs() == getMinimumOccurs() &&
- that.getMaximumOccurs() == getMaximumOccurs() &&
- that.getValidValues() == null &&
- that.getMinimumValue() == null &&
- that.getMaximumValue() == null;
+ that.getDirection() == getDirection()
&&
+ that.getMinimumOccurs() ==
getMinimumOccurs() &&
+ that.getMaximumOccurs() ==
getMaximumOccurs() &&
+ that.getValidValues() == null &&
+ that.getMinimumValue() == null &&
+ that.getMaximumValue() == null;
}
}
return false;
Modified:
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyAccessor.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -29,6 +29,7 @@ import org.opengis.annotation.UML;
import org.opengis.metadata.citation.Citation;
import org.opengis.metadata.ExtendedElementInformation;
import org.apache.sis.internal.util.Citations;
+import org.apache.sis.internal.util.Numerics;
import org.apache.sis.measure.ValueRange;
import org.apache.sis.util.Debug;
import org.apache.sis.util.Classes;
@@ -48,7 +49,6 @@ import org.apache.sis.xml.IdentifiedObje
import static org.apache.sis.metadata.PropertyComparator.*;
import static org.apache.sis.metadata.ValueExistencePolicy.isNullOrEmpty;
-import static org.apache.sis.internal.util.Numerics.floatEpsilonEqual;
import static org.apache.sis.internal.util.CollectionsExt.snapshot;
import static org.apache.sis.internal.util.CollectionsExt.modifiableCopy;
import static org.apache.sis.util.collection.Containers.hashMapCapacity;
@@ -176,9 +176,8 @@ class PropertyAccessor {
private final Method[] setters;
/**
- * The JavaBeans property names. They are computed at construction time,
- * {@linkplain String#intern() interned} then cached. Those names are often
- * the same than field names (at least in SIS implementation), so it is
+ * The JavaBeans property names. They are computed at construction time,
{@linkplain String#intern() interned}
+ * then cached. Those names are often the same than field names (at least
in SIS implementation), so it is
* reasonable to intern them in order to share {@code String} instances.
*
* <p>This array shall not contains any {@code null} elements.</p>
@@ -1112,10 +1111,17 @@ class PropertyAccessor {
// Empty strings are also considered equal to null (this is
more questionable).
continue;
}
- if (!Utilities.deepEquals(value1, value2, mode)) {
- if (mode.ordinal() >= ComparisonMode.APPROXIMATIVE.ordinal()
&& floatEpsilonEqual(value1, value2)) {
- continue; // Accept this slight difference.
- }
+ final boolean equals;
+ if ((value1 instanceof Double || value1 instanceof Float) &&
+ (value2 instanceof Double || value2 instanceof Float))
+ {
+ equals = Numerics.epsilonEqual(((Number) value1).doubleValue(),
+ ((Number)
value2).doubleValue(), mode);
+ } else {
+ equals = Utilities.deepEquals(value1, value2, mode);
+ }
+ if (!equals) {
+ assert (mode != ComparisonMode.DEBUG) : type.getSimpleName() +
'.' + names[i] + " differ.";
return false;
}
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/AbstractEnvelope.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -532,6 +532,7 @@ public abstract class AbstractEnvelope i
*
* @since 0.4
*/
+ @SuppressWarnings("ReturnOfCollectionOrArrayField")
public Envelope[] toSimpleEnvelopes() {
long isWrapAround = 0; // A bitmask of the dimensions having a "wrap
around" behavior.
CoordinateReferenceSystem crs = null;
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -36,7 +36,6 @@ import org.apache.sis.referencing.crs.De
import org.apache.sis.referencing.cs.AxesConvention;
import static java.util.Collections.singletonMap;
-import static org.apache.sis.internal.util.Numerics.epsilonEqual;
/**
@@ -59,27 +58,6 @@ public final class ReferencingUtilities
}
/**
- * Returns {@code true} if the Greenwich longitude of the {@code actual}
prime meridian is equals to the
- * Greenwich longitude of the {@code expected} prime meridian. The
comparison is performed in unit of the
- * expected prime meridian.
- *
- * <p>A {@code null} argument is interpreted as "unknown prime meridian".
Consequently this method
- * unconditionally returns {@code false} if one or both arguments is
{@code null}.</p>
- *
- * @param expected The expected prime meridian, or {@code null}.
- * @param actual The actual prime meridian, or {@code null}.
- * @return {@code true} if both prime meridian have the same Greenwich
longitude,
- * in unit of the expected prime meridian.
- */
- public static boolean isGreenwichLongitudeEquals(final PrimeMeridian
expected, final PrimeMeridian actual) {
- if (expected == null || actual == null) {
- return false; // See method javadoc.
- }
- return (expected == actual) ||
epsilonEqual(expected.getGreenwichLongitude(),
- getGreenwichLongitude(actual, expected.getAngularUnit()));
- }
-
- /**
* Returns the longitude value relative to the Greenwich Meridian,
expressed in the specified units.
* This method provides the same functionality than {@link
DefaultPrimeMeridian#getGreenwichLongitude(Unit)},
* but on arbitrary implementation.
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -20,7 +20,7 @@ import java.util.Map;
import javax.measure.unit.SI;
import javax.measure.unit.Unit;
import javax.measure.quantity.Length;
-import javax.measure.converter.ConversionException;
+import javax.measure.converter.UnitConverter;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@@ -44,7 +44,6 @@ import org.apache.sis.util.resources.Err
import static java.lang.Math.*;
import static java.lang.Double.*;
-import static org.apache.sis.internal.util.Numerics.epsilonEqual;
import static org.apache.sis.util.ArgumentChecks.ensureStrictlyPositive;
import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
@@ -422,13 +421,10 @@ public class DefaultEllipsoid extends Ab
* Sets the semi-major axis value.
* This method is invoked by JAXB at unmarshalling time only.
*
- * @throws ConversionException If semi-major and semi-minor axes use
inconsistent units
- * and we can not convert from one to the other.
- *
* @see #setSecondDefiningParameter(SecondDefiningParameter)
* @see #afterUnmarshal()
*/
- private void setSemiMajorAxisMeasure(final Measure measure) throws
ConversionException {
+ private void setSemiMajorAxisMeasure(final Measure measure) {
if (semiMajorAxis != 0) {
warnDuplicated("semiMajorAxis");
} else {
@@ -525,13 +521,10 @@ public class DefaultEllipsoid extends Ab
* value or the semi minor axis value, according to what have been defined
in the
* second defining parameter given. This is for JAXB unmarshalling process
only.
*
- * @throws ConversionException If semi-major and semi-minor axes use
inconsistent units
- * and we can not convert from one to the other.
- *
* @see #setSemiMajorAxisMeasure(Measure)
* @see #afterUnmarshal()
*/
- private void setSecondDefiningParameter(SecondDefiningParameter second)
throws ConversionException {
+ private void setSecondDefiningParameter(SecondDefiningParameter second) {
while (second.secondDefiningParameter != null) {
second = second.secondDefiningParameter;
}
@@ -563,15 +556,13 @@ public class DefaultEllipsoid extends Ab
* Ensures that the semi-minor axis uses the same unit than the semi-major
one.
* The {@link #unit} field shall be set to the semi-major axis unit before
this method call.
*
- * @param uom The semi-minor axis unit.
- * @throws ConversionException If semi-major and semi-minor axes use
inconsistent units
- * and we can not convert from one to the other.
+ * @param uom The semi-minor axis unit.
*/
- private void harmonizeAxisUnits(final Unit<Length> uom) throws
ConversionException {
+ private void harmonizeAxisUnits(final Unit<Length> uom) {
if (unit == null) {
unit = uom;
} else if (uom != null && uom != unit) {
- semiMinorAxis = uom.getConverterToAny(unit).convert(semiMinorAxis);
+ semiMinorAxis = uom.getConverterTo(unit).convert(semiMinorAxis);
}
}
@@ -730,12 +721,48 @@ public class DefaultEllipsoid extends Ab
}
// Fall through
}
+ case IGNORE_METADATA: {
+ /*
+ * "Inverse flattening factor" and "semi-minor axis length"
are computed from each other,
+ * so we do not need to compare both of them. But in
non-approximative mode we nevertheless
+ * compare both as a safety against rounding errors.
+ */
+ if (!Numerics.equals(getInverseFlattening(), ((Ellipsoid)
object).getInverseFlattening())) {
+ return false;
+ }
+ // Fall through
+ }
default: {
+ /*
+ * Note: DefaultPrimeMeridian.equals(object, IGNORE_METADATA)
ignores the unit.
+ * But we do not perform the same relaxation here because the
ellipsoid unit will
+ * become the linear unit of map projections if the user does
not overwrite them
+ * with an explicit CoordinateSystem declaration.
+ */
final Ellipsoid that = (Ellipsoid) object;
- return epsilonEqual(getSemiMajorAxis(),
that.getSemiMajorAxis(), mode) &&
- epsilonEqual(getSemiMinorAxis(),
that.getSemiMinorAxis(), mode) &&
- epsilonEqual(getInverseFlattening(),
that.getInverseFlattening(), mode) &&
- Objects.equals(getAxisUnit(),
that.getAxisUnit());
+ final Unit<Length> unit = getAxisUnit(); // In case the user
override this method.
+ if (!Objects.equals(unit, that.getAxisUnit())) {
+ return false;
+ }
+ final UnitConverter c = mode.isApproximative() ?
unit.getConverterTo(SI.METRE) : null;
+ boolean isMinor = false;
+ double v1 = this.getSemiMajorAxis();
+ double v2 = that.getSemiMajorAxis();
+ if (c == null ? Numerics.equals(v1, v2) :
Numerics.epsilonEqual(
+ c.convert(v1), c.convert(v2),
Formulas.LINEAR_TOLERANCE))
+ {
+ isMinor = true;
+ v1 = this.getSemiMinorAxis();
+ v2 = that.getSemiMinorAxis();
+ if (c == null ? Numerics.equals(v1, v2) :
Numerics.epsilonEqual(
+ c.convert(v1), c.convert(v2),
Formulas.LINEAR_TOLERANCE))
+ {
+ return true;
+ }
+ }
+ assert (mode != ComparisonMode.DEBUG) :
Numerics.messageForDifference(
+ isMinor ? "semiMinorAxis" : "semiMajorAxis", v1, v2);
+ return false;
}
}
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -29,6 +29,7 @@ import org.opengis.metadata.Identifier;
import org.opengis.referencing.datum.PrimeMeridian;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.apache.sis.referencing.AbstractIdentifiedObject;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.util.PatchedUnitFormat;
import org.apache.sis.internal.metadata.WKTKeywords;
import org.apache.sis.internal.jaxb.gco.Measure;
@@ -39,10 +40,10 @@ import org.apache.sis.util.ComparisonMod
import static org.apache.sis.util.ArgumentChecks.ensureFinite;
import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
-import static
org.apache.sis.internal.referencing.ReferencingUtilities.canSetProperty;
// Branch-dependent imports
import java.util.Objects;
+import org.apache.sis.internal.referencing.Formulas;
/**
@@ -265,7 +266,7 @@ public class DefaultPrimeMeridian extend
* Invoked by JAXB for setting the Greenwich longitude and its unit of
measurement.
*/
private void setGreenwichMeasure(final Measure measure) {
- if (measure != null && canSetProperty(DefaultPrimeMeridian.class,
+ if (measure != null &&
ReferencingUtilities.canSetProperty(DefaultPrimeMeridian.class,
"setGreenwichMeasure", "greenwichLongitude",
greenwichLongitude != 0 || angularUnit != null))
{
greenwichLongitude = measure.value;
@@ -299,10 +300,7 @@ public class DefaultPrimeMeridian extend
if (object == this) {
return true; // Slight optimization.
}
- if (!super.equals(object, mode)) {
- return false;
- }
- switch (mode) {
+ if (super.equals(object, mode)) switch (mode) {
case STRICT: {
final DefaultPrimeMeridian that = (DefaultPrimeMeridian)
object;
return Numerics.equals(this.greenwichLongitude,
that.greenwichLongitude) &&
@@ -314,16 +312,25 @@ public class DefaultPrimeMeridian extend
Objects.equals(getAngularUnit(),
that.getAngularUnit());
}
default: {
- final DefaultPrimeMeridian that = castOrCopy((PrimeMeridian)
object);
- return
Numerics.epsilonEqual(this.getGreenwichLongitude(NonSI.DEGREE_ANGLE),
-
that.getGreenwichLongitude(NonSI.DEGREE_ANGLE), mode);
- /*
- * Note: if mode==IGNORE_METADATA, we relax the unit check
because EPSG uses
- * sexagesimal degrees for the Greenwich meridian.
Requirying the same
- * unit prevent Geodetic.isWGS84(...) method to
recognize EPSG's WGS84.
- */
+ final double v1 = getGreenwichLongitude(NonSI.DEGREE_ANGLE);
+ final double v2 =
ReferencingUtilities.getGreenwichLongitude((PrimeMeridian) object,
NonSI.DEGREE_ANGLE);
+ if (mode == ComparisonMode.IGNORE_METADATA) {
+ /*
+ * We relax the check on unit of measurement because EPSG
uses sexagesimal degrees
+ * for the Greenwich meridian. Requirying the same unit
would make more difficult
+ * for isWGS84(…) methods to recognize EPSG's WGS84. We
allow this relaxation here
+ * because the unit of the prime meridian is usually not
inherited by axes (indeed,
+ * they are often not the same in the EPSG dataset). The
same is not true for other
+ * objects like DefaultEllipsoid.
+ */
+ return Numerics.equals(v1, v2);
+ } else if (Numerics.epsilonEqual(v1, v2,
Formulas.ANGULAR_TOLERANCE)) {
+ return true;
+ }
+ assert (mode != ComparisonMode.DEBUG) :
Numerics.messageForDifference("greenwichLongitude", v1, v2);
}
}
+ 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=1693283&r1=1693282&r2=1693283&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] Wed Jul 29 14:55:12 2015
@@ -133,14 +133,19 @@ public abstract class NormalizedProjecti
/**
* Maximum difference allowed when comparing longitudes or latitudes in
radians.
- * The current value take the system-wide angular tolerance value
(equivalent to
+ * The current value takes the system-wide angular tolerance value
(equivalent to
* about 1 cm on Earth) converted to radians.
*
* <p>Some formulas use this tolerance value for testing sines or cosines
of an angle.
* In the sine case, this is justified because sin(θ) ≅ θ when θ is small.
* Similar reasoning applies to cosine with cos(θ) ≅ θ + π/2 when θ is
small.</p>
+ *
+ * <p>Some formulas may use this tolerance value as a <em>linear</em>
tolerance on the unit sphere.
+ * This is okay because the arc length for an angular tolerance θ is r⋅θ,
but in this class r=1.</p>
*/
static final double ANGULAR_TOLERANCE = Formulas.ANGULAR_TOLERANCE *
(PI/180);
+ // Note: an alternative way to compute this value could be
Formulas.LINEAR_TOLERANCE / AUTHALIC_RADIUS.
+ // But the later is only 0.07% lower than the current value.
/**
* Desired accuracy for the result of iterative computations, in radians.
@@ -150,7 +155,7 @@ public abstract class NormalizedProjecti
* So if the linear tolerance is 1 cm, then the accuracy that we will seek
for is 0.25 cm (about
* 4E-10 radians). The 0.25 factor is a safety margin for meeting the 1 cm
accuracy.</p>
*/
- static final double ITERATION_TOLERANCE = Formulas.ANGULAR_TOLERANCE *
(PI/180) * 0.25;
+ static final double ITERATION_TOLERANCE = ANGULAR_TOLERANCE * 0.25;
/**
* Maximum number of iterations for iterative computations.
@@ -832,50 +837,83 @@ public abstract class NormalizedProjecti
* @return {@code true} if the given object is equivalent to this map
projection.
*/
@Override
+ @SuppressWarnings("fallthrough")
public boolean equals(final Object object, final ComparisonMode mode) {
if (object == this) {
return true;
}
- if (super.equals(object, mode)) {
- final double e1, e2;
- final NormalizedProjection that = (NormalizedProjection) object;
- if (mode.ordinal() < ComparisonMode.IGNORE_METADATA.ordinal()) {
+ if (!super.equals(object, mode)) {
+ return false;
+ }
+ final NormalizedProjection that = (NormalizedProjection) object;
+ switch (mode) {
+ case STRICT:
+ case BY_CONTRACT: {
if (!Objects.equals(context, that.context)) {
return false;
}
- e1 = this.excentricitySquared;
- e2 = that.excentricitySquared;
- } else {
- e1 = this.excentricity;
- e2 = that.excentricity;
+ // Fall through for comparing the excentricity.
+ }
+ case IGNORE_METADATA: {
+ /*
+ * There is no need to compare both 'excentricity' and
'excentricitySquared' since the former
+ * is computed from the later. We are better to compare
'excentricitySquared' since it is the
+ * original value from which the other value is derived.
+ */
+ if (!Numerics.equals(excentricitySquared,
that.excentricitySquared)) {
+ return false;
+ }
+ break;
+ }
+ default: {
+ /*
+ * We want to compare the excentricity with a tolerance
threshold corresponding approximatively
+ * to an error of 1 cm on Earth. The excentricity for an
ellipsoid of semi-major axis a=1 is:
+ *
+ * ℯ² = 1 - b²
+ *
+ * If we add a slight ε error to the semi-minor axis length
(where ε will be our linear tolerance
+ * threshold), we get:
+ *
+ * (ℯ + ε′)² = 1 - (b + ε)² ≈ 1 - (b² + 2⋅b⋅ε)
assuming ε ≪ b
+ *
+ * Replacing 1 - b² by ℯ²:
+ *
+ * ℯ² + 2⋅ℯ⋅ε′ ≈ ℯ² - 2⋅b⋅ε
+ *
+ * After a few rearrangements:
+ *
+ * ε′ ≈ ε⋅(ℯ - 1/ℯ)
+ *
+ * Note that ε′ is negative for ℯ < 1 so we actually need
to compute ε⋅(1/ℯ - ℯ) instead.
+ * The result is less than 2E-8 for the excentricity of the
Earth.
+ */
+ final double e = max(excentricity, that.excentricity);
+ if (!Numerics.epsilonEqual(excentricity, that.excentricity,
ANGULAR_TOLERANCE * (1/e - e))) {
+ assert (mode != ComparisonMode.DEBUG) :
Numerics.messageForDifference(
+ "excentricity", excentricity, that.excentricity);
+ return false;
+ }
+ break;
}
+ }
+ final double[] parameters = getInternalParameterValues();
+ if (parameters != null) {
/*
- * 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'.
+ * 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.
*/
- 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;
- }
- }
+ 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)) {
+ assert (mode != ComparisonMode.DEBUG) :
Numerics.messageForDifference(
+ getInternalParameterNames()[i], parameters[i],
others[i]);
+ return false;
}
- return true;
}
}
- return false;
+ return true;
}
Modified:
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractLinearTransform.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -64,6 +64,7 @@ abstract class AbstractLinearTransform e
* Returns a copy of the matrix that user can modify.
*/
@Override
+ @SuppressWarnings("CloneDoesntCallSuperClone")
public final Matrix clone() {
return Matrices.copy(this);
}
@@ -151,10 +152,8 @@ abstract class AbstractLinearTransform e
return true;
}
if (object != null) {
- if (getClass() == object.getClass()) {
- if (mode.ordinal() < ComparisonMode.APPROXIMATIVE.ordinal()) {
- return equalsSameClass(object);
- }
+ if (getClass() == object.getClass() && !mode.isApproximative()) {
+ return equalsSameClass(object);
}
if (mode != ComparisonMode.STRICT) {
if (object instanceof LinearTransform) {
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=1693283&r1=1693282&r2=1693283&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] Wed Jul 29 14:55:12 2015
@@ -895,7 +895,7 @@ public abstract class AbstractMathTransf
* If the classes are the same, then the hash codes should be
computed in the same way. Since those
* codes are cached, this is an efficient way to quickly check if
the two objects are different.
*/
- if (mode.ordinal() < ComparisonMode.APPROXIMATIVE.ordinal()) {
+ if (!mode.isApproximative()) {
final int tc = hashCode;
if (tc != 0) {
final int oc = that.hashCode;
@@ -905,7 +905,7 @@ public abstract class AbstractMathTransf
}
}
// See the policy documented in the LenientComparable javadoc.
- if (mode.ordinal() >= ComparisonMode.IGNORE_METADATA.ordinal()) {
+ if (mode.isIgnoringMetadata()) {
return true;
}
return Utilities.deepEquals(this.getContextualParameters(),
Modified:
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ReferencingUtilitiesTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ReferencingUtilitiesTest.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ReferencingUtilitiesTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ReferencingUtilitiesTest.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -22,7 +22,6 @@ import org.opengis.referencing.cs.*;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.datum.PrimeMeridian;
-import org.apache.sis.referencing.datum.DefaultPrimeMeridian;
import org.apache.sis.referencing.datum.HardCodedDatum;
import org.apache.sis.referencing.crs.HardCodedCRS;
import org.apache.sis.internal.metadata.WKTKeywords;
@@ -31,8 +30,6 @@ import org.apache.sis.test.TestCase;
import org.junit.Test;
import static org.junit.Assert.*;
-import static java.util.Collections.singletonMap;
-import static org.opengis.referencing.IdentifiedObject.NAME_KEY;
import static org.apache.sis.internal.referencing.ReferencingUtilities.*;
@@ -46,26 +43,6 @@ import static org.apache.sis.internal.re
*/
public final strictfp class ReferencingUtilitiesTest extends TestCase {
/**
- * Tests {@link
ReferencingUtilities#isGreenwichLongitudeEquals(PrimeMeridian, PrimeMeridian)}.
- */
- @Test
- public void testIsGreenwichLongitudeEquals() {
- assertFalse(isGreenwichLongitudeEquals(null, null)); // "null"
interpreted as "unknown".
- assertFalse(isGreenwichLongitudeEquals(null,
HardCodedDatum.GREENWICH));
- assertFalse(isGreenwichLongitudeEquals(HardCodedDatum.GREENWICH,
null));
- assertFalse(isGreenwichLongitudeEquals(HardCodedDatum.GREENWICH,
HardCodedDatum.PARIS));
- assertFalse(isGreenwichLongitudeEquals(HardCodedDatum.PARIS,
HardCodedDatum.PARIS_RGS));
- assertFalse(isGreenwichLongitudeEquals(HardCodedDatum.PARIS_RGS,
HardCodedDatum.PARIS));
- assertTrue (isGreenwichLongitudeEquals(HardCodedDatum.PARIS,
HardCodedDatum.PARIS));
- /*
- * Test two prime meridians using different units (Paris in grade and
Paris in degrees).
- */
- final PrimeMeridian pd = new
DefaultPrimeMeridian(singletonMap(NAME_KEY, "Paris"), 2.33722917,
NonSI.DEGREE_ANGLE);
- assertTrue(isGreenwichLongitudeEquals(HardCodedDatum.PARIS, pd));
- assertTrue(isGreenwichLongitudeEquals(pd, HardCodedDatum.PARIS));
- }
-
- /**
* Tests {@link ReferencingUtilities#getGreenwichLongitude(PrimeMeridian,
Unit)}.
*/
@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=1693283&r1=1693282&r2=1693283&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] Wed Jul 29 14:55:12 2015
@@ -68,7 +68,7 @@ public final strictfp class MercatorTest
* 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()
+ * @see LambertConicConformalTest#testNormalizedWKT()
*/
@Test
public void testNormalizedWKT() {
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/simple/SimpleIdentifiedObject.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -203,10 +203,10 @@ public class SimpleIdentifiedObject impl
}
if (object instanceof IdentifiedObject) {
if (mode != ComparisonMode.STRICT || object.getClass() ==
getClass()) {
- final IdentifiedObject that = (IdentifiedObject) object;
- if (mode.ordinal() >=
ComparisonMode.IGNORE_METADATA.ordinal()) {
+ if (mode.isIgnoringMetadata()) {
return true;
}
+ final IdentifiedObject that = (IdentifiedObject) object;
return Objects.equals(getName(), that.getName()) &&
isNullOrEmpty(that.getIdentifiers()) &&
isNullOrEmpty(that.getAlias()) &&
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -18,6 +18,7 @@ package org.apache.sis.internal.util;
import java.util.Map;
import java.util.HashMap;
+import org.apache.sis.util.Debug;
import org.apache.sis.util.Static;
import org.apache.sis.util.ComparisonMode;
@@ -30,7 +31,7 @@ import static java.lang.Math.abs;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.4
+ * @version 0.6
* @module
*/
public final class Numerics extends Static {
@@ -58,9 +59,9 @@ public final class Numerics extends Stat
* Helper method for the construction of the {@link #CACHE} map.
*/
private static void cache(final double value) {
- Double key;
- key = Double.valueOf( value); CACHE.put(key, key);
- key = Double.valueOf(-value); CACHE.put(key, key);
+ Double boxed;
+ boxed = value; CACHE.put(boxed, boxed);
+ boxed = -value; CACHE.put(boxed, boxed);
}
/**
@@ -146,9 +147,9 @@ public final class Numerics extends Stat
* @return The given value as a {@code Double}.
*/
public static Double valueOf(final double value) {
- final Double n = Double.valueOf(value);
- final Object candidate = CACHE.get(value);
- return (candidate != null) ? (Double) candidate : n;
+ final Double boxed = value;
+ final Object candidate = CACHE.get(boxed);
+ return (candidate != null) ? (Double) candidate : boxed;
}
/**
@@ -188,14 +189,14 @@ public final class Numerics extends Stat
* Returns {@code true} if the given floats are equals. Positive and
negative zero are
* considered different, while a NaN value is considered equal to all
other NaN values.
*
- * @param o1 The first value to compare.
- * @param o2 The second value to compare.
+ * @param v1 The first value to compare.
+ * @param v2 The second value to compare.
* @return {@code true} if both values are equal.
*
* @see Float#equals(Object)
*/
- public static boolean equals(final float o1, final float o2) {
- return Float.floatToIntBits(o1) == Float.floatToIntBits(o2);
+ public static boolean equals(final float v1, final float v2) {
+ return Float.floatToIntBits(v1) == Float.floatToIntBits(v2);
}
/**
@@ -203,78 +204,86 @@ public final class Numerics extends Stat
* Positive and negative zeros are considered different.
* NaN values are considered equal to all other NaN values.
*
- * @param o1 The first value to compare.
- * @param o2 The second value to compare.
+ * @param v1 The first value to compare.
+ * @param v2 The second value to compare.
* @return {@code true} if both values are equal.
*
* @see Double#equals(Object)
*/
- public static boolean equals(final double o1, final double o2) {
- return Double.doubleToLongBits(o1) == Double.doubleToLongBits(o2);
+ public static boolean equals(final double v1, final double v2) {
+ return Double.doubleToLongBits(v1) == Double.doubleToLongBits(v2);
}
/**
* Returns {@code true} if the given doubles are equal, ignoring the sign
of zero values.
* NaN values are considered equal to all other NaN values.
*
- * @param o1 The first value to compare.
- * @param o2 The second value to compare.
+ * @param v1 The first value to compare.
+ * @param v2 The second value to compare.
* @return {@code true} if both values are equal.
*/
- public static boolean equalsIgnoreZeroSign(final double o1, final double
o2) {
- return (o1 == o2) || Double.doubleToLongBits(o1) ==
Double.doubleToLongBits(o2);
+ public static boolean equalsIgnoreZeroSign(final double v1, final double
v2) {
+ return (v1 == v2) || Double.doubleToLongBits(v1) ==
Double.doubleToLongBits(v2);
}
/**
- * Returns {@code true} if the given values are approximatively equal,
- * up to the {@linkplain #COMPARISON_THRESHOLD comparison threshold}.
+ * Returns {@code true} if the given values are approximatively equal, up
to the given comparison threshold.
*
* @param v1 The first value to compare.
* @param v2 The second value to compare.
- * @return {@code true} If both values are approximatively equal.
+ * @param threshold The comparison threshold.
+ * @return {@code true} if both values are approximatively equal.
*/
- public static boolean epsilonEqual(final double v1, final double v2) {
- final double threshold = COMPARISON_THRESHOLD * max(abs(v1), abs(v2));
- if (threshold == Double.POSITIVE_INFINITY || Double.isNaN(threshold)) {
- return Double.doubleToLongBits(v1) == Double.doubleToLongBits(v2);
- }
- return abs(v1 - v2) <= threshold;
+ public static boolean epsilonEqual(final double v1, final double v2, final
double threshold) {
+ return (abs(v1 - v2) <= threshold) || equals(v1, v2);
}
/**
* Returns {@code true} if the given values are approximatively equal
given the comparison mode.
+ * In mode {@code APPROXIMATIVE} or {@code DEBUG}, this method will
compute a relative comparison
+ * threshold from the {@link #COMPARISON_THRESHOLD} constant.
*
- * @param v1 The first value to compare.
- * @param v2 The second value to compare.
+ * <p>This method does not thrown {@link AssertionError} in {@link
ComparisonMode#DEBUG}.
+ * It is caller responsibility to handle the {@code DEBUG} case.</p>
+ *
+ * @param v1 The first value to compare.
+ * @param v2 The second value to compare.
* @param mode The comparison mode to use for comparing the numbers.
- * @return {@code true} If both values are approximatively equal.
+ * @return {@code true} if both values are considered equal for the given
comparison mode.
*/
public static boolean epsilonEqual(final double v1, final double v2, final
ComparisonMode mode) {
- switch (mode) {
- default: return equals(v1, v2);
- case APPROXIMATIVE: return epsilonEqual(v1, v2);
- case DEBUG: {
- final boolean equal = epsilonEqual(v1, v2);
- assert equal : "v1=" + v1 + " v2=" + v2 + " Δv=" + abs(v1-v2);
- return equal;
+ if (mode.isApproximative()) {
+ final double mg = max(abs(v1), abs(v2));
+ if (mg != Double.POSITIVE_INFINITY) {
+ return epsilonEqual(v1, v2, COMPARISON_THRESHOLD * mg);
}
}
+ return equals(v1, v2);
}
/**
- * Returns {@code true} if the following objects are floating point
numbers ({@link Float} or
- * {@link Double} types) and approximatively equal. If the given object
are not floating point
- * numbers, then this method returns {@code false} unconditionally on the
assumption that
- * strict equality has already been checked before this method call.
+ * Creates a messages to put in {@link AssertionError} when two values
differ in an unexpected way.
+ * This is a helper method for debugging purpose only, typically used with
{@code assert} statements.
*
- * @param v1 The first value to compare.
- * @param v2 The second value to compare.
- * @return {@code true} If both values are real number and approximatively
equal.
+ * @param name The name of the property which differ, or {@code null} if
unknown.
+ * @param v1 The first value.
+ * @param v2 The second value.
+ * @return The message to put in {@code AssertionError}.
+ *
+ * @since 0.6
*/
- public static boolean floatEpsilonEqual(final Object v1, final Object v2) {
- return (v1 instanceof Float || v1 instanceof Double) &&
- (v2 instanceof Float || v2 instanceof Double) &&
- epsilonEqual(((Number) v1).doubleValue(), ((Number)
v2).doubleValue());
+ @Debug
+ public static String messageForDifference(final String name, final double
v1, final double v2) {
+ final StringBuilder builder = new StringBuilder();
+ if (name != null) {
+ builder.append(name).append(": ");
+ }
+ builder.append("values ").append(v1).append(" and
").append(v2).append(" differ");
+ final float delta = (float) abs(v1 - v2);
+ if (delta < Float.POSITIVE_INFINITY) {
+ builder.append(" by ").append(delta);
+ }
+ return builder.toString();
}
/**
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/ComparisonMode.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -41,7 +41,7 @@ package org.apache.sis.util;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.3
+ * @version 0.6
* @module
*
* @see LenientComparable#equals(Object, ComparisonMode)
@@ -152,6 +152,32 @@ public enum ComparisonMode {
DEBUG;
/**
+ * Returns {@code true} if this comparison ignores metadata.
+ * This method currently returns {@code true} for {@code IGNORE_METADATA},
{@code APPROXIMATIVE}
+ * or {@code DEBUG} only, but this list may be extended in future SIS
versions.
+ *
+ * @return Whether this comparison ignore metadata.
+ *
+ * @since 0.6
+ */
+ public boolean isIgnoringMetadata() {
+ return ordinal() >= IGNORE_METADATA.ordinal();
+ }
+
+ /**
+ * Returns {@code true} if this comparison uses a tolerance threshold.
+ * This method currently returns {@code true} for {@code APPROXIMATIVE} or
{@code DEBUG} only,
+ * but this list may be extended in future SIS versions.
+ *
+ * @return Whether this comparison uses a tolerance threshold.
+ *
+ * @since 0.6
+ */
+ public boolean isApproximative() {
+ return ordinal() >= APPROXIMATIVE.ordinal();
+ }
+
+ /**
* If the two given objects are equals according one of the modes
enumerated in this class,
* then returns that mode. Otherwise returns {@code null}. This method is
used mostly for
* diagnostic purpose.
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -43,6 +43,10 @@ import static java.lang.Double.doubleToL
*
* @see org.apache.sis.math.MathFunctions
*/
+@SuppressWarnings({
+ "UnnecessaryBoxing",
+ "ResultOfObjectAllocationIgnored"
+})
public final class Numbers extends Static {
/**
* Constant of value {@value} used in {@code switch} statements or as
index in arrays.
@@ -88,6 +92,7 @@ public final class Numbers extends Stati
/**
* Creates an entry for a type which is not a primitive type.
*/
+ @SuppressWarnings("ThisEscapedInObjectConstruction")
private Numbers(final Class<?> type, final boolean isFloat, final boolean
isInteger, final byte ordinal) {
primitive = wrapper = type;
this.isFloat = isFloat;
@@ -104,6 +109,7 @@ public final class Numbers extends Stati
/**
* Creates a mapping between a primitive type and its wrapper.
*/
+ @SuppressWarnings("ThisEscapedInObjectConstruction")
private Numbers(final Class<?> primitive, final Class<?> wrapper,
final boolean isFloat, final boolean isInteger,
final byte size, final byte ordinal,
Modified:
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/xml/NilObjectHandler.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -179,7 +179,7 @@ final class NilObjectHandler implements
if (other == proxy) return true;
if (other == null) return false;
if (proxy.getClass() == other.getClass()) {
- if (mode.ordinal() >= ComparisonMode.IGNORE_METADATA.ordinal()) {
+ if (mode.isIgnoringMetadata()) {
return true;
}
final NilObjectHandler h = (NilObjectHandler)
Proxy.getInvocationHandler(other);
Modified:
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
URL:
http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java?rev=1693283&r1=1693282&r2=1693283&view=diff
==============================================================================
---
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
[UTF-8] (original)
+++
sis/branches/JDK8/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
[UTF-8] Wed Jul 29 14:55:12 2015
@@ -20,6 +20,7 @@ import java.util.Random;
import org.apache.sis.math.MathFunctions;
import org.apache.sis.test.TestUtilities;
import org.apache.sis.test.TestCase;
+import org.apache.sis.util.ComparisonMode;
import org.junit.Test;
import static java.lang.Double.NaN;
@@ -34,9 +35,10 @@ import static org.junit.Assert.*;
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3
- * @version 0.4
+ * @version 0.6
* @module
*/
+@SuppressWarnings("UnnecessaryBoxing")
public final strictfp class NumericsTest extends TestCase {
/**
* Tests the {@link Numerics#cached(Object)} method.
@@ -67,20 +69,20 @@ public final strictfp class NumericsTest
}
/**
- * Tests the {@link Numerics#epsilonEqual(double, double)} method.
+ * Tests the {@link Numerics#epsilonEqual(double, double, ComparisonMode)}
method.
*/
@Test
public void testEpsilonEqual() {
- assertTrue (epsilonEqual(POSITIVE_INFINITY, POSITIVE_INFINITY));
- assertTrue (epsilonEqual(NEGATIVE_INFINITY, NEGATIVE_INFINITY));
- assertFalse(epsilonEqual(POSITIVE_INFINITY, NEGATIVE_INFINITY));
- assertFalse(epsilonEqual(POSITIVE_INFINITY, NaN));
- assertTrue (epsilonEqual(NaN, NaN));
- assertFalse(epsilonEqual( 0, COMPARISON_THRESHOLD / 2));
- assertTrue (epsilonEqual( 1, 1 + COMPARISON_THRESHOLD / 2));
- assertFalse(epsilonEqual( 1, 1 + COMPARISON_THRESHOLD * 2));
- assertTrue (epsilonEqual(-100, -100 + COMPARISON_THRESHOLD * 50));
- assertFalse(epsilonEqual( 100, 100 + COMPARISON_THRESHOLD * 150));
+ assertTrue (epsilonEqual(POSITIVE_INFINITY, POSITIVE_INFINITY,
ComparisonMode.APPROXIMATIVE));
+ assertTrue (epsilonEqual(NEGATIVE_INFINITY, NEGATIVE_INFINITY,
ComparisonMode.APPROXIMATIVE));
+ assertFalse(epsilonEqual(POSITIVE_INFINITY, NEGATIVE_INFINITY,
ComparisonMode.APPROXIMATIVE));
+ assertFalse(epsilonEqual(POSITIVE_INFINITY, NaN,
ComparisonMode.APPROXIMATIVE));
+ assertTrue (epsilonEqual(NaN, NaN,
ComparisonMode.APPROXIMATIVE));
+ assertFalse(epsilonEqual( 0, COMPARISON_THRESHOLD / 2,
ComparisonMode.APPROXIMATIVE));
+ assertTrue (epsilonEqual( 1, 1 + COMPARISON_THRESHOLD / 2,
ComparisonMode.APPROXIMATIVE));
+ assertFalse(epsilonEqual( 1, 1 + COMPARISON_THRESHOLD * 2,
ComparisonMode.APPROXIMATIVE));
+ assertTrue (epsilonEqual(-100, -100 + COMPARISON_THRESHOLD * 50,
ComparisonMode.APPROXIMATIVE));
+ assertFalse(epsilonEqual( 100, 100 + COMPARISON_THRESHOLD * 150,
ComparisonMode.APPROXIMATIVE));
}
/**