You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2013/11/14 20:30:08 UTC

svn commit: r1542035 [1/2] - in /sis/trunk: ./ 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/sis-meta...

Author: desruisseaux
Date: Thu Nov 14 19:30:07 2013
New Revision: 1542035

URL: http://svn.apache.org/r1542035
Log:
Merge from the JDK6 branch.

Added:
    sis/trunk/application/sis-console/src/test/java/org/apache/sis/test/suite/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/application/sis-console/src/test/java/org/apache/sis/test/suite/package-info.txt
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/test/suite/package-info.txt
    sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/xml/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/xml/package-info.txt
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtentSelector.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ExtentSelector.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/internal/
      - copied from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/internal/
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectsTest.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/GeodeticObjectsTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/StandardDefinitionsTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultEllipsoidTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultGeodeticDatumTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/DefaultVerticalDatumTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/TimeDependentBWPTest.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/TimeDependentBWPTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-referencing/src/test/java/org/apache/sis/test/suite/package-info.txt
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/mock/GeodeticDatumMock.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/GeodeticDatumMock.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/mock/PrimeMeridianMock.java
      - copied unchanged from r1542034, sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/test/mock/PrimeMeridianMock.java
    sis/trunk/profiles/sis-french-profile/src/test/java/org/apache/sis/test/suite/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/profiles/sis-french-profile/src/test/java/org/apache/sis/test/suite/package-info.txt
    sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/test/suite/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/storage/sis-netcdf/src/test/java/org/apache/sis/test/suite/package-info.txt
    sis/trunk/storage/sis-shapefile/src/test/java/org/apache/sis/test/suite/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/storage/sis-shapefile/src/test/java/org/apache/sis/test/suite/package-info.txt
    sis/trunk/storage/sis-storage/src/test/java/org/apache/sis/test/suite/package-info.txt
      - copied unchanged from r1542034, sis/branches/JDK6/storage/sis-storage/src/test/java/org/apache/sis/test/suite/package-info.txt
Modified:
    sis/trunk/   (props changed)
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
    sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/VerticalDatumTypes.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultImageDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultPrimeMeridian.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultTemporalDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultVerticalDatum.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/Sphere.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix1.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix2.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix3.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrix4.java
    sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
    sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/DoubleConsumer.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
    sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/X364.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/mock/IdentifiedObjectMock.java
    sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/package-info.java

Propchange: sis/trunk/
------------------------------------------------------------------------------
  Merged /sis/branches/JDK7:r1540209-1542033
  Merged /sis/branches/JDK6:r1540210-1542034

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -150,8 +150,7 @@ public class DefaultTemporalExtent exten
      *              or {@code false} for the end time.
      * @return The requested time as a Java date, or {@code null} if none.
      */
