use of org.polymap.core.data.pipeline.ProcessorRequest in project polymap4-core by Polymap4.
the class SimpleWmsServer method doGet.
@Override
protected void doGet(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
log.debug("Request: " + request.getQueryString());
try {
final Map<String, String> kvp = parseKvpSet(request.getQueryString());
sessionContext.execute(() -> {
// LAYERS
final String layer = kvp.get("LAYERS");
assert !layer.contains(INNER_DELIMETER);
final String style = kvp.get("STYLES");
assert style == null || !style.contains(INNER_DELIMETER);
log.info("layers=" + layer + ", style=" + style);
// WIDTH/HEIGHT
int width = Integer.parseInt(kvp.get("WIDTH"));
int height = Integer.parseInt(kvp.get("HEIGHT"));
// BBOX
ReferencedEnvelope bbox = parseBBox(kvp.get("BBOX"));
String srsCode = kvp.get("SRS");
CoordinateReferenceSystem crs = CRS.decode(srsCode);
bbox = new ReferencedEnvelope(bbox, crs);
// FORMAT
String format = kvp.get("FORMAT");
format = format != null ? format : "image/png";
log.debug(" --layers= " + layer);
log.debug(" --imageSize= " + width + "x" + height);
log.debug(" --bbox= " + bbox);
crs = bbox.getCoordinateReferenceSystem();
log.debug(" --CRS= " + bbox.getCoordinateReferenceSystem().getName());
// find/create pipeline
final Pipeline pipeline = pipelines.get(layer, key -> createPipeline(key));
long modifiedSince = request.getDateHeader("If-Modified-Since");
final ProcessorRequest pr = new GetMapRequest(Collections.singletonList(layer), Collections.singletonList(style), srsCode, bbox, format, width, height, modifiedSince);
// process
Lazy<ServletOutputStream> out = new PlainLazyInit(() -> {
try {
return response.getOutputStream();
} catch (Exception e) {
log.warn("Pipeline exception: " + e, e);
response.setStatus(502);
return null;
}
});
try {
createPipelineExecutor().execute(pipeline, pr, new ResponseHandler() {
@Override
public void handle(ProcessorResponse pipeResponse) throws Exception {
if (pipeResponse == EncodedImageResponse.NOT_MODIFIED) {
response.setStatus(304);
} else {
long lastModified = ((EncodedImageResponse) pipeResponse).getLastModified();
// allow the browser to use a cached tile for max-age without a request
if (lastModified > 0) {
long maxAge = ((EncodedImageResponse) pipeResponse).getExpires() - System.currentTimeMillis() / 1000;
response.setDateHeader("Last-Modified", lastModified);
response.setHeader("Cache-Control", "public,must-revalidate");
} else // disable browser cache if there is no internal Cache for this layer
{
response.setHeader("Cache-Control", "no-cache,no-store,must-revalidate");
response.setDateHeader("Expires", 0);
response.setHeader("Pragma", "no-cache");
}
byte[] chunk = ((EncodedImageResponse) pipeResponse).getChunk();
int len = ((EncodedImageResponse) pipeResponse).getChunkSize();
out.get().write(chunk, 0, len);
}
}
});
} catch (Throwable e) {
log.warn("Pipeline exception: " + e, e);
response.setStatus(502);
}
return null;
});
} catch (IOException e) {
// assuming that this is an EOF exception
log.info("Exception: " + e);
} catch (Exception e) {
log.warn(e.toString(), e);
} finally {
// XXX do I have to close out?
// out.close();
}
}
use of org.polymap.core.data.pipeline.ProcessorRequest 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();
}
}
}
}
Aggregations