/** * Extracts legend for layer based on LayerInfo configuration or style LegendGraphics. * * @param published FeatureType representing the layer * @param w width for the image (hint) * @param h height for the image (hint) * @param transparent (should the image be transparent) * @param request GetLegendGraphicRequest being built * @return image with the title */ private RenderedImage getLayerLegend( LegendRequest legend, int w, int h, boolean transparent, GetLegendGraphicRequest request) { LegendInfo legendInfo = legend.getLegendInfo(); if (legendInfo == null) { return null; // nothing provided will need to dynamically generate } String onlineResource = legendInfo.getOnlineResource(); if (onlineResource == null || onlineResource.isEmpty()) { return null; // nothing provided will need to dynamically generate } URL url = null; try { url = new URL(onlineResource); } catch (MalformedURLException invalid) { LOGGER.fine("Unable to obtain " + onlineResource); return null; // should log this! } try { BufferedImage image = ImageIO.read(url); if (image.getWidth() == w && image.getHeight() == h) { return image; } final BufferedImage rescale = ImageUtils.createImage(w, h, (IndexColorModel) null, true); Graphics2D g = (Graphics2D) rescale.getGraphics(); g.setColor(new Color(255, 255, 255, 0)); g.fillRect(0, 0, w, h); double aspect = ((double) h) / ((double) image.getHeight()); int legendWidth = (int) (aspect * ((double) image.getWidth())); g.drawImage(image, 0, 0, legendWidth, h, null); g.dispose(); return rescale; } catch (IOException notFound) { LOGGER.log(Level.FINE, "Unable to legend graphic:" + url, notFound); return null; // unable to access image } }
/** * Writes layer LegendURL pointing to the user supplied icon URL, if any, or to the proper * GetLegendGraphic operation if an URL was not supplied by configuration file. * * <p>It is common practice to supply a URL to a WMS accesible legend graphic when it is * difficult to create a dynamic legend for a layer. * * @param ft The FeatureTypeInfo that holds the legendURL to write out, or<code>null</code> if * dynamically generated. * @task TODO: figure out how to unhack legend parameters such as WIDTH, HEIGHT and FORMAT */ protected void handleLegendURL(String layerName, LegendInfo legend, StyleInfo style) { if (legend != null) { if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("using user supplied legend URL"); } AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute("", "width", "width", "", String.valueOf(legend.getWidth())); attrs.addAttribute("", "height", "height", "", String.valueOf(legend.getHeight())); start("LegendURL", attrs); element("Format", legend.getFormat()); attrs.clear(); attrs.addAttribute("", "xmlns:xlink", "xmlns:xlink", "", XLINK_NS); attrs.addAttribute(XLINK_NS, "type", "xlink:type", "", "simple"); attrs.addAttribute(XLINK_NS, "href", "xlink:href", "", legend.getOnlineResource()); element("OnlineResource", null, attrs); end("LegendURL"); } else { String defaultFormat = GetLegendGraphicRequest.DEFAULT_FORMAT; if (null == wmsConfig.getLegendGraphicOutputFormat(defaultFormat)) { if (LOGGER.isLoggable(Level.WARNING)) { LOGGER.warning( new StringBuffer("Default legend format (") .append(defaultFormat) .append(")is not supported (jai not available?), can't add LegendURL element") .toString()); } return; } if (LOGGER.isLoggable(Level.FINE)) { LOGGER.fine("Adding GetLegendGraphic call as LegendURL"); } AttributesImpl attrs = new AttributesImpl(); attrs.addAttribute( "", "width", "width", "", String.valueOf(GetLegendGraphicRequest.DEFAULT_WIDTH)); // DJB: problem here is that we do not know the size of the // legend apriori - we need // to make one and find its height. Not the best way, but it // would work quite well. // This was advertising a 20*20 icon, but actually producing // ones of a different size. // An alternative is to just scale the resulting icon to what // the server requested, but this isnt // the nicest thing since warped images dont look nice. The // client should do the warping. // however, to actually estimate the size is a bit difficult. // I'm going to do the scaling // so it obeys the what the request says. For people with a // problem with that should consider // changing the default size here so that the request is for the // correct size. attrs.addAttribute( "", "height", "height", "", String.valueOf(GetLegendGraphicRequest.DEFAULT_HEIGHT)); start("LegendURL", attrs); element("Format", defaultFormat); attrs.clear(); Map<String, String> params = params( "request", "GetLegendGraphic", "format", defaultFormat, "width", String.valueOf(GetLegendGraphicRequest.DEFAULT_WIDTH), "height", String.valueOf(GetLegendGraphicRequest.DEFAULT_HEIGHT), "layer", layerName); if (style != null) { params.put("style", style.getName()); } String legendURL = buildURL(request.getBaseUrl(), "wms", params, URLType.SERVICE); attrs.addAttribute("", "xmlns:xlink", "xmlns:xlink", "", XLINK_NS); attrs.addAttribute(XLINK_NS, "type", "xlink:type", "", "simple"); attrs.addAttribute(XLINK_NS, "href", "xlink:href", "", legendURL); element("OnlineResource", null, attrs); end("LegendURL"); } }