Class ExtentSelector<T>

java.lang.Object
org.apache.sis.internal.referencing.ExtentSelector<T>
Type Parameters:
T - the type of object to be selected.

public final class ExtentSelector<T> extends Object
Selects an object in a sequence of objects using their extent as a criterion. The selection is based on the temporal extent and geographic area using the following rules:
  1. Object having largest intersection with the time of interest (TOI) is selected.
  2. If two or more candidates have the same intersection with TOI, then the one with less "overtime" (time outside TOI) is selected.
  3. If two or more candidates are considered equal after above criteria, then the one best centered on the TOI is selected.
Rational: the "smallest time outside" criterion (rule 2) is before "best centered" criterion (rule 3) because of the following scenario: if a user specifies a "time of interest" (TOI) of 1 day and if the candidates are a raster of monthly averages and a raster of daily data, we want the daily data to be selected even if by coincidence the monthly averages is more centered.
If there is no time of interest, or the candidate objects do not declare time range, or some objects are still at equality after application of above criteria, then the selection continues on the basis of geographic criteria:
  1. Largest intersection with the area of interest (AOI) is selected.
  2. If two or more candidates have the same intersection area with AOI, then the one with the less "irrelevant" material is selected. "Irrelevant" material are area outside the AOI.
  3. If two or more candidates are considered equal after above criteria, the one best centered on the AOI is selected.
  4. If two or more candidates are considered equal after above criteria, then the first of those candidates is selected.

Change of rule order

The following configuration flags change the order in which above rules are applied.

Usage

