// ... base image memory
long memory = getDrawingSurfaceMemoryUse(paintArea.width, paintArea.height, palette,
transparent);
// .. use a fake streaming renderer to evaluate the extra back buffers used when rendering
// multiple featureTypeStyles against the same layer
StreamingRenderer testRenderer = new StreamingRenderer();
testRenderer.setContext(mapContext);
memory += testRenderer.getMaxBackBufferMemory(paintArea.width, paintArea.height);
if (maxMemory > 0 && memory > maxMemory) {
long kbUsed = memory / KB;
long kbMax = maxMemory / KB;
throw new ServiceException("Rendering request would use " + kbUsed + "KB, whilst the "
+ "maximum memory allowed is " + kbMax + "KB");
}
// TODO: allow rendering to continue with vector layers
// TODO: allow rendering to continue with layout
// TODO: handle rotated rasters
// TODO: handle color conversions
// TODO: handle meta-tiling
// TODO: how to handle timeout here? I guess we need to move it into the dispatcher?
RenderedImage image = null;
// fast path for pure coverage rendering
if (DefaultWebMapService.isDirectRasterPathEnabled() &&
mapContext.getLayerCount() == 1
&& mapContext.getAngle() == 0.0
&& (layout == null || layout.isEmpty())) {
List<GridCoverage2D> renderedCoverages = new ArrayList<GridCoverage2D>(2);
try {
image = directRasterRender(mapContext, 0, renderedCoverages);
} catch (Exception e) {
throw new ServiceException("Error rendering coverage on the fast path", e);
}
if (image != null) {
RenderedImageMap result = new RenderedImageMap(mapContext, image, getMimeType());
result.setRenderedCoverages(renderedCoverages);
return result;
}
}
// we use the alpha channel if the image is transparent or if the meta tiler
// is enabled, since apparently the Crop operation inside the meta-tiler
// generates striped images in that case (see GEOS-
boolean useAlpha = transparent || MetatileMapOutputFormat.isRequestTiled(request, this);
final RenderedImage preparedImage = prepareImage(paintArea.width, paintArea.height,
palette, useAlpha);
final Map<RenderingHints.Key, Object> hintsMap = new HashMap<RenderingHints.Key, Object>();
final Graphics2D graphic = ImageUtils.prepareTransparency(transparent, bgColor,
preparedImage, hintsMap);
// set up the antialias hints
if (AA_NONE.equals(antialias)) {
hintsMap.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
if (preparedImage.getColorModel() instanceof IndexColorModel) {
// otherwise we end up with dithered colors where the match is
// not 100%
hintsMap.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_DISABLE);
}
} else if (AA_TEXT.equals(antialias)) {
hintsMap.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
hintsMap.put(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
} else {
if (antialias != null && !AA_FULL.equals(antialias)) {
LOGGER.warning("Unrecognized antialias setting '" + antialias
+ "', valid values are " + AA_SETTINGS);
}
hintsMap.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
// these two hints improve text layout in diagonal labels and reduce artifacts
// in line rendering (without hampering performance)
hintsMap.put(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
hintsMap.put(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
// turn off/on interpolation rendering hint
if (wms != null) {
if (WMSInterpolation.Nearest.equals(wms.getInterpolation())) {
hintsMap.put(JAI.KEY_INTERPOLATION, NN_INTERPOLATION);
hintsMap.put(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
} else if (WMSInterpolation.Bilinear.equals(wms.getInterpolation())) {
hintsMap.put(JAI.KEY_INTERPOLATION, BIL_INTERPOLATION);
hintsMap.put(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
} else if (WMSInterpolation.Bicubic.equals(wms.getInterpolation())) {
hintsMap.put(JAI.KEY_INTERPOLATION, BIC_INTERPOLATION);
hintsMap.put(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
}
}
// make sure the hints are set before we start rendering the map
graphic.setRenderingHints(hintsMap);
RenderingHints hints = new RenderingHints(hintsMap);
GTRenderer renderer;
if (DefaultWebMapService.useShapefileRenderer()) {
renderer = new ShapefileRenderer();
} else {
StreamingRenderer sr = new StreamingRenderer();
sr.setThreadPool(DefaultWebMapService.getRenderingPool());
renderer = sr;
}
renderer.setContext(mapContext);
renderer.setJava2DHints(hints);