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