protected Response returnEmptyTile(final int width, final int height, final String format) throws Exception { // return an empty image ImageResponseWriter writer = (ImageResponseWriter) ImageHandlerFactory.getHandler(format, ImageResponseWriter.class); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int bands; Double[] nodatas; if (format.equalsIgnoreCase("jpg") || format.equalsIgnoreCase("jpeg")) { bands = 3; nodatas = new Double[] {0.0, 0.0, 0.0}; } else { bands = 4; nodatas = new Double[] {0.0, 0.0, 0.0, 0.0}; } Raster raster = RasterUtils.createEmptyRaster(width, height, bands, DataBuffer.TYPE_BYTE, nodatas); writer.writeToStream(raster, ArrayUtils.toPrimitive(nodatas), baos); byte[] imageData = baos.toByteArray(); IOUtils.closeQuietly(baos); final String type = mimeTypeMap.getContentType("output." + format); return Response.ok(imageData).header("Content-Type", type).build(); // A 404 - Not Found response may be the most appropriate, but results in pink tiles, // maybe change that behavior on the OpenLayers client? // return Response.status( Response.Status.NOT_FOUND).build(); }
@SuppressWarnings("static-method") @GET @Produces("image/*") @Path("{version}/{raster}/{z}/{x}/{y}.{format}") public Response getTile( @PathParam("version") final String version, @PathParam("raster") String pyramid, @PathParam("z") final Integer z, @PathParam("x") final Integer x, @PathParam("y") final Integer y, @PathParam("format") final String format, @QueryParam("color-scale-name") final String colorScaleName, @QueryParam("color-scale") final String colorScale, @QueryParam("min") final Double min, @QueryParam("max") final Double max, @DefaultValue("1") @QueryParam("maskMax") final Double maskMax, @QueryParam("mask") final String mask) { final ImageRenderer renderer; Raster raster; try { renderer = (ImageRenderer) ImageHandlerFactory.getHandler(format, ImageRenderer.class); // TODO: Need to construct provider properties from the WebRequest using // a new security layer and pass those properties. // Apply mask if requested ProviderProperties providerProperties = SecurityUtils.getProviderProperties(); if (mask != null && !mask.isEmpty()) { raster = renderer.renderImage(pyramid, x, y, z, mask, maskMax, providerProperties); } else { raster = renderer.renderImage(pyramid, x, y, z, providerProperties); } if (!(renderer instanceof TiffImageRenderer) && raster.getNumBands() != 3 && raster.getNumBands() != 4) { ColorScale cs = null; if (colorScaleName != null) { cs = ColorScaleManager.fromName(colorScaleName, props); } else if (colorScale != null) { cs = ColorScaleManager.fromJSON(colorScale); } // else // { // cs = ColorScaleManager.fromPyramid(pyramid, driver); // } final double[] extrema = renderer.getExtrema(); // Check for min/max override values from the request if (min != null) { extrema[0] = min; } if (max != null) { extrema[1] = max; } raster = ((ColorScaleApplier) ImageHandlerFactory.getHandler(format, ColorScaleApplier.class)) .applyColorScale(raster, cs, extrema, renderer.getDefaultValues()); } // Apply mask if requested // if (mask != null && !mask.isEmpty()) // { // try // { // final MrsImagePyramidMetadata maskMetadata = service.getMetadata(mask); // // final Raster maskRaster = renderer.renderImage(mask, x, y, z, props, driver); // final WritableRaster wr = RasterUtils.makeRasterWritable(raster); // // final int band = 0; // final double nodata = maskMetadata.getDefaultValue(band); // // for (int w = 0; w < maskRaster.getWidth(); w++) // { // for (int h = 0; h < maskRaster.getHeight(); h++) // { // final double maskPixel = maskRaster.getSampleDouble(w, h, band); // if (maskPixel > maskMax || Double.compare(maskPixel, nodata) == 0) // { // wr.setSample(w, h, band, nodata); // } // } // } // } // catch (final TileNotFoundException ex) // { // raster = RasterUtils.createEmptyRaster(raster.getWidth(), raster.getHeight(), // raster // .getNumBands(), raster.getTransferType(), 0); // } // } return ((ImageResponseWriter) ImageHandlerFactory.getHandler(format, ImageResponseWriter.class)) .write(raster, renderer.getDefaultValues()) .build(); } catch (final IllegalArgumentException e) { return Response.status(Status.BAD_REQUEST) .entity("Unsupported image format - " + format) .build(); } catch (final IOException e) { return Response.status(Status.NOT_FOUND).entity("Tile map not found - " + pyramid).build(); } catch (final MrsImageException e) { return Response.status(Status.NOT_FOUND) .entity("Tile map not found - " + pyramid + ": " + z) .build(); } catch (final TileNotFoundException e) { // return Response.status(Status.NOT_FOUND).entity("Tile not found").build(); try { final MrsImagePyramidMetadata metadata = service.getMetadata(pyramid); return createEmptyTile( ((ImageResponseWriter) ImageHandlerFactory.getHandler(format, ImageResponseWriter.class)), metadata.getTilesize(), metadata.getTilesize()); } catch (final Exception e1) { log.error( "Exception occurred creating blank tile " + pyramid + "/" + z + "/" + x + "/" + y + "." + format, e1); } } catch (final ColorScale.BadJSONException e) { return Response.status(Status.NOT_FOUND).entity("Unable to parse color scale JSON").build(); } catch (final ColorScale.BadSourceException e) { return Response.status(Status.NOT_FOUND).entity("Unable to open color scale file").build(); } catch (final ColorScale.BadXMLException e) { return Response.status(Status.NOT_FOUND).entity("Unable to parse color scale XML").build(); } catch (final ColorScale.ColorScaleException e) { return Response.status(Status.NOT_FOUND).entity("Unable to open color scale").build(); } catch (final Exception e) { log.error( "Exception occurred getting tile " + pyramid + "/" + z + "/" + x + "/" + y + "." + format, e); } return Response.status(Status.INTERNAL_SERVER_ERROR).entity(GENERAL_ERROR).build(); }