sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1542034 [2/2] - in /sis/branches/JDK6: ./ application/sis-console/src/test/java/org/apache/sis/test/suite/ core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/ core/sis-metadata/src/test/java/org/apache/sis/test/suite/ core/...
Date Thu, 14 Nov 2013 19:26:46 GMT
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -17,18 +17,23 @@
 package org.apache.sis.referencing.datum;
 
 import java.util.Map;
-import java.util.Set;
 import java.util.Arrays;
-import java.util.HashSet;
+import java.util.Date;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.metadata.extent.Extent;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.datum.Ellipsoid;
 import org.opengis.referencing.datum.PrimeMeridian;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
+import org.apache.sis.metadata.iso.extent.Extents;
+import org.apache.sis.internal.referencing.ExtentSelector;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.ComparisonMode;
@@ -37,6 +42,7 @@ import org.apache.sis.io.wkt.Formatter;
 
 import static org.apache.sis.util.Utilities.deepEquals;
 import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
+import static org.apache.sis.util.ArgumentChecks.ensureNonNullElement;
 
 // Related to JDK7
 import org.apache.sis.internal.jdk7.Objects;
@@ -120,7 +126,7 @@ public class DefaultGeodeticDatum extend
 
     /**
      * The <code>{@value #BURSA_WOLF_KEY}</code> property for
-     * {@linkplain #getBursaWolfParameters(GeodeticDatum) Bursa-Wolf parameters}.
+     * {@linkplain #getBursaWolfParameters() Bursa-Wolf parameters}.
      */
     public static final String BURSA_WOLF_KEY = "bursaWolf";
 
