# Interface FeatureSet

All Superinterfaces:
  `DataSet`, `Resource`

All Known Subinterfaces:
  `WritableFeatureSet`

All Known Implementing Classes:
  `AbstractFeatureSet`, `ConcatenatedFeatureSet`, `JoinFeatureSet`

public interface FeatureSet extends DataSet
A dataset providing access to a stream of features. All features share a common set of properties described by `getType()`. The common set of properties does not need to enumerate all possible properties since additional properties can be defined in subtypes. In many cases at least one property is a geometry, but features without geometry are also allowed.

Since:
  0.8

- ## Nested Class Summary

  ### Nested classes/interfaces inherited from interface Resource

  `Resource​.FileSet`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `Stream<AbstractFeature>`
  `features(boolean parallel)`
  Returns a stream of all features contained in this dataset.
  `DefaultFeatureType`
  `getType()`
  Returns a description of properties that are common to all features in this dataset.
  `default FeatureSet`
  `subset(Query query)`
  Requests a subset of features and/or feature properties from this resource.

  ### Methods inherited from interface DataSet

  `getEnvelope`

  ### Methods inherited from interface Resource

  `addListener, getFileSet, getIdentifier, getMetadata, removeListener`

- ## Method Details

  - ### getType

    DefaultFeatureType getType() throws DataStoreException
    Returns a description of properties that are common to all features in this dataset. The feature type contains the definition of all properties, including but not only:
    - Name to use for accessing the property
    - Human-readable description
    - Type of values
    - Multiplicity (minimum and maximum number of occurrences)
    - Coordinate Reference System.
    All features returned by `features(boolean)` will be either of that type, or a sub-type of it.

    #### Relationship with metadata

    if subtypes exist, their list may be obtained from the metadata like below (if the `FeatureSet` implementation provides that information):

        for (ContentInformation content : metadata.getContentInfo()) {
            if (content instanceof FeatureCatalogueDescription) {
                for (FeatureTypeInfo info : ((FeatureCatalogueDescription) content).getFeatureTypeInfo()) {
                    GenericName name = info.getFeatureTypeName();
                    // ... add the name to some list ...
                }
            }
        }

    Returns:
      description of common properties (never `null`).
    Throws:
      `DataStoreException` - if an error occurred while reading definitions from the underlying data store.

  - ### subset

    default FeatureSet subset(Query query) throws UnsupportedQueryException, DataStoreException
    Requests a subset of features and/or feature properties from this resource. The filtering can be applied in two domains:
    - The returned `FeatureSet` may contain a smaller number of `Feature` instances.
    - In each `Feature` instance of the returned set, the number of properties may be smaller.
    While it is technically possible to return a transformed feature set (i.e. containing feature properties not found in this original `FeatureSet`, for example as a result of some computation), such usages should be rare. Transformations should be the topic of a separated processing package. This `subset(Query)` method is rather for allowing `DataStore` implementations to optimize the overall filtering by using the tools available with their format (for example an R-tree). `BoundingBox` filters are the most common case of optimization implemented by `DataStore`.

    The returned subset may be a view of this set, i.e. changes in this `FeatureSet` may be reflected immediately on the returned subset (and conversely), but not necessarily. However, the returned subset may not have the same capabilities as this `FeatureSet`. In particular, write operations may become unsupported after complex queries.

    #### Default implementation

    The default implementation delegates to `FeatureQuery​.execute(FeatureSet)` if the given query is an instance of `FeatureQuery`, or throws `UnsupportedQueryException` otherwise. The default `FeatureQuery` implementation tries to execute the query by filtering the stream of features, which may be inefficient — subclasses are encouraged to override this `subset(Query)` method.
    Parameters:
      `query` - definition of feature and feature properties filtering applied at reading time.
    Returns:
      resulting subset of features (never `null`).
    Throws:
      `UnsupportedQueryException` - if this `FeatureSet` cannot execute the given query.
      `DataStoreException` - if another error occurred while processing the query.
    See Also:
      - `GridCoverageResource​.subset(CoverageQuerty)`
      - `FeatureQuery​.execute(FeatureSet)`

  - ### features

    Stream<AbstractFeature> features(boolean parallel) throws DataStoreException
    Returns a stream of all features contained in this dataset. For all features, the following condition shall be true:

    > `getType().isAssignableFrom(feature.getType())`

    Most implementations will create `Feature` instances on-the-fly when the stream terminal operation is executed. A `try` … `finally` block should be used for releasing `DataStore` resources used by the operation. If a checked exception happens during stream execution, that exception will be wrapped in an unchecked `BackingStoreException`. The following code shows how this stream can be used:

            void myReadOperation() throws DataStoreException {
                try (Stream<Feature> features = myDataStore.features(false)) {
                    // Use the stream here.
                } catch (BackingStoreException e) {
                    throw e.unwrapOrRethrow(DataStoreException.class);
                }
            }

    The `parallel` argument specifies whether a parallelized stream is desired. If `false`, the stream is guaranteed to be sequential. If `true`, the stream may or may not be parallel; implementations are free to ignore this argument if they do not support parallelism.
    Parameters:
      `parallel` - `true` for a parallel stream (if supported), or `false` for a sequential stream.
    Returns:
      all features contained in this dataset.
    Throws:
      `DataStoreException` - if an error occurred while creating the stream.