use of org.geoserver.platform.ServiceException in project polymap4-core by Polymap4.
the class PipelineMapOutputFormat method produceMap.
@Override
public final RenderedImageMap produceMap(WMSMapContent mapContent) throws ServiceException {
// single layer? -> request ENCODED_IMAGE
if (mapContent.layers().size() == 1) {
try {
Layer mapLayer = mapContent.layers().get(0);
ILayer layer = findLayer(mapLayer);
Pipeline pipeline = server.getOrCreatePipeline(layer, ImageProducer.class).get();
ProcessorRequest request = prepareProcessorRequest(mapContent);
AtomicReference<BufferedImage> result = new AtomicReference<BufferedImage>();
server.createPipelineExecutor().execute(pipeline, request, (ImageResponse pipeResponse) -> {
BufferedImage layerImage = (BufferedImage) pipeResponse.getImage();
result.set(layerImage);
});
return buildMap(mapContent, result.get());
} catch (Exception e) {
throw new ServiceException(e);
}
} else // multiple layers -> render into one image
{
List<Job> jobs = new ArrayList();
final Map<Layer, Image> images = new HashMap();
// run jobs for all layers
for (final Layer mapLayer : mapContent.layers()) {
UIJob job = new UIJob("PipelineMapOutputFormat: " + mapLayer.getTitle()) {
@Override
protected void runWithException(IProgressMonitor monitor) throws Exception {
try {
final ILayer layer = findLayer(mapLayer);
Pipeline pipeline = server.getOrCreatePipeline(layer, ImageProducer.class).get();
GetMapRequest request = prepareProcessorRequest(mapContent);
server.createPipelineExecutor().execute(pipeline, request, (ImageResponse pipeResponse) -> {
BufferedImage layerImage = (BufferedImage) pipeResponse.getImage();
images.put(mapLayer, layerImage);
});
} catch (Exception e) {
// XXX put a error image in the map
log.warn("", e);
images.put(mapLayer, null);
throw e;
}
}
};
job.schedule();
jobs.add(job);
}
// join jobs
for (Job job : jobs) {
try {
job.join();
} catch (InterruptedException e) {
log.warn("", e);
}
}
// put images together (MapContext order)
Graphics2D g = null;
try {
// result image
BufferedImage result = ImageUtils.createImage(mapContent.getMapWidth(), mapContent.getMapHeight(), null, true);
g = result.createGraphics();
// rendering hints
RenderingHints hints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
hints.add(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
hints.add(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
g.setRenderingHints(hints);
for (Layer mapLayer : mapContent.layers()) {
Image layerImage = images.get(mapLayer);
// load image data
// new javax.swing.ImageIcon( image ).getImage();
// ILayer layer = findLayer( mapLayer );
int rule = AlphaComposite.SRC_OVER;
// TODO opacity
// ((float)layer.getOpacity()) / 100;
float alpha = 1;
g.setComposite(AlphaComposite.getInstance(rule, alpha));
g.drawImage(layerImage, 0, 0, null);
}
return buildMap(mapContent, result);
} finally {
if (g != null) {
g.dispose();
}
}
}
}
use of org.geoserver.platform.ServiceException in project polymap4-core by Polymap4.
the class PDFMapResponse method formatImageOutputStream.
/**
* Writes the PDF.
* <p>
* NOTE: the document seems to actually be created in memory, and being written
* down to {@code output} once we call {@link Document#close()}. If there's no
* other way to do so, it'd be better to actually split out the process into
* produceMap/write?
* </p>
*
* @see org.geoserver.ows.Response#write(java.lang.Object, java.io.OutputStream,
* org.geoserver.platform.Operation)
*/
@Override
public void formatImageOutputStream(RenderedImage image, OutputStream out, WMSMapContent mapContent) throws ServiceException, IOException {
final int width = mapContent.getMapWidth();
final int height = mapContent.getMapHeight();
log.debug("setting up " + width + "x" + height + " image");
try {
// step 1: creation of a document-object
// width of document-object is width*72 inches
// height of document-object is height*72 inches
com.lowagie.text.Rectangle pageSize = new com.lowagie.text.Rectangle(width, height);
Document document = new Document(pageSize);
document.setMargins(0, 0, 0, 0);
// step 2: creation of the writer
PdfWriter writer = PdfWriter.getInstance(document, out);
// step 3: we open the document
document.open();
// step 4: we grab the ContentByte and do some stuff with it
// we create a fontMapper and read all the fonts in the font
// directory
DefaultFontMapper mapper = new DefaultFontMapper();
FontFactory.registerDirectories();
// we create a template and a Graphics2D object that corresponds
// with it
PdfContentByte cb = writer.getDirectContent();
PdfTemplate tp = cb.createTemplate(width, height);
PdfGraphics2D graphic = (PdfGraphics2D) tp.createGraphics(width, height, mapper);
// we set graphics options
if (!mapContent.isTransparent()) {
graphic.setColor(mapContent.getBgColor());
graphic.fillRect(0, 0, width, height);
} else {
if (log.isDebugEnabled()) {
log.debug("setting to transparent");
}
int type = AlphaComposite.SRC;
graphic.setComposite(AlphaComposite.getInstance(type));
Color c = new Color(mapContent.getBgColor().getRed(), mapContent.getBgColor().getGreen(), mapContent.getBgColor().getBlue(), 0);
graphic.setBackground(mapContent.getBgColor());
graphic.setColor(c);
graphic.fillRect(0, 0, width, height);
type = AlphaComposite.SRC_OVER;
graphic.setComposite(AlphaComposite.getInstance(type));
}
// Rectangle paintArea = new Rectangle(width, height);
// Envelope dataArea = mapContent.getRenderingArea();
graphic.drawImage(PlanarImage.wrapRenderedImage(image).getAsBufferedImage(), 0, 0, width, height, null);
graphic.dispose();
cb.addTemplate(tp, 0, 0);
// step 5: we close the document
document.close();
writer.flush();
writer.close();
} catch (DocumentException t) {
throw new ServiceException("Error setting up the PDF", t, "internalError");
}
}
use of org.geoserver.platform.ServiceException in project sldeditor by robward-scisys.
the class SLDEditorBufferedImageLegendGraphicBuilder method buildLegendGraphic.
/**
* Takes a GetLegendGraphicRequest and produces a BufferedImage that then can be used by a
* subclass to encode it to the appropriate output format.
*
* @param request the "parsed" request, where "parsed" means that it's values are already
* validated so this method must not take care of verifying the requested layer exists
* and the like.
*
* @throws ServiceException if there are problems creating a "sample" feature instance for the
* FeatureType <code>request</code> returns as the required layer (which should not
* occur).
*/
public BufferedImage buildLegendGraphic(GetLegendGraphicRequest request) throws ServiceException {
// list of images to be rendered for the layers (more than one if
// a layer group is given)
List<RenderedImage> layersImages = new ArrayList<RenderedImage>();
List<LegendRequest> layers = request.getLegends();
boolean forceLabelsOn = false;
boolean forceLabelsOff = false;
if (request.getLegendOptions().get("forceLabels") instanceof String) {
String forceLabelsOpt = (String) request.getLegendOptions().get("forceLabels");
if (forceLabelsOpt.equalsIgnoreCase("on")) {
forceLabelsOn = true;
} else if (forceLabelsOpt.equalsIgnoreCase("off")) {
forceLabelsOff = true;
}
}
boolean forceTitlesOff = false;
if (request.getLegendOptions().get("forceTitles") instanceof String) {
String forceTitlesOpt = (String) request.getLegendOptions().get("forceTitles");
if (forceTitlesOpt.equalsIgnoreCase("off")) {
forceTitlesOff = true;
}
}
double imageSizeFactor = 1.0;
if (request.getLegendOptions().get("imageSizeFactor") instanceof String) {
String imageSizeFactorOpt = (String) request.getLegendOptions().get("imageSizeFactor");
imageSizeFactor = Double.valueOf(imageSizeFactorOpt);
}
FeatureCountProcessor countProcessor = null;
if (Boolean.TRUE.equals(request.getLegendOption(GetLegendGraphicRequest.COUNT_MATCHED_KEY, Boolean.class))) {
countProcessor = new FeatureCountProcessor(request);
}
for (LegendRequest legend : layers) {
FeatureType layer = legend.getFeatureType();
// style and rule to use for the current layer
Style gt2Style = legend.getStyle();
if (gt2Style == null) {
throw new NullPointerException("request.getStyle()");
}
// get rule corresponding to the layer index
// normalize to null for NO RULE
// was null
String ruleName = legend.getRule();
// width and height, we might have to rescale those in case of DPI usage
int w = request.getWidth();
int h = request.getHeight();
// apply dpi rescale
double dpi = RendererUtilities.getDpi(request.getLegendOptions());
double standardDpi = RendererUtilities.getDpi(Collections.emptyMap());
if (dpi != standardDpi) {
double scaleFactor = dpi / standardDpi;
w = (int) Math.round(w * scaleFactor);
h = (int) Math.round(h * scaleFactor);
DpiRescaleStyleVisitor dpiVisitor = new DpiRescaleStyleVisitor(scaleFactor);
dpiVisitor.visit(gt2Style);
gt2Style = (Style) dpiVisitor.getCopy();
}
// apply UOM rescaling if we have a scale
if (request.getScale() > 0) {
double pixelsPerMeters = RendererUtilities.calculatePixelsPerMeterRatio(request.getScale(), request.getLegendOptions());
UomRescaleStyleVisitor rescaleVisitor = new UomRescaleStyleVisitor(pixelsPerMeters);
rescaleVisitor.visit(gt2Style);
gt2Style = (Style) rescaleVisitor.getCopy();
}
boolean strict = request.isStrict();
final boolean transparent = request.isTransparent();
RenderedImage titleImage = null;
// if we have more than one layer, we put a title on top of each layer legend
if (layers.size() > 1 && !forceTitlesOff) {
titleImage = getLayerTitle(legend, w, h, transparent, request);
}
// Check for rendering transformation
boolean hasVectorTransformation = false;
boolean hasRasterTransformation = false;
List<FeatureTypeStyle> ftsList = gt2Style.featureTypeStyles();
for (int i = 0; i < ftsList.size(); i++) {
FeatureTypeStyle fts = ftsList.get(i);
Expression exp = fts.getTransformation();
if (exp != null) {
ProcessFunction processFunction = (ProcessFunction) exp;
Name processName = processFunction.getProcessName();
Map<String, Parameter<?>> outputs = Processors.getResultInfo(processName, null);
if (outputs.isEmpty()) {
continue;
}
// we assume there is
Parameter<?> output = outputs.values().iterator().next();
// only one output
if (SimpleFeatureCollection.class.isAssignableFrom(output.getType())) {
hasVectorTransformation = true;
break;
} else if (GridCoverage2D.class.isAssignableFrom(output.getType())) {
hasRasterTransformation = true;
break;
}
}
}
final boolean buildRasterLegend = (!strict && layer == null && LegendUtils.checkRasterSymbolizer(gt2Style)) || (LegendUtils.checkGridLayer(layer) && !hasVectorTransformation) || hasRasterTransformation;
// Just checks LegendInfo currently, should check gtStyle
final boolean useProvidedLegend = layer != null && legend.getLayerInfo() != null;
RenderedImage legendImage = null;
if (useProvidedLegend) {
legendImage = getLayerLegend(legend, w, h, transparent, request);
}
if (buildRasterLegend) {
final RasterLayerLegendHelper rasterLegendHelper = new RasterLayerLegendHelper(request, gt2Style, ruleName);
final BufferedImage image = rasterLegendHelper.getLegend();
if (image != null) {
if (titleImage != null) {
layersImages.add(titleImage);
}
layersImages.add(image);
}
} else if (useProvidedLegend && legendImage != null) {
if (titleImage != null) {
layersImages.add(titleImage);
}
layersImages.add(legendImage);
} else {
final Feature sampleFeature;
if (layer == null || hasVectorTransformation) {
sampleFeature = createSampleFeature();
} else {
sampleFeature = createSampleFeature(layer);
}
final FeatureTypeStyle[] ftStyles = gt2Style.featureTypeStyles().toArray(new FeatureTypeStyle[0]);
final double scaleDenominator = request.getScale();
Rule[] applicableRules;
if (ruleName != null) {
Rule rule = LegendUtils.getRule(ftStyles, ruleName);
if (rule == null) {
throw new ServiceException("Specified style does not contains a rule named " + ruleName);
}
applicableRules = new Rule[] { rule };
} else {
applicableRules = LegendUtils.getApplicableRules(ftStyles, scaleDenominator);
}
// do we have to alter the style to do context sensitive feature counts?
if (countProcessor != null && !forceLabelsOff) {
applicableRules = updateRuleTitles(countProcessor, legend, applicableRules);
}
final NumberRange<Double> scaleRange = NumberRange.create(scaleDenominator, scaleDenominator);
final int ruleCount = applicableRules.length;
/**
* A legend graphic is produced for each applicable rule. They're being held here
* until the process is done and then painted on a "stack" like legend.
*/
final List<RenderedImage> legendsStack = new ArrayList<RenderedImage>(ruleCount);
final SLDStyleFactory styleFactory = new SLDStyleFactory();
double minimumSymbolSize = MINIMUM_SYMBOL_SIZE;
// get minSymbolSize from LEGEND_OPTIONS, if defined
if (request.getLegendOptions().get("minSymbolSize") instanceof String) {
String minSymbolSizeOpt = (String) request.getLegendOptions().get("minSymbolSize");
try {
minimumSymbolSize = Double.parseDouble(minSymbolSizeOpt);
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Invalid minSymbolSize value: should be a number");
}
}
// calculate the symbols rescaling factor necessary for them to be
// drawn inside the icon box
double symbolScale = calcSymbolScale(w, h, layer, sampleFeature, applicableRules, minimumSymbolSize);
for (int i = 0; i < ruleCount; i++) {
final RenderedImage image = ImageUtils.createImage(w, h, (IndexColorModel) null, transparent);
final Map<RenderingHints.Key, Object> hintsMap = new HashMap<RenderingHints.Key, Object>();
final Graphics2D graphics = ImageUtils.prepareTransparency(transparent, LegendUtils.getBackgroundColor(request), image, hintsMap);
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Feature sample = getSampleFeatureForRule(layer, sampleFeature, applicableRules[i]);
FilterFactory ff = CommonFactoryFinder.getFilterFactory();
final Symbolizer[] symbolizers = applicableRules[i].getSymbolizers();
final GraphicLegend graphic = applicableRules[i].getLegend();
// If this rule has a legend graphic defined in the SLD, use it
if (graphic != null) {
if (this.samplePoint == null) {
Coordinate coord = new Coordinate(w / 2, h / 2);
try {
this.samplePoint = new LiteShape2(geomFac.createPoint(coord), null, null, false);
} catch (Exception e) {
this.samplePoint = null;
}
}
shapePainter.paint(graphics, this.samplePoint, graphic, scaleDenominator, false);
} else {
for (int sIdx = 0; sIdx < symbolizers.length; sIdx++) {
Symbolizer symbolizer = symbolizers[sIdx];
if (symbolizer instanceof RasterSymbolizer) {
// skip it
} else {
// rescale symbols if needed
if (symbolScale > 1.0 && symbolizer instanceof PointSymbolizer) {
PointSymbolizer pointSymbolizer = (PointSymbolizer) cloneSymbolizer(symbolizer);
if (pointSymbolizer.getGraphic() != null) {
double size = getGraphicSize(sample, pointSymbolizer.getGraphic(), Math.min(w, h) - 4);
pointSymbolizer.getGraphic().setSize(ff.literal(size / symbolScale + minimumSymbolSize));
symbolizer = pointSymbolizer;
}
}
if (!(Math.abs(imageSizeFactor - 1.0) < 0.0001)) {
if (symbolizer instanceof PointSymbolizer) {
PointSymbolizer pointSymbolizer2 = (PointSymbolizer) cloneSymbolizer(symbolizer);
if (pointSymbolizer2.getGraphic() != null) {
double size = getGraphicSize(sample, pointSymbolizer2.getGraphic(), Math.min(w, h) - 4);
pointSymbolizer2.getGraphic().setSize(ff.literal(size * imageSizeFactor + minimumSymbolSize));
symbolizer = pointSymbolizer2;
}
} else if (symbolizer instanceof PolygonSymbolizer) {
PolygonSymbolizer polygonSymbolizer2 = (PolygonSymbolizer) cloneSymbolizer(symbolizer);
if (polygonSymbolizer2.getFill() != null) {
// Fill
double size = 0.0;
if (polygonSymbolizer2.getFill().getGraphicFill() != null) {
size = getGraphicSize(sample, polygonSymbolizer2.getFill().getGraphicFill(), Math.min(w, h) - 4);
polygonSymbolizer2.getFill().getGraphicFill().setSize(ff.literal(size * imageSizeFactor + minimumSymbolSize));
}
}
if (polygonSymbolizer2.getStroke() != null) {
// Stroke
double size = getGraphicSize(sample, polygonSymbolizer2.getStroke().getGraphicFill(), Math.min(w, h) - 4);
polygonSymbolizer2.getStroke().getGraphicFill().setSize(ff.literal(size * imageSizeFactor + minimumSymbolSize));
if (polygonSymbolizer2.getStroke().getGraphicStroke() != null) {
size = getGraphicSize(sample, polygonSymbolizer2.getStroke().getGraphicStroke(), Math.min(w, h) - 4);
polygonSymbolizer2.getStroke().getGraphicStroke().setSize(ff.literal(size * imageSizeFactor + minimumSymbolSize));
}
}
symbolizer = polygonSymbolizer2;
} else if (symbolizer instanceof LineSymbolizer) {
LineSymbolizer lineSymbolizer2 = (LineSymbolizer) cloneSymbolizer(symbolizer);
if (lineSymbolizer2.getStroke() != null) {
// Stroke
double size = 0.0;
if (lineSymbolizer2.getStroke().getGraphicFill() != null) {
size = getGraphicSize(sample, lineSymbolizer2.getStroke().getGraphicFill(), Math.min(w, h) - 4);
lineSymbolizer2.getStroke().getGraphicFill().setSize(ff.literal(size * imageSizeFactor + minimumSymbolSize));
}
if (lineSymbolizer2.getStroke().getGraphicStroke() != null) {
size = getGraphicSize(sample, lineSymbolizer2.getStroke().getGraphicStroke(), Math.min(w, h) - 4);
lineSymbolizer2.getStroke().getGraphicStroke().setSize(ff.literal(size * imageSizeFactor + minimumSymbolSize));
}
if (lineSymbolizer2.getStroke().getWidth() != null) {
size = getWidthSize(sample, lineSymbolizer2.getStroke().getWidth(), 1);
lineSymbolizer2.getStroke().setWidth(ff.literal(size * imageSizeFactor));
}
}
symbolizer = lineSymbolizer2;
}
}
}
Style2D style2d = styleFactory.createStyle(sample, symbolizer, scaleRange);
LiteShape2 shape = getSampleShape(symbolizer, w, h);
if (style2d != null) {
shapePainter.paint(graphics, shape, style2d, scaleDenominator);
}
}
}
if (image != null && titleImage != null) {
layersImages.add(titleImage);
titleImage = null;
}
legendsStack.add(image);
graphics.dispose();
}
int labelMargin = 3;
if (!StringUtils.isEmpty(request.getLegendOptions().get("labelMargin"))) {
labelMargin = Integer.parseInt(request.getLegendOptions().get("labelMargin").toString());
}
LegendMerger.MergeOptions options = LegendMerger.MergeOptions.createFromRequest(legendsStack, 0, 0, 0, labelMargin, request, forceLabelsOn, forceLabelsOff, forceTitlesOff);
if (ruleCount > 0) {
BufferedImage image = LegendMerger.mergeLegends(applicableRules, request, options);
if (image != null) {
layersImages.add(image);
}
}
}
}
// all legend graphics are merged if we have a layer group
BufferedImage finalLegend = mergeGroups(layersImages, null, request, forceLabelsOn, forceLabelsOff, forceTitlesOff);
if (finalLegend == null) {
throw new IllegalArgumentException("no legend passed");
}
return finalLegend;
}
Aggregations