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.
*/