# Interface CoverageModifier

public interface CoverageModifier
Modifies the metadata, grid geometry or sample dimensions inferred by a data store for a (grid) coverage. The modifications are applied by callback methods which are invoked at reading time when first needed. The caller is usually a `GridCoverageResource`, but not necessarily. It may also be a more generic coverage.

## Usage

For modifying the coverages provided by a data store, register an instance of `CoverageModifier` at the store opening time as below:

    StorageConnector storage = ...;
    CoverageModifier modifier = ...;
    storage.setOption(DataOptionKey.COVERAGE_MODIFIER, modifier);
    try (DataStore store = DataStores.open(connector)) {
        // Modified resources will be returned.
    }

Not all `DataStore` implementations recognize this options. Data stores that do not support modifications will ignore the above option. A `DataStore` may also support modifications only partially, by invoking only a subset of the methods defined in this interface.

Since:
  1.5
See Also:
  - `DataOptionKey​.COVERAGE_MODIFIER`

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Interface
  Description
  `static class`
  `CoverageModifier​.BandSource`
  Information about which sample dimension (band) is subject to modification.
  `static class`
  `CoverageModifier​.Source`
  Information about which file and coverage (image) is subject to modification.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `default SampleDimension`
  `customize(CoverageModifier​.BandSource source, SampleDimension​.Builder dimension)`
  Invoked when a sample dimension is created in a coverage.
  `default GridGeometry`
  `customize(CoverageModifier​.Source source, GridGeometry domain)`
  Invoked when a grid geometry is created for a coverage.
  `default Metadata`
  `customize(CoverageModifier​.Source source, DefaultMetadata metadata)`
  Invoked when a metadata is created for a single coverage or for the whole file.
  `default GenericName`
  `customize(CoverageModifier​.Source source, GenericName identifier)`
  Invoked when an identifier is created for a single coverage or for the whole file.
  `static CoverageModifier`
  `getOrDefault(StorageConnector connector)`
  Returns modifier specified in the options of the given storage connector.
  `default boolean`
  `isElectromagneticMeasurement(CoverageModifier​.Source source)`
  Returns `true` if the converted values are measurement in the electromagnetic spectrum.

- ## Method Details

  - ### getOrDefault

    static CoverageModifier getOrDefault(StorageConnector connector)
    Returns modifier specified in the options of the given storage connector. This convenience method fetches the value associated to `DataOptionKey​.COVERAGE_MODIFIER`. If there is no such value, then this method returns the
    invalid reference

        #DEFAULT

    instance.
    Parameters:
      `connector` - the storage connector from which to get the modifier.
    Returns:
      the modifier to use, never `null`.

  - ### customize

    default GenericName customize(CoverageModifier.Source source, GenericName identifier) throws DataStoreException
    Invoked when an identifier is created for a single coverage or for the whole file. Implementations can override this method for replacing the given identifier by their own.

    #### Default implementation

    The default implementation returns the given `identifier` unchanged. It may be null.
    Parameters:
      `source` - contains the index of the coverage for which to compute an identifier. If the coverage index is absent, then the identifier applies to the whole file.
      `identifier` - the default identifier computed by `DataStore`. May be `null` if the `DataStore` has been unable to determine an identifier by itself.
    Returns:
      the identifier to use, or `null` if none.
    Throws:
      `DataStoreException` - if an exception occurred while computing an identifier.

  - ### customize

    default Metadata customize(CoverageModifier.Source source, DefaultMetadata metadata) throws DataStoreException
    Invoked when a metadata is created for a single coverage or for the whole file. Implementations can override this method for modifying or replacing the given metadata. The given `DefaultMetadata` instance is still in modifiable state when this method is invoked.

    #### Default implementation

    The default implementation declares the given metadata as final (unmodifiable), then returns the metadata instance.
    Parameters:
      `source` - contains the index of the coverage for which to compute metadata. If the coverage index is absent, then the metadata applies to the whole file.
      `metadata` - metadata pre-filled by the `DataStore` (never null). Can be modified in-place.
    Returns:
      the metadata to return to user. This is often the same instance as the given `metadata`.
    Throws:
      `DataStoreException` - if an exception occurred while updating metadata.

  - ### customize

    default GridGeometry customize(CoverageModifier.Source source, GridGeometry domain) throws DataStoreException
    Invoked when a grid geometry is created for a coverage. Implementations can override this method for replacing the given grid geometry by a derived instance. A typical use case is to check if the Coordinate Reference System (CRS) is present and, if not, provide a default CRS.

    #### Default implementation

    The default implementation returns the given `domain` unchanged.
    Parameters:
      `source` - contains the index of the coverage for which to compute metadata.
      `domain` - the domain computed by the data store.
    Returns:
      the domain to return to user.
    Throws:
      `DataStoreException` - if an exception occurred while computing the domain.

  - ### customize

    default SampleDimension customize(CoverageModifier.BandSource source, SampleDimension.Builder dimension) throws DataStoreException
    Invoked when a sample dimension is created in a coverage. The data store invokes this method with a `SampleDimension` builder initialized to a default name, which may be the band number. The builder may also contain a background value and categories. Implementations can override this method for setting a better name or for declaring the meaning of sample values (by replacing categories).

    #### Default implementation

    The default implementation returns `dimensions​.build()` with no modification on the given builder.

    #### Example: measurement data

    The following example declares that the values 0 means "no data". The presence of such "no data" category will cause the raster to be converted to floating point values before operations such as `resample`, in order to replace those "no data" by NaN values. When a "no data" category is declared, it is strongly recommended to also declare the range of real data. The following example declares the range 1 to 255 inclusive.

        @Override
        public SampleDimension customize(BandSource source, SampleDimension.Builder dimension) {
            dimension.categories().clear();      // Discard the categories created by the store.
            dimension.addQualitative(null, 0);   // Declare value 0 as "no data".
            dimension.addQuantitative("Some name for my data", 1, 255, null);
            return dimension.build();
        }

    See the various `addQuantitative(…)` methods for information about how to declare a transfer function (a conversion from pixel values to the unit of measurement).

    #### Example: visualization only

    If the pixel values have no meaning other than visualization, this method can be overridden as below for making sure that they raster is not interpreted as measurement data:

        @Override
        public SampleDimension customize(BandSource source, SampleDimension.Builder dimension) {
            dimension.categories().clear();      // Discard the categories created by the store.
            return dimension.build();
        }

    Parameters:
      `source` - contains index of the coverage and band for which to create sample dimension.
      `dimension` - a sample dimension builder initialized with band number as the dimension name. This builder can be modified in-place.
    Returns:
      the sample dimension to use.
    Throws:
      `DataStoreException` - if an exception occurred while fetching sample dimension information.

  - ### isElectromagneticMeasurement

    default boolean isElectromagneticMeasurement(CoverageModifier.Source source) throws DataStoreException
    Returns `true` if the converted values are measurement in the electromagnetic spectrum. This flag controls the kind of metadata objects (ImageDescription versus CoverageDescription) to be created for describing a coverage with these sample dimensions. Those metadata have properties specific to electromagnetic spectrum, such as wavelength of peak response.
    Parameters:
      `source` - contains the index of the coverage for which to compute metadata.
    Returns:
      `true` if the coverage contains measurements in the electromagnetic spectrum.
    Throws:
      `DataStoreException` - if an exception occurred while fetching metadata.