001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.4_testing/src/org/deegree/graphics/sld/Rule.java $
002 /*----------------------------------------------------------------------------
003 This file is part of deegree, http://deegree.org/
004 Copyright (C) 2001-2009 by:
005 Department of Geography, University of Bonn
006 and
007 lat/lon GmbH
008
009 This library is free software; you can redistribute it and/or modify it under
010 the terms of the GNU Lesser General Public License as published by the Free
011 Software Foundation; either version 2.1 of the License, or (at your option)
012 any later version.
013 This library is distributed in the hope that it will be useful, but WITHOUT
014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
016 details.
017 You should have received a copy of the GNU Lesser General Public License
018 along with this library; if not, write to the Free Software Foundation, Inc.,
019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020
021 Contact information:
022
023 lat/lon GmbH
024 Aennchenstr. 19, 53177 Bonn
025 Germany
026 http://lat-lon.de/
027
028 Department of Geography, University of Bonn
029 Prof. Dr. Klaus Greve
030 Postfach 1147, 53001 Bonn
031 Germany
032 http://www.geographie.uni-bonn.de/deegree/
033
034 e-mail: info@deegree.org
035 ----------------------------------------------------------------------------*/
036 package org.deegree.graphics.sld;
037
038 import static org.deegree.framework.xml.XMLTools.escape;
039
040 import java.util.ArrayList;
041 import java.util.List;
042
043 import org.deegree.framework.xml.Marshallable;
044 import org.deegree.model.filterencoding.Filter;
045
046 /**
047 * A rule is used to attach a condition to and group the individual symbolizers used for rendering.
048 * The Title and Abstract describe the rule and may be used to generate a legend, as may the
049 * LegendGraphic. The Filter, ElseFilter, MinScale, and MaxScale elements allow the selection of
050 * features and rendering scales for a rule. The scale selection works as follows. When a map is to
051 * be rendered, the scale denominator is computed and all rules in all UserStyles that have a scale
052 * outside of the request range are dropped. (This also includes Rules that have an ElseFilter.) An
053 * ElseFilter is simply an ELSE condition to the conditions (Filters) of all other rules in the same
054 * UserStyle. The exact meaning of the ElseFilter is determined after Rules have been eliminated for
055 * not fitting the rendering scale. This definition of the behaviour of ElseFilters may seem a
056 * little strange, but it allows for scale- dependent and scale-independent ELSE conditions. For the
057 * Filter, only SqlExpression is available for specification, but this is a hack and should be
058 * replaced with Filter as defined in WFS. A missing Filter element means "always true". If a set of
059 * Rules has no ElseFilters, then some features may not be rendered (which is presumably the desired
060 * behavior). The Scales are actually scale denominators (as double floats), so "10e6" would be
061 * interpreted as 1:10M. A missing MinScale means there is no lower bound to the scale- denominator
062 * range (lim[x->0+](x)), and a missing MaxScale means there is no upper bound (infinity). 0.28mm
063 *
064 *
065 * @author <a href="mailto:k.lupp@web.de">Katharina Lupp </a>
066 * @author last edited by: $Author: mschneider $
067 * @version $Revision: 18195 $ $Date: 2009-06-18 17:55:39 +0200 (Do, 18. Jun 2009) $
068 */
069
070 public class Rule implements Marshallable {
071
072 private List<Symbolizer> symbolizers = null;
073
074 /**
075 *
076 */
077 private Filter filter = null;
078
079 /**
080 *
081 */
082 private LegendGraphic legendGraphic = null;
083
084 private String abstract_ = null;
085
086 private String name = null;
087
088 private String title = null;
089
090 private boolean elseFilter = false;
091
092 private double maxScaleDenominator = 0;
093
094 private double minScaleDenominator = 0;
095
096 /**
097 * default constructor
098 */
099 Rule() {
100 symbolizers = new ArrayList<Symbolizer>();
101 }
102
103 /**
104 * constructor initializing the class with the Rule
105 * @param symbolizers
106 * @param name
107 * @param title
108 * @param abstract_
109 * @param legendGraphic
110 * @param filter
111 * @param elseFilter
112 * @param minScaleDenominator
113 * @param maxScaleDenominator
114 */
115 Rule( Symbolizer[] symbolizers, String name, String title, String abstract_, LegendGraphic legendGraphic,
116 Filter filter, boolean elseFilter, double minScaleDenominator, double maxScaleDenominator ) {
117 this();
118 setSymbolizers( symbolizers );
119 setName( name );
120 setTitle( title );
121 setAbstract( abstract_ );
122 setLegendGraphic( legendGraphic );
123 setFilter( filter );
124 setElseFilter( elseFilter );
125 setMinScaleDenominator( minScaleDenominator );
126 setMaxScaleDenominator( maxScaleDenominator );
127 }
128
129 /**
130 * returns the name of the rule. this for machine interpreting.
131 *
132 * @return the name of the rule
133 *
134 */
135 public String getName() {
136 return name;
137 }
138
139 /**
140 * sets the name of the rule. this for machine interpreting.
141 *
142 * @param name
143 * the name of the rule
144 *
145 */
146 public void setName( String name ) {
147 this.name = name;
148 }
149
150 /**
151 * returns the human readable title of the rule
152 *
153 * @return the title of the rule
154 *
155 */
156 public String getTitle() {
157 return title;
158 }
159
160 /**
161 * sets the human readable title of the rule
162 *
163 * @param title
164 * the title of the rule
165 *
166 */
167 public void setTitle( String title ) {
168 this.title = title;
169 }
170
171 /**
172 * returns the human readable abstract of the rule
173 *
174 * @return the abstract of the rule
175 */
176 public String getAbstract() {
177 return abstract_;
178 }
179
180 /**
181 * sets the human readable abstract of the rule
182 *
183 * @param abstract_
184 * the abstract of the rule
185 */
186 public void setAbstract( String abstract_ ) {
187 this.abstract_ = abstract_;
188 }
189
190 /**
191 * The LegendGraphic element gives an optional explicit Graphic symbol to be displayed in a
192 * legend for this rule.
193 *
194 * @return the legendGraphic of the rule
195 *
196 */
197 public LegendGraphic getLegendGraphic() {
198 return legendGraphic;
199 }
200
201 /**
202 * sets the LegendGraphic element
203 *
204 * @param legendGraphic
205 * the legendGraphic of the rule
206 *
207 */
208 public void setLegendGraphic( LegendGraphic legendGraphic ) {
209 this.legendGraphic = legendGraphic;
210 }
211
212 /**
213 * The Filter element has a relatively straightforward meaning. The syntax of the Filter element
214 * is defined in the WFS specification and allows both attribute (property) and spatial
215 * filtering.
216 *
217 * @return the filter element
218 *
219 */
220 public Filter getFilter() {
221 return filter;
222 }
223
224 /**
225 * sets the <Filter>
226 *
227 * @param filter
228 * the filter element
229 *
230 */
231 public void setFilter( Filter filter ) {
232 this.filter = filter;
233 }
234
235 /**
236 * The ElseFilter allows rules to be specified that are activated for features are not selected
237 * by any other rule in a feature-type style.
238 *
239 * @return true if the rule has an elseFilter
240 */
241 public boolean hasElseFilter() {
242 return elseFilter;
243 }
244
245 /**
246 * sets the <ElseFilter>
247 *
248 * @param elseFilter
249 * an elseFilter
250 *
251 */
252 public void setElseFilter( boolean elseFilter ) {
253 this.elseFilter = elseFilter;
254 }
255
256 /**
257 * The MinScaleDenominator and MaxScaleDenominator elements of a Rule define the range of
258 * map-rendering scales for which the rule should be applied. The MinScaleDenominator and
259 * MaxScaleDenominator elements, as their names suggest, are simply the minimum and maximum
260 * ranges of scale (denominators) of maps for which a rule should apply.
261 *
262 * @return the MinScaleDenominator for the rule
263 *
264 */
265 public double getMinScaleDenominator() {
266 return minScaleDenominator;
267 }
268
269 /**
270 * sets the <MinScaleDenominator>
271 *
272 * @param minScaleDenominator
273 * the MinScaleDenominator for the rule
274 *
275 */
276 public void setMinScaleDenominator( double minScaleDenominator ) {
277 this.minScaleDenominator = minScaleDenominator;
278 }
279
280 /**
281 * The MinScaleDenominator and MaxScaleDenominator elements of a Rule define the range of
282 * map-rendering scales for which the rule should be applied. The MinScaleDenominator and
283 * MaxScaleDenominator elements, as their names suggest, are simply the minimum and maximum
284 * ranges of scale (denominators) of maps for which a rule should apply.
285 *
286 * @return the MaxScaleDenominator for the rule
287 *
288 */
289 public double getMaxScaleDenominator() {
290 return maxScaleDenominator;
291 }
292
293 /**
294 * sets the <MaxScaleDenominator>
295 *
296 * @param maxScaleDenominator
297 * the MaxScaleDenominator for the rule
298 *
299 */
300 public void setMaxScaleDenominator( double maxScaleDenominator ) {
301 this.maxScaleDenominator = maxScaleDenominator;
302 }
303
304 /**
305 * Embedded inside of Rules, which group conditions for styling features, are Symbolizers. A
306 * symbolizer describes how a feature is to appear on a map. The symbolizer describes not just
307 * the shape that should appear but also such graphical properties as color and opacity. A
308 * symbol is obtained by specifying one of a small number of different types of symbolizer and
309 * then supplying parameters to override its default behaviour. Currently, five types of
310 * symbolizers are defined.
311 * <p>
312 * </p>
313 * The Symbolizers will be returned in the sequece of their occurence with in the rule
314 * definition. Its the users function to determine what type of Symbolizer(s) are returned. This
315 * can be done for example by using the <tt>instanceof</tt> operator of Java.
316 *
317 * @return the Symbolizer for the rule
318 *
319 */
320 public Symbolizer[] getSymbolizers() {
321 return symbolizers.toArray( new Symbolizer[symbolizers.size()] );
322 }
323
324 /**
325 * sets the <Symbolizer>
326 *
327 * @param symbolizers
328 * symbolizers for the rule
329 */
330 public void setSymbolizers( Symbolizer[] symbolizers ) {
331 this.symbolizers.clear();
332
333 if ( symbolizers != null ) {
334 for ( int i = 0; i < symbolizers.length; i++ ) {
335 this.symbolizers.add( symbolizers[i] );
336 }
337 }
338 }
339
340 /**
341 * adds a <Symbolizer>
342 *
343 * @param symbolizer
344 * symbolizer to add
345 */
346 public void addSymbolizer( Symbolizer symbolizer ) {
347 symbolizers.add( symbolizer );
348 }
349
350 /**
351 * Removes a <Symbolizer>from a set of Symbolizers.
352 *
353 * @param symbolizer
354 * symbolizer to remove
355 */
356 public void removeSymbolizer( Symbolizer symbolizer ) {
357 if ( symbolizers.indexOf( symbolizer ) != -1 ) {
358 symbolizers.remove( symbolizers.indexOf( symbolizer ) );
359 }
360 }
361
362 /**
363 * exports the content of the Rule as XML formated String
364 *
365 * @return xml representation of the Rule
366 */
367 public String exportAsXML() {
368
369 StringBuffer sb = new StringBuffer( 1000 );
370 sb.append( "<Rule>" );
371 if ( name != null && !name.equals( "" ) ) {
372 sb.append( "<Name>" ).append( escape( name ) ).append( "</Name>" );
373 }
374 if ( title != null && !title.equals( "" ) ) {
375 sb.append( "<Title>" ).append( escape( title ) ).append( "</Title>" );
376 }
377 if ( abstract_ != null && !abstract_.equals( "" ) ) {
378 sb.append( "<Abstract>" ).append( escape( abstract_ ) ).append( "</Abstract>" );
379 }
380 if ( legendGraphic != null ) {
381 sb.append( "<LegendGraphic>" ).append( ( (Marshallable) legendGraphic ).exportAsXML() ).append(
382 "</LegendGraphic>" );
383 }
384 if ( filter != null ) {
385 sb.append( filter.toXML() );
386 }
387 if ( elseFilter ) {
388 sb.append( "<ElseFilter/>" );
389 }
390 sb.append( "<MinScaleDenominator>" ).append( minScaleDenominator );
391 sb.append( "</MinScaleDenominator>" );
392 sb.append( "<MaxScaleDenominator>" ).append( maxScaleDenominator );
393 sb.append( "</MaxScaleDenominator>" );
394 for ( int i = 0; i < symbolizers.size(); i++ ) {
395 sb.append( ( (Marshallable) symbolizers.get( i ) ).exportAsXML() );
396 }
397 sb.append( "</Rule>" );
398
399 return sb.toString();
400 }
401 }