//
// extract the raster symbolizers and the eventual rendering transformation
//
double scaleDenominator = mapContent.getScaleDenominator(true);
Layer layer = mapContent.layers().get(layerIndex);
FeatureType featureType = layer.getFeatureSource().getSchema();
Style style = layer.getStyle();
RasterSymbolizerVisitor visitor = new RasterSymbolizerVisitor(scaleDenominator, featureType);
style.accept(visitor);
List<RasterSymbolizer> symbolizers = visitor.getRasterSymbolizers();
if (symbolizers.size() != 1) {
return null;
}
RasterSymbolizer symbolizer = symbolizers.get(0);
Expression transformation = visitor.getRasterRenderingTransformation();
//
// Dimensions
//
final int mapWidth = mapContent.getMapWidth();
final int mapHeight= mapContent.getMapHeight();
// force east/north, otherwise the reading code might think we are reprojecting
// and start adding padding around the requests
final ReferencedEnvelope mapEnvelope = getEastNorthEnvelope(mapContent.getRenderingArea());
final CoordinateReferenceSystem mapCRS = mapEnvelope.getCoordinateReferenceSystem();
final Rectangle mapRasterArea = new Rectangle(0, 0, mapWidth,mapHeight);
final AffineTransform worldToScreen = RendererUtilities.worldToScreenTransform(mapEnvelope, mapRasterArea);
//
// Check transparency and bg color
//
final boolean transparent = mapContent.isTransparent() && isTransparencySupported();
Color bgColor = mapContent.getBgColor();
// set transparency
if (transparent) {
bgColor = new Color(bgColor.getRed(), bgColor.getGreen(), bgColor.getBlue(), 0);
} else {
bgColor = new Color(bgColor.getRed(), bgColor.getGreen(), bgColor.getBlue(), 255);
}
//
// Grab the interpolation
//
final Interpolation interpolation;
if (wms != null) {
if (WMSInterpolation.Nearest.equals(wms.getInterpolation())) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
} else if (WMSInterpolation.Bilinear.equals(wms.getInterpolation())) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_BILINEAR);
} else if (WMSInterpolation.Bicubic.equals(wms.getInterpolation())) {
interpolation = Interpolation.getInstance(Interpolation.INTERP_BICUBIC);
} else {
interpolation = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
}
} else {
interpolation = Interpolation.getInstance(Interpolation.INTERP_NEAREST);
}
//
// Tiling
//
// if there is a output tile size hint, use it, otherwise use the output size itself
final int tileSizeX;
final int tileSizeY;
if (mapContent.getTileSize() != -1) {
tileSizeX = tileSizeY = mapContent.getTileSize();
} else {
tileSizeX = mapContent.getMapWidth();
tileSizeY = mapContent.getMapHeight();
}
// actual read
RenderedImage image = null;
GridCoverage2D coverage;
RenderingHints interpolationHints = new RenderingHints(JAI.KEY_INTERPOLATION, interpolation);
try {
final Color readerBgColor = transparent ? null : bgColor;
if (transformation == null) {
//
// Get the reader
//
final Feature feature = mapContent.layers().get(0).getFeatureSource().getFeatures()
.features().next();
final GridCoverage2DReader reader = (GridCoverage2DReader) feature.getProperty(
"grid").getValue();
// render via grid coverage renderer, that will apply the advanced projection
// handling
final Object params = feature.getProperty("params").getValue();
GeneralParameterValue[] readParameters = getReadParameters(params, null, null,
interpolation, readerBgColor);
final GridCoverageRenderer gcr = new GridCoverageRenderer(mapEnvelope.getCoordinateReferenceSystem(), mapEnvelope,
mapRasterArea, worldToScreen, interpolationHints);
gcr.setAdvancedProjectionHandlingEnabled(true);
gcr.setWrapEnabled(DefaultWebMapService.isContinuousMapWrappingEnabled());
image = gcr.renderImage(reader, readParameters, symbolizer, interpolation,
mapContent.getBgColor(), tileSizeX, tileSizeY);
if (image == null) {
// we're outside of the coverage definition area, return an empty space
image = createBkgImage(mapWidth, mapHeight, bgColor, null);
}
} else {
//
// Prepare the reading parameters (for the RT case)
//
final CoordinateReferenceSystem coverageCRS = layer.getFeatureSource().getSchema()
.getCoordinateReferenceSystem();
final GridGeometry2D readGG;
final boolean equalsMetadata = CRS.equalsIgnoreMetadata(mapCRS, coverageCRS);
boolean sameCRS;
try {
sameCRS = equalsMetadata ? true : CRS.findMathTransform(mapCRS, coverageCRS,
true).isIdentity();
} catch (FactoryException e1) {
final IOException ioe = new IOException();
ioe.initCause(e1);
throw ioe;
}
final boolean needsGutter = !sameCRS
|| !(interpolation instanceof InterpolationNearest);
if (!needsGutter) {
readGG = new GridGeometry2D(new GridEnvelope2D(mapRasterArea), mapEnvelope);
} else {
//
// SG added gutter to the drawing. We need to investigate much more and also we
// need to do this only when needed
//
// enlarge raster area
Rectangle bufferedTargetArea = (Rectangle) mapRasterArea.clone();
bufferedTargetArea.add(mapRasterArea.x + mapRasterArea.width + 10,
mapRasterArea.y + mapRasterArea.height + 10);
bufferedTargetArea.add(mapRasterArea.x - 10, mapRasterArea.y - 10);
// now create the final envelope accordingly
try {
readGG = new GridGeometry2D(new GridEnvelope2D(bufferedTargetArea),
PixelInCell.CELL_CORNER, new AffineTransform2D(
worldToScreen.createInverse()), mapCRS, null);
} catch (Exception e) {
final IOException ioe = new IOException();
ioe.initCause(e);
throw ioe;
}
}
RenderingTransformationHelper helper = new RenderingTransformationHelper() {
protected GridCoverage2D readCoverage(GridCoverage2DReader reader, Object params, GridGeometry2D readGG)
throws IOException {
return readBestCoverage(
reader,
params,
ReferencedEnvelope.reference(readGG.getEnvelope()),
readGG.getGridRange2D(),
interpolation,
readerBgColor);
}
};
Object result = helper.applyRenderingTransformation(transformation, layer.getFeatureSource(),
layer.getQuery(), Query.ALL, readGG, coverageCRS, interpolationHints);
if(result == null) {
coverage = null;
} else if(result instanceof GridCoverage2D) {
coverage = (GridCoverage2D) result;
} else {