GridCoverage2D coverage = null;
if(FeatureUtilities.isWrappedCoverage(simpleSchema) || FeatureUtilities.isWrappedCoverageReader(simpleSchema)) {
isRasterData = true;
// get the desired grid geometry
GridGeometry2D readGG = gridGeometry;
if(transformation instanceof RenderingTransformation) {
RenderingTransformation tx = (RenderingTransformation) transformation;
readGG = (GridGeometry2D) tx.invertGridGeometry(renderingQuery, gridGeometry);
// TODO: override the read params and force this grid geometry, or something
// similar to this (like passing it as a param to readCoverage
}
FeatureCollection<?,?> sample = featureSource.getFeatures();
Feature gridWrapper = DataUtilities.first( sample );
if(FeatureUtilities.isWrappedCoverageReader(simpleSchema)) {
final Object params = PARAMS_PROPERTY_NAME.evaluate(gridWrapper);
final GridCoverage2DReader reader = (GridCoverage2DReader) GRID_PROPERTY_NAME.evaluate(gridWrapper);
// don't read more than the native resolution (in case we are oversampling)
if(CRS.equalsIgnoreMetadata(reader.getCoordinateReferenceSystem(), gridGeometry.getCoordinateReferenceSystem())) {
MathTransform g2w = reader.getOriginalGridToWorld(PixelInCell.CELL_CENTER);
if(g2w instanceof AffineTransform2D && readGG.getGridToCRS2D() instanceof AffineTransform2D) {
AffineTransform2D atOriginal = (AffineTransform2D) g2w;
AffineTransform2D atMap = (AffineTransform2D) readGG.getGridToCRS2D();
if(XAffineTransform.getScale(atMap) < XAffineTransform.getScale(atOriginal)) {
// we need to go trough some convoluted code to make sure the new grid geometry
// has at least one pixel
org.opengis.geometry.Envelope worldEnvelope = gridGeometry.getEnvelope();
GeneralEnvelope transformed = org.geotools.referencing.CRS.transform(atOriginal.inverse(), worldEnvelope);
int minx = (int) Math.floor(transformed.getMinimum(0));
int miny = (int) Math.floor(transformed.getMinimum(1));
int maxx = (int) Math.ceil(transformed.getMaximum(0));
int maxy = (int) Math.ceil(transformed.getMaximum(1));
Rectangle rect = new Rectangle(minx, miny, (maxx - minx), (maxy - miny));
GridEnvelope2D gridEnvelope = new GridEnvelope2D(rect);
readGG = new GridGeometry2D(gridEnvelope, atOriginal, worldEnvelope.getCoordinateReferenceSystem());
}
}
}
coverage = readCoverage(reader, params, readGG);
} else {
coverage = (GridCoverage2D) GRID_PROPERTY_NAME.evaluate(gridWrapper);
}
// readers will return null if there is no coverage in the area
if(coverage != null) {
if(readGG != null) {
// Crop will fail if we try to crop outside of the coverage area
ReferencedEnvelope renderingEnvelope = new ReferencedEnvelope(readGG.getEnvelope());
CoordinateReferenceSystem coverageCRS = coverage.getCoordinateReferenceSystem2D();
if(!CRS.equalsIgnoreMetadata(renderingEnvelope.getCoordinateReferenceSystem(), coverageCRS)) {
renderingEnvelope = renderingEnvelope.transform(coverageCRS, true);
}
if(coverage.getEnvelope2D().intersects(renderingEnvelope)) {
// the resulting coverage might be larger than the readGG envelope, shall we crop it?
final ParameterValueGroup param = CROP.getParameters();
param.parameter("Source").setValue(coverage);
param.parameter("Envelope").setValue(renderingEnvelope);
coverage = (GridCoverage2D) PROCESSOR.doOperation(param);
} else {
coverage = null;
}
if(coverage != null) {
// we might also need to scale the coverage to the desired resolution
MathTransform2D coverageTx = readGG.getGridToCRS2D();
if(coverageTx instanceof AffineTransform) {
AffineTransform coverageAt = (AffineTransform) coverageTx;
AffineTransform renderingAt = (AffineTransform) gridGeometry.getGridToCRS2D();
// we adjust the scale only if we have many more pixels than required (30% or more)
final double ratioX = coverageAt.getScaleX() / renderingAt.getScaleX();