001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/portal/standard/wms/control/LegendListener.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53115 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042:
043: ---------------------------------------------------------------------------*/
044: package org.deegree.portal.standard.wms.control;
045:
046: import java.awt.Color;
047: import java.awt.Graphics;
048: import java.awt.Rectangle;
049: import java.awt.geom.Rectangle2D;
050: import java.awt.image.BufferedImage;
051: import java.io.FileOutputStream;
052: import java.io.IOException;
053: import java.net.MalformedURLException;
054: import java.net.URL;
055: import java.util.ArrayList;
056: import java.util.HashMap;
057: import java.util.StringTokenizer;
058:
059: import javax.servlet.http.HttpServletRequest;
060: import javax.servlet.http.HttpSession;
061:
062: import org.deegree.enterprise.control.FormEvent;
063: import org.deegree.enterprise.control.RPCMember;
064: import org.deegree.enterprise.control.RPCMethodCall;
065: import org.deegree.enterprise.control.RPCParameter;
066: import org.deegree.enterprise.control.RPCStruct;
067: import org.deegree.enterprise.control.RPCWebEvent;
068: import org.deegree.framework.log.ILogger;
069: import org.deegree.framework.log.LoggerFactory;
070: import org.deegree.framework.util.IDGenerator;
071: import org.deegree.framework.util.ImageUtils;
072: import org.deegree.ogcwebservices.InconsistentRequestException;
073: import org.deegree.ogcwebservices.wms.operation.GetLegendGraphic;
074: import org.deegree.portal.context.GeneralExtension;
075: import org.deegree.portal.context.IOSettings;
076: import org.deegree.portal.context.ViewContext;
077:
078: /**
079: * will be called if the client forces a dynamic legend.
080: *
081: *
082: * @author <a href="mailto:lupp@lat-lon.de">Katharina Lupp</a>
083: * @version $Revision: 9346 $ $Date: 2007-12-27 08:39:07 -0800 (Thu, 27 Dec 2007) $
084: */
085: public class LegendListener extends AbstractMapListener {
086:
087: private static final ILogger LOG = LoggerFactory
088: .getLogger(LegendListener.class);
089:
090: /**
091: * the method will be called if a zoomout action/event occurs.
092: */
093: public void actionPerformed(FormEvent event) {
094:
095: super .actionPerformed(event);
096:
097: RPCWebEvent rpc = (RPCWebEvent) event;
098: RPCMethodCall mc = rpc.getRPCMethodCall();
099: RPCParameter[] para = mc.getParameters();
100: RPCStruct struct = (RPCStruct) para[0].getValue();
101: HttpSession session = ((HttpServletRequest) this .getRequest())
102: .getSession(true);
103: ViewContext vc = (ViewContext) session
104: .getAttribute("DefaultMapContext");
105:
106: HashMap[] model = createWMSRequestModel(struct);
107:
108: try {
109: GetLegendGraphic legendParam = getLegendRequestParameter();
110: HashMap symbols = setLegend(legendParam, model);
111: Rectangle rect = calcLegendSize(symbols);
112: BufferedImage bi = new BufferedImage(rect.width + 30,
113: rect.height + 50, BufferedImage.TYPE_INT_RGB);
114: bi = drawSymbolsToBI(symbols, bi);
115: saveImage(vc, bi);
116: } catch (Exception e) {
117: LOG.logError("Error occurred in PrintListener: ", e);
118: }
119:
120: }
121:
122: private Rectangle calcLegendSize(HashMap map) {
123:
124: String[] layers = (String[]) map.get("NAMES");
125: BufferedImage[] legs = (BufferedImage[]) map.get("IMAGES");
126:
127: int w = 0;
128: int h = 0;
129: for (int i = 0; i < layers.length; i++) {
130: h += legs[i].getHeight() + 6;
131: Graphics g = legs[i].getGraphics();
132: Rectangle2D rect = g.getFontMetrics().getStringBounds(
133: layers[i], g);
134: g.dispose();
135: if (rect.getWidth() > w) {
136: w = (int) rect.getWidth();
137: }
138: }
139: w += 50;
140:
141: return new Rectangle(w, h);
142: }
143:
144: private BufferedImage drawSymbolsToBI(HashMap map, BufferedImage bi) {
145:
146: Graphics g = bi.getGraphics();
147: g.setColor(Color.WHITE);
148: g.fillRect(1, 1, bi.getWidth() - 2, bi.getHeight() - 2);
149:
150: String[] layers = (String[]) map.get("NAMES");
151: BufferedImage[] legs = (BufferedImage[]) map.get("IMAGES");
152: int h = 5;
153: for (int i = layers.length - 1; i >= 0; i--) {
154: g.drawImage(legs[i], 20, h, null);
155: g.setColor(Color.BLACK);
156: if (legs[i].getHeight() < 50) {
157: g.drawString(layers[i], 30 + legs[i].getWidth(), h
158: + (int) (legs[i].getHeight() / 1.2));
159: }
160: h += legs[i].getHeight() + 5;
161: }
162: g.dispose();
163: return bi;
164: }
165:
166: private HashMap[] createWMSRequestModel(RPCStruct struct) {
167:
168: RPCMember[] member = struct.getMembers();
169:
170: HashMap<String, String>[] getMR = new HashMap[member.length];
171: for (int i = 0; i < member.length; i++) {
172: String request = (String) member[i].getValue();
173: getMR[i] = toMap(request);
174: StringTokenizer st = new StringTokenizer(request, "?");
175: getMR[i].put("URL", st.nextToken());
176: }
177: return getMR;
178: }
179:
180: private void saveImage(ViewContext vc, BufferedImage bg) {
181:
182: GeneralExtension ge = vc.getGeneral().getExtension();
183: IOSettings ios = ge.getIOSettings();
184: String dir = ios.getPrintDirectory().getDirectoryName();
185: String format = "jpeg";
186: long l = IDGenerator.getInstance().generateUniqueID();
187: String file = "legend" + l + '.' + format;
188: try {
189: FileOutputStream fos = new FileOutputStream(dir + "/"
190: + file);
191:
192: ImageUtils.saveImage(bg, fos, format, 1);
193:
194: fos.close();
195: } catch (Exception e) {
196: LOG.logError("Error occurred in saving legend image: ", e);
197: }
198: int pos = dir.lastIndexOf('/');
199: String access = "./" + dir.substring(pos + 1, dir.length())
200: + "/" + file;
201: this .getRequest().setAttribute("DYNLEGENDIMAGE", access);
202:
203: }
204:
205: private GetLegendGraphic getLegendRequestParameter()
206: throws InconsistentRequestException {
207:
208: HashMap<String, String> legend = toMap("VERSION=1.1.1&REQUEST=GetLegendGraphic&FORMAT=image/jpeg&WIDTH=50&HEIGHT=50&"
209: + "EXCEPTIONS=application/vnd.ogc.se_inimage&LAYER=europe:major_rivers&STYLE=default&"
210: + "SLD=file:///styles.xml");
211: legend.put("ID", "1");
212: return GetLegendGraphic.create(legend);
213:
214: }
215:
216: /**
217: * creates legend
218: */
219: private HashMap setLegend(GetLegendGraphic glr, HashMap[] model)
220: throws MalformedURLException, IOException {
221:
222: ArrayList<String> list1 = new ArrayList<String>();
223: ArrayList<BufferedImage> list2 = new ArrayList<BufferedImage>();
224:
225: StringTokenizer st = null;
226: String format = glr.getFormat();
227: if (format.equals("image/jpg"))
228: format = "image/jpeg";
229: String legendURL = "";
230: int lgHeight = 0;
231: for (int i = 0; i < model.length; i++) {
232:
233: String style = (String) model[i].get("STYLE");
234: if (style != null) {
235: st = new StringTokenizer(style, ",");
236: style = st.nextToken();
237: } else
238: style = "default";
239: st = new StringTokenizer((String) model[i].get("LAYERS"),
240: ",");
241:
242: while (st.hasMoreTokens()) {
243: String layer = st.nextToken();
244: legendURL = setLegendURL(layer, style, format, glr,
245: model[0]);
246: lgHeight = lgHeight + 30;
247: BufferedImage legendGraphic = ImageUtils
248: .loadImage(new URL(legendURL));
249: list1.add(layer);
250: list2.add(legendGraphic);
251: }
252: }
253:
254: String[] layers = list1.toArray(new String[list1.size()]);
255: BufferedImage[] legs = list2.toArray(new BufferedImage[list2
256: .size()]);
257: HashMap<String, Object> map = new HashMap<String, Object>();
258: map.put("NAMES", layers);
259: map.put("IMAGES", legs);
260: return map;
261: }
262:
263: private String setLegendURL(String layer, String style,
264: String format, GetLegendGraphic glr, HashMap model) {
265:
266: StringBuffer sb = new StringBuffer(500);
267: sb.append(model.get("URL")).append('?');
268: sb.append("&VERSION=").append(glr.getVersion());
269: sb.append("&REQUEST=GetLegendGraphic");
270: sb.append("&FORMAT=").append(format);
271: sb.append("&WIDTH=15");
272: sb
273: .append("&HEIGHT=15&EXCEPTIONS=application/vnd.ogc.se_inimage");
274: sb.append("&LAYER=").append(layer);
275: sb.append("&STYLE=").append(style);
276:
277: return sb.toString();
278: }
279:
280: }
|