/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2008, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*/
package org.geotools.coverage.io;
import java.awt.Rectangle;
import java.io.IOException;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import org.geotools.coverage.grid.io.DimensionDescriptor;
import org.geotools.coverage.io.metadata.MetadataNode;
import org.geotools.coverage.io.range.RangeType;
import org.geotools.data.Parameter;
import org.geotools.data.ResourceInfo;
import org.geotools.referencing.CRS;
import org.geotools.util.DateRange;
import org.geotools.util.NumberRange;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.feature.type.Name;
import org.opengis.geometry.BoundingBox;
import org.opengis.geometry.Envelope;
import org.opengis.geometry.TransfiniteSet;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.TemporalCRS;
import org.opengis.referencing.crs.VerticalCRS;
import org.opengis.referencing.operation.MathTransform2D;
import org.opengis.util.ProgressListener;
/**
* Allows read-only access to a Coverage.
*
* @author Simone Giannecchini, GeoSolutions
* @author Jody Garnett
*
* @source $URL$
*/
public interface CoverageSource {
enum DomainType {
NUMBER, NUMBERRANGE, DATE, DATERANGE, STRING
}
public abstract class SpatialDomain {
/**
* The first {@link BoundingBox} of this {@link List} should contain the overall bounding for the underlying coverage in its native coordinate
* reference system. However, by setting the <code>global</code> param to <code>false</code> we can request additional bounding boxes in case
* the area covered by the mentioned coverage is poorly approximated by a single coverage, like it could happen for a mosaic which has some
* holes.
*
* @param overall
* @param listener
* @return
* @throws IOException
* @see {@link BoundingBox}
*
*/
public abstract Set<? extends BoundingBox> getSpatialElements(final boolean overall, final ProgressListener listener) throws IOException;
public abstract CoordinateReferenceSystem getCoordinateReferenceSystem2D();
/**
* Transformation between the 2D raster space and the 2D model space. In case the underlying coverage is unrectified this transformation maybe
* a georeferencing transformation of simply the identity in case we do not have means to georeference the mentioned coverage.
*
* @param brief
* @param listener
* @return
* @throws IOException
*/
public abstract MathTransform2D getGridToWorldTransform(final ProgressListener listener) throws IOException;
/**
* The first {@link Rectangle} should describe the overall bidimensional raster range for the underlying coverage. However, by setting the
* <code>
* overall</code> param to true we can request additional raster ranges in case the area covered by the mentioned coverage is poorly
* approximated by a single {@link Rectangle}, like it could happen for a mosaic which has some holes.
*
* @param overall
* @param listener
* @return
* @throws IOException
*
* @todo should we consider {@link GridEnvelope}?? or RasterLayout which also contains tiling information??? This has also an impact on the
* {@link #getOptimalDataBlockSizes()} method, which may become useless
*/
public abstract Set<? extends RasterLayout> getRasterElements(final boolean overall, final ProgressListener listener) throws IOException;
}
public abstract class TemporalDomain {
/**
* Describes the temporal domain for the underlying {@link RasterDataset} by returning a {@link Set} of {@link DateRange} elements for it.
* Note that the {@link TemporalCRS} for the listed {@link DateRange} objects can be obtained from the overall {@link CRS} for the underlying
* coverage.
*
* @param listener
* @return a {@link Set} of {@link DateRange}s elements.
* @todo allow transfinite sets!
* @throws IOException
*/
public abstract SortedSet<? extends DateRange> getTemporalElements(final boolean overall, final ProgressListener listener) throws IOException;
public abstract CoordinateReferenceSystem getCoordinateReferenceSystem();
}
public abstract class VerticalDomain {
/**
* A {@link Set} of {@link Envelope} element for the underlying coverage. Note that the {@link CRS} for such envelope can be <code>null</code>
* in case the overall spatial {@link CRS} is a non-separable 3D {@link CRS} like WGS84-3D. Otherwise, all the envelopes should share the same
* {@link VerticalCRS}. Finally, note that the envelope should be 1-dimensional. In case of single vertical value, the lower coordinate should
* match the upper coordinate while lower and upper coordinates may be different to define vertical intervals.
*
* @param overall
* @param listener
* @return
* @throws IOException
* @todo consider {@link TransfiniteSet} as an alternative to {@link SortedSet}
* @todo allow using an interval as well as a direct position
* @todo allow transfinite sets!
*/
public abstract SortedSet<? extends NumberRange<Double>> getVerticalElements(final boolean overall, final ProgressListener listener) throws IOException;
public abstract CoordinateReferenceSystem getCoordinateReferenceSystem();
}
public abstract class AdditionalDomain {
/**
* Describes the additional domain for the underlying {@link RasterDataset} by returning a {@link Set} of elements for it.
*
* @param listener
* @return a {@link Set} of {@link DateRange}s elements.
* @todo allow transfinite sets!
* @throws IOException
*/
public abstract Set<Object> getElements(final boolean overall, final ProgressListener listener) throws IOException;
public abstract String getName();
public abstract DomainType getType();
}
/**
* Name of the Coverage (ie data product) provided by this CoverageSource.
*
* @since 2.5
* @return Name of the Coverage (ie data product) provided.
*/
Name getName(final ProgressListener listener);
/**
* Information describing the contents of this resource.
* <p>
* Please note that for FeatureContent:
* <ul>
* <li>name - unique with in the context of a Service
* <li>schema - used to identify the type of resource; usually the format or data product being represented
* <ul>
*
* @todo do we need this??
*/
ResourceInfo getInfo(final ProgressListener listener);
//
// /**
// * The first {@link Rectangle} should describe the overall bidimensional
// * raster range for the underlying coverage. However, by setting the
// * <code>overall</code> param to true we can request additional raster
// * ranges in case the area covered by the mentioned coverage is poorly
// * approximated by a single {@link Rectangle}, like it could happen for a
// * mosaic which has some holes.
// *
// * @param overall
// * @param listener
// * @return
// * @throws IOException
// *
// * @todo should we consider {@link GridEnvelope}?? or {@link ImageLayout} which also contains tiling information???
// */
// public List<Rectangle> getRasterDomain(final boolean overall,
// final ProgressListener listener) throws IOException;
/**
* Describes the required (and optional) parameters that can be passed to the {@link #read(CoverageReadRequest, ProgressListener)} method.
* <p>
*
* @return Param a {@link Map} describing the {@link Map} for {@link #read(CoverageReadRequest, ProgressListener)}.
*/
public Map<String, Parameter<?>> getReadParameterInfo();
/**
* Obtain a {@link CoverageResponse} from this {@link CoverageSource} given a specified {@link DefaultCoverageRequest}.
*
* @param request the input {@link DefaultCoverageRequest}.
* @param listener
* @return
* @throws IOException
*/
public CoverageResponse read(final CoverageReadRequest request, final ProgressListener listener) throws IOException;
/**
* Retrieves a {@link RangeType} instance which can be used to describe the codomain for the underlying coverage.
*
* @param listener
* @return a {@link RangeType} instance which can be used to describe the codomain for the underlying coverage.
* @throws IOException in case something bad occurs
*/
public RangeType getRangeType(final ProgressListener listener) throws IOException;
/**
* Closes this {@link CoverageSource} and releases any lock or cached information it holds.
*
* <p>
* Once a {@link CoverageAccess} has been disposed it can be seen as being in unspecified state, hence calling a method on it may have
* unpredictable results.
*/
public void dispose();
/**
* Set of supported {@link CoverageCapabilities} which can be used to discover capabilities of a certain {@link CoverageSource}.
* <p>
* You can use set membership to quickly test abilities:<code><pre>
* if( getCapabilities().contains( CoverageCapabilities.READ_SUBSAMPLING ) ){
* ...
* }
* </code></pre>
*
* @return a {@link EnumSet} of CoverageCapabilities which can be used to discover capabilities of this {@link CoverageSource}.
*/
public EnumSet<CoverageCapabilities> getCapabilities();
public MetadataNode getMetadata(String metadataDomain, final ProgressListener listener);
public Set<Name> getMetadataDomains();
public CoordinateReferenceSystem getCoordinateReferenceSystem();
public SpatialDomain getSpatialDomain() throws IOException;
public TemporalDomain getTemporalDomain() throws IOException;
public VerticalDomain getVerticalDomain() throws IOException;
public List<AdditionalDomain> getAdditionalDomains() throws IOException;
public List<? extends RasterLayout> getOverviewsLayouts(final ProgressListener listener)
throws IOException;
public int getOverviewsNumber(final ProgressListener listener) throws IOException;
public List<DimensionDescriptor> getDimensionDescriptors() throws IOException;
// /**
// * @todo TBD, I am not even sure this should leave at the general interface level!
// *
// * @return
// * @throws IOException
// */
// public Object getGCPManager(final ProgressListener listener)throws IOException;
//
// /**
// * @todo TBD, I am not even sure this should leave at the general interface level!
// *
// * @return
// * @throws IOException
// */
// public Object getStatisticsManager(final ProgressListener listener)throws IOException;
//
//
//
// /**
// * @todo TBD, I am not even sure this should leave at the general interface level!
// *
// * @return
// * @throws IOException
// */
// public Object getOverviewsManager(final ProgressListener listener)throws IOException;
}