@@ -148,7 +154,7 @@ public class DefaultGeodeticDatum extend
 
     /**
      * Creates a geodetic datum from the given properties. The properties map is given
-     * unchanged to the {@link AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
      * In addition to the properties documented in the parent constructor,
      * the following properties are understood by this constructor:
      *
@@ -160,9 +166,52 @@ public class DefaultGeodeticDatum extend
      *   </tr>
      *   <tr>
      *     <td>{@value #BURSA_WOLF_KEY}</td>
-     *     <td>{@link BursaWolfParameters} or {@code BursaWolfParameters[]}</td>
+     *     <td>{@link BursaWolfParameters} (optionally as array)</td>
      *     <td>{@link #getBursaWolfParameters()}</td>
      *   </tr>
+     *   <tr>
+     *     <th colspan="3" class="hsep">Defined in parent classes (reminder)</th>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} or {@link String}</td>
+     *     <td>{@link #getName()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td>
+     *     <td>{@link GenericName} or {@link CharSequence} (optionally as array)</td>
+     *     <td>{@link #getAlias()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} (optionally as array)</td>
+     *     <td>{@link #getIdentifiers()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getRemarks()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#ANCHOR_POINT_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getAnchorPoint()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#REALIZATION_EPOCH_KEY}</td>
+     *     <td>{@link Date}</td>
+     *     <td>{@link #getRealizationEpoch()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#DOMAIN_OF_VALIDITY_KEY}</td>
+     *     <td>{@link Extent}</td>
+     *     <td>{@link #getDomainOfValidity()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#SCOPE_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getScope()}</td>
+     *   </tr>
      * </table>
      *
      * @param properties    The properties to be given to the identified object.
@@ -180,6 +229,15 @@ public class DefaultGeodeticDatum extend
         this.primeMeridian = primeMeridian;
         bursaWolf = CollectionsExt.nonEmpty(CollectionsExt.nonNullArraySet(
                 BURSA_WOLF_KEY, properties.get(BURSA_WOLF_KEY), EMPTY_ARRAY));
+        if (bursaWolf != null) {
+            for (int i=0; i<bursaWolf.length; i++) {
+                BursaWolfParameters param = bursaWolf[i];
+                ensureNonNullElement("bursaWolf", i, param);
+                param = param.clone();
+                param.verify();
+                bursaWolf[i] = param;
+            }
+        }
     }
 
     /**
@@ -238,142 +296,119 @@ public class DefaultGeodeticDatum extend
 
     /**
      * Returns all Bursa-Wolf parameters specified in the {@code properties} map at construction time.
-     * For a discussion about what Bursa-Wolf parameters are, see the class javadpc.
+     * For a discussion about what Bursa-Wolf parameters are, see the class javadoc.
      *
      * @return The Bursa-Wolf parameters, or an empty array if none.
      */
     public BursaWolfParameters[] getBursaWolfParameters() {
-        return (bursaWolf != null) ? bursaWolf.clone() : EMPTY_ARRAY;
-    }
-
-    /**
-     * Returns Bursa-Wolf parameters for a datum shift toward the specified target, or {@code null} if none.
-     * This method searches only for Bursa-Wolf parameters explicitly specified in the {@code properties} map
-     * given at construction time. This method doesn't try to infer a set of parameters from indirect informations.
-     * For example it does not try to inverse the parameters specified in the {@code target} datum if none were found
-     * in this datum.
-     * If a more elaborated search is wanted, use {@link #getPositionVectorTransformation(GeodeticDatum)} instead.
-     *
-     * @param  target The target geodetic datum.
-     * @return Bursa-Wolf parameters from this datum to the given target datum, or {@code null} if none.
-     */
-    public BursaWolfParameters getBursaWolfParameters(final GeodeticDatum target) {
-        if (bursaWolf != null) {
-            for (final BursaWolfParameters candidate : bursaWolf) {
-                if (deepEquals(target, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) {
-                    return candidate;
-                }
-            }
+        if (bursaWolf == null) {
+            return EMPTY_ARRAY;
         }
-        return null;
-    }
-
-    /**
-     * Returns a direct reference to the {@link #bursaWolf} of the given datum if it exists,
-     * or {@code null} otherwise. This method does not clone the array - do not modify!
-     */
-    private static BursaWolfParameters[] bursaWolf(final GeodeticDatum datum) {
-        return (datum instanceof DefaultGeodeticDatum) ? ((DefaultGeodeticDatum) datum).bursaWolf : null;
+        final BursaWolfParameters[] copy = bursaWolf.clone();
+        for (int i=0; i<copy.length; i++) {
+            copy[i] = copy[i].clone();
+        }
+        return copy;
     }
 
     /**
      * Returns the position vector transformation (geocentric domain) to the specified datum.
-     * If no transformation path is found, then this method returns {@code null}.
-     * If non-null, then the representation is represented as an affine transform.
+     * This method performs the search in the following order:
      *
-     * {@note This is identified in the EPSG database as operation method 1033 -
-     *        <cite>Position Vector transformation (geocentric domain)</cite>.}
+     * <ul>
+     *   <li>If this {@code GeodeticDatum} contains {@code BursaWolfParameters} having the given
+     *       {@linkplain BursaWolfParameters#getTargetDatum() target datum} (ignoring metadata),
+     *       then the matrix will be built from those parameters.</li>
+     *   <li>Otherwise if the other datum contains {@code BursaWolfParameters} having this datum
+     *       as their target (ignoring metadata), then the matrix will be built from those parameters
+     *       and {@linkplain MatrixSIS#inverse() inverted}.</li>
+     *   <li>Otherwise this method returns {@code null}.</li>
+     * </ul>
+     *
+     * If more than one {@code BursaWolfParameters} instance is found in any of the above steps, then the one having
+     * the largest intersection between its {@linkplain BursaWolfParameters#getDomainOfValidity() domain of validity}
+     * and the given extent will be selected. If more than one instance have the same intersection, then the first
+     * occurrence is selected.
+     *
+     * <p>If the given extent contains a {@linkplain org.opengis.metadata.extent.TemporalExtent temporal extent},
+     * then the instant located midway between start and end time will be taken as the date where to evaluate the
+     * Bursa-Wolf parameters. This apply only to {@linkplain TimeDependentBWP time-dependent parameters}.</p>
+     *
+     * <p>If the returned matrix is non-null, then the transformation is represented by an affine transform which can be
+     * applied on <strong>geocentric</strong> coordinates. This is identified in the EPSG database as operation method
+     * 1033 – <cite>Position Vector transformation (geocentric domain)</cite>, or
+     * 1053 – <cite>Time-dependent Position Vector transformation</cite>.</p>
      *
      * @param  targetDatum The target datum.
+     * @param  areaOfInterest The geographic and temporal extent where the transformation should be valid, or {@code null}.
      * @return An affine transform from {@code this} to {@code target} in geocentric space, or {@code null} if none.
      *
-     * @see BursaWolfParameters#getPositionVectorTransformation()
+     * @see BursaWolfParameters#getPositionVectorTransformation(Date)
      */
-    public Matrix getPositionVectorTransformation(final GeodeticDatum targetDatum) {
+    public Matrix getPositionVectorTransformation(final GeodeticDatum targetDatum, final Extent areaOfInterest) {
         ensureNonNull("targetDatum", targetDatum);
-        return getPositionVectorTransformation(this, targetDatum, null);
-    }
-
-    /**
-     * Returns a matrix that can be used to define a transformation to the specified datum.
-     * If no transformation path is found, then this method returns {@code null}.
-     *
-     * @param  source The source datum, or {@code null}.
-     * @param  target The target datum, or {@code null}.
-     * @param  exclusion The set of datum to exclude from the search, or {@code null}.
-     *         This is used in order to avoid never-ending recursivity.
-     * @return An affine transform from {@code source} to {@code target}, or {@code null} if none.
-     */
-    private static Matrix getPositionVectorTransformation(final GeodeticDatum source, final GeodeticDatum target,
-            Set<GeodeticDatum> exclusion)
-    {
-        final BursaWolfParameters[] sourceParam = bursaWolf(source);
-        if (sourceParam != null) {
-            for (final BursaWolfParameters candidate : sourceParam) {
-                if (deepEquals(target, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) {
-                    return candidate.getPositionVectorTransformation();
-                }
-            }
+        final ExtentSelector<BursaWolfParameters> selector = new ExtentSelector<BursaWolfParameters>(areaOfInterest);
+        BursaWolfParameters candidate = select(targetDatum, selector);
+        if (candidate != null) {
+            return createTransformation(candidate, areaOfInterest);
         }
         /*
-         * No transformation found to the specified target datum.
-         * Search if a transform exists in the opposite direction.
+         * Found no suitable BursaWolfParameters associated to this instance.
+         * Search in the BursaWolfParameters associated to the other instance.
          */
-        final BursaWolfParameters[] targetParam = bursaWolf(target);
-        if (targetParam != null) {
-            for (final BursaWolfParameters candidate : targetParam) {
-                if (deepEquals(source, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) try {
-                    return MatrixSIS.castOrCopy(candidate.getPositionVectorTransformation()).inverse();
-                } catch (NoninvertibleMatrixException e) {
-                    /*
-                     * Should never happen because BursaWolfParameters.getPositionVectorTransformation()
-                     * is defined in such a way that matrix should always be invertible. If it happen anyway,
-                     * search for an other BursaWolfParameters instance. If none are found, returning 'null'
-                     * is allowed by this method's contract.
-                     */
-                    Logging.unexpectedException(DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
-                }
+        if (targetDatum instanceof DefaultGeodeticDatum) {
+            candidate = ((DefaultGeodeticDatum) targetDatum).select(this, selector);
+            if (candidate != null) try {
+                return MatrixSIS.castOrCopy(createTransformation(candidate, areaOfInterest)).inverse();
+            } catch (NoninvertibleMatrixException e) {
+                /*
+                 * Should never happen because BursaWolfParameters.getPositionVectorTransformation(Date)
+                 * is defined in such a way that matrix should always be invertible. If it happen anyway,
+                 * returning 'null' is allowed by this method's contract.
+                 */
+                Logging.unexpectedException(DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
             }
         }
         /*
-         * No direct tranformation found. Search for a path through some intermediate datum.
-         * First, search if there is some BursaWolfParameters for the same target in both
-         * 'source' and 'target' datum. If such an intermediate is found, ask for a path as below:
+         * In a previous version (Geotk), we were used to search for a transformation path through a common datum:
          *
-         *    source   →   [common datum]   →   target
+         *     source   →   [common datum]   →   target
+         *
+         * This has been removed, because it was dangerous (many paths may be possible - we are better to rely on
+         * the EPSG database, which do define some transformation paths explicitely). Especially since our javadoc
+         * now said that associating BursaWolfParameters to GeodeticDatum is not recommended except in a few special
+         * cases, this method does not have a picture complete enough for attempting anything else than a direct path.
          */
-        if (sourceParam != null && targetParam != null) {
-            for (int i=0; i<sourceParam.length; i++) {
-                final GeodeticDatum sourceStep = sourceParam[i].targetDatum;
-                for (int j=0; j<targetParam.length; j++) {
-                    final GeodeticDatum targetStep = targetParam[j].targetDatum;
-                    if (deepEquals(sourceStep, targetStep, ComparisonMode.IGNORE_METADATA)) {
-                        if (exclusion == null) {
-                            exclusion = new HashSet<GeodeticDatum>();
-                        }
-                        if (exclusion.add(source)) {
-                            if (exclusion.add(target)) {
-                                final Matrix step1 = getPositionVectorTransformation(source, sourceStep, exclusion);
-                                if (step1 != null) {
-                                    final Matrix step2 = getPositionVectorTransformation(targetStep, target, exclusion);
-                                    if (step2 != null) {
-                                        /*
-                                         * MatrixSIS.multiply(MatrixSIS) is equivalent to AffineTransform.concatenate(…):
-                                         * First transform by the supplied transform and then transform the result
-                                         * by the original transform.
-                                         */
-                                        return MatrixSIS.castOrCopy(step2).multiply(step1);
-                                    }
-                                }
-                                exclusion.remove(target);
-                            }
-                            exclusion.remove(source);
-                        }
-                    }
-                }
+        return null;
+    }
+
+    /**
+     * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)} for a date calculated from
+     * the temporal elements on the given extent.  This method chooses an instant located midway between the
+     * start and end time.
+     */
+    private static Matrix createTransformation(final BursaWolfParameters bursaWolf, final Extent areaOfInterest) {
+        /*
+         * Implementation note: we know that we do not need to compute an instant if the parameters is
+         * not a subclass of BursaWolfParameters. This optimisation covers the vast majority of cases.
+         */
+        return bursaWolf.getPositionVectorTransformation(bursaWolf.getClass() != BursaWolfParameters.class ?
+                Extents.getDate(areaOfInterest, 0.5) : null); // 0.5 is for choosing midway instant.
+    }
+
+    /**
+     * Returns the best parameters matching the given criteria, or {@code null} if none.
+     */
+    private BursaWolfParameters select(final GeodeticDatum targetDatum, final ExtentSelector<BursaWolfParameters> selector) {
+        if (bursaWolf == null) {
+            return null;
+        }
+        for (final BursaWolfParameters candidate : bursaWolf) {
+            if (deepEquals(targetDatum, candidate.getTargetDatum(), ComparisonMode.IGNORE_METADATA)) {
+                selector.evaluate(candidate.getDomainOfValidity(), candidate);
             }
         }
-        return null;
+        return selector.best();
     }
 
     /**

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -19,6 +19,9 @@ package org.apache.sis.referencing.datum
 import java.util.Map;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlRootElement;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.datum.ImageDatum;
 import org.opengis.referencing.datum.PixelInCell;
 import org.apache.sis.io.wkt.Formatter;
@@ -58,6 +61,55 @@ public class DefaultImageDatum extends A
     /**
      * Creates an image datum from the given properties. The properties map is given
      * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     * The following table is a reminder of main (not all) properties:
+     *
+     * <table class="sis">
+     *   <tr>
+     *     <th>Property name</th>
+     *     <th>Value type</th>
+     *     <th>Returned by</th>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} or {@link String}</td>
+     *     <td>{@link #getName()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td>
+     *     <td>{@link GenericName} or {@link CharSequence} (optionally as array)</td>
+     *     <td>{@link #getAlias()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} (optionally as array)</td>
+     *     <td>{@link #getIdentifiers()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getRemarks()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#ANCHOR_POINT_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getAnchorPoint()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#REALIZATION_EPOCH_KEY}</td>
+     *     <td>{@link Date}</td>
+     *     <td>{@link #getRealizationEpoch()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#DOMAIN_OF_VALIDITY_KEY}</td>
+     *     <td>{@link Extent}</td>
+     *     <td>{@link #getDomainOfValidity()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#SCOPE_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getScope()}</td>
+     *   </tr>
+     * </table>
      *
      * @param properties  The properties to be given to the identified object.
      * @param pixelInCell The way the image grid is associated with the image data attributes.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -23,6 +23,9 @@ import javax.measure.quantity.Angle;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.datum.PrimeMeridian;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.internal.util.Numerics;
@@ -96,9 +99,37 @@ public class DefaultPrimeMeridian extend
     private final Unit<Angle> angularUnit;
 
     /**
-     * Creates a prime meridian from the given properties. The properties map is given
-     * unchanged to the {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map)
-     * super-class constructor}.
+     * Creates a prime meridian from the given properties. The properties map is given unchanged to the
+     * {@linkplain AbstractIdentifiedObject#AbstractIdentifiedObject(Map) super-class constructor}.
+     * The following table is a reminder of main (not all) properties:
+     *
+     * <table class="sis">
+     *   <tr>
+     *     <th>Property name</th>
+     *     <th>Value type</th>
+     *     <th>Returned by</th>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} or {@link String}</td>
+     *     <td>{@link #getName()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td>
+     *     <td>{@link GenericName} or {@link CharSequence} (optionally as array)</td>
+     *     <td>{@link #getAlias()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} (optionally as array)</td>
+     *     <td>{@link #getIdentifiers()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getRemarks()}</td>
+     *   </tr>
+     * </table>
      *
      * @param properties          The properties to be given to the identified object.
      * @param greenwichLongitude  The longitude value relative to the Greenwich Meridian.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java Thu Nov 14 19:26:45 2013
@@ -20,6 +20,9 @@ import java.util.Date;
 import java.util.Map;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlRootElement;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.datum.TemporalDatum;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Immutable;
@@ -81,6 +84,55 @@ public class DefaultTemporalDatum extend
     /**
      * Creates a temporal datum from the given properties. The properties map is given
      * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     * The following table is a reminder of main (not all) properties:
+     *
+     * <table class="sis">
+     *   <tr>
+     *     <th>Property name</th>
+     *     <th>Value type</th>
+     *     <th>Returned by</th>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} or {@link String}</td>
+     *     <td>{@link #getName()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td>
+     *     <td>{@link GenericName} or {@link CharSequence} (optionally as array)</td>
+     *     <td>{@link #getAlias()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} (optionally as array)</td>
+     *     <td>{@link #getIdentifiers()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getRemarks()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#ANCHOR_POINT_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getAnchorPoint()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#REALIZATION_EPOCH_KEY}</td>
+     *     <td>{@link Date}</td>
+     *     <td>{@link #getRealizationEpoch()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#DOMAIN_OF_VALIDITY_KEY}</td>
+     *     <td>{@link Extent}</td>
+     *     <td>{@link #getDomainOfValidity()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#SCOPE_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getScope()}</td>
+     *   </tr>
+     * </table>
      *
      * @param properties The properties to be given to the identified object.
      * @param origin The date and time origin of this temporal datum.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -20,6 +20,9 @@ import java.util.Map;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.XmlRootElement;
+import org.opengis.util.GenericName;
+import org.opengis.util.InternationalString;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.io.wkt.Formatter;
@@ -89,6 +92,55 @@ public class DefaultVerticalDatum extend
     /**
      * Creates a vertical datum from the given properties. The properties map is given
      * unchanged to the {@linkplain AbstractDatum#AbstractDatum(Map) super-class constructor}.
+     * The following table is a reminder of main (not all) properties:
+     *
+     * <table class="sis">
+     *   <tr>
+     *     <th>Property name</th>
+     *     <th>Value type</th>
+     *     <th>Returned by</th>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} or {@link String}</td>
+     *     <td>{@link #getName()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#ALIAS_KEY}</td>
+     *     <td>{@link GenericName} or {@link CharSequence} (optionally as array)</td>
+     *     <td>{@link #getAlias()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#IDENTIFIERS_KEY}</td>
+     *     <td>{@link ReferenceIdentifier} (optionally as array)</td>
+     *     <td>{@link #getIdentifiers()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.IdentifiedObject#REMARKS_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getRemarks()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#ANCHOR_POINT_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getAnchorPoint()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#REALIZATION_EPOCH_KEY}</td>
+     *     <td>{@link Date}</td>
+     *     <td>{@link #getRealizationEpoch()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#DOMAIN_OF_VALIDITY_KEY}</td>
+     *     <td>{@link Extent}</td>
+     *     <td>{@link #getDomainOfValidity()}</td>
+     *   </tr>
+     *   <tr>
+     *     <td>{@value org.opengis.referencing.datum.Datum#SCOPE_KEY}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
+     *     <td>{@link #getScope()}</td>
+     *   </tr>
+     * </table>
      *
      * @param properties The properties to be given to the identified object.
      * @param type       The type of this vertical datum.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -83,27 +83,18 @@ final class Sphere extends DefaultEllips
      * The orthodromic distance is the shortest distance between two points
      * on a sphere's surface. The orthodromic path is always on a great circle.
      *
-     * @param  x1 Longitude of first point (in decimal degrees).
-     * @param  y1 Latitude of first point (in decimal degrees).
-     * @param  x2 Longitude of second point (in decimal degrees).
-     * @param  y2 Latitude of second point (in decimal degrees).
+     * @param  λ1 Longitude of first point (in decimal degrees).
+     * @param  φ1 Latitude of first point (in decimal degrees).
+     * @param  λ2 Longitude of second point (in decimal degrees).
+     * @param  φ2 Latitude of second point (in decimal degrees).
      * @return The orthodromic distance (in the units of this ellipsoid's axis).
      */
     @Override
-    public double orthodromicDistance(double x1, double y1, double x2, double y2) {
-        /*
-         * The calculation of orthodromic distance on an ellipsoidal surface is complex,
-         * subject to rounding errors and has no solution near the poles. In some situation
-         * we use a calculation based on a spherical shape of the earth.  A Fortran program
-         * which calculates orthodromic distances on an ellipsoidal surface can be downloaded
-         * from the NOAA site:
-         *
-         *            ftp://ftp.ngs.noaa.gov/pub/pcsoft/for_inv.3d/source/
-         */
-        y1 = toRadians(y1);
-        y2 = toRadians(y2);
-        final double dx = toRadians(abs(x2-x1) % 360);
-        double rho = sin(y1)*sin(y2) + cos(y1)*cos(y2)*cos(dx);
+    public double orthodromicDistance(double λ1, double φ1, double λ2, double φ2) {
+        φ1 = toRadians(φ1);
+        φ2 = toRadians(φ2);
+        final double dx = toRadians(abs(λ2-λ1) % 360);
+        double rho = sin(φ1)*sin(φ2) + cos(φ1)*cos(φ2)*cos(dx);
         assert abs(rho) < 1.0000001 : rho;
         if (rho > +1) rho = +1; // Catch rounding error.
         if (rho < -1) rho = -1; // Catch rounding error.

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -47,6 +47,23 @@ class GeneralMatrix extends MatrixSIS {
     private static final long serialVersionUID = 8447482612423035360L;
 
     /**
+     * Threshold value relative to 1 ULP of the greatest magnitude of elements added in a sum.
+     * For example in a sum like {@code A + B + C + D}, if the greatest term in absolute value
+     * is {@code C}, then the threshold is <code>Math.ulp(C) * {@value}</code>.  If the sum is
+     * lower than that threshold, then the result is assumed to be zero.
+     *
+     * <p>Note that if we were using {@code double} arithmetic instead than double-double, then all results smaller
+     * than {@code Math.ulp(max)} would not be significant. Those cases could be caught by a {@code ZERO_THRESHOLD}
+     * value of 1.  On the other hand, if all the extra precision of double-double arithmetic was considered valid,
+     * then the {@code ZERO_THRESHOLD} value would be approximatively 1E-16.   In reality, the extra digits in our
+     * double-double arithmetic were usually guessed rather than provided, and the last digits are also subject to
+     * rounding errors anyway. So we put the threshold to some arbitrary mid-value, which may change in any future
+     * SIS version according experience gained. As long as the value is smaller than 1, it still more accurate than
+     * {@code double} arithmetic anyway.</p>
+     */
+    private static final double ZERO_THRESHOLD = 1E-14;
+
+    /**
      * All matrix elements in a flat, row-major (column indices vary fastest) array.
      * The array length is <code>{@linkplain #numRow} * {@linkplain #numCol}</code>.
      *
@@ -212,9 +229,33 @@ class GeneralMatrix extends MatrixSIS {
     }
 
     /**
+     * Retrieves the value at the specified row and column of this matrix, wrapped in a {@code Number}
+     * or a {@link DoubleDouble} depending on available precision.
+     *
+     * @param row    The row index, from 0 inclusive to {@link #getNumRow()} exclusive.
+     * @param column The column index, from 0 inclusive to {@link #getNumCol()} exclusive.
+     * @return       The current value at the given row and column.
+     */
+    @Override
+    public Number getNumber(int row, int column) {
+        if (row >= 0 && row < numRow && column >= 0 && column < numCol) {
+            int i = row * numCol + column;
+            final double value = elements[i];
+            i += numRow * numCol;
+            if (i < elements.length) {
+                return new DoubleDouble(value, elements[i]);
+            } else {
+                return value;
+            }
+        } else {
+            throw indexOutOfBounds(row, column);
+        }
+    }
+
+    /**
      * Retrieves the value at the specified row and column of this matrix.
      *
-     * @param row    The row index, from 0 inclusive to {@link #getNumRow() } exclusive.
+     * @param row    The row index, from 0 inclusive to {@link #getNumRow()} exclusive.
      * @param column The column index, from 0 inclusive to {@link #getNumCol()} exclusive.
      * @return       The current value at the given row and column.
      */
@@ -514,6 +555,7 @@ class GeneralMatrix extends MatrixSIS {
         for (int k=0,j=0; j<numRow; j++) {
             for (int i=0; i<numCol; i++) {
                 sum.clear();
+                double max = 0;
                 int iB = i;       // Index of values in a single column of B.
                 int iA = j * nc;  // Index of values in a single row of A.
                 final int nextRow = iA + nc;
@@ -523,6 +565,11 @@ class GeneralMatrix extends MatrixSIS {
                     sum.add(dot);
                     iB += numCol; // Move to next row of B.
                     iA++;         // Move to next column of A.
+                    final double value = Math.abs(dot.value);
+                    if (value > max) max = value;
+                }
+                if (Math.abs(sum.value) < Math.ulp(max) * ZERO_THRESHOLD) {
+                    sum.clear(); // Sum is not significant according double arithmetic.
                 }
                 sum.storeTo(elements, k++, errorOffset);
             }

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -26,7 +26,7 @@ import org.apache.sis.internal.util.Nume
  * The matrix member is:
  *
  * <blockquote><pre> ┌     ┐
- * │ {@link #m00} │
+ * │ {@linkplain #m00} │
  * └     ┘</pre></blockquote>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -26,8 +26,8 @@ import org.apache.sis.internal.util.Nume
  * The matrix members are:
  *
  * <blockquote><pre> ┌         ┐
- * │ {@link #m00} {@link #m01} │
- * │ {@link #m10} {@link #m11} │
+ * │ {@linkplain #m00} {@linkplain #m01} │
+ * │ {@linkplain #m10} {@linkplain #m11} │
  * └         ┘</pre></blockquote>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -27,9 +27,9 @@ import org.apache.sis.math.MathFunctions
  * The matrix members are:
  *
  * <blockquote><pre> ┌             ┐
- * │ {@link #m00} {@link #m01} {@link #m02} │
- * │ {@link #m10} {@link #m11} {@link #m12} │
- * │ {@link #m20} {@link #m21} {@link #m22} │
+ * │ {@linkplain #m00} {@linkplain #m01} {@linkplain #m02} │
+ * │ {@linkplain #m10} {@linkplain #m11} {@linkplain #m12} │
+ * │ {@linkplain #m20} {@linkplain #m21} {@linkplain #m22} │
  * └             ┘</pre></blockquote>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -27,10 +27,10 @@ import org.apache.sis.math.MathFunctions
  * The matrix members are:
  *
  * <blockquote><pre> ┌                 ┐
- * │ {@link #m00} {@link #m01} {@link #m02} {@link #m03} │
- * │ {@link #m10} {@link #m11} {@link #m12} {@link #m13} │
- * │ {@link #m20} {@link #m21} {@link #m22} {@link #m23} │
- * │ {@link #m30} {@link #m31} {@link #m32} {@link #m33} │
+ * │ {@linkplain #m00} {@linkplain #m01} {@linkplain #m02} {@linkplain #m03} │
+ * │ {@linkplain #m10} {@linkplain #m11} {@linkplain #m12} {@linkplain #m13} │
+ * │ {@linkplain #m20} {@linkplain #m21} {@linkplain #m22} {@linkplain #m23} │
+ * │ {@linkplain #m30} {@linkplain #m31} {@linkplain #m32} {@linkplain #m33} │
  * └                 ┘</pre></blockquote>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)

Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java Thu Nov 14 19:26:45 2013
@@ -125,6 +125,28 @@ public abstract class MatrixSIS implemen
     }
 
     /**
+     * Retrieves the value at the specified row and column of this matrix, wrapped in a {@code Number}.
+     * The {@code Number} type depends on the matrix accuracy.
+     *
+     * @param row    The row index, from 0 inclusive to {@link #getNumRow()} exclusive.
+     * @param column The column index, from 0 inclusive to {@link #getNumCol()} exclusive.
+     * @return       The current value at the given row and column.
+     */
+    public Number getNumber(int row, int column) {
+        return getElement(row, column);
+    }
+
+    /**
+     * Retrieves the value at the specified row and column of this matrix.
+     *
+     * @param row    The row index, from 0 inclusive to {@link #getNumRow()} exclusive.
+     * @param column The column index, from 0 inclusive to {@link #getNumCol()} exclusive.
+     * @return       The current value at the given row and column.
+     */
+    @Override
+    public abstract double getElement(int row, int column);
+
+    /**
      * Returns a copy of all matrix elements in a flat, row-major (column indices vary fastest) array.
      * The array length is <code>{@linkplain #getNumRow()} * {@linkplain #getNumCol()}</code>.
      *

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -16,6 +16,11 @@
  */
 package org.apache.sis.referencing.datum;
 
+import java.util.Date;
+import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.metadata.iso.extent.Extents;
+import org.apache.sis.metadata.iso.extent.DefaultExtent;
+import org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.referencing.operation.matrix.Matrix4;
@@ -25,6 +30,7 @@ import org.apache.sis.test.TestCase;
 import org.junit.Test;
 
 import static org.apache.sis.test.Assert.*;
+import static org.apache.sis.test.mock.GeodeticDatumMock.WGS84;
 
 
 /**
@@ -42,8 +48,39 @@ public final strictfp class BursaWolfPar
     private static final double TO_RADIANS = Math.PI / (180 * 60 * 60);
 
     /**
-     * Invokes {@link BursaWolfParameters#getPositionVectorTransformation()} and compares
-     * with our own matrix calculated using double arithmetic.
+     * Returns the parameters for the <cite>WGS 72 to WGS 84 (2)</cite> transformation (EPSG:1238).
+     * Area of validity is the World.
+     */
+    static BursaWolfParameters createWGS72_to_WGS84() {
+        final BursaWolfParameters bursaWolf = new BursaWolfParameters(WGS84, Extents.WORLD);
+        bursaWolf.tZ = 4.5;
+        bursaWolf.rZ = 0.554;
+        bursaWolf.dS = 0.219;
+        bursaWolf.verify();
+        return bursaWolf;
+    }
+
+    /**
+     * Returns the parameters for the <cite>ED87 to WGS 84 (1)</cite> transformation (EPSG:1146).
+     * Area of validity is the North Sea: 5.05°W to 11.13°E in longitude and 51.04°N to 62.0°N in latitude.
+     */
+    static BursaWolfParameters createED87_to_WGS84() {
+        final BursaWolfParameters bursaWolf = new BursaWolfParameters(WGS84, new DefaultExtent("Europe - North Sea",
+                new DefaultGeographicBoundingBox(-5.05, 11.13, 51.04, 62.0), null, null));
+        bursaWolf.tX =  -82.981;
+        bursaWolf.tY =  -99.719;
+        bursaWolf.tZ = -110.709;
+        bursaWolf.rX =   -0.5076;
+        bursaWolf.rY =    0.1503;
+        bursaWolf.rZ =    0.3898;
+        bursaWolf.dS =   -0.3143;
+        bursaWolf.verify();
+        return bursaWolf;
+    }
+
+    /**
+     * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)}
+     * and compares with our own matrix calculated using double arithmetic.
      */
     private static MatrixSIS getPositionVectorTransformation(final BursaWolfParameters p) {
         final double   S = 1 + p.dS / BursaWolfParameters.PPM;
@@ -54,13 +91,13 @@ public final strictfp class BursaWolfPar
             -p.rY*RS,  +p.rX*RS,         S,  p.tZ,
                    0,         0,         0,  1);
 
-        final MatrixSIS matrix = MatrixSIS.castOrCopy(p.getPositionVectorTransformation());
+        final MatrixSIS matrix = MatrixSIS.castOrCopy(p.getPositionVectorTransformation(null));
         assertMatrixEquals("getPositionVectorTransformation", expected, matrix, p.isTranslation() ? 0 : 1E-14);
         return matrix;
     }
 
     /**
-     * Tests {@link BursaWolfParameters#getPositionVectorTransformation()}.
+     * Tests {@link BursaWolfParameters#getPositionVectorTransformation(Date)}.
      * This test transform a point from WGS72 to WGS84, and conversely,
      * as documented in the example section of EPSG operation method 9606.
      *
@@ -68,9 +105,9 @@ public final strictfp class BursaWolfPar
      */
     @Test
     public void testGetPositionVectorTransformation() throws NoninvertibleMatrixException {
-        final BursaWolfParameters bursaWolf = new BursaWolfParameters(0, 0, 4.5, 0, 0, 0.554, 0.219, null);
+        final BursaWolfParameters bursaWolf = createWGS72_to_WGS84();
         final MatrixSIS toWGS84 = getPositionVectorTransformation(bursaWolf);
-        final MatrixSIS toWGS72 = getPositionVectorTransformation(bursaWolf).inverse();
+        final MatrixSIS toWGS72 = toWGS84.inverse();
         final MatrixSIS source  = Matrices.create(4, 1, new double[] {3657660.66, 255768.55, 5201382.11, 1});
         final MatrixSIS target  = Matrices.create(4, 1, new double[] {3657660.78, 255778.43, 5201387.75, 1});
         assertMatrixEquals("toWGS84", target, toWGS84.multiply(source), 0.01);
@@ -78,6 +115,21 @@ public final strictfp class BursaWolfPar
     }
 
     /**
+     * Tests the {@link BursaWolfParameters#setPositionVectorTransformation(Matrix, double)} method.
+     * This is an internal consistency test.
+     */
+    @Test
+    @DependsOnMethod("testGetPositionVectorTransformation")
+    public void testSetPositionVectorTransformation() {
+        final BursaWolfParameters bursaWolf = createED87_to_WGS84();
+        final Matrix matrix = bursaWolf.getPositionVectorTransformation(null);
+        final BursaWolfParameters actual = new BursaWolfParameters(
+                bursaWolf.getTargetDatum(), bursaWolf.getDomainOfValidity());
+        actual.setPositionVectorTransformation(matrix, 1E-10);
+        assertEquals(bursaWolf, actual);
+    }
+
+    /**
      * Multiplies the <cite>ED87 to WGS 84</cite> parameters (EPSG:1146) transformation by its inverse and
      * verifies that the result is very close to the identity matrix, thanks to the double-double arithmetic.
      * This is an internal consistency test.
@@ -87,12 +139,26 @@ public final strictfp class BursaWolfPar
     @Test
     @DependsOnMethod("testGetPositionVectorTransformation")
     public void testProductOfInverse() throws NoninvertibleMatrixException {
-        final BursaWolfParameters bursaWolf = new BursaWolfParameters(
-                -82.981, -99.719, -110.709, -0.5076, 0.1503, 0.3898, -0.3143, null);
+        final BursaWolfParameters bursaWolf = createED87_to_WGS84();
         final MatrixSIS toWGS84 = getPositionVectorTransformation(bursaWolf);
         final MatrixSIS toED87  = getPositionVectorTransformation(bursaWolf).inverse();
         final MatrixSIS product = toWGS84.multiply(toED87);
-        assertTrue(Matrices.isIdentity(product, 1E-37));
+        assertTrue(product.isIdentity());
+    }
+
+    /**
+     * Tests {@link BursaWolfParameters#invert()}.
+     *
+     * @throws NoninvertibleMatrixException Should never happen.
+     */
+    @Test
+    @DependsOnMethod("testProductOfInverse")
+    public void testInvert() throws NoninvertibleMatrixException {
+        final BursaWolfParameters bursaWolf = createED87_to_WGS84();
+        final Matrix original = getPositionVectorTransformation(bursaWolf).inverse();
+        bursaWolf.invert();
+        final Matrix inverse = getPositionVectorTransformation(bursaWolf);
+        assertMatrixEquals("invert", original, inverse, 0.001);
     }
 
     /**
@@ -100,8 +166,7 @@ public final strictfp class BursaWolfPar
      */
     @Test
     public void testToString() {
-        final BursaWolfParameters bursaWolf = new BursaWolfParameters(
-                -82.981, -99.719, -110.709, -0.5076, 0.1503, 0.3898, -0.3143, null);
+        final BursaWolfParameters bursaWolf = createED87_to_WGS84();
         assertEquals("TOWGS84[-82.981, -99.719, -110.709, -0.5076, 0.1503, 0.3898, -0.3143]", bursaWolf.toString());
     }
 
@@ -110,8 +175,7 @@ public final strictfp class BursaWolfPar
      */
     @Test
     public void testSerialization() {
-        final BursaWolfParameters bursaWolf = new BursaWolfParameters(
-                -82.981, -99.719, -110.709, -0.5076, 0.1503, 0.3898, -0.3143, null);
+        final BursaWolfParameters bursaWolf = createED87_to_WGS84();
         assertSerializedEquals(bursaWolf);
     }
 }

Copied: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java (from r1542033, sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java?p2=sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java&p1=sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java&r1=1542033&r2=1542034&rev=1542034&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -51,7 +51,7 @@ public final strictfp class DefaultGeode
      */
     @Test
     public void testCreateAndSerialize() {
-        final Map<String,Object> properties = new HashMap<>();
+        final Map<String,Object> properties = new HashMap<String,Object>();
         assertNull(properties.put(DefaultEllipsoid.NAME_KEY, "Asteroid"));
         final DefaultEllipsoid ellipsoid = DefaultEllipsoid.createEllipsoid(properties, 1200, 1000, SI.METRE);
 
@@ -92,7 +92,7 @@ public final strictfp class DefaultGeode
     @Test
     @DependsOnMethod("testCreateAndSerialize")
     public void testGetPositionVectorTransformation() {
-        final Map<String,Object> properties = new HashMap<>();
+        final Map<String,Object> properties = new HashMap<String,Object>();
         assertNull(properties.put(DefaultGeodeticDatum.NAME_KEY, "Invalid dummy datum"));
         /*
          * Associate two BursaWolfParameters, one valid only in a local area and the other one

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -171,6 +171,7 @@ public abstract strictfp class MatrixTes
                 final double e = expected.get(j,i);
                 final double a = actual.getElement(j,i);
                 assertEquals(name, e, a, tolerance);
+                assertEquals(name, e, actual.getNumber(j,i).doubleValue(), tolerance);
                 if (tolerance != STRICT && statistics != null) {
                     synchronized (statistics) {
                         statistics.accept(StrictMath.abs(e - a));

Modified: sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -41,6 +41,8 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.operation.matrix.MatricesTest.class,
     org.apache.sis.referencing.operation.matrix.AffineTransforms2DTest.class,
 
+    org.apache.sis.internal.referencing.FormulasTest.class,
+    org.apache.sis.internal.referencing.VerticalDatumTypesTest.class,
     org.apache.sis.io.wkt.ConventionTest.class,
     org.apache.sis.io.wkt.SymbolsTest.class,
     org.apache.sis.io.wkt.FormatterTest.class,
@@ -48,6 +50,12 @@ import org.junit.BeforeClass;
     org.apache.sis.referencing.AbstractIdentifiedObjectTest.class,
     org.apache.sis.referencing.AbstractReferenceSystemTest.class,
     org.apache.sis.referencing.datum.BursaWolfParametersTest.class,
+    org.apache.sis.referencing.datum.TimeDependentBWPTest.class,
+    org.apache.sis.referencing.datum.DefaultEllipsoidTest.class,
+    org.apache.sis.referencing.datum.DefaultVerticalDatumTest.class,
+    org.apache.sis.referencing.datum.DefaultGeodeticDatumTest.class,
+    org.apache.sis.referencing.StandardDefinitionsTest.class,
+    org.apache.sis.referencing.GeodeticObjectsTest.class,
 
     org.apache.sis.geometry.AbstractDirectPositionTest.class,
     org.apache.sis.geometry.GeneralDirectPositionTest.class,

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DoubleConsumer.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DoubleConsumer.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DoubleConsumer.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DoubleConsumer.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -18,7 +18,7 @@ package org.apache.sis.internal.jdk8;
 
 
 /**
- * Placeholder for the {@link ava.util.function.DoubleConsumer} interface.
+ * Placeholder for the {@link java.util.function.DoubleConsumer} interface.
  */
 public interface DoubleConsumer {
     /**

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -59,7 +59,7 @@ import org.apache.sis.math.DecimalFuncti
  * @version 0.4
  * @module
  *
- * @see <a href="http://en.wikipedia.org/wiki/Double-double_%28arithmetic%29#Double-double_arithmetic">Double-double arithmetic</a>
+ * @see <a href="http://en.wikipedia.org/wiki/Double-double_%28arithmetic%29#Double-double_arithmetic">Wikipedia: Double-double arithmetic</a>
  */
 public final class DoubleDouble extends Number {
     /**
@@ -199,9 +199,23 @@ public final class DoubleDouble extends 
     }
 
     /**
+     * Creates a new value initialized to the given number. If the given number is an
+     * instance of {@code DoubleDouble}, then its error term will be taken in account.
+     *
+     * @param otherValue The initial value.
+     */
+    public DoubleDouble(final Number otherValue) {
+        value = otherValue.doubleValue();
+        error = (otherValue instanceof DoubleDouble) ? ((DoubleDouble) otherValue).error : errorForWellKnownValue(value);
+    }
+
+    /**
      * Creates a new value initialized to the given value and an error term inferred by
      * {@link #errorForWellKnownValue(double)}.
      *
+     * <b>Tip:</b> if the other value is known to be an integer or a power of 2, then invoking
+     * <code>{@linkplain #DoubleDouble(double, double) DoubleDouble}(otherValue, 0)</code> is more efficient.
+     *
      * @param value The initial value.
      */
     public DoubleDouble(final double value) {
@@ -434,13 +448,44 @@ public final class DoubleDouble extends 
      *    add(other.value, other.error);
      * }
      *
-     * @param other The other value to add to this value.
+     * @param other The other value to add to this {@code DoubleDouble}.
      */
     public void add(final DoubleDouble other) {
         add(other.value, other.error);
     }
 
     /**
+     * Adds a {@code Number} value to this {@code DoubleDouble}. If the given number is an instance
+     * of {@code DoubleDouble}, then its error term will be taken in account.
+     *
+     * @param other The other value to add to this {@code DoubleDouble}.
+     */
+    public void add(final Number other) {
+        if (other instanceof DoubleDouble) {
+            add((DoubleDouble) other);
+        } else {
+            add(other.doubleValue());
+        }
+    }
+
+    /**
+     * Adds a {@code double} value to this {@code DoubleDouble} with a default error term.
+     * This is a convenience method for:
+     *
+     * {@preformat java
+     *    add(otherValue, errorForWellKnownValue(otherValue));
+     * }
+     *
+     * <b>Tip:</b> if the other value is known to be an integer or a power of 2, then invoking
+     * <code>{@linkplain #add(double, double) add}(otherValue, 0)</code> is more efficient.
+     *
+     * @param otherValue The other value to add to this {@code DoubleDouble}.
+     */
+    public void add(final double otherValue) {
+        add(otherValue, errorForWellKnownValue(otherValue));
+    }
+
+    /**
      * Adds an other double-double value to this {@code DoubleDouble}.
      * The result is stored in this instance.
      *
@@ -522,6 +567,37 @@ public final class DoubleDouble extends 
     }
 
     /**
+     * Subtracts a {@code Number} from this {@code DoubleDouble}. If the given number is an instance
+     * of {@code DoubleDouble}, then its error term will be taken in account.
+     *
+     * @param other The other value to subtract from this {@code DoubleDouble}.
+     */
+    public void subtract(final Number other) {
+        if (other instanceof DoubleDouble) {
+            subtract((DoubleDouble) other);
+        } else {
+            subtract(other.doubleValue());
+        }
+    }
+
+    /**
+     * Subtracts a {@code double} from this {@code DoubleDouble} with a default error term.
+     * This is a convenience method for:
+     *
+     * {@preformat java
+     *    subtract(otherValue, errorForWellKnownValue(otherValue));
+     * }
+     *
+     * <b>Tip:</b> if the other value is known to be an integer or a power of 2, then invoking
+     * <code>{@linkplain #subtract(double, double) subtract}(otherValue, 0)</code> is more efficient.
+     *
+     * @param otherValue The other value to subtract from this {@code DoubleDouble}.
+     */
+    public void subtract(final double otherValue) {
+        subtract(otherValue, errorForWellKnownValue(otherValue));
+    }
+
+    /**
      * Subtracts an other double-double value from this {@code DoubleDouble}.
      * The result is stored in this instance.
      *
@@ -556,13 +632,44 @@ public final class DoubleDouble extends 
      *    multiply(other.value, other.error);
      * }
      *
-     * @param other The other value to add to this value.
+     * @param other The other value to multiply by this value.
      */
     public void multiply(final DoubleDouble other) {
         multiply(other.value, other.error);
     }
 
     /**
+     * Multiplies this {@code DoubleDouble} by a {@code Number}. If the given number is an instance
+     * of {@code DoubleDouble}, then its error term will be taken in account.
+     *
+     * @param other The other value to multiply by this {@code DoubleDouble}.
+     */
+    public void multiply(final Number other) {
+        if (other instanceof DoubleDouble) {
+            multiply((DoubleDouble) other);
+        } else {
+            multiply(other.doubleValue());
+        }
+    }
+
+    /**
+     * Multiplies this {@code DoubleDouble} by a {@code double} with a default error term.
+     * This is a convenience method for:
+     *
+     * {@preformat java
+     *    multiply(otherValue, errorForWellKnownValue(otherValue));
+     * }
+     *
+     * <b>Tip:</b> if the other value is known to be an integer or a power of 2, then invoking
+     * <code>{@linkplain #multiply(double, double) multiply}(otherValue, 0)</code> is more efficient.
+     *
+     * @param otherValue The other value to multiply by this {@code DoubleDouble}.
+     */
+    public void multiply(final double otherValue) {
+        multiply(otherValue, errorForWellKnownValue(otherValue));
+    }
+
+    /**
      * Multiplies this {@code DoubleDouble} by an other double-double value.
      * The result is stored in this instance.
      *
@@ -626,13 +733,44 @@ public final class DoubleDouble extends 
      *    divide(other.value, other.error);
      * }
      *
-     * @param other The other value to add to this value.
+     * @param other The other value to by which to divide this value.
      */
     public void divide(final DoubleDouble other) {
         divide(other.value, other.error);
     }
 
     /**
+     * Divides this {@code DoubleDouble} by a {@code Number}. If the given number is an instance
+     * of {@code DoubleDouble}, then its error term will be taken in account.
+     *
+     * @param other The other value by which to divide this {@code DoubleDouble}.
+     */
+    public void divide(final Number other) {
+        if (other instanceof DoubleDouble) {
+            divide((DoubleDouble) other);
+        } else {
+            divide(other.doubleValue());
+        }
+    }
+
+    /**
+     * Divides this {@code DoubleDouble} by a {@code double} with a default error term.
+     * This is a convenience method for:
+     *
+     * {@preformat java
+     *    divide(otherValue, errorForWellKnownValue(otherValue));
+     * }
+     *
+     * <b>Tip:</b> if the other value is known to be an integer or a power of 2, then invoking
+     * <code>{@linkplain #divide(double, double) divide}(otherValue, 0)</code> is more efficient.
+     *
+     * @param otherValue The other value by which to divide this {@code DoubleDouble}.
+     */
+    public void divide(final double otherValue) {
+        divide(otherValue, errorForWellKnownValue(otherValue));
+    }
+
+    /**
      * Divides this {@code DoubleDouble} by an other double-double value.
      * The result is stored in this instance.
      *
@@ -676,13 +814,44 @@ public final class DoubleDouble extends 
      *    inverseDivide(other.value, other.error);
      * }
      *
-     * @param other The other value to add to this value.
+     * @param other The other value to divide by this value.
      */
     public void inverseDivide(final DoubleDouble other) {
         inverseDivide(other.value, other.error);
     }
 
     /**
+     * Divides the given {@code Number} value by this {@code DoubleDouble}. If the given number
+     * is an instance of {@code DoubleDouble}, then its error term will be taken in account.
+     *
+     * @param other The other value to divide by this {@code DoubleDouble}.
+     */
+    public void inverseDivide(final Number other) {
+        if (other instanceof DoubleDouble) {
+            inverseDivide((DoubleDouble) other);
+        } else {
+            inverseDivide(other.doubleValue());
+        }
+    }
+
+    /**
+     * Divides the given {@code double} value by this {@code DoubleDouble} with a default error term.
+     * This is a convenience method for:
+     *
+     * {@preformat java
+     *    inverseDivide(numeratorValue, errorForWellKnownValue(numeratorValue));
+     * }
+     *
+     * <b>Tip:</b> if the other value is known to be an integer or a power of 2, then invoking
+     * <code>{@linkplain #inverseDivide(double, double) inverseDivide}(otherValue, 0)</code> is more efficient.
+     *
+     * @param numeratorValue The other value to divide by this {@code DoubleDouble}.
+     */
+    public void inverseDivide(final double numeratorValue) {
+        inverseDivide(numeratorValue, errorForWellKnownValue(numeratorValue));
+    }
+
+    /**
      * Divides the given double-double value by this {@code DoubleDouble}.
      * The result is stored in this instance.
      *

Modified: sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -36,7 +36,7 @@ import org.apache.sis.util.resources.Err
  * @version 0.3
  * @module
  *
- * @see <a href="http://en.wikipedia.org/wiki/ANSI_escape_code">ANSI escape codes</a>
+ * @see <a href="http://en.wikipedia.org/wiki/ANSI_escape_code">Wikipedia: ANSI escape codes</a>
  * @see org.apache.sis.io.wkt.Colors
  */
 public enum X364 {

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/IdentifiedObjectMock.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/IdentifiedObjectMock.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/IdentifiedObjectMock.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/IdentifiedObjectMock.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -16,29 +16,40 @@
  */
 package org.apache.sis.test.mock;
 
+import java.util.Arrays;
 import java.util.Set;
 import java.util.Collection;
 import java.util.Collections;
+import java.io.Serializable;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
+import org.opengis.metadata.citation.Citation;
 import org.opengis.referencing.IdentifiedObject;
 import org.opengis.referencing.ReferenceIdentifier;
-import javax.xml.bind.annotation.XmlElement;
-import javax.xml.bind.annotation.XmlRootElement;
-import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
 import org.apache.sis.internal.jaxb.gco.GO_GenericName;
 
 
 /**
  * A dummy implementation of {@link IdentifiedObject} with minimal XML (un)marshalling capability.
+ * This object can also be its own identifier, with a {@linkplain #getCode() code} defined in the
+ * {@code "test"} {@linkplain #getCodeSpace() codespace}.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.4
  * @module
  */
+@SuppressWarnings("serial")
 @XmlRootElement(name = "IO_IdentifiedObject")
-public final strictfp class IdentifiedObjectMock implements IdentifiedObject {
+public strictfp class IdentifiedObjectMock implements IdentifiedObject, ReferenceIdentifier, Serializable {
+    /**
+     * The object name to be returned by {@link #getCode()}.
+     */
+    private String code;
+
     /**
      * The alias to (un)marshal to XML
      */
@@ -47,6 +58,14 @@ public final strictfp class IdentifiedOb
     public GenericName alias;
 
     /**
+     * Returns all properties defined in this object,
+     * for the convenience of {@link #equals(Object)} and {@link #hashCode()}.
+     */
+    Object[] properties() {
+        return new Object[] {code, alias};
+    }
+
+    /**
      * Creates an initially empty identified object.
      * This constructor is required by JAXB.
      */
@@ -54,7 +73,17 @@ public final strictfp class IdentifiedOb
     }
 
     /**
-     * Creates an initially empty identified object of the given alias.
+     * Creates an identified object of the given name.
+     * Callers are free to assign new value to the {@link #alias} field directly.
+     *
+     * @param code The initial {@link #getCode()} value, or {@code null} if none.
+     */
+    public IdentifiedObjectMock(final String code) {
+        this.code = code;
+    }
+
+    /**
+     * Creates an identified object of the given alias.
      * Callers are free to assign new value to the {@link #alias} field directly.
      *
      * @param alias The initial {@link #alias} value (can be {@code null}).
@@ -64,22 +93,62 @@ public final strictfp class IdentifiedOb
     }
 
     /**
-     * Returns the name (currently null).
+     * Returns the object name, or {@code null} if none.
+     *
+     * @return The name of this object, or {@code null} if none.
+     */
+    @Override
+    public final ReferenceIdentifier getName() {
+        return (code != null) ? this : null;
+    }
+
+    /**
+     * Returns the code supplied at construction time, or {@code null} if none.
+     *
+     * @return The object code, or {@code null}.
+     */
+    @Override
+    public final String getCode() {
+        return code;
+    }
+
+    /**
+     * Returns the codespace, which is fixed to {@code "test"}.
      *
-     * @return The name of this object.
+     * @return {@code "test"}.
      */
     @Override
-    public ReferenceIdentifier getName() {
+    public final String getCodeSpace() {
+        return "test";
+    }
+
+    /**
+     * Returns the identifier version ({@code null} for now).
+     *
+     * @return The identifier version.
+     */
+    @Override
+    public final String getVersion() {
         return null;
     }
 
     /**
-     * Returns {@link #alias} in an unmodifiable collection.
+     * Returns the authority that define the object ({@code null} for now).
      *
-     * @return {@link #alias} singleton.
+     * @return The defining authority.
      */
     @Override
-    public Collection<GenericName> getAlias() {
+    public final Citation getAuthority() {
+        return null;
+    }
+
+    /**
+     * Returns {@link #alias} in an unmodifiable collection, or an empty collection if the alias is null.
+     *
+     * @return {@link #alias} singleton or an empty collection.
+     */
+    @Override
+    public final Collection<GenericName> getAlias() {
         return (alias != null) ? Collections.singleton(alias) : Collections.<GenericName>emptySet();
     }
 
@@ -89,7 +158,7 @@ public final strictfp class IdentifiedOb
      * @return The identifiers of this object.
      */
     @Override
-    public Set<ReferenceIdentifier> getIdentifiers() {
+    public final Set<ReferenceIdentifier> getIdentifiers() {
         return null;
     }
 
@@ -99,7 +168,7 @@ public final strictfp class IdentifiedOb
      * @return The remarks associated to this object.
      */
     @Override
-    public InternationalString getRemarks() {
+    public final InternationalString getRemarks() {
         return null;
     }
 
@@ -110,7 +179,39 @@ public final strictfp class IdentifiedOb
      * @throws UnsupportedOperationException If there is no WKT representation.
      */
     @Override
-    public String toWKT() throws UnsupportedOperationException {
+    public final String toWKT() throws UnsupportedOperationException {
         throw new UnsupportedOperationException();
     }
+
+    /**
+     * Returns a string representation for debugging purpose.
+     */
+    @Override
+    public final String toString() {
+        return getClass().getSimpleName() + '[' + code + ']';
+    }
+
+    /**
+     * Returns a hash code value for this object.
+     *
+     * @return A hash code value.
+     */
+    @Override
+    public final int hashCode() {
+        return Arrays.hashCode(properties());
+    }
+
+    /**
+     * Compares this object with the given object for equality.
+     *
+     * @param  object The other object, or {@code null}.
+     * @return {@code true} if both objects are equal.
+     */
+    @Override
+    public final boolean equals(final Object object) {
+        if (object != null && object.getClass() == getClass()) {
+            return Arrays.equals(properties(), ((IdentifiedObjectMock) object).properties());
+        }
+        return false;
+    }
 }

Modified: sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/package-info.java?rev=1542034&r1=1542033&r2=1542034&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/package-info.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/suite/package-info.java [UTF-8] Thu Nov 14 19:26:45 2013
@@ -17,11 +17,12 @@
 
 /**
  * Suites for all SIS tests in dependency order.
- * This package contains exactly one {@code TestSuite} class for each module.
+ * Each module will typically provide one {@code FooTestSuite} class in this class,
+ * where {@code Foo} is the module name.
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3
- * @version 0.3
+ * @version 0.4
  * @module
  */
 package org.apache.sis.test.suite;



Mime
View raw message