use of org.polymap.core.data.image.EncodedImageResponse 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.image.EncodedImageResponse in project polymap4-core by Polymap4.
the class WmsRenderProcessor method getMapRequest.
@Override
public void getMapRequest(GetMapRequest request, ProcessorContext context) throws Exception {
int width = request.getWidth();
int height = request.getHeight();
BoundingBox bbox = request.getBoundingBox();
log.debug("bbox=" + bbox + ", imageSize=" + width + "x" + height);
org.geotools.data.wms.request.GetMapRequest getMap = wms.createGetMapRequest();
getMap.setFormat(request.getFormat());
getMap.setDimensions(width, height);
getMap.setTransparent(true);
Color color = request.getBgColor();
if (color != null) {
getMap.setBGColour(String.format("#%02X%02X%02X", color.getRed(), color.getGreen(), color.getBlue()));
}
setBBox(getMap, bbox);
getMap.setSRS(request.getCRS());
getMap.addLayer(layer);
// log.info( " WMS URL:" + getMap.getFinalURL() );
InputStream in = null;
try {
long start = System.currentTimeMillis();
GetMapResponse wmsResponse = wms.issueRequest(getMap);
log.debug("Got repsonse (" + (System.currentTimeMillis() - start) + "ms). providing data: " + wmsResponse.getContentType());
in = wmsResponse.getInputStream();
int count = 0;
byte[] buf = new byte[4 * 1024];
for (int c = in.read(buf); c != -1; c = in.read(buf)) {
context.sendResponse(new EncodedImageResponse(buf, c));
buf = new byte[8 * 1024];
log.debug(" ---> data sent: " + c);
count += c;
}
if (count == 0) {
throw new IOException("WMSResponse is empty.");
}
context.sendResponse(ProcessorResponse.EOP);
log.debug("...all data send.");
} finally {
IOUtils.closeQuietly(in);
}
}
use of org.polymap.core.data.image.EncodedImageResponse in project polymap4-core by Polymap4.
the class ImageCacheProcessor method getMapRequest.
@Override
public void getMapRequest(GetMapRequest request, ProcessorContext context) throws Exception {
Timer timer = new Timer();
CachedTile cachedTile = cache.get(site, request);
// cached
if (cachedTile != null) {
// check If-Modified-Since
long modifiedSince = request.getIfModifiedSince();
long lastModified = cachedTile.lastModified.get();
if (modifiedSince > 0 && lastModified > modifiedSince) {
log.info("### CACHE: 304! :) -- " + timer.elapsedTime() + "ms");
context.sendResponse(EncodedImageResponse.NOT_MODIFIED);
context.sendResponse(ProcessorResponse.EOP);
} else // in cache but modified
{
byte[] data = cachedTile.data.get();
log.info("### CACHE: Hit (" + data.length + " bytes) -- " + timer.elapsedTime() + "ms");
EncodedImageResponse response = new EncodedImageResponse(data, data.length);
response.setLastModified(cachedTile.lastModified.get());
response.setExpires(cachedTile.expires.get());
context.sendResponse(response);
context.sendResponse(ProcessorResponse.EOP);
}
} else // not in cache -> send request down the pipeline
{
log.info("### CACHE: Miss -- " + timer.elapsedTime() + "ms");
ByteArrayOutputStream cacheBuf = new ByteArrayOutputStream(128 * 1024);
context.put("cacheBuf", cacheBuf);
context.put("request", request);
context.put("created", System.currentTimeMillis());
context.sendRequest(request);
}
}
Aggregations