/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, Open Source Geospatial Foundation (OSGeo) * * 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; * version 2.1 of the License. * * 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. */ package org.geotools.styling; import java.awt.Color; import java.io.IOException; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; import org.geotools.data.AbstractDataStore; import org.geotools.factory.CommonFactoryFinder; import org.geotools.filter.Filters; import org.geotools.styling.visitor.DuplicatingStyleVisitor; import org.opengis.feature.simple.SimpleFeatureType; import org.opengis.feature.type.FeatureType; import org.opengis.feature.type.GeometryDescriptor; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory; import org.opengis.filter.expression.Expression; import org.opengis.style.GraphicalSymbol; import org.opengis.style.SemanticType; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPoint; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; /** * Utility class that provides static helper methods for common operations on * GeoTools styling objects (e.g. StyledLayerDescriptor, Style, FeatureTypeStyle, * Rule, Symbolizer, Stroke and Fill). * * @author Jody Garnett * * * @source $URL$ * @version $Id$ */ public class SLD { private static StyleFactory sf = CommonFactoryFinder.getStyleFactory(null); private static FilterFactory ff = CommonFactoryFinder.getFilterFactory(null); /** NOTFOUND indicates int value was unavailable */ public static final int NOTFOUND = Filters.NOTFOUND; public static final double ALIGN_LEFT = 1.0; public static final double ALIGN_CENTER = 0.5; public static final double ALIGN_RIGHT = 0.0; public static final double ALIGN_BOTTOM = 1.0; public static final double ALIGN_MIDDLE = 0.5; public static final double ALIGN_TOP = 0.0; /** * Retrieve linestring color from linesymbolizer if available. * * @param symbolizer Line symbolizer information. * * @return Color of linestring, or null if unavailable. */ public static Color lineColor(LineSymbolizer symbolizer) { if (symbolizer == null) { return null; } Stroke stroke = symbolizer.getStroke(); return color(stroke); } /** * Retrieve the color of a stroke object * @param stroke a Stroke object * @return color or null if stroke was null */ public static Color color(Stroke stroke) { if (stroke == null) { return null; } return color(stroke.getColor()); } /** * Retrieve the color of a fill object * @param fill a Fill object * @return color or null if fill was null */ public static Color color(Fill fill) { if (fill == null) { return null; } return color(fill.getColor()); } /** * Updates the color for line symbolizers in the current style. *

* This method will update the Style in place; some of the symbolizers * will be replaced with modified copies. * * @param style the Style object to be updated * @param colour Color to to use */ public static void setLineColour(Style style, final Color colour) { if (style == null) { return; } for (FeatureTypeStyle featureTypeStyle : style.featureTypeStyles()) { for (int i = 0; i < featureTypeStyle.rules().size(); i++) { Rule rule = featureTypeStyle.rules().get(i); DuplicatingStyleVisitor update = new DuplicatingStyleVisitor() { @Override public void visit(LineSymbolizer line) { String name = line.getGeometryPropertyName(); Stroke stroke = update(line.getStroke()); LineSymbolizer copy = sf.createLineSymbolizer(stroke, name); pages.push(copy); } Stroke update(Stroke stroke) { Expression color = ff.literal(colour); Expression width = copy(stroke.getWidth()); Expression opacity = copy(stroke.getOpacity()); Expression lineJoin = copy(stroke.getLineJoin()); Expression lineCap = copy(stroke.getLineCap()); float[] dashArray = copy(stroke.getDashArray()); Expression dashOffset = copy(stroke.getDashOffset()); Graphic graphicStroke = copy(stroke.getGraphicStroke()); Graphic graphicFill = copy(stroke.getGraphicFill()); return sf.createStroke(color, width, opacity, lineJoin, lineCap, dashArray, dashOffset, graphicFill, graphicStroke); } }; rule.accept(update); Rule updatedRule = (Rule) update.getCopy(); featureTypeStyle.rules().set(i, updatedRule); } } } /** * Sets the Colour for the given Line symbolizer * * @param symbolizer * @param colour */ public static void setLineColour(LineSymbolizer symbolizer, Color colour) { if (symbolizer == null || colour == null) { return; } Stroke stroke = symbolizer.getStroke(); if (stroke == null) { stroke = sf.createStroke(ff.literal(colour), Stroke.DEFAULT.getWidth()); symbolizer.setStroke(stroke); } else { stroke.setColor(ff.literal(colour)); } } /** * Retrieve color from linesymbolizer if available. * * @param symbolizer Line symbolizer information. * * @return Color of linestring, or null if unavailable. */ public static Color color(LineSymbolizer symbolizer) { return lineColor(symbolizer); } /** * Retrieve linestring width from symbolizer if available. * * @param symbolizer Line symbolizer information. * * @return width of linestring, or NOTFOUND */ public static int lineWidth(LineSymbolizer symbolizer) { if (symbolizer == null) { return NOTFOUND; } Stroke stroke = symbolizer.getStroke(); return width(stroke); } /** * Retrieve the width of a Stroke object. * * @param stroke the Stroke object. * * @return width or {@linkplain #NOTFOUND} if not available. */ public static int width(Stroke stroke) { if (stroke == null) { return NOTFOUND; } return Filters.asInt(stroke.getWidth()); } /** * Retrieve the size of a Mark object * @param mark the Mark object * @return size or {@linkplain #NOTFOUND} if not available * @deprecated please check graphic as an indication of mark size */ public static int size(Mark mark) { return NOTFOUND; } /** * Retrieve linestring width from symbolizer if available. * * @param symbolizer Line symbolizer information. * * @return width or {@linkplain #NOTFOUND} if not available */ public static int width(LineSymbolizer symbolizer) { return lineWidth(symbolizer); } /** * Retrieve the opacity from a LineSymbolizer object. * * @param symbolizer Line symbolizer information. * * @return double of the line symbolizer's opacity, or NaN if unavailable. */ public static double lineOpacity(LineSymbolizer symbolizer) { if (symbolizer == null) { return Double.NaN; } Stroke stroke = symbolizer.getStroke(); return opacity(stroke); } /** * Retrieve the opacity from a Stroke object. * * @param stroke the Stroke object. * * @return double of the line stroke's opacity, or NaN if unavailable. */ public static double opacity(Stroke stroke) { if (stroke == null) { return Double.NaN; } return opacity( stroke.getOpacity() ); } /** * Retrieve the opacity from a RasterSymbolizer object. * * @param symbolizer raster symbolizer information. * * @return double of the raster symbolizer's opacity, or 1.0 if unavailable. */ public static double opacity(RasterSymbolizer rasterSymbolizer ){ if( rasterSymbolizer == null ){ return 1.0; } return opacity( rasterSymbolizer.getOpacity() ); } /** * Retrieve the opacity value of an Expression. * * @param opacity Expression object * * @returna double value or 1.0 if unavailable. */ private static double opacity( Expression opacity ) { if( opacity == null ){ return 1.0; } double value = Filters.asDouble(opacity); return (Double.isNaN(value) ? 1.0 : value); } /** * Retrieves the linejoin from a LineSymbolizer. * * @param symbolizer Line symbolizer information. * * @return String of the linejoin, or null if unavailable. */ public static String lineLinejoin(LineSymbolizer symbolizer) { if (symbolizer == null) { return null; } Stroke stroke = symbolizer.getStroke(); if (stroke == null) { return null; } Expression linejoinExp = stroke.getLineJoin(); return linejoinExp.toString(); } /** * Retrieves the line cap from a LineSymbolizer. * * @param symbolizer Line symbolizer information. * * @return String of the line stroke's line cap, or null if unavailable. */ public static String lineLinecap(LineSymbolizer symbolizer) { if (symbolizer == null) { return null; } Stroke stroke = symbolizer.getStroke(); if (stroke == null) { return null; } Expression linecapExp = stroke.getLineCap(); return linecapExp.toString(); } /** * Retrieves the dashes array from a LineSymbolizer. * * @param symbolizer Line symbolizer information. * * @return float[] of the line dashes array, or null if unavailable. */ public static float[] lineDash(LineSymbolizer symbolizer) { if (symbolizer == null) { return null; } Stroke stroke = symbolizer.getStroke(); if (stroke == null) { return null; } float[] linedash = stroke.getDashArray(); return linedash; } /** * Retrieves the location of the first external graphic in * a Style object. * * @param style SLD style information. * * @return Location of the first external graphic, or null if unavailabe. */ public static URL pointGraphic(Style style) { PointSymbolizer point = pointSymbolizer(style); if (point == null) { return null; } Graphic graphic = point.getGraphic(); if (graphic == null) { return null; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof ExternalGraphic) { ExternalGraphic externalGraphic = (ExternalGraphic) gs; try { URL location = externalGraphic.getLocation(); // Should check format is supported by SWT if (location != null) { return location; } } catch (MalformedURLException e) { // ignore, try the next one } } } return null; } /** * Retrieves the first Mark used in a Style object. * * @param style the Style * * @return the first Mark object or null if unavailable. */ public static Mark pointMark(Style style) { if (style == null) { return null; } return mark(pointSymbolizer(style)); } /** * Retrieves the first Mark used in a PointSymbolizer object. * * @param sym the PointSymbolizer * * @return the first Mark object or null if unavailable. */ public static Mark mark(PointSymbolizer sym) { return mark(graphic(sym)); } /** * Retrieves the first Mark object from the given Graphic object. * * @param graphic the Graphic object. * * @return a Mark object or null if unavailable. */ public static Mark mark(Graphic graphic) { if (graphic == null) { return null; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { return (Mark) gs; } } return null; } public static Graphic graphic(PointSymbolizer sym) { if (sym == null) { return null; } return sym.getGraphic(); } /** * Retrieves the size of the point's graphic, if found. *

* If you are using something fun like symbols you will need to do your * own thing. * * @param symbolizer Point symbolizer information. * * @return size of the graphic or {@linkplain #NOTFOUND} */ public static int pointSize(PointSymbolizer symbolizer) { if (symbolizer == null) { return NOTFOUND; } Graphic g = symbolizer.getGraphic(); if (g == null) { return NOTFOUND; } Expression exp = g.getSize(); return Filters.asInt(exp); } /** * Retrieves the well known name of the first Mark that has one in a * PointSymbolizer object *

* If you are using something fun like symbols you will need to do your * own thing. * * @param symbolizer Point symbolizer information. * * @return well known name of the first Mark or null if unavailable. */ public static String pointWellKnownName(PointSymbolizer symbolizer) { if (symbolizer == null) { return null; } Graphic graphic = symbolizer.getGraphic(); if (graphic == null) { return null; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { Mark mark = (Mark) gs; String s = wellKnownName(mark); if (s != null) { return s; } } } return null; } /** * Retrieves the "well known name" of a Mark object. * * @param mark the Mark object * * @return well known name or null if unavailable. */ public static String wellKnownName(Mark mark) { if (mark == null) { return null; } Expression exp = mark.getWellKnownName(); if (exp == null) { return null; } return Filters.asString(exp); } /** * Retrieves the color of the first Mark in a PointSymbolizer object. * This method is identical to {@linkplain #color(org.geotools.styling.PointSymbolizer)}. *

* If you are using something fun like symbols you will need to do your * own thing. * * @param symbolizer Point symbolizer information. * * @return Color of the point's mark, or null if unavailable. */ public static Color pointColor(PointSymbolizer symbolizer) { return color(symbolizer); } /** * Sets the Colour for the point symbolizer * * @param style * @param colour */ public static void setPointColour(Style style, Color colour) { if (style == null) { return; } setPointColour(pointSymbolizer(style), colour); } /** * Sets the Colour for the given point symbolizer * * @param symbolizer the point symbolizer * * @param colour the new colour */ public static void setPointColour(PointSymbolizer symbolizer, Color colour) { if (symbolizer == null || colour == null) { return; } Graphic graphic = symbolizer.getGraphic(); if (graphic == null) { graphic = sf.createDefaultGraphic(); } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { Mark mark = (Mark) gs; Stroke stroke = mark.getStroke(); if (stroke == null) { stroke = sf.createStroke(ff.literal(Color.BLACK), Stroke.DEFAULT.getWidth()); mark.setStroke(stroke); } Fill fill = mark.getFill(); if (fill != null) { fill.setColor(ff.literal(colour)); } } } } /** * Retrieves the color from the first Mark in a PointSymbolizer object. *

* If you are using something fun like symbols you will need to do your * own thing. * * @param symbolizer Point symbolizer information. * * @return Color of the point's mark, or null if unavailable. */ public static Color color(PointSymbolizer symbolizer) { if (symbolizer == null) { return null; } Graphic graphic = symbolizer.getGraphic(); if (graphic == null) { return null; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { Mark mark = (Mark) gs; Stroke stroke = mark.getStroke(); if (stroke != null) { Color colour = color(stroke); if (colour != null) { return colour; } } } } return null; } /** * Retrieves the width of the first Mark with a Stroke that has a non-null * width. *

* If you are using something fun like symbols you will need to do your * own thing. * * @param symbolizer Point symbolizer information. * * @return width of the points border or {@linkplain #NOTFOUND} if unavailable. */ public static int pointWidth(PointSymbolizer symbolizer) { if (symbolizer == null) { return NOTFOUND; } Graphic graphic = symbolizer.getGraphic(); if (graphic == null) { return NOTFOUND; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { Mark mark = (Mark) gs; Stroke stroke = mark.getStroke(); if (stroke != null) { Expression exp = stroke.getWidth(); if (exp != null) { int width = Filters.asInt(exp); if (width != NOTFOUND) { return width; } } } } } return NOTFOUND; } /** * Retrieves the point border opacity from a PointSymbolizer. *

* If you are using something fun like rules you will need to do your own * thing. * * @param symbolizer Point symbolizer information. * * @return double of the point's border opacity, or NaN if unavailable. */ public static double pointBorderOpacity(PointSymbolizer symbolizer) { if (symbolizer == null) { return Double.NaN; } Graphic graphic = symbolizer.getGraphic(); if (graphic == null) { return Double.NaN; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { Mark mark = (Mark) gs; Stroke stroke = mark.getStroke(); if (stroke != null) { Expression exp = stroke.getOpacity(); return Filters.asDouble(exp); } } } return Double.NaN; } /** * Retrieves the point opacity from a PointSymbolizer. *

* If you are using something fun like rules you will need to do your own * thing. * * @param symbolizer Point symbolizer information. * * @return double of the point's opacity, or NaN if unavailable. */ public static double pointOpacity(PointSymbolizer symbolizer) { if (symbolizer == null) { return Double.NaN; } Graphic graphic = symbolizer.getGraphic(); if (graphic == null) { return Double.NaN; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { Mark mark = (Mark) gs; Fill fill = mark.getFill(); if (fill != null) { Expression expr = fill.getOpacity(); if (expr != null) { return SLD.opacity(expr); } } } } return Double.NaN; } /** * Retrieves the fill from the first Mark defined in a PointSymbolizer. *

* If you are using something fun like symbols you will need to do your * own thing. * * @param symbolizer Point symbolizer information. * * @return Color of the point's fill, or null if unavailable. */ public static Color pointFill(PointSymbolizer symbolizer) { if (symbolizer == null) { return null; } Graphic graphic = symbolizer.getGraphic(); if (graphic == null) { return null; } for (GraphicalSymbol gs : graphic.graphicalSymbols()) { if (gs != null && gs instanceof Mark) { Mark mark = (Mark) gs; Fill fill = mark.getFill(); if (fill != null) { Color colour = color(fill.getColor()); if (colour != null) { return colour; } } } } return null; } /** * Retrieves the outline width from a PolygonSymbolizer *

* If you are using something fun like rules you will need to do your own * thing. * * @param symbolizer Polygon symbolizer information. * * @return outline width or {@linkplain #NOTFOUND} if unavailable. */ public static int polyWidth(PolygonSymbolizer symbolizer) { if (symbolizer == null) { return NOTFOUND; } Stroke stroke = symbolizer.getStroke(); if (stroke != null) { return Filters.asInt(stroke.getWidth()); } return NOTFOUND; } /** * Retrieves the outline (stroke) color from a PolygonSymbolizer. *

* If you are using something fun like rules you will need to do your own * thing. * * @param symbolizer Polygon symbolizer information. * * @return Color of the polygon's stroke, or null if unavailable. */ public static Color polyColor(PolygonSymbolizer symbolizer) { if (symbolizer == null) { return null; } Stroke stroke = symbolizer.getStroke(); if (stroke == null) { return null; } Color colour = color(stroke.getColor()); if (colour != null) { return colour; } return null; } /** * Updates the raster opacity in the current style *

* Note: This method will update the Style in place; some of the rules * and symbolizers will be replaced with modified copies. * All symbolizers associated with all rules are modified. * * @param style the Style object to be updated * @param opacity - a new opacity value between 0 and 1 */ public static void setRasterOpacity(Style style, final double opacity) { if (style == null) { return; } for (FeatureTypeStyle featureTypeStyle : style.featureTypeStyles()) { for (int i = 0; i < featureTypeStyle.rules().size(); i++) { Rule rule = featureTypeStyle.rules().get(i); DuplicatingStyleVisitor update = new DuplicatingStyleVisitor() { @Override public void visit(RasterSymbolizer raster) { ChannelSelection channelSelection = copy(raster.getChannelSelection()); ColorMap colorMap = copy(raster.getColorMap()); ContrastEnhancement ce = copy(raster.getContrastEnhancement()); String geometryProperty = raster.getGeometryPropertyName(); Symbolizer outline = copy(raster.getImageOutline()); Expression overlap = copy(raster.getOverlap()); ShadedRelief shadedRelief = copy(raster.getShadedRelief()); Expression newOpacity = ff.literal(opacity); RasterSymbolizer copy = sf.createRasterSymbolizer(geometryProperty, newOpacity, channelSelection, overlap, colorMap, ce, shadedRelief, outline); if (STRICT && !copy.equals(raster)) { throw new IllegalStateException("Was unable to duplicate provided raster:" + raster); } pages.push(copy); } }; rule.accept(update); Rule updatedRule = (Rule) update.getCopy(); featureTypeStyle.rules().set(i, updatedRule); } } } /** * Updates the raster channel selection in a Style object *

* This method will update the Style in place; some of the rules & * symbolizers will be replace with modified copies. * All symbolizes associated with all rules are updated. * * @param style the Style object to be updated * @param rgb - an array of the new red, green, blue channels or null if setting the gray channel * @param gray - the new gray channel; ignored if rgb is not null */ public static void setChannelSelection(Style style, final SelectedChannelType[] rgb, final SelectedChannelType gray) { if (style == null) { return; } for (FeatureTypeStyle featureTypeStyle : style.featureTypeStyles()) { for (int i = 0; i < featureTypeStyle.rules().size(); i++) { Rule rule = featureTypeStyle.rules().get(i); DuplicatingStyleVisitor update = new DuplicatingStyleVisitor() { @Override public void visit(RasterSymbolizer raster) { ChannelSelection channelSelection = createChannelSelection(); ColorMap colorMap = copy(raster.getColorMap()); ContrastEnhancement ce = copy(raster.getContrastEnhancement()); String geometryProperty = raster.getGeometryPropertyName(); Symbolizer outline = copy(raster.getImageOutline()); Expression overlap = copy(raster.getOverlap()); ShadedRelief shadedRelief = copy(raster.getShadedRelief()); Expression opacity = copy(raster.getOpacity()); RasterSymbolizer copy = sf.createRasterSymbolizer(geometryProperty, opacity, channelSelection, overlap, colorMap, ce, shadedRelief, outline); if (STRICT && !copy.equals(raster)) { throw new IllegalStateException("Was unable to duplicate provided raster:" + raster); } pages.push(copy); } private ChannelSelection createChannelSelection() { if (rgb == null) { return sf.createChannelSelection(new SelectedChannelType[]{gray}); } else { return sf.createChannelSelection(rgb); } } }; rule.accept(update); Rule updatedRule = (Rule) update.getCopy(); featureTypeStyle.rules().set(i, updatedRule); } } } /** * Sets the colour for the first polygon symbolizer defined in * the provided style * * @param style the Style object * @param colour the colour for polygon outlines and fill */ public static void setPolyColour(Style style, Color colour) { if (style == null) { return; } setPolyColour(polySymbolizer(style), colour); } /** * Sets the colour to use for outline (stroke) and fill in a polygon symbolizer * * @param symbolizer the polygon symbolizer * @param colour the colour for polygon outlines and fill */ public static void setPolyColour(PolygonSymbolizer symbolizer, Color colour) { if (symbolizer == null || colour == null) { return; } Expression colourExp = ff.literal(colour); Stroke stroke = symbolizer.getStroke(); if (stroke == null) { stroke = sf.createStroke(colourExp, Stroke.DEFAULT.getWidth()); symbolizer.setStroke(stroke); } else { stroke.setColor(ff.literal(colour)); } Fill fill = symbolizer.getFill(); if (fill != null) { fill.setColor(colourExp); } } /** * Retrieves the fill colour from a PolygonSymbolizer. *

* If you are using something fun like rules you will need to do your own * thing. * * @param symbolizer Polygon symbolizer information. * * @return Color of the polygon's fill, or null if unavailable. */ public static Color polyFill(PolygonSymbolizer symbolizer) { if (symbolizer == null) { return null; } Fill fill = symbolizer.getFill(); if (fill == null) { return null; } return color(fill.getColor()); } /** * Retrieves the border (stroke) opacity from a PolygonSymbolizer. *

* If you are using something fun like rules you will need to do your own * thing. * * @param symbolizer Polygon symbolizer information. * * @return double of the polygon's border opacity, or NaN if unavailable. */ public static double polyBorderOpacity(PolygonSymbolizer symbolizer) { if (symbolizer == null) { return Double.NaN; } Stroke stroke = symbolizer.getStroke(); if (stroke == null) { return Double.NaN; } return opacity(stroke); } /** * Retrieves the fill opacity from the first PolygonSymbolizer. *

* If you are using something fun like rules you will need to do your own * thing. * * @param symbolizer Polygon symbolizer information. * * @return double of the polygon's fill opacity, or NaN if unavailable. */ public static double polyFillOpacity(PolygonSymbolizer symbolizer) { if (symbolizer == null) { return Double.NaN; } Fill fill = symbolizer.getFill(); return opacity(fill); } /** * Retrieve the opacity from the provided fill; or return the default. * @param fill * @return opacity from the above fill; or return the Fill.DEFAULT value */ public static double opacity(Fill fill) { if (fill == null) { fill = Fill.DEFAULT; } Expression opacityExp = fill.getOpacity(); if( opacityExp == null ){ opacityExp = Fill.DEFAULT.getOpacity(); } return Filters.asDouble(opacityExp); } /** * Retrieves the opacity from a RasterSymbolizer. *

* If you are using something fun like rules you will need to do your own * thing. *

* * @param symbolizer Raster symbolizer information. * @return opacity of the first RasterSymbolizer or NaN if unavailable. */ public static double rasterOpacity(RasterSymbolizer symbolizer) { if (symbolizer == null) { return Double.NaN; } return Filters.asDouble(symbolizer.getOpacity()); } /** * Retrieves the opacity from the first RasterSymbolizer defined * in a style. * * @param style the Style object * * @return opacity of the raster symbolizer or NaN if unavailable. */ public static double rasterOpacity(Style style) { return rasterOpacity(rasterSymbolizer(style)); } /** * Retrieve the first TextSymbolizer from the provided FeatureTypeStyle. * * @param fts FeatureTypeStyle information. * * @return TextSymbolizer, or null if not found. */ public static TextSymbolizer textSymbolizer(FeatureTypeStyle fts) { return (TextSymbolizer) symbolizer(fts, TextSymbolizer.class); } /** * Retrieve the first TextSymbolizer from the provided Style. * * @param style the Style object * * @return TextSymbolizer, or null if not found. */ public static TextSymbolizer textSymbolizer(Style style) { return (TextSymbolizer) symbolizer(style, TextSymbolizer.class); } /** * Retrieves the font from a TextSymbolizer. Equivalent to * {@code symbolizer.getFont()}. * * @param symbolizer the symbolizer * * @return the first font defined in the symbolizer or null if unavailable. */ public static Font font( TextSymbolizer symbolizer ) { if(symbolizer == null) { return null; } return symbolizer.getFont(); } /** * Retrieves the label from a TextSymbolizer. * * @param symbolizer Text symbolizer information. * * @return Expression of the label's text, or null if unavailable. */ public static Expression textLabel(TextSymbolizer symbolizer) { if (symbolizer == null) { return null; } Expression exp = symbolizer.getLabel(); if (exp == null) { return null; } return exp; } /** * Retrieves the label from a TextSymbolizer. * * @param symbolizer Text symbolizer information. * * @return the label's text, or null if unavailable. */ public static String textLabelString(TextSymbolizer sym) { Expression exp = textLabel(sym); return (exp == null) ? null : exp.toString(); } /** * Retrieves the colour of the font fill from a TextSymbolizer. * * @param symbolizer Text symbolizer information. * * @return Color of the font's fill, or null if unavailable. */ public static Color textFontFill(TextSymbolizer symbolizer) { if (symbolizer == null) { return null; } Fill fill = symbolizer.getFill(); if (fill == null) { return null; } return color(fill.getColor()); } /** * Retrieves the colour of the halo fill a TextSymbolizer. * * @param symbolizer Text symbolizer information. * * @return Color of the halo's fill, or null if unavailable. */ public static Color textHaloFill(TextSymbolizer symbolizer) { Halo halo = symbolizer.getHalo(); if (halo == null) { return null; } Fill fill = halo.getFill(); if (fill == null) { return null; } return color(fill.getColor()); } /** * Retrieves the halo width from a TextSymbolizer. * * @param symbolizer Text symbolizer information. * * @return the halo's width, or 0 if unavailable. */ public static int textHaloWidth(TextSymbolizer symbolizer) { Halo halo = symbolizer.getHalo(); if (halo == null) { return 0; } Expression exp = halo.getRadius(); if (exp == null) { return 0; } int width = (int) Float.parseFloat(exp.toString()); if (width != 0) { return width; } return 0; } /** * Retrieves the halo opacity from the first TextSymbolizer. * * @param symbolizer Text symbolizer information. * * @return double of the halo's opacity, or NaN if unavailable. */ public static double textHaloOpacity(TextSymbolizer symbolizer) { if (symbolizer == null) { return Double.NaN; } Halo halo = symbolizer.getHalo(); if (halo == null) { return Double.NaN; } Fill fill = halo.getFill(); if (fill == null) { return Double.NaN; } Expression expr = fill.getOpacity(); if( expr == null ){ return Double.NaN; } return Filters.asDouble(expr); } /** * Navigate through the expression finding the first mentioned Color. *

* If you have a specific Feature in mind please use: *


     * Object value = expr.getValue( feature );
     * return value instanceof Color ? (Color) value : null;
     * 
* * @param expr the Expression object * * @return First available color, or null. */ public static Color color(Expression expr) { if (expr == null) { return null; } return expr.evaluate(null, Color.class ); } /** * Retrieve the first RasterSymbolizer from the provided FeatureTypeStyle. * * @param fts the FeatureTypeStyle information. * * @return RasterSymbolizer, or null if not found. */ public static RasterSymbolizer rasterSymbolizer(FeatureTypeStyle fts) { return (RasterSymbolizer) symbolizer(fts, RasterSymbolizer.class); } /** * Retrieve the first RasterSymbolizer from the provided Style. * * @param style the Style object * * @return RasterSymbolizer, or null if not found. */ public static RasterSymbolizer rasterSymbolizer(Style style) { return (RasterSymbolizer) symbolizer(style, RasterSymbolizer.class); } /** * Retrieve the first LineSymbolizer from the provided FeatureTypeStyle. * * @param fts the FeatureTypeStyle object * * @return LineSymbolizer, or null if not found. */ public static LineSymbolizer lineSymbolizer(FeatureTypeStyle fts) { return (LineSymbolizer) symbolizer(fts, LineSymbolizer.class); } /** * Retrieve the first LineSymbolizer from the provided Style. * * @param style the Style object * * @return LineSymbolizer, or null if not found. */ public static LineSymbolizer lineSymbolizer(Style style) { return (LineSymbolizer) symbolizer(style, LineSymbolizer.class); } /** * Retrieves the Stroke from a LineSymbolizer. * @param sym the symbolizer * @return the Stroke or null if not found. */ public static Stroke stroke(LineSymbolizer sym) { if (sym == null) { return null; } return sym.getStroke(); } /** * Retrieves the Stroke from a PolygonSymbolizer. * @param sym the symbolizer * @return the Stroke or null if not found. */ public static Stroke stroke(PolygonSymbolizer sym) { if (sym == null) { return null; } return sym.getStroke(); } /** * Retrieves the Stroke from a PointSymbolizer. * @param sym the symbolizer * @return the Stroke or null if not found. */ public static Stroke stroke(PointSymbolizer sym) { Mark mark = mark(sym); return (mark == null) ? null : mark.getStroke(); } /** * Retrieves the Fill from a PolygonSymbolizer. * @param sym the symbolizer * @return the Fill or null if not found. */ public static Fill fill(PolygonSymbolizer sym) { if (sym == null) { return null; } return sym.getFill(); } /** * Retrieves the Fill from a PointSymbolizer. * @param sym the symbolizer * @return the Fill or null if not found. */ public static Fill fill(PointSymbolizer sym) { Mark mark = mark(sym); return (mark == null) ? null : mark.getFill(); } /** * Retrieve the first PointSymbolizer from the provided FeatureTypeStyle. * * @param fts the FeatureTypeStyle object * * @return PointSymbolizer, or null if not found. */ public static PointSymbolizer pointSymbolizer(FeatureTypeStyle fts) { return (PointSymbolizer) symbolizer(fts, PointSymbolizer.class); } /** * Retrieve the first PointSymbolizer from the provided Style. * * @param style the Style object * * @return PointSymbolizer, or null if not found. */ public static PointSymbolizer pointSymbolizer(Style style) { return (PointSymbolizer) symbolizer(style, PointSymbolizer.class); } /** * Retrieve the first PolygonSymbolizer from the provided FeatureTypeStyle. * * @param fts FeatureTypeStyle object. * * @return PolygonSymbolizer, or null if not found. */ public static PolygonSymbolizer polySymbolizer(FeatureTypeStyle fts) { return (PolygonSymbolizer) symbolizer(fts, PolygonSymbolizer.class); } /** * Retrieve the first PolygonSymbolizer from the provided Style. * * @param style the Style object * * @return PolygonSymbolizer, or null if not found. */ public static PolygonSymbolizer polySymbolizer(Style style) { return (PolygonSymbolizer) symbolizer(style, PolygonSymbolizer.class); } /** * Returns the feature type style in the style which matched a particular * name. * * @param style the Style object * @param type the feature type (must be non-null) * * @return The FeatureTypeStyle object if it exists, otherwise false. */ public static FeatureTypeStyle featureTypeStyle(Style style, SimpleFeatureType type) { if (style == null) { return null; } if ((type == null) || (type.getTypeName() == null)) { return null; } for (FeatureTypeStyle fts : style.featureTypeStyles()) { if (type.getTypeName().equalsIgnoreCase(fts.getName())) { return fts; } } return null; } /** * Returns the first style object which matches a given schema. * * @param styles Array of style objects. * @param schema Feature schema. * * @return The first object to match the feature type, otherwise null if no * match. */ public static Style matchingStyle(Style[] styles, SimpleFeatureType schema) { if ((styles == null) || (styles.length == 0)) { return null; } for (int i = 0; i < styles.length; i++) { Style style = styles[i]; if (featureTypeStyle(style, schema) != null) { return style; } } return null; } /** * Retrieve the first Symbolizer from the provided Style. * * @param style SLD style information. * @param SYMBOLIZER LineSymbolizer.class, PointSymbolizer.class, * PolygonSymbolizer.class, RasterSymbolizer.class, or TextSymbolizer.class * * @return symbolizer instance from style, or null if not found. */ protected static Symbolizer symbolizer(Style style, final Class SYMBOLIZER) { if (style == null) { return null; } for (FeatureTypeStyle fts : style.featureTypeStyles()) { Symbolizer sym = symbolizer(fts, SYMBOLIZER); if (sym != null) { return sym; } } return null; } /** * Retrieve the first Symbolizer from the provided FeatureTypeStyle. * * @param fts the FeatureTypeStyle SLD style information. * @param SYMBOLIZER LineSymbolizer.class, PointSymbolizer.class, * PolygonSymbolizer.class, RasterSymbolizer.class, * or TextSymbolizer.class * * @return symbolizer instance from fts, or null if not found. */ protected static Symbolizer symbolizer(FeatureTypeStyle fts, final Class SYMBOLIZER) { if (fts == null) { return null; } for (Rule rule : fts.rules()) { for (Symbolizer sym : rule.symbolizers()) { if (SYMBOLIZER.isInstance(sym)) { return sym; } } } return null; } /** * Convert a Color object to hex representation * @param c the Color object * @return a hex String */ public static String colorToHex(Color c) { return "#" + Integer.toHexString(c.getRGB() & 0x00ffffff); } /** * Get the Styles defined in the given StyledLayerDescriptor * @param sld the StyledLayerDescriptor object * @return an array of Styles */ public static Style[] styles(StyledLayerDescriptor sld) { StyledLayer[] layers = sld.getStyledLayers(); List