Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

Contact:

Andrea Aime, Daniele Romagnoli

Tracker:

httphttps://jira.codehaus.org/browse/GEOT-XXXX4501

Tagline:

Excerpt

Structured grid coverages, multidimensional rasters

Section
Column
width70%
Table of Contents
Column

Children:

Children Display

Description

Exposing structure

The current grid coverage API is based on the idea of a coverage reader containing a single coverage, which can be, according to the read parameters, subsetted, rescaled, eventually reprojected too. Some readers, like image mosaic, are actually based on a collection of internal raster data (referred to as "granules") which:

...

The current image mosaic is not the only example of "structured" readers, NetCDF data sources, PostGIS rasters and other in database rasters are another example where variables and dimensions could be exposed with higher control and better details. This can be leveraged by callers to have higher flexibilty in exposing dimensions, as well as allowing callers to inspect the inner structure of a complex coverage and better tailor their requests (WCS-EO is an example that allows to expose the inner structure of a mosaic and allows the caller to work against the single granules composing it).Also, very

Allowing granule addition/removal

Very often these structured readers need to be modified in terms of the granules they contain by:
  • adding new granules
  • removing existing granules
A simple and typical case is keeping a moving time window of data, e.g., the last month of satellite observations for a certain atmospheric gas. In order to support these cases we propose interfaces mimicking the vector data source, GranuleSource and GranuleStore, that allow access and modification of the granules internals. A structured reader might be read only, in which case it can only return a GranuleSource, or be writable, in which case a GranuleStore is returned instead. FeatureSource/FeatureStore have not been used directly to keep the work needed to implement a structured reader to a minimum (their interface is significantly larger).
In order to allow each reader to acquire extra data the way it prefers a "harvest" operation has been added that works against the file system, and allows each reader to add data into its backend storage the preferred way: a file oriented tool like ImageMosaic will just add references to the files being harvested internally, a database oriented tool like PostGIS raster can instead read the files and copy them into its internal storage.
Implementors of the harvest operation will have to consider the case of harvesting from another structured data source, for example, a image mosaic could with NetCDF files, which have in turn their own internal structure, taking that into account and eventually building not only new granules in the respective existing coverages: for example, a mosaic could be made of NetCDF files having each three variables, NO2, O3 and BrO, each file contains granules for the three gases at different batches of times and elevation, and the mosaic exposes the same three coverages, but hiding the fact the bits and pieces are split among various source NetCDF files.

Implementation

Implementation wise the proposal will come with two implementations:

...

Voting has not started yet:

 

Tasks

 

This section is used to make sure your proposal is complete (did you remember documentation?) and has enough paid or volunteer time lined up to be a success

 

no progress

(tick)

done

(error)

impeded

(warning)

lack mandate/funds/time

(question)

volunteer needed

  • API changed based on BEFORE / AFTER
  • Update default implementation
  • Update wiki (both module matrix and upgrade to to 2.5 pages) |
  • Remove deprecated code from GeoTools project
  • Update the user guide
  • Update or provided sample code in demo
  • review user documentation

 

API Changes

StructuredCoverageGridReader

...

Code Block
public interface StructuredGridCoverage2DReader extends GridCoverage2DReader {
    /**
     * Returns the granule source for the specified coverage (might be null, if there is only one supported coverage)
     * 
     * @param coverageName the name of the specified coverage
     * @param readOnly a boolean indicating whether we may want modify the GranuleSource
     * @return the requested {@link GranuleSource}
     * @throws IOException
     * @throws UnsupportedOperationException
     */
    GranuleSource getGranules(String coverageName, boolean readOnly) throws IOException, UnsupportedOperationException;
    /**
     * Return whether this reader can modify the granule source 
     * @return
     */
    boolean isReadOnly();
    /**
     * Creates a granule store for a new coverage with the given feature type
     */
    void createCoverage(String coverageName, SimpleFeatureType schema) throws
                                               IOException, UnsupportedOperationException;
    /**
     * removes a granule store for the specified coverageName
     */
    boolean removeCoverage(String coverageName) throws IOException, UnsupportedOperationException;
    
