/*
* 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 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;
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.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;
/**
* 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 */ public static int size(Mark mark) { if (mark == null) { return NOTFOUND; } return Filters.asInt(mark.getSize()); } /** * 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