Search in sources :

Example 1 with EncodedImageResponse

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();
    }
}
Also used : ProcessorResponse(org.polymap.core.data.pipeline.ProcessorResponse) ResponseHandler(org.polymap.core.data.pipeline.ResponseHandler) ServletOutputStream(javax.servlet.ServletOutputStream) IOException(java.io.IOException) PlainLazyInit(org.polymap.core.runtime.PlainLazyInit) FactoryException(org.opengis.referencing.FactoryException) ServletException(javax.servlet.ServletException) NoSuchAuthorityCodeException(org.opengis.referencing.NoSuchAuthorityCodeException) ServiceException(org.osgi.framework.ServiceException) IOException(java.io.IOException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) Pipeline(org.polymap.core.data.pipeline.Pipeline) ReferencedEnvelope(org.geotools.geometry.jts.ReferencedEnvelope) EncodedImageResponse(org.polymap.core.data.image.EncodedImageResponse) ProcessorRequest(org.polymap.core.data.pipeline.ProcessorRequest) GetMapRequest(org.polymap.core.data.image.GetMapRequest) CoordinateReferenceSystem(org.opengis.referencing.crs.CoordinateReferenceSystem)

Example 2 with EncodedImageResponse

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);
    }
}
Also used : InputStream(java.io.InputStream) Color(java.awt.Color) IOException(java.io.IOException) GetMapResponse(org.geotools.data.wms.response.GetMapResponse) EncodedImageResponse(org.polymap.core.data.image.EncodedImageResponse) BoundingBox(org.opengis.geometry.BoundingBox)

Example 3 with EncodedImageResponse

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);
    }
}
Also used : Timer(org.polymap.core.runtime.Timer) EncodedImageResponse(org.polymap.core.data.image.EncodedImageResponse) ByteArrayOutputStream(java.io.ByteArrayOutputStream)

Aggregations

EncodedImageResponse (org.polymap.core.data.image.EncodedImageResponse)3 IOException (java.io.IOException)2 Color (java.awt.Color)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 InputStream (java.io.InputStream)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 ServletException (javax.servlet.ServletException)1 ServletOutputStream (javax.servlet.ServletOutputStream)1 GetMapResponse (org.geotools.data.wms.response.GetMapResponse)1 ReferencedEnvelope (org.geotools.geometry.jts.ReferencedEnvelope)1 BoundingBox (org.opengis.geometry.BoundingBox)1 FactoryException (org.opengis.referencing.FactoryException)1 NoSuchAuthorityCodeException (org.opengis.referencing.NoSuchAuthorityCodeException)1 CoordinateReferenceSystem (org.opengis.referencing.crs.CoordinateReferenceSystem)1 ServiceException (org.osgi.framework.ServiceException)1 GetMapRequest (org.polymap.core.data.image.GetMapRequest)1 Pipeline (org.polymap.core.data.pipeline.Pipeline)1 ProcessorRequest (org.polymap.core.data.pipeline.ProcessorRequest)1 ProcessorResponse (org.polymap.core.data.pipeline.ProcessorResponse)1 ResponseHandler (org.polymap.core.data.pipeline.ResponseHandler)1