Example:
Since:
0.4
Version:
1.3
  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    boolean
    Whether to use an alternate conditions order where the time center criterion is tested last.
    private org.opengis.metadata.extent.GeographicBoundingBox
    The area of interest (AOI), or null if unbounded.
    private T
    The best object found so far.
    private long
    Granularity of the time of interest in seconds, or 0 if none.
    private double
    The area covered by the best object (m²).
    private Duration
    Duration of the best object, or null if none.
    private Instant
    Start/end of the time of interest (TOI), or null if unbounded.
    private Instant
    Start/end of the time of interest (TOI), or null if unbounded.
    private static final int
    Identification of which fields need to be recomputed.
    private static final int
    Identification of which fields need to be recomputed.
    private double
    Area of best object which is outside the area of interest.
    private Duration
    Duration of best object which is outside the time of interest.
    private static final int
    Identification of which fields need to be recomputed.
    private static final int
    Identification of which fields need to be recomputed.
    private double
    A pseudo-distance from best object center to areaOfInterest center.
    private static final int
    Identification of which fields need to be recomputed.
    private double
    Time between best entry center and TOI center.
  • Constructor Summary

    Constructors
    Constructor
    Description
    ExtentSelector(org.opengis.metadata.extent.Extent domain)
    Creates a selector for the given area of interest.
    ExtentSelector(org.opengis.metadata.extent.GeographicBoundingBox aoi, Instant[] toi)
    Creates a selector for the given area and time of interest.
  • Method Summary

    Modifier and Type
    Method
    Description
    Returns the object associated to the largest area found so far.
    private static int
    compare(double a, double b, int missing)
    Compares the given values as documented in Double.compareTo(Double) except in the handling of zero and NaN values.
    private static int
    compare(Duration a, Duration b, int missing)
    Compares the given duration as documented in Duration.compareTo(Duration) with the addition of supporting null values.
    void
    evaluate(org.opengis.metadata.extent.Extent domain, T object)
    Evaluates the given extent against the criteria represented by this ExtentSelector.
    void
    evaluate(org.opengis.metadata.extent.GeographicBoundingBox bbox, Instant startTime, Instant endTime, T object)
    Evaluates the given bounding box and time range against the criteria represented by this ExtentSelector.
    final org.opengis.metadata.extent.GeographicBoundingBox
    Returns the area of interest.
    final Instant[]
    Returns the time of interest as an array of length 2, or null if none.
    private static double
    median(Instant startTime, Instant endTime)
    Returns instant (in milliseconds) in the middle of given time range, or Double.NaN if none.
    private Duration
    overtime(Instant startTime, Instant endTime, Duration intersection)
    Computes the amount of time outside the time of interest (TOI).
    private double
    pseudoDistance(org.opengis.metadata.extent.GeographicBoundingBox area)
    Computes a pseudo-distance between the center of given area and of areaOfInterest.
    private Duration
    round(Duration duration)
    Returns the given duration rounded to the nearest integer amount of temporal granularity.
    final boolean
    setExtentOfInterest(org.opengis.metadata.extent.Extent domain, org.opengis.metadata.extent.GeographicBoundingBox aoi, Instant[] toi)
    Sets the area of interest (AOI) and time of interest (TOI) to the intersection of given arguments.
    final void
    Sets the temporal granularity of the Time of Interest (TOI).
    private double
    temporalDistance(Instant startTime, Instant endTime)
    Computes a temporal distance between the center of given range and center of time of interest.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Field Details

    • areaOfInterest

      private org.opengis.metadata.extent.GeographicBoundingBox areaOfInterest
      The area of interest (AOI), or null if unbounded. This is initialized at construction time, but can be modified later.
      See Also:
    • minTOI

      private Instant minTOI
      Start/end of the time of interest (TOI), or null if unbounded. This is initialized at construction time, but can be modified later.
      See Also:
    • maxTOI

      private Instant maxTOI
      Start/end of the time of interest (TOI), or null if unbounded. This is initialized at construction time, but can be modified later.
      See Also:
    • granularity

      private long granularity
      Granularity of the time of interest in seconds, or 0 if none. If non-zero, this this is always positive.
      See Also:
    • alternateOrdering

      public boolean alternateOrdering
      Whether to use an alternate conditions order where the time center criterion is tested last. This flag can be set to true if the Time Of Interest (TOI) is expected to be larger than the temporal extent of candidate objects, in which case many objects may fit in the TOI. Those candidates may be considered practically equally good regarding temporal aspect, in which case the caller may want to give precedence to geographic area.

      This flag is often used together with setTimeGranularity(Duration) method for reducing the preponderance of temporal criteria.

    • best

      private T best
      The best object found so far.
    • largestArea

      private double largestArea
      The area covered by the best object (m²). This is the first criterion cited in class javadoc.
    • longestTime

      private Duration longestTime
      Duration of the best object, or null if none. This is equivalent to largestArea in the temporal domain. Value is rounded by round(Duration).
    • outsideArea

      private double outsideArea
      Area of best object which is outside the area of interest. This is used as a discriminatory criterion only when largestArea has the same value for two or more objects. This is the second criterion cited in class javadoc.
    • overtime

      private Duration overtime
      Duration of best object which is outside the time of interest. This is used as a discriminatory criterion only when longestTime has the same value for two or more objects. This is equivalent to outsideArea in the temporal domain.
    • pseudoDistance

      private double pseudoDistance
      A pseudo-distance from best object center to areaOfInterest center. This is not a real distance, neither great circle distance or rhumb line. The only requirements are: a value equals to zero when the two centers are coincident and increasing when the centers are mowing away.

      This value is used as a discriminatory criterion only when largestArea and outsideArea have the same values for two or more objects. This is the third criterion cited in class javadoc.

    • temporalDistance

      private double temporalDistance
      Time between best entry center and TOI center. This value is used as a discriminatory criterion only when longestTime and overtime have the same values for two or more objects. This is equivalent to pseudoDistance in the temporal domain.
    • OVERTIME

      private static final int OVERTIME
      Identification of which fields need to be recomputed. This is an ordered enumeration: recomputing a field implies recomputing all following fields (identified by greater values). For example if the temporalDistance field needs to be recomputed, then the outsideArea and pseudoDistance fields must be recomputed as well. This is a consequence of the order in which criteria documented in class javadoc are applied.
      See Also:
    • TEMPORAL_DISTANCE

      private static final int TEMPORAL_DISTANCE
      Identification of which fields need to be recomputed. This is an ordered enumeration: recomputing a field implies recomputing all following fields (identified by greater values). For example if the temporalDistance field needs to be recomputed, then the outsideArea and pseudoDistance fields must be recomputed as well. This is a consequence of the order in which criteria documented in class javadoc are applied.
      See Also:
    • OUTSIDE_AREA

      private static final int OUTSIDE_AREA
      Identification of which fields need to be recomputed. This is an ordered enumeration: recomputing a field implies recomputing all following fields (identified by greater values). For example if the temporalDistance field needs to be recomputed, then the outsideArea and pseudoDistance fields must be recomputed as well. This is a consequence of the order in which criteria documented in class javadoc are applied.
      See Also:
    • PSEUDO_DISTANCE

      private static final int PSEUDO_DISTANCE
      Identification of which fields need to be recomputed. This is an ordered enumeration: recomputing a field implies recomputing all following fields (identified by greater values). For example if the temporalDistance field needs to be recomputed, then the outsideArea and pseudoDistance fields must be recomputed as well. This is a consequence of the order in which criteria documented in class javadoc are applied.
      See Also:
    • NONE

      private static final int NONE
      Identification of which fields need to be recomputed. This is an ordered enumeration: recomputing a field implies recomputing all following fields (identified by greater values). For example if the temporalDistance field needs to be recomputed, then the outsideArea and pseudoDistance fields must be recomputed as well. This is a consequence of the order in which criteria documented in class javadoc are applied.
      See Also:
  • Constructor Details

    • ExtentSelector

      public ExtentSelector(org.opengis.metadata.extent.GeographicBoundingBox aoi, Instant[] toi)
      Creates a selector for the given area and time of interest.
      Parameters:
      aoi - the area of interest, or null if unbounded.
      toi - the time of interest, or null or empty if unbounded. The first element is start time and the last element is end time.
    • ExtentSelector

      public ExtentSelector(org.opengis.metadata.extent.Extent domain)
      Creates a selector for the given area of interest.
      Parameters:
      domain - the area and time of interest, or null if none.
      Throws:
      IllegalArgumentException - if AOI or TOI has an invalid range.
  • Method Details

    • setExtentOfInterest

      public final boolean setExtentOfInterest(org.opengis.metadata.extent.Extent domain, org.opengis.metadata.extent.GeographicBoundingBox aoi, Instant[] toi)
      Sets the area of interest (AOI) and time of interest (TOI) to the intersection of given arguments. This method should be invoked only if best() returned null. It allows to make new attempts with a different domain of interest when the search using previous AOI/TOI gave no result.

      Callers should not use this ExtentSelector if this method returns false, except for invoking this setExtentOfInterest(…) method again with different values until this method returns true.

      Parameters:
      domain - the area and time of interest, or null if none.
      aoi - second area of interest as a bounding box, or null if none.
      toi - second time of interest as a an array of length 2, 1 or 0, or null. If array length is 2, it contains start time and end time in that order. If array length is 1, start time and end time are assumed the same. If array length is 0 or array reference is null, there is no temporal range to intersect.
      Returns:
      whether the intersections of domain with aoi and toi have valid ranges.
    • getAreaOfInterest

      public final org.opengis.metadata.extent.GeographicBoundingBox getAreaOfInterest()
      Returns the area of interest.
      Returns:
      area of interest, or null if none.
    • getTimeOfInterest

      public final Instant[] getTimeOfInterest()
      Returns the time of interest as an array of length 2, or null if none.
      Returns:
      the start time and end time of interest, or null if none.
    • setTimeGranularity

      public final void setTimeGranularity(Duration resolution)
      Sets the temporal granularity of the Time of Interest (TOI). If non-null, intersections with TOI will be rounded to an integer amount of this granularity. This is useful if data are expected at an approximately regular interval (for example one remote sensing image per day) and we want to ignore slight variations in the temporal extent declared for each image.

      This method is often used together with alternateOrdering flag for reducing the preponderance of temporal criteria.

      Parameters:
      resolution - granularity of the time of interest, or null if none.
      Throws:
      IllegalArgumentException - if the given resolution is zero or negative.
    • round

      private Duration round(Duration duration)
      Returns the given duration rounded to the nearest integer amount of temporal granularity. If no granularity has been specified, then this method returns the given duration unmodified.
    • pseudoDistance

      private double pseudoDistance(org.opengis.metadata.extent.GeographicBoundingBox area)
      Computes a pseudo-distance between the center of given area and of areaOfInterest. This is not a real distance, neither great circle distance or rhumb line. May be Double.NaN if information is unknown.
      See Also:
    • temporalDistance

      private double temporalDistance(Instant startTime, Instant endTime)
      Computes a temporal distance between the center of given range and center of time of interest. This is always a positive value or Double.NaN. Unit is irrelevant (as long as constant) because we only compare distances with other distances.
      See Also:
    • median

      private static double median(Instant startTime, Instant endTime)
      Returns instant (in milliseconds) in the middle of given time range, or Double.NaN if none. Used for temporalDistance(Instant, Instant) implementation only.
    • overtime

      private Duration overtime(Instant startTime, Instant endTime, Duration intersection)
      Computes the amount of time outside the time of interest (TOI). The returned value is always positive because intersection should always be less than endTimestartTime duration. Value is rounded by round(Duration).
      Parameters:
      startTime - start time of of the candidate object, or null if none (unbounded).
      endTime - end time of the candidate object, or null if none (unbounded).
      intersection - duration of the intersection of [startTimeendTime] with [minTOImaxTOI].
    • evaluate

      public void evaluate(org.opengis.metadata.extent.Extent domain, T object)
      Evaluates the given extent against the criteria represented by this ExtentSelector. See class javadoc for a list of criteria and the order in which they are applied. Implementation delegates to evaluate(GeographicBoundingBox, Instant, Instant, Object).
      Parameters:
      domain - the extent to evaluate, or null if none.
      object - a user object associated to the given extent.
    • evaluate

      public void evaluate(org.opengis.metadata.extent.GeographicBoundingBox bbox, Instant startTime, Instant endTime, T object)
      Evaluates the given bounding box and time range against the criteria represented by this ExtentSelector. See class javadoc for a list of criteria and the order in which they are applied.
      Parameters:
      bbox - the geographic extent of object, or null if none.
      startTime - start time of object, or null if none (unbounded).
      endTime - end time of object, or null if none (unbounded).
      object - a user object associated to the given extent.
    • compare

      private static int compare(Duration a, Duration b, int missing)
      Compares the given duration as documented in Duration.compareTo(Duration) with the addition of supporting null values. The missing argument tells whether null values shall be considered smaller (-1) or greater (+1) than all non-null values.
    • compare

      private static int compare(double a, double b, int missing)
      Compares the given values as documented in Double.compareTo(Double) except in the handling of zero and NaN values.
      • The missing argument tells whether NaN values shall be considered smaller (-1) or greater (+1) than all non-NaN values.
      • Positive and negative zeros are considered equal.
    • best

      public T best()
      Returns the object associated to the largest area found so far.
      Returns:
      the object associated to the largest area found so far, or null.