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 }