001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/graphics/sld/StyleUtils.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 java.util.ArrayList;
039 import java.util.Iterator;
040 import java.util.List;
041 import java.util.Map;
042
043 import org.deegree.datatypes.QualifiedName;
044 import org.deegree.framework.util.StringTools;
045 import org.deegree.io.datastore.PropertyPathResolvingException;
046 import org.deegree.model.filterencoding.Expression;
047 import org.deegree.model.filterencoding.Filter;
048 import org.deegree.model.filterencoding.FilterTools;
049 import org.deegree.ogcbase.PropertyPath;
050 import org.deegree.ogcbase.PropertyPathFactory;
051
052 /**
053 * Collects all property names used by a list of styles. E.g. this can be used to optimze GetFeature requests from a WMS
054 * against a WFS.
055 *
056 * @version $Revision: 32310 $
057 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
058 * @author last edited by: $Author: apoth $
059 *
060 * @version 1.0. $Revision: 32310 $, $Date: 2011-10-26 15:34:57 +0200 (Mi, 26 Okt 2011) $
061 *
062 * @since 2.0
063 */
064 public class StyleUtils {
065
066 /**
067 * @return a list of all
068 *
069 * @param featureType
070 * @param styles
071 * @param scaleDen
072 * @throws PropertyPathResolvingException
073 */
074 public static List<PropertyPath> extractRequiredProperties( QualifiedName featureType, List<UserStyle> styles,
075 double scaleDen )
076 throws PropertyPathResolvingException {
077 List<PropertyPath> pp = new ArrayList<PropertyPath>();
078
079 for ( int i = 0; i < styles.size(); i++ ) {
080 FeatureTypeStyle[] fts = styles.get( i ).getFeatureTypeStyles();
081 for ( int j = 0; j < fts.length; j++ ) {
082 Rule[] rules = fts[j].getRules();
083 for ( int k = 0; k < rules.length; k++ ) {
084 // double minScale = rules[k].getMinScaleDenominator();
085 // double maxScale = rules[k].getMaxScaleDenominator();
086 //if ( minScale <= scaleDen && maxScale > scaleDen ) {
087 Filter filter = rules[k].getFilter();
088 List<PropertyPath> list = FilterTools.extractPropertyPaths( filter );
089 pp.addAll( list );
090 Symbolizer[] sym = rules[k].getSymbolizers();
091 for ( int d = 0; d < sym.length; d++ ) {
092 if ( sym[d] instanceof PointSymbolizer ) {
093 pp = extractPPFromPointSymbolizer( featureType, (PointSymbolizer) sym[d], pp );
094 } else if ( sym[d] instanceof LineSymbolizer ) {
095 pp = extractPPFromLineSymbolizer( (LineSymbolizer) sym[d], pp );
096 } else if ( sym[d] instanceof PolygonSymbolizer ) {
097 pp = extractPPFromPolygonSymbolizer( (PolygonSymbolizer) sym[d], pp );
098 } else if ( sym[d] instanceof TextSymbolizer ) {
099 pp = extractPPFromTextSymbolizer( (TextSymbolizer) sym[d], pp );
100 }
101 }
102 //}
103 }
104 }
105 }
106
107 List<PropertyPath> tmp = new ArrayList<PropertyPath>( pp.size() );
108 for ( int i = 0; i < pp.size(); i++ ) {
109 if ( !tmp.contains( pp.get( i ) ) ) {
110 tmp.add( pp.get( i ) );
111 }
112 }
113
114 return tmp;
115 }
116
117 private static List<PropertyPath> extractPPFromTextSymbolizer( TextSymbolizer symbolizer, List<PropertyPath> pp )
118 throws PropertyPathResolvingException {
119
120 ParameterValueType[] bbox = symbolizer.getBoundingBox();
121 if ( bbox != null ) {
122 pp = extractPPFromParamValueType( bbox[0], pp );
123 pp = extractPPFromParamValueType( bbox[1], pp );
124 pp = extractPPFromParamValueType( bbox[2], pp );
125 pp = extractPPFromParamValueType( bbox[3], pp );
126 }
127
128 Map<?, ?> css = null;
129 if ( symbolizer.getFill() != null ) {
130 css = symbolizer.getFill().getCssParameters();
131 pp = extractPPFromCssParameter( css, pp );
132 }
133 if ( symbolizer.getFont() != null ) {
134 css = symbolizer.getFont().getCssParameters();
135 pp = extractPPFromCssParameter( css, pp );
136 }
137 if ( symbolizer.getGeometry() != null ) {
138 pp.add( symbolizer.getGeometry().getPropertyPath() );
139 }
140 Halo halo = symbolizer.getHalo();
141 ParameterValueType pvt = null;
142 if ( halo != null ) {
143 pvt = halo.getRadius();
144 pp = extractPPFromParamValueType( pvt, pp );
145
146 if ( halo.getFill() != null ) {
147 css = halo.getFill().getCssParameters();
148 pp = extractPPFromCssParameter( css, pp );
149 }
150 if ( halo.getStroke() != null ) {
151 css = halo.getStroke().getCssParameters();
152 pp = extractPPFromCssParameter( css, pp );
153 }
154 }
155 pvt = symbolizer.getLabel();
156 pp = extractPPFromParamValueType( pvt, pp );
157
158 // collect property names from line placement
159 LinePlacement lp = symbolizer.getLabelPlacement().getLinePlacement();
160 if ( lp != null ) {
161 pvt = lp.getGap();
162 pp = extractPPFromParamValueType( pvt, pp );
163 pvt = lp.getLineWidth();
164 pp = extractPPFromParamValueType( pvt, pp );
165 pvt = lp.getPerpendicularOffset();
166 pp = extractPPFromParamValueType( pvt, pp );
167 }
168
169 // collect property names from line placement
170 PointPlacement ppl = symbolizer.getLabelPlacement().getPointPlacement();
171 if ( ppl != null ) {
172 pvt = ppl.getRotation();
173 pp = extractPPFromParamValueType( pvt, pp );
174 ParameterValueType[] pvta = ppl.getAnchorPoint();
175 if ( pvta != null ) {
176 for ( int i = 0; i < pvta.length; i++ ) {
177 pp = extractPPFromParamValueType( pvta[i], pp );
178 }
179 }
180 pvta = ppl.getDisplacement();
181 if ( pvta != null ) {
182 for ( int i = 0; i < pvta.length; i++ ) {
183 pp = extractPPFromParamValueType( pvta[i], pp );
184 }
185 }
186 }
187
188 return pp;
189 }
190
191 private static List<PropertyPath> extractPPFromPolygonSymbolizer( PolygonSymbolizer symbolizer,
192 List<PropertyPath> pp )
193 throws PropertyPathResolvingException {
194
195 Map<?, ?> css = null;
196 if ( symbolizer != null ) {
197 if ( symbolizer.getFill() != null ) {
198 css = symbolizer.getFill().getCssParameters();
199 pp = extractPPFromCssParameter( css, pp );
200 }
201
202 if ( symbolizer.getGeometry() != null ) {
203 pp.add( symbolizer.getGeometry().getPropertyPath() );
204 }
205
206 if ( symbolizer.getStroke() != null ) {
207 css = symbolizer.getStroke().getCssParameters();
208 pp = extractPPFromCssParameter( css, pp );
209 }
210 }
211
212 return pp;
213 }
214
215 private static List<PropertyPath> extractPPFromLineSymbolizer( LineSymbolizer symbolizer, List<PropertyPath> pp )
216 throws PropertyPathResolvingException {
217
218 if ( symbolizer.getGeometry() != null ) {
219 pp.add( symbolizer.getGeometry().getPropertyPath() );
220 }
221
222 Map<?, ?> css = symbolizer.getStroke().getCssParameters();
223 pp = extractPPFromCssParameter( css, pp );
224
225 return pp;
226 }
227
228 private static List<PropertyPath> extractPPFromPointSymbolizer( QualifiedName featureType,
229 PointSymbolizer symbolizer, List<PropertyPath> pp )
230 throws PropertyPathResolvingException {
231
232 Graphic graphic = symbolizer.getGraphic();
233 if ( graphic != null ) {
234 if ( graphic.getOpacity() != null ) {
235 pp = extractPPFromParamValueType( graphic.getOpacity(), pp );
236 }
237
238 if ( graphic.getRotation() != null ) {
239 pp = extractPPFromParamValueType( graphic.getRotation(), pp );
240 }
241
242 if ( graphic.getDisplacement() != null ) {
243 pp = extractPPFromParamValueType( graphic.getDisplacement()[0], pp );
244 pp = extractPPFromParamValueType( graphic.getDisplacement()[1], pp );
245 }
246
247 if ( graphic.getSize() != null ) {
248 pp = extractPPFromParamValueType( graphic.getSize(), pp );
249 }
250
251 if ( symbolizer.getGeometry() != null ) {
252 pp.add( symbolizer.getGeometry().getPropertyPath() );
253 }
254
255 if ( graphic.getMarksAndExtGraphics().length > 0 ) {
256 for ( Object obj : graphic.getMarksAndExtGraphics() ) {
257 if ( obj instanceof ExternalGraphic ) {
258 String file = ( (ExternalGraphic) obj ).getOnlineResource().toExternalForm();
259 String[] tags = StringTools.extractStrings( file, "$", "$" );
260 if ( tags != null ) {
261 for ( int i = 0; i < tags.length; i++ ) {
262 String tag = tags[i].substring( 1, tags[i].length() - 1 );
263 QualifiedName pn = new QualifiedName( tag, featureType.getNamespace() );
264 pp.add( PropertyPathFactory.createPropertyPath( pn ) );
265 }
266 }
267 }
268 }
269 }
270
271 }
272
273 return pp;
274 }
275
276 private static List<PropertyPath> extractPPFromCssParameter( Map<?, ?> css, List<PropertyPath> pp )
277 throws PropertyPathResolvingException {
278 if ( css != null ) {
279 Iterator<?> iter = css.values().iterator();
280 while ( iter.hasNext() ) {
281 ParameterValueType pvt = ( (CssParameter) iter.next() ).getValue();
282 pp = extractPPFromParamValueType( pvt, pp );
283 }
284 }
285 return pp;
286 }
287
288 private static List<PropertyPath> extractPPFromParamValueType( ParameterValueType pvt, List<PropertyPath> pp )
289 throws PropertyPathResolvingException {
290 if ( pvt != null ) {
291 Object[] components = pvt.getComponents();
292 for ( int i = 0; i < components.length; i++ ) {
293 if ( components[i] instanceof Expression ) {
294 pp = FilterTools.extractPropertyPaths( (Expression) components[i], pp );
295 }
296 }
297 }
298 return pp;
299 }
300
301 }