Class CoverageAggregator

java.lang.Object
org.apache.sis.storage.aggregate.Group<GroupBySample>
org.apache.sis.storage.aggregate.CoverageAggregator

public final class CoverageAggregator extends Group<GroupBySample>
Creates a grid coverage resource from an aggregation of an arbitrary number of other resources.
Example: a collection of GridCoverage instances may represent the same phenomenon (for example Sea Surface Temperature) over the same geographic area but at different dates and times. CoverageAggregator can be used for building a single data cube with a time axis.
All source coverages should share the same CRS and have the same ranges (sample dimensions). If this is not the case, then the source coverages will be grouped in different aggregates with an uniform CRS and set of ranges in each sub-aggregates. More specifically, CoverageAggregator organizes resources as below, except that parent nodes having only one child are omitted: Where:
  • Equivalent reference systems means two CoordinateReferenceSystem instances for which Utilities.equalsIgnoreMetadata(Object, Object) returns true.
  • Compatible grid to CRS means two grid to CRS transforms which are identical (with small tolerance for rounding errors) except for the translation terms, with the additional condition that the translations, when expressed in units of grid cell indices, can differ only by integer amounts of cells.
  • Slices means source coverages declared to this aggregator by calls to add(…) methods, after they have been incorporated in a data cube by this aggregator. Above tree does not contain the individual slices, but data cubes containing all slices that can fit.

Multi-threading and concurrency

All add(…) methods can be invoked concurrently from arbitrary threads. It is okay to load GridCoverageResource instances in parallel threads and add those resources to CoverageAggregator without synchronization. However, the final build() method is not thread-safe; that method shall be invoked from a single thread after all sources have been added and no more addition are in progress.
Since:
1.3
Version:
1.3
  • Field Details

    • listeners

      private final StoreListeners listeners
      The listeners of the parent resource (typically a DataStore), or null if none.
    • aggregates

      private final Map<Set<Resource>,Queue<Aggregate>> aggregates
      The aggregates which where the sources of components added during a call to addComponents(Aggregate). This is used for reusing existing aggregates instead of GroupAggregate when the content is the same.
    • strategy

      private volatile MergeStrategy strategy
      Algorithm to apply when more than one grid coverage can be found at the same grid index. This is null by default.
      See Also:
  • Constructor Details

    • CoverageAggregator

      public CoverageAggregator(StoreListeners listeners)
      Creates an initially empty aggregator.
      Parameters:
      listeners - listeners of the parent resource, or null if none. This is usually the listeners of the DataStore.
  • Method Details

    • createName

      final String createName(Locale locale)
      Returns a name of the aggregate to be created. This is used only if this aggregator find resources having different sample dimensions.
      Specified by:
      createName in class Group<GroupBySample>
      Parameters:
      locale - the locale for the name to return, or null for the default.
      Returns:
      a name which can be used as aggregation name, or null if none.
    • addAll

      public void addAll(Stream<? extends GridCoverageResource> resources) throws DataStoreException
      Adds all grid resources provided by the given stream. This method can be invoked from any thread. It delegates to add(GridCoverageResource) for each element in the stream.
      Parameters:
      resources - resources to add.
      Throws:
      DataStoreException - if a resource cannot be used.
    • add

      public void add(GridCoverageResource resource) throws DataStoreException
      Adds the given resource. This method can be invoked from any thread. This method does not recursively decomposes an Aggregate into its component.
      Parameters:
      resource - resource to add.
      Throws:
      DataStoreException - if the resource cannot be used.
    • addComponents

      public void addComponents(Aggregate resource) throws DataStoreException
      Adds all components of the given aggregate. This method can be invoked from any thread. It delegates to add(GridCoverageResource) for each component in the aggregate which is an instance of GridCoverageResource. Components that are themselves instance of Aggregate are decomposed recursively.
      Parameters:
      resource - resource to add.
      Throws:
      DataStoreException - if a component of the resource cannot be used.
    • existingAggregate

      final Optional<Aggregate> existingAggregate(Resource[] components)
      If a user supplied aggregate exists for all the given components, returns that aggregate. The returned aggregate is removed from the pool; aggregates are not returned twice. This method is thread-safe.
      Parameters:
      components - the components for which to get user supplied aggregate.
      Returns:
      user supplied aggregate if it exists. The returned aggregate is removed from the pool.
    • getMergeStrategy

      public MergeStrategy getMergeStrategy()
      Returns the algorithm to apply when more than one grid coverage can be found at the same grid index. This is the most recent value set by a call to setMergeStrategy(MergeStrategy), or null if no strategy has been specified. In the latter case, a SubspaceNotSpecifiedException will be thrown by GridCoverage.render(GridExtent) if more than one source coverage (slice) is found for a specified grid index.
      Returns:
      algorithm to apply for merging source coverages at the same grid index, or null if none.
    • setMergeStrategy

      public void setMergeStrategy(MergeStrategy strategy)
      Sets the algorithm to apply when more than one grid coverage can be found at the same grid index. The new strategy applies to the next coverages to be added; previously added coverage may or may not be impacted by this change (see below). Consequently, this method should usually be invoked before to add the first coverage.

      Effect on previously added coverages

      The merge strategy of previously added coverages is not modified by this method call, except for coverages (slices) that become part of the same aggregated GridCoverageResource (data cube) than a coverage added after this method call. In such case, the strategy set by this call to setMergeStrategy(…) prevails. Said otherwise, the merge strategy of a data cube is the strategy which was active at the time of the most recently added slice.
      Parameters:
      strategy - new algorithm to apply for merging source coverages at the same grid index, or null if none.
    • build

      public Resource build()
      Builds a resource which is the aggregation or concatenation of all components added to this aggregator. The returned resource will be an instance of GridCoverageResource if possible, or an instance of Aggregate if some heterogeneity in grid geometries or sample dimensions prevent the concatenation of all coverages in a single resource.

      This method is not thread safe. If the add(…) and addAll(…) methods were invoked in background threads, then all additions must be finished before this method is invoked.

      Returns:
      the aggregation or concatenation of all components added to this aggregator.