/* * Geotoolkit.org - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2005-2012, Open Source Geospatial Foundation (OSGeo) * (C) 2007-2012, Geomatys * * 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.geotoolkit.coverage.sql; import java.io.File; import java.util.Map; import java.util.Date; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.Collection; import java.awt.image.RenderedImage; import org.opengis.metadata.extent.GeographicBoundingBox; import org.geotoolkit.util.DateRange; import org.apache.sis.measure.MeasurementRange; import org.geotoolkit.coverage.grid.GeneralGridGeometry; import org.geotoolkit.coverage.io.CoverageStoreException; /** * A layer of grid coverages sharing common properties. Layers are created by the * {@link CoverageDatabase#getLayer(String)} method. The list of layers available * in a database can be displayed in a <cite>Swing</cite> widget using the * {@link org.geotoolkit.gui.swing.coverage.LayerList} panel. * <p> * {@code Layer} instances are immutable and thread-safe. * * @author Martin Desruisseaux (IRD, Geomatys) * @version 3.16 * * @since 3.10 (derived from Seagis) * @module */ public interface Layer { /** * Returns the database which created this layer, or {@code null} if unknown. * The returned value is never null except when this {@code Layer} is the result * of a deserialization. * * @return The database which created this layer, or {@code null} if unknown. * * @since 3.12 */ CoverageDatabase getCoverageDatabase(); /** * Returns the name of this layer. * * @return The layer name. */ String getName(); /** * Returns the number of coverages in this layer. * * @return The number of coverages in this layer. * @throws CoverageStoreException if an error occurred while counting the coverages. */ int getCoverageCount() throws CoverageStoreException; /** * Returns a time range encompassing all coverages in this layer, or {@code null} if none. * * @return The time range encompassing all coverages, or {@code null}. * @throws CoverageStoreException if an error occurred while fetching the time range. */ DateRange getTimeRange() throws CoverageStoreException; /** * Returns the set of dates when a coverage is available. * * @return The set of dates, or {@code null} if unknown. * @throws CoverageStoreException if an error occurred while fetching the set. */ SortedSet<Date> getAvailableTimes() throws CoverageStoreException; /** * Returns the set of altitudes where a coverage is available. If different coverages * have different set of altitudes, then this method returns the union of all altitudes * set. * * @return The set of altitudes, or {@code null} if unknown. * @throws CoverageStoreException if an error occurred while fetching the set. */ SortedSet<Number> getAvailableElevations() throws CoverageStoreException; /** * Returns the ranges of valid <cite>geophysics</cite> values for each band. The length of * the returned list is the maximal number of bands in all coverages. If some coverages * found in this layer have different range of values, then this method returns the union * of their ranges. * * @return The range of valid sample values for each bands. * @throws CoverageStoreException If an error occurred while fetching the information. */ List<MeasurementRange<?>> getSampleValueRanges() throws CoverageStoreException; /** * Creates a color ramp for the coverages in this layer. This method searches for a * {@linkplain org.geotoolkit.coverage.Category category} which intersect the given * range. Then, an image is created with the colors from that category and optionally * a graduation for the given range. * <p> * Note that the default implementation of this method requires the optional * <a href="http://www.geotoolkit.org/modules/display/geotk-display">{@code geotk-display}</a> * module to be on reachable the classpath. * * {@note There is usually only one quantitative category for a layer. However if more * than one quantitative category is found, the one which seems the "best fit" for the * given range is selected. The definition of "best fit" is implementation-dependent.} * * The range given to this method is typically the following value: * * {@preformat java * MeasurementRange<?> range = getSampleValueRanges().get(band); * } * * However a different value can be specified, typically in the following situations: * <p> * <ul> * <li>When no graduation is desired, the range can be {@code null}.</li> * <li>When the same range needs to be expressed in different units. * In such case, the value given to this method can be computed by * <code>range.{@linkplain MeasurementRange#convertTo convertTo}(displayUnit)</code>.</li> * <li>When the caller want to apply the color palette on a subrange of the layer range. * In such case, the range given to this method can be the subrange of interest. * Note that it is caller responsibility to apply a corresponding * {@link org.geotoolkit.coverage.processing.ColorMap} operation on the * {@linkplain GridCoverageReference#read coverage read}.</li> * </ul> * <p> * This method accepts an optional map of properties, which provide more control on * the image to be generated. Current implementation recognizes the following entries * (all other entries are silently ignored): * <p> * <table border="1" cellspacing="0" cellpadding="3"> * <tr> * <th nowrap>Key</th> * <th nowrap>Value type</th> * <th nowrap>Description</th> * </tr> * <tr valign="top"> * <td>{@code "size"}</td> * <td>{@link java.awt.Dimension}</td> * <td>The image size, in pixels.</td> * </tr> * <tr valign="top"> * <td>{@code "font"}</td> * <td>{@link java.awt.Font}</td> * <td>The font to use for rendering graduation labels.</td> * </tr> * <tr valign="top"> * <td>{@code "foreground"}</td> * <td>{@link java.awt.Color}</td> * <td>The color to use for rendering graduation labels.</td> * </tr> * <tr valign="top"> * <td>{@code "graphics"}</td> * <td>{@link java.awt.Graphics2D}</td> * <td>If provided, paints the image using the given graphics handle instead than * creating a new image. In such case, this method returns {@code null}.</td> * </tr> * </table> * * @param band The band for which to create a color ramp, from 0 inclusive to * <code>{@linkplain #getSampleValueRanges()}.size()</code> exclusive. * @param range The range for the graduation, or {@code null} if no graduation * should be written. See the above javadoc for a suggested value. * @param properties An optional map of properties controlling the rendering. * See the above javadoc for a description of expected entries. * @return The color ramp as an image, or {@code null} if none. * @throws IllegalArgumentException If the units of the given range are incompatible * with the units of measurement found in this layer. * @throws CoverageStoreException If an error occurred while creating the color ramp. * * @see org.geotoolkit.gui.swing.image.ColorRamp * * @since 3.16 */ RenderedImage getColorRamp(int band, MeasurementRange<?> range, Map<String,?> properties) throws CoverageStoreException, IllegalArgumentException; /** * Returns the image format used by the coverages in this layer, sorted by decreasing frequency * of use. The strings in the returned set shall be names known to the {@linkplain javax.imageio * Java Image I/O} framework. * * @return The image formats, with the most frequently used format first. * @throws CoverageStoreException if an error occurred while querying the database. */ SortedSet<String> getImageFormats() throws CoverageStoreException; /** * Returns the directories where the image files are stored, sorted by decreasing frequency * of use. * * @return The image directories, with the most frequently used directory first. * @throws CoverageStoreException if an error occurred while querying the database. * * @since 3.12 */ SortedSet<File> getImageDirectories() throws CoverageStoreException; /** * Returns the typical pixel resolution in this layer. Values are in the unit of the * {@linkplain CoverageDatabase#getCoordinateReferenceSystem() main CRS used by the database} * (typically degrees of longitude and latitude for the horizontal part, and days for the * temporal part). Some elements of the returned array may be {@link Double#NaN NaN} if * they are unknown. * * @return The typical pixel resolution. * @throws CoverageStoreException if an error occurred while fetching the resolution. */ double[] getTypicalResolution() throws CoverageStoreException; /** * Returns the grid geometries used by the coverages in this layer, sorted by decreasing * frequency of use. The grid geometries may be 2D, 3D or 4D, including the vertical and * temporal ranges if any. The Coordinate Reference System is the one declared in the * database for the coverages. * * @return The grid geometries, with the most frequently used geometry first. * @throws CoverageStoreException if an error occurred while querying the database. */ SortedSet<GeneralGridGeometry> getGridGeometries() throws CoverageStoreException; /** * Returns the geographic bounding box, or {@code null} if unknown. If the CRS used by * the database is not geographic (for example if it is a projected CRS), then this method * will transform the layer envelope from the layer CRS to a geographic CRS. * * @return The layer geographic bounding box, or {@code null} if none. * @throws CoverageStoreException if an error occurred while querying the database * or while projecting the layer envelope. * * @since 3.11 */ GeographicBoundingBox getGeographicBoundingBox() throws CoverageStoreException; /** * Returns the envelope of this layer, optionally centered at the given date and * elevation. Callers are free to modify the returned instance before to pass it * to the {@code getCoverageReference} methods. * * @param time The central date, or {@code null}. * @param elevation The central elevation, or {@code null}. * @return A default envelope instance. * @throws CoverageStoreException if an error occurred while querying the database. */ CoverageEnvelope getEnvelope(Date time, Number elevation) throws CoverageStoreException; /** * Returns a reference to every coverages available in this layer which intersect the * given envelope. This method does not load immediately the coverages; it returns only * <em>references</em> to the coverages. * <p> * If the given envelope is {@code null}, then this method returns the references to * every coverages available in this layer regardless of their envelope. * * @param envelope The envelope for filtering the coverages, or {@code null} for no filtering. * @return The set of coverages in the layer which intersect the given envelope. * @throws CoverageStoreException if an error occurred while querying the database. */ Set<GridCoverageReference> getCoverageReferences(CoverageEnvelope envelope) throws CoverageStoreException; /** * Returns a reference to a coverage that intersect the given envelope. If more than one * coverage intersect the given envelope, then this method will select the one which seem * the most representative. The criterion for this selection is implementation-dependant * and may change in future versions. * * @param envelope The envelope for filtering the coverages, or {@code null} for no * filtering. A {@code null} value is useful for layers that are expected to * contain only one coverage, but should be avoided otherwise. * @return A reference to a coverage, or {@code null} if no coverage was found. * @throws CoverageStoreException if an error occurred while querying the database. */ GridCoverageReference getCoverageReference(CoverageEnvelope envelope) throws CoverageStoreException; /** * Adds new coverage references in the database. The new references are given by a collection * of inputs. Each input can be any of the following instances: * * <ul> * <li><p>{@link java.io.File}, {@link java.net.URL}, {@link java.net.URI} or * {@link String} instances.</p></li> * * <li><p>{@link org.geotoolkit.image.io.mosaic.Tile} instances, which will be added to the * {@code "GridCoverages"} table (not to the {@code "Tiles"} table).</p></li> * * <li><p>{@link javax.imageio.ImageReader} instances with their * {@linkplain javax.imageio.ImageReader#getInput() input} set and * {@linkplain javax.imageio.ImageReader#getImageMetadata image metadata} conform to the Geotk * {@linkplain org.geotoolkit.image.io.metadata.SpatialMetadata spatial metadata} format. The * reader input shall be one of the above-cited instances. If this is not possible (for example * because a {@link javax.imageio.stream.ImageInputStream} is required), consider wrapping * the {@link javax.imageio.spi.ImageReaderSpi} and the input in a * {@link org.geotoolkit.image.io.mosaic.Tile} instance.</p></li> * </ul> * * This method will typically read only the required metadata rather than the full image. * * {@section Multi-images files} * If a file contains more than one image, then the images to insert can be selected by the * {@link CoverageDatabaseController#filterImages(List, boolean)} method. If no controller * has been supplied, then the default behavior is to insert only the first image on the * assumption that other images are typically error estimations or overviews. * * @param files The image inputs. * @param controller An optional controller to be notified when new references are added. * The controller can modify the values declared in {@link NewGridCoverageReference} * before they are written in the database. * @throws DatabaseVetoException If a {@linkplain CoverageDatabaseListener listener} * vetoed against the operation. * @throws CoverageStoreException If an error occurred while accessing the database. * * @since 3.12 */ void addCoverageReferences(Collection<?> files, CoverageDatabaseController controller) throws DatabaseVetoException, CoverageStoreException; /** * Returns a layer to use as a fallback if no data is available in this layer for a given * position. For example if no data is available in a weekly averaged <cite>Sea Surface * Temperature</cite> (SST) coverage because a location is masked by clouds, we may want * to look in the monthly averaged SST coverage as a fallback. * * @return The fallback layer, or {@code null} if none. * @throws CoverageStoreException If an error occurred while fetching the information. */ Layer getFallback() throws CoverageStoreException; }