sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1541929 - in /sis/branches/JDK7/core: sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/ sis-referencing/src/main/java/org/apache/sis/referencing/datum/
Date Thu, 14 Nov 2013 15:23:44 GMT
Author: desruisseaux
Date: Thu Nov 14 15:23:44 2013
New Revision: 1541929

URL: http://svn.apache.org/r1541929
Log:
Compute the date where to evaluate the position vector transformation from the given extent.

Modified:
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
    sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
    sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java

Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java?rev=1541929&r1=1541928&r2=1541929&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java
[UTF-8] Thu Nov 14 15:23:44 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/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java?rev=1541929&r1=1541928&r2=1541929&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java
[UTF-8] Thu Nov 14 15:23:44 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.

Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1541929&r1=1541928&r2=1541929&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
[UTF-8] (original)
+++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
[UTF-8] Thu Nov 14 15:23:44 2013
@@ -32,6 +32,7 @@ import org.opengis.referencing.datum.Geo
 import org.opengis.referencing.operation.Matrix;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
 import org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
+import org.apache.sis.metadata.iso.extent.Extents;
 import org.apache.sis.internal.referencing.ExtentSelector;
 import org.apache.sis.internal.util.CollectionsExt;
 import org.apache.sis.util.logging.Logging;
@@ -325,39 +326,40 @@ public class DefaultGeodeticDatum extend
      * </ul>
      *
      * If more than one {@code BursaWolfParameters} instance is found in any of the above
steps, then the one having
-     * the largest intersection between their {@linkplain BursaWolfParameters#getDomainOfValidity()
domain of validity}
+     * the largest intersection between its {@linkplain BursaWolfParameters#getDomainOfValidity()
domain of validity}
      * and the given extent will be selected. If more than one instance have the same intersection,
then the first
      * occurrence is selected.
      *
-     * <p>If non-null, then the transformation is represented by an affine transform
which can be applied on
-     * <strong>geocentric</strong> coordinates. This is identified in the EPSG
database as operation method
-     * 1033 - <cite>Position Vector transformation (geocentric domain)</cite>,
or
-     * 1053 - <cite>Time-dependent Position Vector transformation</cite>.</p>
+     * <p>If the given extent contains a {@linkplain org.opengis.metadata.extent.TemporalExtent
temporal extent},
+     * then the instant located midway between start and end time will be taken as the date
where to evaluate the
+     * Bursa-Wolf parameters. This apply only to {@linkplain TimeDependentBWP time-dependent
parameters}.</p>
+     *
+     * <p>If the returned matrix is non-null, then the transformation is represented
by an affine transform which can be
+     * applied on <strong>geocentric</strong> coordinates. This is identified
in the EPSG database as operation method
+     * 1033 – <cite>Position Vector transformation (geocentric domain)</cite>,
or
+     * 1053 – <cite>Time-dependent Position Vector transformation</cite>.</p>
      *
      * @param  targetDatum The target datum.
-     * @param  extent The geographic and temporal extent where the transformation is valid,
or {@code null}.
+     * @param  areaOfInterest The geographic and temporal extent where the transformation
should be valid, or {@code null}.
      * @return An affine transform from {@code this} to {@code target} in geocentric space,
or {@code null} if none.
      *
      * @see BursaWolfParameters#getPositionVectorTransformation(Date)
      */
-    public Matrix getPositionVectorTransformation(final GeodeticDatum targetDatum, final
Extent extent) {
+    public Matrix getPositionVectorTransformation(final GeodeticDatum targetDatum, final
Extent areaOfInterest) {
         ensureNonNull("targetDatum", targetDatum);
-        final ExtentSelector<BursaWolfParameters> selector = new ExtentSelector<>(extent);
-        Date time = null; // TODO
-        /*
-         * Search in the BursaWolfParameters associated to this instance.
-         */
+        final ExtentSelector<BursaWolfParameters> selector = new ExtentSelector<>(areaOfInterest);
         BursaWolfParameters candidate = select(targetDatum, selector);
         if (candidate != null) {
-            return candidate.getPositionVectorTransformation(time);
+            return createTransformation(candidate, areaOfInterest);
         }
         /*
-         * Search in the BursaWolfParameters associated to the other instance, if any.
+         * Found no suitable BursaWolfParameters associated to this instance.
+         * Search in the BursaWolfParameters associated to the other instance.
          */
         if (targetDatum instanceof DefaultGeodeticDatum) {
             candidate = ((DefaultGeodeticDatum) targetDatum).select(this, selector);
             if (candidate != null) try {
-                return MatrixSIS.castOrCopy(candidate.getPositionVectorTransformation(time)).inverse();
+                return MatrixSIS.castOrCopy(createTransformation(candidate, areaOfInterest)).inverse();
             } catch (NoninvertibleMatrixException e) {
                 /*
                  * Should never happen because BursaWolfParameters.getPositionVectorTransformation(Date)
@@ -371,6 +373,20 @@ public class DefaultGeodeticDatum extend
     }
 
     /**
+     * Invokes {@link BursaWolfParameters#getPositionVectorTransformation(Date)} for a date
calculated from
+     * the temporal elements on the given extent.  This method chooses an instant located
midway between the
+     * start and end time.
+     */
+    private static Matrix createTransformation(final BursaWolfParameters bursaWolf, final
Extent areaOfInterest) {
+        /*
+         * Implementation note: we know that we do not need to compute an instant if the
parameters is
+         * not a subclass of BursaWolfParameters. This optimisation covers the vast majority
of cases.
+         */
+        return bursaWolf.getPositionVectorTransformation(bursaWolf.getClass() != BursaWolfParameters.class
?
+                Extents.getDate(areaOfInterest, 0.5) : null); // 0.5 is for choosing midway
instant.
+    }
+
+    /**
      * Returns the best parameters matching the given criteria, or {@code null} if none.
      */
     private BursaWolfParameters select(final GeodeticDatum targetDatum, final ExtentSelector<BursaWolfParameters>
selector) {



Mime
View raw message