/*---------------- FILE HEADER ------------------------------------------ This file is part of deegree. Copyright (C) 2001-2007 by: Department of Geography, University of Bonn http://www.giub.uni-bonn.de/deegree/ lat/lon GmbH http://www.lat-lon.de This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Contact: Andreas Poth lat/lon GmbH Aennchenstr. 19 53177 Bonn Germany E-Mail: poth@lat-lon.de Prof. Dr. Klaus Greve Department of Geography University of Bonn Meckenheimer Allee 166 53115 Bonn Germany E-Mail: greve@giub.uni-bonn.de ---------------------------------------------------------------------------*/ package org.deegree.igeo.style.classification; import static org.deegree.igeo.style.utils.SldCreatorUtils.getAsCssParameter; import static org.deegree.igeo.style.utils.SldCreatorUtils.getParameterValueType; import java.awt.Color; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.vecmath.Point2d; import org.deegree.framework.util.ColorUtils; import org.deegree.framework.util.Pair; import org.deegree.graphics.sld.CssParameter; import org.deegree.graphics.sld.ExternalGraphic; import org.deegree.graphics.sld.Fill; import org.deegree.graphics.sld.Font; import org.deegree.graphics.sld.Graphic; import org.deegree.graphics.sld.GraphicFill; import org.deegree.graphics.sld.Halo; import org.deegree.graphics.sld.LabelPlacement; import org.deegree.graphics.sld.LineSymbolizer; import org.deegree.graphics.sld.Mark; import org.deegree.graphics.sld.ParameterValueType; import org.deegree.graphics.sld.PointPlacement; import org.deegree.graphics.sld.PointSymbolizer; import org.deegree.graphics.sld.PolygonSymbolizer; import org.deegree.graphics.sld.Rule; import org.deegree.graphics.sld.Stroke; import org.deegree.graphics.sld.StyleFactory; import org.deegree.graphics.sld.TextSymbolizer; import org.deegree.igeo.style.model.FillPattern; import org.deegree.igeo.style.model.GraphicSymbol; import org.deegree.igeo.style.model.SldProperty; import org.deegree.igeo.style.model.SldValues; import org.deegree.igeo.style.model.Symbol; import org.deegree.igeo.style.model.WellKnownMark; import org.deegree.igeo.style.model.classification.ClassificationTableRow; import org.deegree.igeo.style.model.classification.Column.COLUMNTYPE; import org.deegree.igeo.style.model.classification.ValueRange; import org.deegree.model.filterencoding.Expression; import org.deegree.model.filterencoding.PropertyName; /** * <code>SldFromClassification</code> * * @author <a href="mailto:buesching@lat-lon.de">Lyn Buesching</a> * @author last edited by: $Author$ * * @version $Revision$, $Date$ * */ public class SldFromClassification<U extends Comparable<U>> { public final List<Rule> createPolygonClassificationRules( List<ClassificationTableRow<U>> classification, PropertyName propertyName, boolean isInPixel ) { List<Rule> rules = new ArrayList<Rule>(); for ( int i = 0; i < classification.size(); i++ ) { ClassificationTableRow<U> row = classification.get( i ); double v = ( 100d - row.getLineTransparency() ) / 100d; CssParameter width = getAsCssParameter( "stroke-width", isInPixel, row.getLineWidth() ); HashMap<String, Object> params = new HashMap<String, Object>(); params.put( "stroke-width", width ); Stroke stroke = new Stroke( params, null, null ); stroke.setOpacity( v ); stroke.setStroke( row.getLineColor() ); if ( row.getLineStyle() != null && !SldValues.isContinous( row.getLineStyle().getDashArray() ) ) { stroke.setDashArray( row.getLineStyle().getDashArray() ); } PolygonSymbolizer ps = StyleFactory.createPolygonSymbolizer( stroke, getFill( row ) ); Rule newRule = StyleFactory.createRule( ps ); ValueRange<U> vr = row.getValue(); newRule.setTitle( row.getLabel() ); newRule.setFilter( vr.getFilter( propertyName ) ); rules.add( newRule ); } return rules; } public final List<Rule> createPointClassificationRules( List<ClassificationTableRow<U>> classification, PropertyName propertyName, boolean isInPixel ) { List<Rule> rules = new ArrayList<Rule>(); for ( int i = 0; i < classification.size(); i++ ) { ClassificationTableRow<U> row = classification.get( i ); ExternalGraphic eg = null; Mark wkm = null; Symbol s = row.getSymbol(); if ( s instanceof GraphicSymbol ) { eg = StyleFactory.createExternalGraphic( ( (GraphicSymbol) s ).getUrl(), ( (GraphicSymbol) s ).getFormat(), ( (GraphicSymbol) s ).getName() ); } else if ( s instanceof WellKnownMark ) { wkm = StyleFactory.createMark( ( (WellKnownMark) s ).getSldName() ); wkm.setFill( getFill( row ) ); wkm.setStroke( StyleFactory.createStroke( row.getLineColor() ) ); } Graphic graphic = StyleFactory.createGraphic( eg, wkm, SldValues.getDefaultOpacity(), SldValues.getDefaultSize(), SldValues.getDefaultRotation() ); Object rotationValue = row.getValue( COLUMNTYPE.ROTATION ); if ( rotationValue instanceof PropertyName ) { graphic.setRotation( StyleFactory.createParameterValueType( new Expression[] { (PropertyName) rotationValue } ) ); } else if ( rotationValue instanceof Double ) { graphic.setRotation( (Double) rotationValue ); } if ( isInPixel ) { graphic.setSize( row.getSize() ); } else { graphic.setSize( getParameterValueType( row.getSize() ) ); } PointSymbolizer ps = StyleFactory.createPointSymbolizer(); ps.setGraphic( graphic ); Rule newRule = StyleFactory.createRule( ps ); ValueRange<U> vr = row.getValue(); newRule.setTitle( row.getLabel() ); newRule.setFilter( vr.getFilter( propertyName ) ); rules.add( newRule ); } return rules; } public final List<Rule> createLineClassificationRules( List<ClassificationTableRow<U>> classification, PropertyName propertyName, boolean isInPixel ) { List<Rule> rules = new ArrayList<Rule>(); for ( int i = 0; i < classification.size(); i++ ) { ClassificationTableRow<U> row = classification.get( i ); CssParameter width = getAsCssParameter( "stroke-width", isInPixel, row.getLineWidth() ); HashMap<String, Object> params = new HashMap<String, Object>(); params.put( "stroke-width", width ); Stroke stroke = new Stroke( params, null, null ); stroke.setStroke( row.getLineColor() ); stroke.setOpacity( SldValues.getOpacity( row.getLineTransparency() ) ); if ( row.getLineCap() != null ) { stroke.setLineCap( row.getLineCap().getTypeCode() ); } if ( row.getLineStyle() != null && !SldValues.isContinous( row.getLineStyle().getDashArray() ) ) { stroke.setDashArray( row.getLineStyle().getDashArray() ); } LineSymbolizer ls = StyleFactory.createLineSymbolizer( stroke ); Rule newRule = StyleFactory.createRule( ls ); ValueRange<U> vr = row.getValue(); newRule.setTitle( row.getLabel() ); newRule.setFilter( vr.getFilter( propertyName ) ); rules.add( newRule ); } return rules; } @SuppressWarnings("unchecked") public final List<Rule> createLabelClassificationRules( List<ClassificationTableRow<U>> classification, PropertyName propertyName, boolean isInPixel ) { List<Rule> rules = new ArrayList<Rule>(); for ( int i = 0; i < classification.size(); i++ ) { ClassificationTableRow<U> row = classification.get( i ); Map<String, CssParameter> fontParams = new HashMap<String, CssParameter>(); addParameter( fontParams, "font-family", row.getValue( COLUMNTYPE.FONTFAMILY ) ); addParameter( fontParams, "font-style", row.getValue( COLUMNTYPE.FONTSTYLE ) ); addParameter( fontParams, "font-weight", row.getValue( COLUMNTYPE.FONTWEIGHT ) ); addParameter( fontParams, "font-color", row.getValue( COLUMNTYPE.FONTCOLOR ) ); addParameter( fontParams, "font-size", row.getValue( COLUMNTYPE.FONTSIZE ), isInPixel ); Font font = new Font( (HashMap<String, CssParameter>) fontParams ); HashMap<String, Object> fillParams = new HashMap<String, Object>(); Object fontTrans = row.getValue( COLUMNTYPE.FONTTRANSPARENCY ); if ( fontTrans instanceof Integer ) { fontTrans = SldValues.getOpacity( (Integer) fontTrans ); } addParameterAsObject( fillParams, "fill-opacity", fontTrans ); addParameterAsObject( fillParams, "fill", row.getValue( COLUMNTYPE.FONTCOLOR ) ); Fill fill = new Fill( fillParams, null ); // placement ParameterValueType[] pvtAnchorPoint = null; Object anchorPointValue = row.getValue( COLUMNTYPE.ANCHORPOINT ); if ( anchorPointValue instanceof Pair<?, ?> && ( (Pair<?, ?>) anchorPointValue ).first instanceof PropertyName && ( (Pair<?, ?>) anchorPointValue ).second instanceof PropertyName ) { pvtAnchorPoint = new ParameterValueType[] { StyleFactory.createParameterValueType( new Expression[] { (PropertyName) ( (Pair<?, ?>) anchorPointValue ).first } ), StyleFactory.createParameterValueType( new Expression[] { (PropertyName) ( (Pair<?, ?>) anchorPointValue ).second } ) }; } else if ( anchorPointValue instanceof Point2d ) { ParameterValueType pvtAnchorX = new ParameterValueType( new Object[] { ( (Point2d) anchorPointValue ).x } ); ParameterValueType pvtAnchorY = new ParameterValueType( new Object[] { ( (Point2d) anchorPointValue ).y } ); pvtAnchorPoint = new ParameterValueType[] { pvtAnchorX, pvtAnchorY }; } ParameterValueType[] pvtDisplacementPoint = null; Object displacementPointValue = row.getValue( COLUMNTYPE.DISPLACEMENT ); if ( displacementPointValue instanceof Pair<?, ?> && ( (Pair<?, ?>) displacementPointValue ).first instanceof PropertyName && ( (Pair<?, ?>) displacementPointValue ).second instanceof PropertyName ) { Pair<PropertyName, PropertyName> pair = (Pair<PropertyName, PropertyName>) displacementPointValue; ParameterValueType pvtAnchorX; ParameterValueType pvtAnchorY; if ( !isInPixel ) { pvtAnchorX = getParameterValueType( pair.first ); pvtAnchorY = getParameterValueType( pair.second ); } else { pvtAnchorX = StyleFactory.createParameterValueType( new Expression[] { (PropertyName) pair.first } ); pvtAnchorY = StyleFactory.createParameterValueType( new Expression[] { (PropertyName) pair.second } ); } pvtDisplacementPoint = new ParameterValueType[] { pvtAnchorX, pvtAnchorY }; } else if ( displacementPointValue instanceof Point2d ) { ParameterValueType pvtAnchorX; ParameterValueType pvtAnchorY; if ( !isInPixel ) { pvtAnchorX = getParameterValueType( ( (Point2d) displacementPointValue ).x ); pvtAnchorY = getParameterValueType( ( (Point2d) displacementPointValue ).y ); } else { pvtAnchorX = new ParameterValueType( new Object[] { ( (Point2d) displacementPointValue ).x } ); pvtAnchorY = new ParameterValueType( new Object[] { ( (Point2d) displacementPointValue ).y } ); } pvtDisplacementPoint = new ParameterValueType[] { pvtAnchorX, pvtAnchorY }; } ParameterValueType rotation = null; Object rotationValue = row.getValue( COLUMNTYPE.ROTATION ); if ( rotationValue instanceof PropertyName ) { rotation = StyleFactory.createParameterValueType( new Expression[] { (PropertyName) rotationValue } ); } else if ( rotationValue instanceof Double ) { rotation = StyleFactory.createParameterValueType( (Double) rotationValue ); } PointPlacement pointPlacement = new PointPlacement( pvtAnchorPoint, pvtDisplacementPoint, rotation, false ); // pointPlacement.setAuto( isAutoPlacement ); LabelPlacement labelPlacement = StyleFactory.createLabelPlacement( pointPlacement ); // halo ParameterValueType haloRadius = null; Object radiusValue = row.getValue( COLUMNTYPE.HALORADIUS ); if ( radiusValue instanceof PropertyName ) { haloRadius = StyleFactory.createParameterValueType( new Expression[] { (PropertyName) radiusValue } ); } else if ( radiusValue instanceof Double ) { haloRadius = StyleFactory.createParameterValueType( (Double) radiusValue ); } // Map<String, CssParameter> haloFillParams = new HashMap<String, CssParameter>(); Map<String, Object> haloFillParams = new HashMap<String, Object>(); addParameterAsObject( haloFillParams, "fill", row.getValue( COLUMNTYPE.HALOCOLOR ) ); Halo halo = new Halo( haloRadius, new Fill( haloFillParams, null ), StyleFactory.createStroke() ); TextSymbolizer ts = StyleFactory.createTextSymbolizer( null, "", font, labelPlacement, halo, fill, 0.0, 9E99 ); Rule newRule = StyleFactory.createRule( ts ); ValueRange<U> vr = row.getValue(); newRule.setTitle( row.getLabel() ); newRule.setFilter( vr.getFilter( propertyName ) ); rules.add( newRule ); } return rules; } /** * @param fontParams * @param string * @param value * @param isInPixel */ private void addParameter( Map<String, CssParameter> params, String name, Object value, boolean isInPixel ) { if ( value != null ) { if ( !isInPixel && ( value instanceof Integer || value instanceof Double || value instanceof PropertyName ) ) { ParameterValueType pvt = null; if ( value instanceof Double ) { pvt = getParameterValueType( (Double) value, 1 ); } else if ( value instanceof Integer ) { pvt = getParameterValueType( ( (Integer) value ).toString(), 1 ); } else if ( value instanceof PropertyName ) { pvt = getParameterValueType( (PropertyName) value, 1 ); } if ( pvt != null ) params.put( name, new CssParameter( name, pvt ) ); } else { addParameter( params, name, value ); } } } private void addParameter( Map<String, CssParameter> params, String name, Object value ) { if ( value != null ) { if ( value instanceof PropertyName ) { params.put( name, getAsCssParameter( name, (PropertyName) value ) ); } else if ( value instanceof Integer ) { params.put( name, StyleFactory.createCssParameter( name, (Integer) value ) ); } else if ( value instanceof Double ) { params.put( name, StyleFactory.createCssParameter( name, (Double) value ) ); } else if ( value instanceof Color ) { params.put( name, StyleFactory.createCssParameter( name, ColorUtils.toHexCode( "#", (Color) value ) ) ); } else if ( value instanceof SldProperty ) { params.put( name, StyleFactory.createCssParameter( name, ( (SldProperty) value ).getSldName() ) ); } else if ( value instanceof String ) { params.put( name, StyleFactory.createCssParameter( name, (String) value ) ); } } } private void addParameterAsObject( Map<String, Object> params, String name, Object value ) { if ( value != null ) { if ( value instanceof PropertyName ) { params.put( name, getAsCssParameter( name, (PropertyName) value ) ); } else if ( value instanceof Integer ) { params.put( name, StyleFactory.createCssParameter( name, (Integer) value ) ); } else if ( value instanceof Double ) { params.put( name, StyleFactory.createCssParameter( name, (Double) value ) ); } else if ( value instanceof Color ) { params.put( name, StyleFactory.createCssParameter( name, ColorUtils.toHexCode( "#", (Color) value ) ) ); } else if ( value instanceof SldProperty ) { params.put( name, StyleFactory.createCssParameter( name, ( (SldProperty) value ).getSldName() ) ); } else if ( value instanceof String ) { params.put( name, StyleFactory.createCssParameter( name, (String) value ) ); } } } private Fill getFill( ClassificationTableRow<U> row ) { Fill fill = StyleFactory.createFill(); fill.setOpacity( SldValues.getOpacity( row.getFillTransparency() ) ); if ( row.getFillColor() instanceof Color ) { fill.setFill( (Color) row.getFillColor() ); } else if ( row.getFillColor() instanceof GraphicSymbol ) { GraphicSymbol fp = (GraphicSymbol) row.getFillColor(); ExternalGraphic eg = StyleFactory.createExternalGraphic( fp.getUrl(), fp.getFormat(), fp.getName() ); Graphic graphic = StyleFactory.createGraphic( eg, null, SldValues.getDefaultOpacity(), SldValues.getDefaultSize(), SldValues.getDefaultRotation() ); double fillGraphicSize = fp.getSize(); if ( Double.isNaN( fillGraphicSize ) || fillGraphicSize < 0 ) { graphic.setSize( null ); } else { graphic.setSize( fillGraphicSize ); } GraphicFill graphicFill = StyleFactory.createGraphicFill( graphic ); fill.setGraphicFill( graphicFill ); if ( fp instanceof FillPattern ) { fill.setFill( ( (FillPattern) fp ).getColor() ); } } return fill; } }