    /**
     * Harvests the specified filesource into the reader. Depending on the implementation, the original filesource
     * is harvested in place (e.g., image mosaic), or might be copied into the reader persistent storage (e.g., database raster handling)
     *
     * @param defaultCoverage Default target coverage, to be used in case the filessources being harvested are not structured ones. The parameter is optional,
     *                        in case it's missing the reader will use the first coverage as the default target. 
     *                        
     * @param source The source can be aany singlekind fileof object, orit's aup folder.to Thethe filereader typesimplementation supportedto byunderstand theand harvestuse operationit.
     *               varyCommons dependingsource ontypes thecould implementation,be buta generallysingle speakingfile, allor coverages having a readerfolder. should
be supported.      * @param hints Used to provide implementation specific hints on how to harvest the filessources
     * @throws IOException
     * @throws UnsupportedOperationException
     */
    List<HarvestedFile>List<HarvestedSource> harvest(String defaultTargetCoverage, FileObject source, Hints hints) throws IOException,
            UnsupportedOperationException;

    /**
     * Describes the dimensions supported by the specified coverage, if any.
     * (coverageName might be null, if there is only one supported coverage)
     */
    List<DimensionDescriptor> getDimensionDescriptors(String coverageName) throws IOException;
 }
 
/**
 * Information about one of the sources that have been processed by
 * {@link StructuredGridCoverage2DReader#harvest(String, Object, org.geotools.factory.Hints)},
 * indicating whether the object was successfully ingested or not.
 * 
 * @author Andrea Aime - GeoSolutions
 * 
 */
public interface HarvestedFileHarvestedSource {
    /**
     * The fileobject that has been processed
     * 
     * @return
     */
    FileObject getFilegetSource();
    /**
     * If true, the file has been ingested and generated new granules in the reader, false otherwise
     * 
     * @return
     */
    boolean success();
    /**
     * In case the file was not ingested, provides a reason why it was skipped
     * 
     * @return
     */
    String getMessage();
}
/**
 * Describes a "dimension" exposed by a structured grid coverage reader. 
 */
public interface DimensionDescriptor {
    /**
    * The dimension name
    *
    * @return
    */
   String getName();
   /**
    * The dimension unit symbol
    *
    * @return
    */
   String getUnitSymbol();
   /**
    * The dimension units
    *
    * @return
    */
   String getUnits();
   /**
    * The start attribute 
    *
    * @return
    */
   String getStartAttribute();
   /**
    * The end attribute (In case of dimensions with ranges) 
    *
    * @return
    */
   String getEndAttribute();
}  

GranuleSource

 

AFTER:

Code Block
public interface GranuleSource {
    /**
     * Retrieves granules, in the form of a {@code SimpleFeatureCollection}, based on a {@code Query}.
     * 
     * @param q the {@link Query} to select granules
     * @return the resulting granules.
     * @throws IOException
     */
    public SimpleFeatureCollection getGranules(Query q) throws IOException;
    /**
     * Gets the number of the granules that would be returned by the given {@code Query}, taking into account any settings for max features and start
     * index set on the {@code Query}.
     * 
     * @param q the {@link Query} to select granules
     * @return the number of granules
     * @throws IOException
     */
    public int getCount(Query q) throws IOException;
    /**
     * Get the spatial bounds of the granules that would be returned by the given {@code Query}.
     * 
     * @param q the {@link Query} to select granules
     * @return The bounding envelope of the requested data
     * @throws IOException
     */
    public ReferencedEnvelope getBounds(Query q) throws IOException;
    /**
     * Retrieves the schema (feature type) that will apply to granules retrieved from this {@code GranuleSource}.
     * 
     * @return
     * @throws IOException
     */
    public SimpleFeatureType getSchema() throws IOException;
    /**
     * This will free/release any resource (cached granules, ...).
     * 
     * @throws IOException
     */
    public void dispose() throws IOException;
} 

...