-    private Date getTime(final boolean begin) {
-        final TemporalPrimitive extent = this.extent;
+    static Date getTime(final TemporalPrimitive extent, final boolean begin) {
         final Instant instant;
         if (extent instanceof Instant) {
             instant = (Instant) extent;
@@ -170,7 +169,7 @@ public class DefaultTemporalExtent exten
      * @return The start time, or {@code null} if none.
      */
     public Date getStartTime() {
-        return getTime(true);
+        return getTime(extent, true);
     }
 
     /**
@@ -180,7 +179,7 @@ public class DefaultTemporalExtent exten
      * @return The end time, or {@code null} if none.
      */
     public Date getEndTime() {
-        return getTime(false);
+        return getTime(extent, false);
     }
 
     /**

Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -16,12 +16,16 @@
  */
 package org.apache.sis.metadata.iso.extent;
 
+import java.util.Date;
+import org.opengis.temporal.TemporalPrimitive;
 import org.opengis.metadata.extent.Extent;
+import org.opengis.metadata.extent.TemporalExtent;
 import org.opengis.metadata.extent.BoundingPolygon;
 import org.opengis.metadata.extent.GeographicExtent;
 import org.opengis.metadata.extent.GeographicBoundingBox;
 import org.apache.sis.measure.Longitude;
 import org.apache.sis.util.resources.Vocabulary;
+import org.apache.sis.util.ArgumentChecks;
 import org.apache.sis.util.Static;
 
 import static java.lang.Math.*;
@@ -31,6 +35,14 @@ import static org.apache.sis.internal.me
 
 /**
  * Convenience static methods for extracting information from {@link Extent} objects.
+ * This class provides methods for:
+ *
+ * <ul>
+ *   <li>{@link #getGeographicBoundingBox(Extent)} and {@link #getDate(Extent, double)}
+ *       for fetching geographic or temporal components in a convenient form.</li>
+ *   <li>Methods for computing {@linkplain #intersection intersection} of bounding boxes
+ *       and {@linkplain #area area} estimations.</li>
+ * </ul>
  *
  * @author  Martin Desruisseaux (Geomatys)
  * @since   0.3 (derived from geotk-2.2)
@@ -113,6 +125,57 @@ public final class Extents extends Stati
     }
 
     /**
+     * Returns an instant in the {@linkplain Extent#getTemporalElements() temporal elements} of the given extent,
+     * or {@code null} if none. First, this method computes the union of all temporal elements. Then this method
+     * computes the linear interpolation between the start and end time as in the following pseudo-code:
+     *
+     * {@preformat java
+     *     return new Date(startTime + (endTime - startTime) * location);
+     * }
+     *
+     * Special cases:
+     * <ul>
+     *   <li>If {@code location} is 0, then this method returns the {@linkplain DefaultTemporalExtent#getStartTime() start time}.</li>
+     *   <li>If {@code location} is 1, then this method returns the {@linkplain DefaultTemporalExtent#getEndTime() end time}.</li>
+     *   <li>If {@code location} is 0.5, then this method returns the average of start time and end time.</li>
+     *   <li>If {@code location} is outside the [0 … 1] range, then the result will be outside the temporal extent.</li>
+     * </ul>
+     *
+     * @param  extent   The extent from which to get an instant, or {@code null}.
+     * @param  location 0 for the start time, 1 for the end time, 0.5 for the average time, or the
+     *                  coefficient (usually in the [0 … 1] range) for interpolating an instant.
+     * @return An instant interpolated at the given location, or {@code null} if none.
+     *
+     * @since 0.4
+     */
+    public static Date getDate(final Extent extent, final double location) {
+        ArgumentChecks.ensureFinite("location", location);
+        Date min = null;
+        Date max = null;
+        if (extent != null) {
+            for (final TemporalExtent t : extent.getTemporalElements()) {
+                Date startTime = null;
+                Date   endTime = null;
+                if (t instanceof DefaultTemporalExtent) {
+                    final DefaultTemporalExtent dt = (DefaultTemporalExtent) t;
+                    if (location != 1) startTime = dt.getStartTime(); // Maybe user has overridden those methods.
+                    if (location != 0)   endTime = dt.getEndTime();
+                } else {
+                    final TemporalPrimitive p = t.getExtent();
+                    if (location != 1) startTime = DefaultTemporalExtent.getTime(p, true);
+                    if (location != 0)   endTime = DefaultTemporalExtent.getTime(p, false);
+                }
+                if (startTime != null && (min == null || startTime.before(min))) min = startTime;
+                if (  endTime != null && (max == null ||   endTime.after (max))) max =   endTime;
+            }
+        }
+        if (min == null) return max;
+        if (max == null) return min;
+        final long startTime = min.getTime();
+        return new Date(startTime + Math.round((max.getTime() - startTime) * location)); // addExact on JDK8 branch.
+    }
+
+    /**
      * Returns the intersection of the given geographic bounding boxes. If any of the arguments is {@code null},
      * then this method returns the other argument (which may be null). Otherwise this method returns a box which
      * is the intersection of the two given boxes.
@@ -149,7 +212,7 @@ public final class Extents extends Stati
      * However this may change in any future SIS version.</p>
      *
      * @param  box The geographic bounding box for which to compute the area, or {@code null}.
-     * @return An estimation of the geographic area in the given bounding box,
+     * @return An estimation of the area in the given bounding box (m²),
      *         or {@linkplain Double#NaN NaN} if the given box was null.
      *
      * @since 0.4

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Formulas.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -56,6 +56,15 @@ public final class Formulas extends Stat
     public static final double ANGULAR_TOLERANCE = LINEAR_TOLERANCE / (NAUTICAL_MILE * 60);
 
     /**
+     * The length of a <cite>Julian year</cite> in milliseconds.
+     * From Wikipedia, "<cite>In astronomy, a Julian year (symbol: <b>a</b>) is a unit of measurement of time
+     * defined as exactly 365.25 days of 86,400 SI seconds each.</cite>".
+     *
+     * @see <a href="http://en.wikipedia.org/wiki/Julian_year_%28astronomy%29">Wikipedia: Julian year (astronomy)</a>
+     */
+    public static final long JULIAN_YEAR_LENGTH = 31557600000L;
+
+    /**
      * Do not allow instantiation of this class.
      */
     private Formulas() {

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -16,6 +16,8 @@
  */
 package org.apache.sis.internal.referencing;
 
+import org.opengis.referencing.operation.Matrix;
+import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.util.Static;
 
 
@@ -38,5 +40,20 @@ public final class ReferencingUtilities 
     private ReferencingUtilities() {
     }
 
-    // TODO: methods to be ported from Geotk later.
+    /**
+     * Retrieves the value at the specified row and column of the given matrix, wrapped in a {@code Number}.
+     * The {@code Number} type depends on the matrix accuracy.
+     *
+     * @param matrix The matrix from which to get the number.
+     * @param row    The row index, from 0 inclusive to {@link Matrix#getNumRow()} exclusive.
+     * @param column The column index, from 0 inclusive to {@link Matrix#getNumCol()} exclusive.
+     * @return       The current value at the given row and column.
+     */
+    public static Number getNumber(final Matrix matrix, final int row, final int column) {
+        if (matrix instanceof MatrixSIS) {
+            return ((MatrixSIS) matrix).getNumber(row, column);
+        } else {
+            return matrix.getElement(row, column);
+        }
+    }
 }

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/VerticalDatumTypes.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/VerticalDatumTypes.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/VerticalDatumTypes.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/VerticalDatumTypes.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -16,8 +16,8 @@
  */
 package org.apache.sis.internal.referencing;
 
-import org.opengis.referencing.datum.Datum;
 import org.opengis.util.CodeList;
+import org.opengis.referencing.datum.VerticalDatum;
 import org.opengis.referencing.datum.VerticalDatumType;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.util.StringBuilders;
@@ -114,16 +114,16 @@ public final class VerticalDatumTypes im
      * Guesses the type of the given datum using its name or identifiers. This is sometime needed
      * after XML unmarshalling, since GML 3.2 does not contain any attribute for the datum type.
      *
-     * <p>This method uses heuristic rules and may be changed in any future SIS version. If the type can not be
-     * determined, default on the ellipsoidal type since it will usually implies no additional calculation.</p>
+     * <p>This method uses heuristic rules and may be changed in any future SIS version.
+     * If the type can not be determined, default on {@link VerticalDatumType#OTHER_SURFACE}.</p>
      *
      * @param  datum The datum for which to guess a type.
-     * @return A datum type, or {@link #ELLIPSOIDAL} if none can be guessed.
+     * @return A datum type, or {@link VerticalDatumType#OTHER_SURFACE} if none can be guessed.
      */
-    public static VerticalDatumType guess(final Datum datum) {
+    public static VerticalDatumType guess(final VerticalDatum datum) {
         final VerticalDatumType type = CodeList.valueOf(VerticalDatumType.class,
                 new VerticalDatumTypes(IdentifiedObjects.getName(datum, null)));
-        return (type != null) ? type : ELLIPSOIDAL;
+        return (type != null) ? type : VerticalDatumType.OTHER_SURFACE;
     }
 
     /**
@@ -144,7 +144,7 @@ public final class VerticalDatumTypes im
         datum = new StringBuilder(length);
         for (int i=0; i<length;) {
             final int c = name.codePointAt(i);
-            datum.appendCodePoint(Character.toUpperCase(i));
+            datum.appendCodePoint(Character.toUpperCase(c));
             i += Character.charCount(c);
         }
         StringBuilders.toASCII(datum);

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/package-info.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -59,7 +59,7 @@
  * <ul>
  *   <li><a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html">Well Known Text specification</a></li>
  *   <li><a href="http://home.gdal.org/projects/opengis/wktproblems.html">OGC WKT Coordinate System Issues</a></li>
- *   <li><a href="http://en.wikipedia.org/wiki/Well-known_text">Well Known Text in Wikipedia</a></li>
+ *   <li><a href="http://en.wikipedia.org/wiki/Well-known_text">Wikipedia: Well Known Text</a></li>
  * </ul>
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractIdentifiedObject.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -170,15 +170,10 @@ public class AbstractIdentifiedObject ex
      *   </tr>
      *   <tr>
      *     <td>{@value org.opengis.referencing.IdentifiedObject#NAME_KEY}</td>
-     *     <td>{@link String} or {@link ReferenceIdentifier}</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 CharSequence}, {@link GenericName} or an array of those</td>
-     *     <td>{@link #getAlias()}</td>
-     *   </tr>
-     *   <tr>
      *     <td>{@value org.opengis.metadata.Identifier#AUTHORITY_KEY}</td>
      *     <td>{@link String} or {@link Citation}</td>
      *     <td>{@link NamedIdentifier#getAuthority()} on the {@linkplain #getName() name}</td>
@@ -199,13 +194,18 @@ public class AbstractIdentifiedObject ex
      *     <td>{@link NamedIdentifier#getVersion()} on the {@linkplain #getName() name}</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} or <code>{@linkplain ReferenceIdentifier}[]</code></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 String} or {@link InternationalString}</td>
+     *     <td>{@link InternationalString} or {@link String}</td>
      *     <td>{@link #getRemarks()}</td>
      *   </tr>
      * </table>

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/AbstractReferenceSystem.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -18,8 +18,10 @@ package org.apache.sis.referencing;
 
 import java.util.Map;
 import javax.xml.bind.annotation.XmlElement;
+import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.referencing.ReferenceSystem;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.opengis.metadata.extent.Extent;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Immutable;
@@ -112,6 +114,29 @@ public class AbstractReferenceSystem ext
      *     <td>{@link String} or {@link InternationalString}</td>
      *     <td>{@link #getScope}</td>
      *   </tr>
+     *   <tr>
+     *     <th colspan="3" class="hsep">Defined in parent class (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>
      * </table>
      *
      * @param properties The properties to be given to this object.

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/GeodeticObjects.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -220,7 +220,7 @@ public enum GeodeticObjects {
     /**
      * The EPSG code of the ellipsoid.
      */
-    private final short ellipsoid;
+    final short ellipsoid;
 
     /**
      * The cached object. This is initially {@code null}, then set to various kind of objects depending

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/AbstractDatum.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -21,9 +21,11 @@ import java.util.Map;
 import javax.xml.bind.annotation.XmlType;
 import javax.xml.bind.annotation.XmlElement;
 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
+import org.opengis.util.GenericName;
 import org.opengis.util.InternationalString;
 import org.opengis.metadata.extent.Extent;
 import org.opengis.referencing.datum.Datum;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.apache.sis.referencing.AbstractIdentifiedObject;
 import org.apache.sis.referencing.IdentifiedObjects;
 import org.apache.sis.io.wkt.Formatter;
@@ -128,6 +130,29 @@ public class AbstractDatum extends Abstr
      *     <td>{@link InternationalString} or {@link String}</td>
      *     <td>{@link #getScope()}</td>
      *   </tr>
+     *   <tr>
+     *     <th colspan="3" class="hsep">Defined in parent class (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>
      * </table>
      *
      * @param properties The properties to be given to the identified object.
@@ -198,10 +223,9 @@ public class AbstractDatum extends Abstr
     }
 
     /**
-     * Returns the region or timeframe in which this reference system is valid,
-     * or {@code null} if unspecified.
+     * Returns the region or timeframe in which this datum is valid, or {@code null} if unspecified.
      *
-     * @return Area or region or timeframe in which this (coordinate) reference system is valid, or {@code null}.
+     * @return Area or region or timeframe in which this datum is valid, or {@code null}.
      *
      * @see org.apache.sis.metadata.iso.extent.DefaultExtent
      */

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -16,24 +16,25 @@
  */
 package org.apache.sis.referencing.datum;
 
+import java.util.Date;
 import java.util.Arrays;
 import java.io.Serializable;
+import org.opengis.metadata.extent.Extent;
 import org.opengis.referencing.datum.GeodeticDatum;
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.referencing.operation.matrix.Matrix4;
 import org.apache.sis.referencing.operation.matrix.Matrices;
 import org.apache.sis.io.wkt.FormattableObject;
 import org.apache.sis.io.wkt.Formatter;
-import org.apache.sis.util.Immutable;
 import org.apache.sis.util.resources.Errors;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.util.DoubleDouble;
 import org.apache.sis.referencing.IdentifiedObjects;
 
-import static java.lang.Math.PI;
 import static java.lang.Math.abs;
 import static org.apache.sis.util.ArgumentChecks.*;
 import static org.apache.sis.referencing.operation.matrix.Matrix4.SIZE;
+import static org.apache.sis.internal.referencing.ReferencingUtilities.getNumber;
 
 // Related to JDK7
 import org.apache.sis.internal.jdk7.Objects;
@@ -41,8 +42,9 @@ import org.apache.sis.internal.jdk7.Obje
 
 /**
  * Parameters for a geographic transformation between two datum.
- * For an explanation of Bursa-Wolf parameters purpose, see the <cite>Bursa-Wolf parameters</cite>
- * section of {@link DefaultGeodeticDatum} class javadoc.
+ * Bursa-Wolf parameters are also known as <cite>Helmert transformation parameters</cite>.
+ * For an explanation of their purpose, see the <cite>Bursa-Wolf parameters</cite> section
+ * of {@link DefaultGeodeticDatum} class javadoc.
  *
  * <p>The Bursa-Wolf parameters shall be applied to geocentric coordinates,
  * where the <var>X</var> axis points towards the Greenwich Prime Meridian,
@@ -124,7 +126,7 @@ import org.apache.sis.internal.jdk7.Obje
  * </math></p>
  * </tr></td></table>
  *
- * The numerical fields in this {@code BursaWolfParameters} class uses the EPSG abbreviations
+ * The numerical fields in this {@code BursaWolfParameters} class use the EPSG abbreviations
  * with 4 additional constraints compared to the EPSG definitions:
  *
  * <ul>
@@ -136,13 +138,27 @@ import org.apache.sis.internal.jdk7.Obje
  *       The Position Vector convention is used by IAG and recommended by ISO 19111.</li>
  * </ul>
  *
- * {@section Target datum}
+ * {@section Source and target geodetic datum}
  * The <var>source datum</var> in above coordinates transformation is the {@link DefaultGeodeticDatum} instance
  * that contain this {@code BursaWolfParameters}. It can be any datum, including datum that are valid only locally.
- * But the {@linkplain #targetDatum target datum} is often fixed to WGS 84, since it is the target of the
- * {@code TOWGS84} element in <cite>Well Known Text</cite> (WKT) representations.
- * A different target may be specified at construction time, however users are encouraged to always specify a
- * target datum having a world-wide {@linkplain DefaultGeodeticDatum#getDomainOfValidity() domain of validity}.
+ * The <var>{@linkplain #getTargetDatum() target datum}</var> is specified at construction time and often fixed to
+ * WGS 84 for the needs of the {@code TOWGS84[…]} element in <cite>Well Known Text</cite> (WKT 1) representation.
+ *
+ * {@section When Bursa-Wolf parameters are used}
+ * {@code BursaWolfParameters} are used in three contexts:
+ * <ol>
+ *   <li>Created as a step while creating a {@linkplain org.apache.sis.referencing.operation.DefaultCoordinateOperation
+ *       coordinate operation} from the EPSG database.</li>
+ *   <li>Associated to a {@link DefaultGeodeticDatum} for the sole needs of the WKT 1 {@code TOWGS84[…]} element.
+ *       In this case, only Bursa-Wolf parameters having a WGS 84 {@linkplain #getTargetDatum() target datum} are
+ *       useful.</li>
+ *   <li>Specified at {@code DefaultGeodeticDatum} construction time for arbitrary target datum.
+ *       Apache SIS will ignore those Bursa-Wolf parameters, except as a fallback if no parameters
+ *       can been found in the EPSG database for a given pair of source and target CRS.</li>
+ * </ol>
+ *
+ * {@note In EPSG terminology, Apache SIS gives precedence to the <cite>late-binding</cite> approach
+ *        (case 1 above) over the <cite>early-binding</cite> approach (case 3 above).}
  *
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @since   0.4 (derived from geotk-1.2)
@@ -150,9 +166,9 @@ import org.apache.sis.internal.jdk7.Obje
  * @module
  *
  * @see DefaultGeodeticDatum#getBursaWolfParameters()
+ * @see <a href="http://en.wikipedia.org/wiki/Helmert_transformation">Wikipedia: Helmert transformation</a>
  */
-@Immutable
-public class BursaWolfParameters extends FormattableObject implements Serializable {
+public class BursaWolfParameters extends FormattableObject implements Cloneable, Serializable {
     /**
      * Serial number for inter-operability with different versions.
      */
@@ -164,45 +180,40 @@ public class BursaWolfParameters extends
     static final double PPM = 1E+6;
 
     /**
-     * The conversion factor from arc-seconds to radians.
-     */
-    private static final double TO_RADIANS = PI / (180 * 60 * 60);
-
-    /**
      * X-axis translation in metres (EPSG:8605).
      * The legacy OGC parameter name is {@code "dx"}.
      */
-    public final double tX;
+    public double tX;
 
     /**
      * Y-axis translation in metres (EPSG:8606).
      * The legacy OGC parameter name is {@code "dy"}.
      */
-    public final double tY;
+    public double tY;
 
     /**
      * Z-axis translation in metres (EPSG:8607).
      * The legacy OGC parameter name is {@code "dz"}.
      */
-    public final double tZ;
+    public double tZ;
 
     /**
-     * X-axis rotation in arc seconds (EPSG:8608), sign following the <cite>Position Vector</cite> convention.
+     * X-axis rotation in arc-seconds (EPSG:8608), sign following the <cite>Position Vector</cite> convention.
      * The legacy OGC parameter name is {@code "ex"}.
      */
-    public final double rX;
+    public double rX;
 
     /**
-     * Y-axis rotation in arc seconds (EPSG:8609), sign following the <cite>Position Vector</cite> convention.
+     * Y-axis rotation in arc-seconds (EPSG:8609), sign following the <cite>Position Vector</cite> convention.
      * The legacy OGC parameter name is {@code "ey"}.
      */
-    public final double rY;
+    public double rY;
 
     /**
-     * Z-axis rotation in arc seconds (EPSG:8610), sign following the <cite>Position Vector</cite> convention.
+     * Z-axis rotation in arc-seconds (EPSG:8610), sign following the <cite>Position Vector</cite> convention.
      * The legacy OGC parameter name is {@code "ez"}.
      */
-    public final double rZ;
+    public double rZ;
 
     /**
      * The scale difference in parts per million (EPSG:8611).
@@ -212,50 +223,51 @@ public class BursaWolfParameters extends
      *           of 100.001 km in the target coordinate reference system, the scale difference is 1 ppm
      *           (the ratio being 1.000001).}
      */
-    public final double dS;
+    public double dS;
 
     /**
-     * The target datum for this set of parameters, or {@code null} if unspecified.
-     * This is usually the WGS 84 datum, but other targets are allowed. We recommend the target datum
-     * to have a world-wide {@linkplain DefaultGeodeticDatum#getDomainOfValidity() domain of validity},
-     * but this is not enforced.
+     * The target datum for this set of parameters.
+     * This is usually the WGS 84 datum, but other targets are allowed.
      *
      * <p>The source datum is the {@link DefaultGeodeticDatum} that contain this {@code BursaWolfParameters}
      * instance.</p>
+     *
+     * @see #getTargetDatum()
      */
-    public final GeodeticDatum targetDatum;
+    private final GeodeticDatum targetDatum;
 
     /**
-     * Creates a new instance with the given parameters.
+     * Region or timeframe in which a coordinate transformation based on those Bursa-Wolf parameters is valid,
+     * or {@code null} if unspecified.
      *
-     * @param tX X-axis translation in metres.
-     * @param tY Y-axis translation in metres.
-     * @param tZ Z-axis translation in metres.
-     * @param rX X-axis rotation in arc seconds.
-     * @param rY Y-axis rotation in arc seconds.
-     * @param rZ Z-axis rotation in arc seconds.
-     * @param dS The scale difference in parts per million.
-     * @param targetDatum The target datum (usually WGS 84) for this set of parameters, or {@code null} if unspecified.
-     */
-    public BursaWolfParameters(final double tX, final double tY, final double tZ,
-                               final double rX, final double rY, final double rZ,
-                               final double dS, final GeodeticDatum targetDatum)
-    {
-        this.tX = tX;
-        this.tY = tY;
-        this.tZ = tZ;
-        this.rX = rX;
-        this.rY = rY;
-        this.rZ = rZ;
-        this.dS = dS;
+     * @see #getDomainOfValidity()
+     */
+    private final Extent domainOfValidity;
+
+    /**
+     * Creates a new instance for the given target datum and domain of validity.
+     * All numerical parameters are initialized to 0, which correspond to an identity transform.
+     * Callers can assign numerical values to the public fields of interest after construction.
+     * For example, many coordinate transformations will provide values only for the translation
+     * terms ({@link #tX}, {@link #tY}, {@link #tZ}).
+     *
+     * <p>Alternatively, numerical fields can also be initialized by a call to
+     * {@link #setPositionVectorTransformation(Matrix, double)}.</p>
+     *
+     * @param targetDatum The target datum (usually WGS 84) for this set of parameters.
+     * @param domainOfValidity Area or region in which a coordinate transformation based on those Bursa-Wolf parameters
+     *        is valid, or {@code null} is unspecified.
+     */
+    public BursaWolfParameters(final GeodeticDatum targetDatum, final Extent domainOfValidity) {
+        ensureNonNull("targetDatum", targetDatum);
         this.targetDatum = targetDatum;
-        verify();
+        this.domainOfValidity = domainOfValidity;
     }
 
     /**
-     * Verifies parameters validity after construction.
+     * Verifies parameters validity after initialization.
      */
-    private void verify() {
+    void verify() {
         ensureFinite("tX", tX);
         ensureFinite("tY", tY);
         ensureFinite("tZ", tZ);
@@ -266,66 +278,16 @@ public class BursaWolfParameters extends
     }
 
     /**
-     * Creates Bursa-Wolf parameters from the given matrix.
-     * The matrix shall comply to the following constraints:
-     *
-     * <ul>
-     *   <li>The matrix shall be {@linkplain org.apache.sis.referencing.operation.matrix.MatrixSIS#isAffine() affine}.</li>
-     *   <li>The sub-matrix defined by {@code matrix} without the last row and last column shall be
-     *       <a href="http://en.wikipedia.org/wiki/Skew-symmetric_matrix">skew-symmetric</a> (a.k.a. antisymmetric).</li>
-     * </ul>
+     * Returns the target datum for this set of parameters.
+     * This is usually the WGS 84 datum, but other targets are allowed.
      *
-     * @param  matrix The matrix to fit as a Bursa-Wolf construct.
-     * @param  tolerance The tolerance error for the antisymmetric matrix test. Should be a small number like {@code 1E-8}.
-     * @param  targetDatum The target datum (usually WGS 84) for this set of parameters, or {@code null} if unspecified.
-     * @throws IllegalArgumentException if the specified matrix does not meet the conditions.
+     * <p>The source datum is the {@link DefaultGeodeticDatum} that contain this {@code BursaWolfParameters}
+     * instance.</p>
      *
-     * @see #getPositionVectorTransformation()
+     * @return The target datum for this set of parameters.
      */
-    public BursaWolfParameters(final Matrix matrix, final double tolerance, final GeodeticDatum targetDatum)
-            throws IllegalArgumentException
-    {
-        final int numRow = matrix.getNumRow();
-        final int numCol = matrix.getNumCol();
-        if (numRow != SIZE || numCol != SIZE) {
-            final Integer n = SIZE;
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedMatrixSize_4, n, n, numRow, numCol));
-        }
-        if (!Matrices.isAffine(matrix)) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.NotAnAffineTransform));
-        }
-        tX = matrix.getElement(0,3);
-        tY = matrix.getElement(1,3);
-        tZ = matrix.getElement(2,3);
-        final double S = (matrix.getElement(0,0) +
-                          matrix.getElement(1,1) +
-                          matrix.getElement(2,2)) / 3;
-        final double RS = TO_RADIANS * S;
-        dS = (S-1) * PPM;
-        double rX=0, rY=0, rZ=0;
-        for (int j=0; j < SIZE-1; j++) {
-            if (!(abs((matrix.getElement(j,j) - 1)*PPM - dS) <= tolerance)) {
-                throw new IllegalArgumentException(Errors.format(Errors.Keys.NonUniformScale));
-            }
-            for (int i = j+1; i < SIZE-1; i++) {
-                final double elt1 = matrix.getElement(j,i) / RS;
-                final double elt2 = matrix.getElement(i,j) / RS;
-                if (!(abs(elt1 + elt2) <= tolerance)) { // We expect elt1 ≈ -elt2
-                    throw new IllegalArgumentException(Errors.format(Errors.Keys.NotASkewSymmetricMatrix));
-                }
-                final double elt = 0.5 * (elt2 - elt1);
-                switch (j*SIZE + i) {
-                    case 1: rZ =  elt; break;
-                    case 2: rY = -elt; break;
-                    case 6: rX =  elt; break;
-                }
-            }
-        }
-        this.rX = rX;
-        this.rY = rY;
-        this.rZ = rZ;
-        this.targetDatum = targetDatum;
-        verify();
+    public GeodeticDatum getTargetDatum() {
+        return targetDatum;
     }
 
     /**
@@ -336,35 +298,82 @@ public class BursaWolfParameters extends
      * @return {@code true} if the given datum is equal to WGS84 for computational purpose.
      */
     final boolean isToWGS84() {
-        return (targetDatum == null) ||
-                (IdentifiedObjects.nameMatches(targetDatum, "WGS 84") ||
-                 IdentifiedObjects.nameMatches(targetDatum, "WGS84"));
+        return IdentifiedObjects.nameMatches(targetDatum, "WGS 84") ||
+               IdentifiedObjects.nameMatches(targetDatum, "WGS84");
     }
 
     /**
-     * Returns {@code true} if this Bursa-Wolf parameters performs no operation.
-     * This is true when all parameters are set to zero.
+     * Returns {@code true} if a transformation built from this set of parameters would perform no operation.
+     * This is true when the value of all parameters is zero.
      *
      * @return {@code true} if the parameters describe no operation.
      */
     public boolean isIdentity() {
-        return tX == 0 && tY == 0 && tZ == 0 &&
-               rX == 0 && rY == 0 && rZ == 0 &&
-               dS == 0;
+        return tX == 0 && tY == 0 && tZ == 0 && isTranslation();
     }
 
     /**
-     * Returns {@code true} if this Bursa-Wolf parameters contains only translation terms.
+     * Returns {@code true} if a transformation built from this set of parameters would perform only a translation.
      *
-     * @return {@code true} if the parameters describe to a translation only.
+     * @return {@code true} if the parameters describe a translation only.
      */
     public boolean isTranslation() {
         return rX == 0 && rY == 0 && rZ == 0 && dS == 0;
     }
 
     /**
+     * Inverts in-place the transformation by inverting the sign of all numerical parameters.
+     * The {@linkplain #getPositionVectorTransformation(Date) position vector transformation} matrix
+     * created from inverted Bursa-Wolf parameters will be <strong>approximatively</strong> equals
+     * to the {@linkplain org.apache.sis.referencing.operation.matrix.MatrixSIS#inverse() inverse}
+     * of the matrix created from the original parameters. The equality holds approximatively only
+     * because the parameter values are very small (parts per millions and arc-seconds).
+     */
+    public void invert() {
+        tX = -tX;
+        tY = -tY;
+        tZ = -tZ;
+        rX = -rX;
+        rY = -rY;
+        rZ = -rZ;
+        dS = -dS;
+    }
+
+    /**
+     * Returns the elapsed time from the {@linkplain TimeDependentBWP#getTimeReference() reference time}
+     * to the given date, in millennium. If this {@code BursaWolfParameters} is not time-dependent, then
+     * returns {@code null}.
+     */
+    DoubleDouble period(final Date time) {
+        return null;
+    }
+
+    /**
+     * Returns the parameter at the given index. If this {@code BursaWolfParameters} is time-dependent,
+     * then the returned value shall be corrected for the given period.
+     *
+     * @param index  0 for {@code tX}, 1 for {@code tY}, <i>etc.</i> in {@code TOWGS84[…]} order.
+     * @param period The value computed by {@link #period(Date)}, or {@code null}.
+     */
+    DoubleDouble param(final int index, final DoubleDouble period) {
+        final double p;
+        switch (index) {
+            case 0: p = tX; break;
+            case 1: p = tY; break;
+            case 2: p = tZ; break;
+            case 3: p = rX; break;
+            case 4: p = rY; break;
+            case 5: p = rZ; break;
+            case 6: p = dS; break;
+            default: throw new AssertionError(index);
+        }
+        return new DoubleDouble(p);
+    }
+
+    /**
      * Returns the position vector transformation (geocentric domain) as an affine transform.
-     * The formula is as below, where {@code R} is a conversion factor from arc-seconds to radians:
+     * For transformations that do not depend on time, the formula is as below where {@code R}
+     * is a conversion factor from arc-seconds to radians:
      *
      * <blockquote><pre> R = toRadians(1″)
      * S = 1 + {@linkplain #dS}/1000000
@@ -377,6 +386,15 @@ public class BursaWolfParameters extends
      *
      * This affine transform can be applied on <strong>geocentric</strong> coordinates.
      * This is identified as operation method 1033 in the EPSG database.
+     * Those geocentric coordinates are typically converted from geographic coordinates
+     * in the region or timeframe given by {@link #getDomainOfValidity()}.
+     *
+     * {@section Time-dependent transformation}
+     * Some transformations use parameters that vary with time (e.g. operation method EPSG:1053).
+     * Users can optionally specify a date for which the transformation is desired.
+     * For transformations that do not depends on time, this date is ignored and can be null.
+     * For time-dependent transformations, {@code null} values default to the transformation's
+     * {@linkplain TimeDependentBWP#getTimeReference() reference time}.
      *
      * {@section Inverse transformation}
      * The inverse transformation can be approximated by reversing the sign of the 7 parameters before to use them
@@ -386,12 +404,14 @@ public class BursaWolfParameters extends
      * that concatenation of transformations <var>A</var> → <var>B</var> followed by <var>B</var> → <var>A</var>
      * gives back the identity transform.
      *
-     * @return An affine transform in geocentric space created from this Bursa-Wolf parameters.
+     * @param  time Date for which the transformation is desired, or {@code null} for the transformation's reference time.
+     * @return An affine transform in geocentric space created from this Bursa-Wolf parameters and the given time.
      *
-     * @see DefaultGeodeticDatum#getPositionVectorTransformation(GeodeticDatum)
+     * @see DefaultGeodeticDatum#getPositionVectorTransformation(GeodeticDatum, Extent)
      */
-    public Matrix getPositionVectorTransformation() {
-        if (isTranslation()) {
+    public Matrix getPositionVectorTransformation(final Date time) {
+        final DoubleDouble period = period(time);
+        if (period == null && isTranslation()) {
             final Matrix4 matrix = new Matrix4();
             matrix.m03 = tX;
             matrix.m13 = tY;
@@ -403,25 +423,137 @@ public class BursaWolfParameters extends
          * translation terms. If we have rotation or scale terms, then use double-double arithmetic.
          */
         final DoubleDouble RS = DoubleDouble.createSecondsToRadians();
-        final DoubleDouble S = new DoubleDouble(dS);
+        final DoubleDouble S = param(6, period);
         S.divide(PPM, 0);
         S.add(1, 0);        // S = 1 + dS / PPM;
         RS.multiply(S);     // RS = toRadians(1″) * S;
-        final DoubleDouble  X = new DoubleDouble(rX); X.multiply(RS);
-        final DoubleDouble  Y = new DoubleDouble(rY); Y.multiply(RS);
-        final DoubleDouble  Z = new DoubleDouble(rZ); Z.multiply(RS);
-        final DoubleDouble mX = new DoubleDouble( X); mX.negate();
-        final DoubleDouble mY = new DoubleDouble( Y); mY.negate();
-        final DoubleDouble mZ = new DoubleDouble( Z); mZ.negate();
+        final DoubleDouble  X = param(3, period); X.multiply(RS);
+        final DoubleDouble  Y = param(4, period); Y.multiply(RS);
+        final DoubleDouble  Z = param(5, period); Z.multiply(RS);
+        final DoubleDouble mX = new DoubleDouble(X); mX.negate();
+        final DoubleDouble mY = new DoubleDouble(Y); mY.negate();
+        final DoubleDouble mZ = new DoubleDouble(Z); mZ.negate();
         final Integer       O = 0; // Fetch Integer instance only once.
         return Matrices.create(4, 4, new Number[] {
-                 S,  mZ,   Y,  Double.valueOf(tX),
-                 Z,   S,  mX,  Double.valueOf(tY),
-                mY,   X,   S,  Double.valueOf(tZ),
+                 S,  mZ,   Y,  param(0, period),
+                 Z,   S,  mX,  param(1, period),
+                mY,   X,   S,  param(2, period),
                  O,   O,   O,  1});
     }
 
     /**
+     * Sets all Bursa-Wolf parameters from the given <cite>Position Vector transformation</cite> matrix.
+     * The matrix shall comply to the following constraints:
+     *
+     * <ul>
+     *   <li>The matrix shall be {@linkplain org.apache.sis.referencing.operation.matrix.MatrixSIS#isAffine() affine}.</li>
+     *   <li>The sub-matrix defined by {@code matrix} without the last row and last column shall be
+     *       <a href="http://en.wikipedia.org/wiki/Skew-symmetric_matrix">skew-symmetric</a> (a.k.a. antisymmetric).</li>
+     * </ul>
+     *
+     * @param  matrix The matrix from which to get Bursa-Wolf parameters.
+     * @param  tolerance The tolerance error for the skew-symmetric matrix test, in units of PPM or arc-seconds (e.g. 1E-8).
+     * @throws IllegalArgumentException if the specified matrix does not meet the conditions.
+     *
+     * @see #getPositionVectorTransformation(Date)
+     */
+    public void setPositionVectorTransformation(final Matrix matrix, final double tolerance) throws IllegalArgumentException {
+        final int numRow = matrix.getNumRow();
+        final int numCol = matrix.getNumCol();
+        if (numRow != SIZE || numCol != SIZE) {
+            final Integer n = SIZE;
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.MismatchedMatrixSize_4, n, n, numRow, numCol));
+        }
+        if (!Matrices.isAffine(matrix)) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.NotAnAffineTransform));
+        }
+        /*
+         * Translation terms, taken "as-is".
+         */
+        tX = matrix.getElement(0,3);
+        tY = matrix.getElement(1,3);
+        tZ = matrix.getElement(2,3);
+        /*
+         * Scale factor: take the average of elements on the diagonal. All those
+         * elements should have the same value, but we tolerate slight deviation
+         * (this will be verified later).
+         */
+        final DoubleDouble S = new DoubleDouble(getNumber(matrix, 0,0));
+        S.add(getNumber(matrix, 1,1));
+        S.add(getNumber(matrix, 2,2));
+        S.divide(3, 0);
+        /*
+         * Computes: RS = S * toRadians(1″)
+         *           dS = (S-1) * PPM
+         */
+        final DoubleDouble RS = DoubleDouble.createSecondsToRadians();
+        RS.multiply(S);
+        S.add(-1, 0);
+        S.multiply(PPM, 0);
+        dS = S.value;
+        /*
+         * Rotation terms. Each rotation terms appear twice, with one value being the negative of the other value.
+         * We verify this skew symmetric aspect in the loop. We also opportunistically verify that the scale terms
+         * are uniform.
+         */
+        for (int j=0; j < SIZE-1; j++) {
+            if (!(abs((matrix.getElement(j,j) - 1)*PPM - dS) <= tolerance)) {
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.NonUniformScale));
+            }
+            for (int i = j+1; i < SIZE-1; i++) {
+                S.setFrom(RS);
+                S.inverseDivide(getNumber(matrix, j,i)); // Negative rotation term.
+                double value = S.value;
+                double error = S.error;
+                S.setFrom(RS);
+                S.inverseDivide(getNumber(matrix, i,j)); // Positive rotation term.
+                if (!(abs(value + S.value) <= tolerance)) { // We expect r1 ≈ -r2
+                    throw new IllegalArgumentException(Errors.format(Errors.Keys.NotASkewSymmetricMatrix));
+                }
+                S.subtract(value, error);
+                S.multiply(0.5, 0);
+                value = S.value; // Average of the two rotation terms.
+                switch (j*SIZE + i) {
+                    case 1: rZ =  value; break;
+                    case 2: rY = -value; break;
+                    case 6: rX =  value; break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the region or timeframe in which a coordinate transformation based on those Bursa-Wolf parameters is
+     * valid, or {@code null} if unspecified. If an extent was specified at construction time, then that extent is
+     * returned. Otherwise the datum domain of validity (which may be {@code null}) is returned.
+     *
+     * @return Area or region or timeframe in which the coordinate transformation is valid, or {@code null}.
+     *
+     * @see org.apache.sis.metadata.iso.extent.DefaultExtent
+     */
+    public Extent getDomainOfValidity() {
+        if (domainOfValidity == null && targetDatum != null) {
+            return targetDatum.getDomainOfValidity();
+        }
+        return domainOfValidity;
+    }
+
+    /**
+     * Returns a copy of this object.
+     *
+     * @return A copy of all parameters.
+     */
+    @Override
+    public BursaWolfParameters clone() {
+        try {
+            return (BursaWolfParameters) super.clone();
+        }  catch (CloneNotSupportedException exception) {
+            // Should not happen, since we are cloneable.
+            throw new AssertionError(exception);
+        }
+    }
+
+    /**
      * Compares the specified object with this object for equality.
      *
      * @param object The object to compare with the parameters.
@@ -429,7 +561,7 @@ public class BursaWolfParameters extends
      */
     @Override
     public boolean equals(final Object object) {
-        if (object instanceof BursaWolfParameters) {
+        if (object != null && object.getClass() == getClass()) {
             final BursaWolfParameters that = (BursaWolfParameters) object;
             return Numerics.equals(this.tX, that.tX) &&
                    Numerics.equals(this.tY, that.tY) &&
@@ -438,7 +570,8 @@ public class BursaWolfParameters extends
                    Numerics.equals(this.rY, that.rY) &&
                    Numerics.equals(this.rZ, that.rZ) &&
                    Numerics.equals(this.dS, that.dS) &&
-                    Objects.equals(this.targetDatum, that.targetDatum);
+                    Objects.equals(this.targetDatum, that.targetDatum) &&
+                    Objects.equals(this.domainOfValidity, that.domainOfValidity);
         }
         return false;
     }
@@ -461,7 +594,7 @@ public class BursaWolfParameters extends
      * <blockquote><code>TOWGS84[{@linkplain #tX}, {@linkplain #tY}, {@linkplain #tZ}, {@linkplain #rX},
      * {@linkplain #rY}, {@linkplain #rZ}, {@linkplain #dS}]</code></blockquote>
      *
-     * The element name is {@code "TOWGS84"} in the common case where the {@linkplain #targetDatum target datum}
+     * The element name is {@code "TOWGS84"} in the common case where the {@linkplain #getTargetDatum() target datum}
      * is WGS 84. For other targets, the element name will be derived from the datum name.
      *
      * @param  formatter The formatter to use.

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Thu Nov 14 19:30:07 2013
@@ -24,7 +24,10 @@ import javax.measure.converter.Conversio
 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.datum.Ellipsoid;
+import org.opengis.referencing.ReferenceIdentifier;
 import org.apache.sis.geometry.DirectPosition2D;
 import org.apache.sis.internal.util.Numerics;
 import org.apache.sis.internal.jaxb.Context;
@@ -180,8 +183,37 @@ public class DefaultEllipsoid extends Ab
      * Creates a new ellipsoid using the specified axis length.
      * 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:
      *
-     * @param  properties       The properties to be given to the identified object.
+     * <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 semiMajorAxis     The equatorial radius.
      * @param semiMinorAxis     The polar radius.
      * @param inverseFlattening The inverse of the flattening value.
@@ -511,24 +543,25 @@ public class DefaultEllipsoid extends Ab
 
     /**
      * Returns the orthodromic distance between two geographic coordinates.
-     * The orthodromic distance is the shortest distance between two points on a sphere's surface.
+     * The orthodromic distance is the shortest distance between two points on a ellipsoid's surface.
      * The orthodromic path is always on a great circle.
-     * This is different from the <cite>loxodromic distance</cite>, which is a
-     * longer distance on a path with a constant direction on the compass.
      *
-     * @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).
+     * {@note Orthodromic distances anre different than the <cite>loxodromic distance</cite>.
+     *        The later is a longer distance on a path with a constant direction on the compass.}
+     *
+     * @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).
      *
      * @see org.apache.sis.referencing.GeodeticCalculator
      */
-    public double orthodromicDistance(double x1, double y1, double x2, double y2) {
-        x1 = toRadians(x1);
-        y1 = toRadians(y1);
-        x2 = toRadians(x2);
-        y2 = toRadians(y2);
+    public double orthodromicDistance(double λ1, double φ1, double λ2, double φ2) {
+        λ1 = toRadians(λ1);
+        φ1 = toRadians(φ1);
+        λ2 = toRadians(λ2);
+        φ2 = toRadians(φ2);
         /*
          * Solution of the geodetic inverse problem after T.Vincenty.
          * Modified Rainsford's method with Helmert's elliptical terms.
@@ -547,15 +580,15 @@ public class DefaultEllipsoid extends Ab
         final double F = 1 / getInverseFlattening();
         final double R = 1 - F;
 
-        double tu1 = R * tan(y1);
-        double tu2 = R * tan(y2);
+        double tu1 = R * tan(φ1);
+        double tu2 = R * tan(φ2);
         double cu1 = 1 / sqrt(tu1*tu1 + 1);
         double cu2 = 1 / sqrt(tu2*tu2 + 1);
         double su1 = cu1 * tu1;
         double s   = cu1 * cu2;
         double baz =   s * tu2;
         double faz = baz * tu1;
-        double x   =  x2 - x1;
+        double x   =  λ2 - λ1;
         for (int i=0; i<MAX_ITERATIONS; i++) {
             final double sx = sin(x);
             final double cx = cos(x);
@@ -574,7 +607,7 @@ public class DefaultEllipsoid extends Ab
             double c = ((-3*c2a+4)*F + 4) * c2a * F/16;
             double d = x;
             x = ((e*cy*c+cz)*sy*c + y) * SA;
-            x = (1-c)*x*F + x2-x1;
+            x = (1-c)*x*F + λ2-λ1;
 
             if (abs(d-x) <= EPS) {
                 x = sqrt((1/(R*R) - 1) * c2a + 1) + 1;
@@ -590,20 +623,20 @@ public class DefaultEllipsoid extends Ab
         }
         // No convergence. It may be because coordinate points
         // are equals or because they are at antipodes.
-        if (abs(x1-x2) <= COMPARISON_THRESHOLD && abs(y1-y2) <= COMPARISON_THRESHOLD) {
+        if (abs(λ1-λ2) <= COMPARISON_THRESHOLD && abs(φ1-φ2) <= COMPARISON_THRESHOLD) {
             return 0; // Coordinate points are equals
         }
-        if (abs(y1) <= COMPARISON_THRESHOLD && abs(y2) <= COMPARISON_THRESHOLD) {
-            return abs(x1-x2) * getSemiMajorAxis(); // Points are on the equator.
+        if (abs(φ1) <= COMPARISON_THRESHOLD && abs(φ2) <= COMPARISON_THRESHOLD) {
+            return abs(λ1-λ2) * getSemiMajorAxis(); // Points are on the equator.
         }
         // At least one input ordinate is NaN.
-        if (isNaN(x1) || isNaN(y1) || isNaN(x2) || isNaN(y2)) {
+        if (isNaN(λ1) || isNaN(φ1) || isNaN(λ2) || isNaN(φ2)) {
             return NaN;
         }
         // Other cases: no solution for this algorithm.
         throw new ArithmeticException(Errors.format(Errors.Keys.NoConvergenceForPoints_2,
-                  new DirectPosition2D(toDegrees(x1), toDegrees(y1)),
-                  new DirectPosition2D(toDegrees(x2), toDegrees(y2))));
+                  new DirectPosition2D(toDegrees(λ1), toDegrees(φ1)),
+                  new DirectPosition2D(toDegrees(λ2), toDegrees(φ2))));
     }
 
     /**

Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java?rev=1542035&r1=1542034&r2=1542035&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEngineeringDatum.java [UTF-8] Thu Nov 14 19:30:07 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.EngineeringDatum;
 import org.apache.sis.util.ComparisonMode;
 import org.apache.sis.util.Immutable;
@@ -48,6 +51,55 @@ public class DefaultEngineeringDatum ext
     /**
      * Creates an engineering 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.
      */