001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/graphics/legend/LegendFactory.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.graphics.legend;
045:
046: import java.awt.image.BufferedImage;
047: import java.util.ArrayList;
048: import java.util.List;
049:
050: import org.deegree.framework.log.ILogger;
051: import org.deegree.framework.log.LoggerFactory;
052: import org.deegree.graphics.sld.AbstractStyle;
053: import org.deegree.graphics.sld.FeatureTypeStyle;
054: import org.deegree.graphics.sld.Rule;
055: import org.deegree.graphics.sld.StyledLayerDescriptor;
056: import org.deegree.graphics.sld.UserStyle;
057: import org.deegree.model.filterencoding.ComplexFilter;
058: import org.deegree.model.filterencoding.Filter;
059: import org.deegree.model.filterencoding.Literal;
060: import org.deegree.model.filterencoding.LogicalOperation;
061: import org.deegree.model.filterencoding.Operation;
062: import org.deegree.model.filterencoding.OperationDefines;
063: import org.deegree.model.filterencoding.PropertyIsCOMPOperation;
064: import org.deegree.model.filterencoding.PropertyIsLikeOperation;
065: import org.deegree.model.filterencoding.PropertyName;
066: import org.deegree.model.filterencoding.SpatialOperation;
067:
068: /**
069: * factory class for creating legend elements/images to be used with WMS GetLegendGraphic request
070: *
071: * @version $Revision: 9340 $
072: * @author $author$
073: */
074: public class LegendFactory {
075:
076: private static final ILogger LOG = LoggerFactory
077: .getLogger(LegendFactory.class);
078:
079: private String label = "";
080:
081: private String legendtitle = "";
082:
083: /**
084: * creates a <tt>LegendElement</tt> using the passed <tt>BufferedImage</tt>
085: *
086: * @return <tt>LegendElement</tt>
087: */
088: public LegendElement createLegendElement(BufferedImage legendImage) {
089: return new LegendElement(legendImage);
090: }
091:
092: /**
093: * creates a <tt>LegendElement</tt> from a SLD <tt>Style</tt>. Depending on the
094: * <tt>Style</tt> the returned <tt>LegendElement</tt> may is a
095: * <tt>LegendElementCollection</tt>.
096: *
097: * @return <tt>LegendElement</tt>
098: */
099: public LegendElement createLegendElement(AbstractStyle style,
100: int width, int height, String title) throws LegendException {
101:
102: setLegendTitle(title);
103:
104: if (style instanceof UserStyle) {
105:
106: LegendElement le = null;
107:
108: FeatureTypeStyle[] fts = ((UserStyle) style)
109: .getFeatureTypeStyles();
110: LegendElementCollection lec = new LegendElementCollection();
111:
112: for (int a = 0; a < fts.length; a++) {
113: // legendtitle
114: if (title != null && title.length() > 0) {
115: if (((UserStyle) style).getTitle() != null) {
116: setLegendTitle(title);
117: } else {
118: setLegendTitle(title);
119: }
120: } else {
121: setLegendTitle(fts[a].getName());
122: }
123: Rule[] rules = fts[a].getRules();
124:
125: for (int b = 0; b < rules.length; b++) {
126:
127: if (rules[b].getFilter() != null) {
128: Filter f = rules[b].getFilter();
129: String category = rules[b].getTitle();
130: if (category == null) {
131: category = rules[b].getName();
132: }
133: if (category == null) {
134: category = getPropertyNameFromFilter(f);
135: }
136: le = new LegendElement(new Rule[] { rules[b] },
137: category, 0, 4, true, width, height);
138: lec.addLegendElement(le);
139: } else {
140: String category = ((UserStyle) style)
141: .getTitle();
142: if (category == null) {
143: category = ((UserStyle) style).getName();
144: }
145: if (category == null) {
146: category = title;
147: }
148: category = "";
149: le = new LegendElement(rules, category, 0, 4,
150: true, width, height);
151: }
152: }
153: }
154:
155: if (lec.getSize() >= 1) {
156: lec.setTitle(getLegendTitle());
157: return lec;
158: }
159: return le;
160: }
161: throw new LegendException(
162: "LegendFactory: Error in creating the LegendElement:\n"
163: + "Given style is not a valid UserStyle.");
164: }
165:
166: /**
167: * creates an empty <tt>LegendElementCollection</tt>
168: *
169: * @return <tt>LegendElementCollection</tt>
170: */
171: public LegendElementCollection createLegendElementCollection() {
172: return new LegendElementCollection();
173: }
174:
175: /**
176: * creates a <tt>LegendElementCollection</tt> and fills it with the passed
177: * <tt>LegendElement</tt>s.
178: *
179: * @return <tt>LegendElementCollection</tt>
180: */
181: public LegendElementCollection createLegendElementCollection(
182: LegendElement[] legendElements) {
183: LegendElementCollection lec = new LegendElementCollection();
184:
185: for (int i = 0; i < legendElements.length; i++) {
186: lec.addLegendElement(legendElements[i]);
187: }
188: return lec;
189: }
190:
191: /**
192: *
193: * @param sld
194: * @param width
195: * @param height
196: * @return
197: * @throws LegendException
198: */
199: public BufferedImage[] createAllThumbnails(
200: StyledLayerDescriptor sld, int width, int height,
201: String mime) throws LegendException {
202:
203: List<AbstractStyle> list = new ArrayList<AbstractStyle>();
204:
205: org.deegree.graphics.sld.AbstractLayer[] nl = sld
206: .getNamedLayers();
207: for (int i = 0; i < nl.length; i++) {
208: AbstractStyle[] styles = nl[i].getStyles();
209: for (int j = 0; j < styles.length; j++) {
210: if (styles[j] instanceof UserStyle) {
211: list.add(styles[j]);
212: }
213: }
214: }
215:
216: nl = sld.getUserLayers();
217: for (int i = 0; i < nl.length; i++) {
218: AbstractStyle[] styles = nl[i].getStyles();
219: for (int j = 0; j < styles.length; j++) {
220: if (styles[j] instanceof UserStyle) {
221: list.add(styles[j]);
222: }
223: }
224: }
225:
226: LegendElement le = null;
227: BufferedImage bi_temp = null; // just temporary
228: BufferedImage[] buffi = new BufferedImage[list.size()]; // @return
229:
230: for (int i = 0; i < list.size(); i++) {
231: AbstractStyle style = list.get(i);
232: String name = style.getName();
233: name = name.replace(':', '_');
234: LOG.logInfo("creating: " + name);
235: le = createLegendElement(style, width, height, "");
236: bi_temp = le.exportAsImage(mime);
237: buffi[i] = bi_temp;
238: }
239:
240: return buffi;
241: }
242:
243: /**
244: * gets the property-names for creating the legend text
245: */
246: private String getPropertyNameFromFilter(Filter filter)
247: throws LegendException {
248: ComplexFilter cf = (ComplexFilter) filter;
249:
250: LOG.logDebug("Name der Operation: "
251: + cf.getOperation().getOperatorName() + "\n"
252: + cf.toXML());
253: Operation operation = cf.getOperation();
254: String ret = getPropertyNameFromOperation(operation);
255: return ret;
256:
257: }
258:
259: /**
260: *
261: * @param operation
262: * @return
263: * @throws LegendException
264: */
265: private String getPropertyNameFromOperation(Operation operation)
266: throws LegendException {
267:
268: String legendlabel = "";
269:
270: // determines the operation
271: // IS COM
272: if (operation instanceof PropertyIsCOMPOperation) {
273: PropertyIsCOMPOperation pCOMPo = (PropertyIsCOMPOperation) operation;
274: // gets the PropertyName of the operation for creating a legendtitle
275: if (pCOMPo.getFirstExpression() instanceof PropertyName) {
276: PropertyName propertyname = (PropertyName) pCOMPo
277: .getFirstExpression();
278: // setLegendTitleFilterProperty(propertyname.getValue());
279: legendlabel += propertyname.getValue();
280: } else {
281: throw new LegendException(
282: "LegendElement_Impl: An error occured "
283: + "during the parsing of the Filter in the SLD."
284: + "First Operation Expression is not of type Literal");
285: }
286: legendlabel += getOperationString(pCOMPo.getOperatorId());
287: // gets the Literal of the operation
288: if (pCOMPo.getSecondExpression() instanceof Literal) {
289: Literal literal = (Literal) pCOMPo
290: .getSecondExpression();
291: legendlabel += literal.getValue();
292: } else {
293: throw new LegendException(
294: "LegendElement_Impl: An error occured "
295: + "during the parsing of the Filter in the SLD."
296: + "Second Operation Expression is not of type Literal");
297: }
298: // LOGICAL
299: } else if (operation instanceof LogicalOperation) {
300: LogicalOperation logOp = (LogicalOperation) operation;
301: String operatorstring = getOperationString(logOp
302: .getOperatorId());
303:
304: // Operator-ID: AND = 200, OR = 201, NOT = 202
305: if (logOp.getOperatorId() == OperationDefines.AND) {
306: List<Operation> andlist = logOp.getArguments();
307: String andstring = "";
308: for (int i = 0; i < andlist.size(); i++) {
309: andstring += getPropertyNameFromOperation(andlist
310: .get(i));
311: if (i < andlist.size() - 1) {
312: andstring += operatorstring;
313: }
314: }
315: legendlabel = andstring;
316: } else if (logOp.getOperatorId() == OperationDefines.OR) {
317: List<Operation> orlist = logOp.getArguments();
318: String orstring = "";
319: for (int i = 0; i < orlist.size(); i++) {
320: orstring += getPropertyNameFromOperation(orlist
321: .get(i));
322: if (i < orlist.size() - 1) {
323: orstring += operatorstring;
324: }
325: }
326: legendlabel = orstring;
327: } else if (logOp.getOperatorId() == OperationDefines.NOT) {
328: List<Operation> notlist = logOp.getArguments();
329: String notstring = getPropertyNameFromOperation(notlist
330: .get(0));
331: // not is followed by brackets: not (ID = 1 and ID = 2)
332: legendlabel = operatorstring + "(" + notstring + ")";
333: }
334:
335: // SPATIAL
336: } else if (operation instanceof SpatialOperation) {
337:
338: SpatialOperation spatop = (SpatialOperation) operation;
339:
340: legendlabel = "spatial operation" + spatop;
341: // PROPERTY IS LIKE
342: } else if (operation instanceof PropertyIsLikeOperation) {
343:
344: PropertyIsLikeOperation prilop = (PropertyIsLikeOperation) operation;
345:
346: legendlabel = prilop.getPropertyName().getValue()
347: + getOperationString(prilop.getOperatorId())
348: + prilop.getLiteral().getValue();
349: // LOGICAL
350: } else {
351: LOG.logWarning(operation.toString());
352: // TODO implement other filter-operations and ELSE!
353: throw new LegendException("Filter-Operation <"
354: + operation.getOperatorName()
355: + "> is no PropertyIsCOMPOperation.");
356: }
357:
358: return legendlabel;
359:
360: }
361:
362: /**
363: *
364: * @param operationID
365: * @return
366: */
367: private String getOperationString(int operationID) {
368: String operationString = "";
369:
370: switch (operationID) {
371: case OperationDefines.PROPERTYISEQUALTO:
372: operationString = " = ";
373: break;
374: case OperationDefines.PROPERTYISLESSTHAN:
375: operationString = " < ";
376: break;
377: case OperationDefines.PROPERTYISGREATERTHAN:
378: operationString = " > ";
379: break;
380: case OperationDefines.PROPERTYISLESSTHANOREQUALTO:
381: operationString = " <= ";
382: break;
383: case OperationDefines.PROPERTYISGREATERTHANOREQUALTO:
384: operationString = " >= ";
385: break;
386: case OperationDefines.PROPERTYISLIKE:
387: operationString = " is like ";
388: break;
389: case OperationDefines.PROPERTYISNULL:
390: operationString = " is NULL ";
391: break;
392: case OperationDefines.PROPERTYISBETWEEN:
393: operationString = " is between ";
394: break;
395: case OperationDefines.AND:
396: operationString = " and ";
397: break;
398: case OperationDefines.OR:
399: operationString = " or ";
400: break;
401: case OperationDefines.NOT:
402: operationString = " not ";
403: break;
404: }
405:
406: return operationString;
407: }
408:
409: /**
410: * sets the label of the <tt>LegendElement</tt>
411: *
412: * @param label
413: * label of the <tt>LegendElement</tt>
414: *
415: */
416: public void setLabel(String label) {
417: this .label = label;
418: }
419:
420: /**
421: * returns the label set to <tt>LegendElement</tt>. If no label is set, the method returns
422: * <tt>null</tt>
423: *
424: * @return label of the <tt>LegendElement</tt> or <tt>null</tt>
425: *
426: */
427: public String getLabel() {
428: return this .label;
429: }
430:
431: /**
432: * @return
433: */
434: protected String getLegendTitle() {
435: return this .legendtitle;
436: }
437:
438: /**
439: * @param string
440: */
441: private void setLegendTitle(String string) {
442: this.legendtitle = string;
443: }
444:
445: }
|