package org.geoserver.wcs2_0.response;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.RenderedImage;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import javax.media.jai.PlanarImage;
import javax.media.jai.TiledImage;
import org.geotools.coverage.grid.GridCoverage2D;
import org.geotools.coverage.grid.GridEnvelope2D;
import org.geotools.coverage.grid.GridGeometry2D;
import org.geotools.geometry.GeneralEnvelope;
import org.geotools.referencing.operation.transform.ProjectiveTransform;
import org.opengis.coverage.CannotEvaluateException;
import org.opengis.coverage.PointOutsideCoverageException;
import org.opengis.coverage.grid.GridEnvelope;
import org.opengis.geometry.DirectPosition;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.datum.PixelInCell;
import org.opengis.referencing.operation.MathTransform;
/**
* A GridCoverage instance composed of several GridCoverage2D Granules which may be obtained through the getGranules() method.
*
* TODO: note that we extends GridCoverage2D since all coverageResponseDelegate.encode has a GridCoverage2D as input parameter.
* we should propose an API change where we encode a GridCoverage instead and where GridCoverage has a dispose method to be implemented.
*
* @author Daniele Romagnoli, GeoSolutions SAS
*
*/
public class GranuleStackImpl extends GridCoverage2D /*AbstractGridCoverage*/ implements GranuleStack {
/**
* Right now, all CoverageResponseDelegate work with GridCoverage2D.
* Therefore, in order to encode a granuleStack we need to implement it as a GridCoverage2D.
* So we pass a Dummy GridCoverage2D with dummy information to avoid
* constructor failures. The provided information will be ignored anyway.
*
* Once we move to extending AbstractGridCoverage instead of GridCoverage2D we may remove this
* dummy class.
*
*/
static class DummyGridCoverage2D extends GridCoverage2D {
static GridEnvelope SAMPLE_GRID_ENVELOPE = new GridEnvelope2D(new Rectangle(0, 0, 1, 1));
static MathTransform SAMPLE_TRANSFORM = ProjectiveTransform.create(AffineTransform
.getScaleInstance(1, 1));
static PlanarImage SAMPLE_IMAGE = new TiledImage(new BufferedImage(1, 1,
BufferedImage.TYPE_BYTE_GRAY), false);
protected DummyGridCoverage2D(CharSequence name, CoordinateReferenceSystem crs)
throws IllegalArgumentException {
super(name, SAMPLE_IMAGE, new GridGeometry2D(SAMPLE_GRID_ENVELOPE, new GeneralEnvelope(
SAMPLE_GRID_ENVELOPE, PixelInCell.CELL_CENTER, SAMPLE_TRANSFORM, crs)), null,
null, null, null);
}
}
/**
* The list of all dimensions available for this stak
*/
private List<DimensionBean> dimensions;
@Override
public String toString() {
return "GranuleStackImpl [dimensions=" + dimensions + ", coverages=" + coverages + "]";
}
/** The coverages stored by this Granule stack */
private List<GridCoverage2D> coverages;
/**
* Granule stack constructor.
* @param name
* @param crs
* @param dimensions
* @param properties
*/
public GranuleStackImpl(CharSequence name, CoordinateReferenceSystem crs, List<DimensionBean> dimensions) {
super(name, new DummyGridCoverage2D(name, crs));
this.dimensions = dimensions;
this.coverages = new ArrayList<GridCoverage2D>();
}
/** serialVersionUID */
private static final long serialVersionUID = 1L;
public RenderedImage getRenderedImage() {
if (LOGGER.isLoggable(Level.FINE)) {
LOGGER.fine("Unable to return a RenderedImage for a GranuleStack which is made of different coverages: returning null");
}
return null;
}
@Override
public Object evaluate(DirectPosition point) throws PointOutsideCoverageException,
CannotEvaluateException {
throw new UnsupportedOperationException(
"This is a multidimensional coverage, you should access its contents calling getGranules");
}
@Override
public int getNumSampleDimensions() {
throw new UnsupportedOperationException(
"This is a multidimensional coverage, you should access its contents calling getGranules");
}
@Override
public List<DimensionBean> getDimensions() {
return dimensions;
}
@Override
public List<GridCoverage2D> getGranules() {
return coverages;
}
public void addCoverage(GridCoverage2D coverage) {
coverages.add(coverage);
}
@Override
public boolean dispose(boolean force) {
boolean disposed = true;
for (GridCoverage2D coverage: coverages) {
disposed &= coverage.dispose(force);
}
return disposed;
}
}