/*
* 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.util.Arrays;
import java.util.Iterator;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
import org.geotools.feature.FeatureCollection;
import org.geotools.filter.IllegalFilterException;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.PropertyIsBetween;
import org.opengis.filter.PropertyIsGreaterThan;
import org.opengis.filter.PropertyIsLessThan;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.PropertyName;
/**
* An utility class designed to ease style building by convinience methods.
*
* @author aaime
* @source $URL$
*/
public class StyleBuilder {
private static final java.util.logging.Logger LOGGER =
org.geotools.util.logging.Logging.getLogger("org.geotools.styling");
public static final String LINE_JOIN_MITRE = "mitre";
public static final String LINE_JOIN_ROUND = "round";
public static final String LINE_JOIN_BEVEL = "bevel";
public static final String LINE_CAP_BUTT = "butt";
public static final String LINE_CAP_ROUND = "round";
public static final String LINE_CAP_SQUARE = "square";
public static final String MARK_SQUARE = "square";
public static final String MARK_CIRCLE = "circle";
public static final String MARK_TRIANGLE = "triangle";
public static final String MARK_STAR = "star";
public static final String MARK_CROSS = "cross";
public static final String MARK_ARROW = "arrow";
public static final String MARK_X = "x";
public static final String FONT_STYLE_NORMAL = "normal";
public static final String FONT_STYLE_ITALIC = "italic";
public static final String FONT_STYLE_OBLIQUE = "oblique";
public static final String FONT_WEIGHT_NORMAL = "normal";
public static final String FONT_WEIGHT_BOLD = "bold";
private StyleFactory sf;
private FilterFactory ff;
/**
* use the default StyleFactory and FilterFactory
*/
public StyleBuilder() {
this( CommonFactoryFinder.getStyleFactory( GeoTools.getDefaultHints() ) );
}
/**
* Use the supplied StyleFactory when building styles
*
* @param styleFactory the StyleFactory to use in building Styles
*/
public StyleBuilder(StyleFactory styleFactory ) {
this( styleFactory, CommonFactoryFinder.getFilterFactory( GeoTools.getDefaultHints() ) );
}
/**
* Use the supplied FilterFactory when building styles
*
* @param filterFactory Use this FilterFactory to build the style
*/
public StyleBuilder(FilterFactory filterFactory ) {
this( CommonFactoryFinder.getStyleFactory( GeoTools.getDefaultHints() ), filterFactory );
}
/**
* Use the supplied StyleFactory and FilterFactory when building styles
*
* @param styleFactory the StyleFactory to use
* @param filterFactory the FilterFactory to use
*/
public StyleBuilder(StyleFactory styleFactory, FilterFactory filterFactory) {
this.sf = styleFactory;
this.ff = filterFactory;
}
/**
* Documented setter injection, StyleBuilder uses a StyleFactory for creation.
*
* @param factory
*/
public void setStyleFactory( StyleFactory factory ){
sf = factory;
}
/**
* getter for StyleFactory
*
* @return the StyleFactory being used
*/
public StyleFactory getStyleFactory() {
return sf;
}
/**
* Documented setter injection, StyleBuilder uses a StyleFactory for creation.
*
* @param factory
*/
public void setFilterFactory( FilterFactory factory ){
ff = factory;
}
/**
* getter for filterFactory
*
* @return the FilterFactory being used
*/
public FilterFactory getFilterFactory() {
return ff;
}
/**
* create a default Stroke
*
* @return the Stroke created
*/
public Stroke createStroke() {
return sf.getDefaultStroke();
}
/**
* create a default stroke with the supplied width
*
* @param width the width of the line
*
* @return the stroke created
*/
public Stroke createStroke(double width) {
return createStroke(Color.BLACK, width);
}
/**
* Create a default stroke with the supplied color
*
* @param color the color of the line
*
* @return the created stroke
*/
public Stroke createStroke(Color color) {
return createStroke(color, 1);
}
/**
* create a stroke with the supplied width and color
*
* @param color the color of the line
* @param width the width of the line
*
* @return the created stroke
*/
public Stroke createStroke(Color color, double width) {
return sf.createStroke(colorExpression(color), literalExpression(width));
}
/**
* create a stroke with color, width, linejoin type and lineCap type.
*
* @param color the color of the line
* @param width the width of the line
* @param lineJoin the type of join to be used at points along the line
* @param lineCap the type of cap to be used at the end of the line
*
* @return the stroke created
*/
public Stroke createStroke(Color color, double width, String lineJoin, String lineCap) {
Stroke stroke = createStroke(color, width);
stroke.setLineJoin(literalExpression(lineJoin));
stroke.setLineCap(literalExpression(lineCap));
return stroke;
}
/**
* create a dashed line of color and width
*
* @param color the color of the line
* @param width the width of the line
* @param dashArray an array of floats describing the length of line and spaces
*
* @return the stroke created
*/
public Stroke createStroke(Color color, double width, float[] dashArray) {
Stroke stroke = createStroke(color, width);
stroke.setDashArray(dashArray);
return stroke;
}
/**
* create a stroke with the color and width supplied
*
* @param color an Expression representing the color of the line
* @param width an Expression representing the width of the line
*
* @return the Stroke created
*/
public Stroke createStroke(Expression color, Expression width) {
return sf.createStroke(color, width);
}
/**
* create a stroke with color, width and opacity supplied
*
* @param color the color of the line
* @param width the width of the line
* @param opacity the opacity or <I>see throughness</I> of the line, 0 - is transparent, 1 is
* completely drawn
*
* @return the stroke created
*/
public Stroke createStroke(Color color, double width, double opacity) {
return sf.createStroke(
colorExpression(color),
literalExpression(width),
literalExpression(opacity));
}
/**
* create a stroke with color, width and opacity supplied
*
* @param color an Expression representing the color of the line
* @param width an Expression representing the width of the line
* @param opacity an Expression representing opacity the opacity or <I>see throughness</I> of
* the line, 0 - is transparent, 1 is completely drawn
*
* @return the stroke created
*/
public Stroke createStroke(Expression color, Expression width, Expression opacity) {
return sf.createStroke(color, width, opacity);
}
/**
* create a default fill 50% gray
*
* @return the fill created
*/
public Fill createFill() {
Fill f = sf.getDefaultFill();
f.setColor(literalExpression("#808080"));
f.setBackgroundColor(literalExpression("#808080"));
f.setOpacity(literalExpression(1.0));
return f;
}
/**
* create a fill of color
*
* @param fillColor the color of the fill
*
* @return the fill created
*/
public Fill createFill(Color fillColor) {
return createFill(colorExpression(fillColor));
}
/**
* create a fill of color
*
* @param fillColor an Expression representing the color of the fill
*
* @return the fill constructed
*/
public Fill createFill(Expression fillColor) {
return sf.createFill(fillColor);
}
/**
* create a fill with the supplied color and opacity
*
* @param fillColor the color to fill with
* @param opacity the opacity of the fill 0 - transparent, 1 - completly filled
*
* @return the fill created
*/
public Fill createFill(Color fillColor, double opacity) {
return sf.createFill(colorExpression(fillColor), literalExpression(opacity));
}
/**
* create a fill with the supplied color and opacity
*
* @param color an expression representing the color to fill with
* @param opacity an expression representing the opacity of the fill 0 - transparent, 1 -
* completly filled
*
* @return the fill created
*/
public Fill createFill(Expression color, Expression opacity) {
return sf.createFill(color, opacity);
}
/**
* create a fill with color, background color and opacity supplied and uses the graphic
* supplied for the fill
*
* @param color the foreground color
* @param backgroundColor the background color
* @param opacity the opacity of the fill
* @param fill the graphic object to use to fill the fill
*
* @return the fill created
*/
public Fill createFill(Color color, Color backgroundColor, double opacity, Graphic fill) {
return sf.createFill(
colorExpression(color),
colorExpression(backgroundColor),
literalExpression(opacity),
fill);
}
/**
* create a fill with color, background color and opacity supplied and uses the graphic
* supplied for the fill
*
* @param color an Expression representing the foreground color
* @param backgroundColor an Expression representing the background color
* @param opacity an Expression representing the opacity of the fill
* @param fill the graphic object to use to fill the fill
*
* @return the fill created
*/
public Fill createFill(
Expression color,
Expression backgroundColor,
Expression opacity,
Graphic fill) {
return sf.createFill(color, backgroundColor, opacity, fill);
}
/**
* Returns the array of all the well known mark names
*
* @return DOCUMENT ME!
*/
public String[] getWellKnownMarkNames() {
return new String[] {
MARK_SQUARE,
MARK_CIRCLE,
MARK_TRIANGLE,
MARK_STAR,
MARK_CROSS,
MARK_ARROW,
MARK_X };
}
/**
* create the named mark
*
* @param wellKnownName the wellknown name of the mark
*
* @return the mark created
*/
public Mark createMark(String wellKnownName) {
Mark mark = sf.createMark();
mark.setWellKnownName(literalExpression(wellKnownName));
return mark;
}
/**
* create the named mark with the colors etc supplied
*
* @param wellKnownName the well known name of the mark
* @param fillColor the color of the mark
* @param borderColor the outline color of the mark
* @param borderWidth the width of the outline
*
* @return the mark created
*/
public Mark createMark(
String wellKnownName,
Color fillColor,
Color borderColor,
double borderWidth) {
Mark mark = sf.createMark();
mark.setWellKnownName(literalExpression(wellKnownName));
mark.setStroke(createStroke(borderColor, borderWidth));
mark.setFill(createFill(fillColor));
return mark;
}
/**
* create a mark with default fill (50% gray) and the supplied outline
*
* @param wellKnownName the well known name of the mark
* @param borderColor the outline color
* @param borderWidth the outline width
*
* @return the mark created
*/
public Mark createMark(String wellKnownName, Color borderColor, double borderWidth) {
Mark mark = sf.createMark();
mark.setWellKnownName(literalExpression(wellKnownName));
mark.setStroke(createStroke(borderColor, borderWidth));
return mark;
}
/**
* create a mark of the supplied color and a default outline (black)
*
* @param wellKnownName the well known name of the mark
* @param fillColor the color of the mark
*
* @return the created mark
*/
public Mark createMark(String wellKnownName, Color fillColor) {
Mark mark = sf.createMark();
mark.setWellKnownName(literalExpression(wellKnownName));
mark.setFill(createFill(fillColor, 1.0));
mark.setStroke(null);
return mark;
}
/**
* create a mark with the supplied fill and stroke
*
* @param wellKnownName the well known name of the mark
* @param fill the fill to use
* @param stroke the stroke to use
*
* @return the mark created
*/
public Mark createMark(String wellKnownName, Fill fill, Stroke stroke) {
Mark mark = sf.createMark();
mark.setWellKnownName(literalExpression(wellKnownName));
mark.setStroke(stroke);
mark.setFill(fill);
return mark;
}
/**
* create a mark with the supplied fill and stroke
*
* @param wellKnownName an Expression representing the well known name of the mark
* @param fill the fill to use
* @param stroke the stroke to use
*
* @return the mark created
*/
public Mark createMark(Expression wellKnownName, Fill fill, Stroke stroke) {
Mark mark = sf.createMark();
mark.setWellKnownName(wellKnownName);
mark.setStroke(stroke);
mark.setFill(fill);
return mark;
}
/**
* wrapper for stylefactory method
*
* @param uri the uri of the image
* @param format mime type of the image
*
* @return the external graphic
*/
public ExternalGraphic createExternalGraphic(String uri, String format) {
return sf.createExternalGraphic(uri, format);
}
/**
* wrapper for stylefactory method
*
* @param url the url of the image
* @param format mime type of the image
*
* @return the external graphic
*/
public ExternalGraphic createExternalGraphic(java.net.URL url, String format) {
return sf.createExternalGraphic(url, format);
}
/**
* Creates the default graphic object
*
* @return the graphic object
*/
public Graphic createGraphic() {
Graphic gr = sf.getDefaultGraphic();
Mark mark = createMark(MARK_SQUARE, Color.decode("#808080"), Color.BLACK, 1);
gr.setMarks( new Mark[] { mark });
gr.setSize(Expression.NIL);
return gr;
}
/**
* creates a graphic object
*
* @param externalGraphic an external graphic to use if displayable
* @param mark a mark to use
* @param symbol a symbol to use
*
* @return the graphic object
*/
public Graphic createGraphic(ExternalGraphic externalGraphic, Mark mark, Symbol symbol) {
Graphic gr = sf.getDefaultGraphic();
if (symbol != null) {
gr.setSymbols(new Symbol[] { symbol });
} else {
gr.setSymbols(new Symbol[0]);
}
if (externalGraphic != null) {
gr.setExternalGraphics(new ExternalGraphic[] { externalGraphic });
}
if (mark != null) {
gr.setMarks(new Mark[] { mark });
} else {
gr.setMarks(new Mark[0]);
}
return gr;
}
/**
* creates a graphic object
*
* @param externalGraphic an external graphic to use if displayable
* @param mark a mark to use
* @param symbol a symbol to use
* @param opacity - the opacity of the graphic
* @param size - the size of the graphic
* @param rotation - the rotation from the top of the page of the graphic
*
* @return the graphic created
*/
public Graphic createGraphic(
ExternalGraphic externalGraphic,
Mark mark,
Symbol symbol,
double opacity,
double size,
double rotation) {
ExternalGraphic[] egs = null;
Mark[] marks = null;
Symbol[] symbols = null;
if (externalGraphic != null) {
egs = new ExternalGraphic[] { externalGraphic };
}
if (mark != null) {
marks = new Mark[] { mark };
}
if (symbol != null) {
symbols = new Symbol[] { symbol };
}
return createGraphic(
egs,
marks,
symbols,
literalExpression(opacity),
literalExpression(size),
literalExpression(rotation));
}
/**
* creates a graphic object
*
* @param externalGraphics an array of external graphics to use if displayable
* @param marks an array of marks to use
* @param symbols an array of symbols to use
* @param opacity - the opacity of the graphic
* @param size - the size of the graphic
* @param rotation - the rotation from the top of the page of the graphic
*
* @return the graphic created
*/
public Graphic createGraphic(
ExternalGraphic[] externalGraphics,
Mark[] marks,
Symbol[] symbols,
double opacity,
double size,
double rotation) {
return createGraphic(
externalGraphics,
marks,
symbols,
literalExpression(opacity),
literalExpression(size),
literalExpression(rotation));
}
/**
* creates a graphic object
*
* @param externalGraphics an array of external graphics to use if displayable
* @param marks an array of marks to use
* @param symbols an array of symbols to use
* @param opacity - an Expression representing the opacity of the graphic
* @param size - an Expression representing the size of the graphic
* @param rotation - an Expression representing the rotation from the top of the page of the
* graphic
*
* @return the graphic created
*/
public Graphic createGraphic(
ExternalGraphic[] externalGraphics,
Mark[] marks,
Symbol[] symbols,
Expression opacity,
Expression size,
Expression rotation) {
ExternalGraphic[] exg = externalGraphics;
if (exg == null) {
exg = new ExternalGraphic[0];
}
Mark[] m = marks;
if (m == null) {
m = new Mark[0];
}
Symbol[] s = symbols;
if (s == null) {
s = new Symbol[0];
}
return sf.createGraphic(exg, m, s, opacity, size, rotation);
}
/**
* wrapper round Stylefactory Method
*
* @param x - the x coordinate of the anchor
* @param y - the y coordinate of the anchor
*
* @return the AnchorPoint created
*/
public AnchorPoint createAnchorPoint(double x, double y) {
return sf.createAnchorPoint(literalExpression(x), literalExpression(y));
}
/**
* wrapper round Stylefactory Method
*
* @param x - an Expression representing the x coordinate of the anchor
* @param y - an Expression representing the y coordinate of the anchor
*
* @return the AnchorPoint created
*/
public AnchorPoint createAnchorPoint(Expression x, Expression y) {
return sf.createAnchorPoint(x, y);
}
/**
* wrapper round Stylefactory Method
*
* @param x - the x displacement
* @param y - the y displacement
*
* @return the Displacement created
*/
public Displacement createDisplacement(double x, double y) {
return sf.createDisplacement(literalExpression(x), literalExpression(y));
}
/**
* wrapper round Stylefactory Method
*
* @param x - an Expression representing the x displacement
* @param y - an Expression representing the y displacement
*
* @return the Displacement created
*/
public Displacement createDisplacement(Expression x, Expression y) {
return sf.createDisplacement(x, y);
}
/**
* wrapper round Stylefactory Method
*
* @return the default pointplacement
*/
public PointPlacement createPointPlacement() {
return sf.getDefaultPointPlacement();
}
/**
* wrapper round Stylefactory Method
*
* @param anchorX - the X coordinate
* @param anchorY - the Y coordinate
* @param rotation - the rotaion of the label
*
* @return the pointplacement created
*/
public PointPlacement createPointPlacement(double anchorX, double anchorY, double rotation) {
AnchorPoint anchorPoint = createAnchorPoint(anchorX, anchorY);
return sf.createPointPlacement(anchorPoint, null, literalExpression(rotation));
}
/**
* wrapper round Stylefactory Method
*
* @param anchorX - the X coordinate
* @param anchorY - the Y coordinate
* @param displacementX - the X distance from the anchor
* @param displacementY - the Y distance from the anchor
* @param rotation - the rotaion of the label
*
* @return the pointplacement created
*/
public PointPlacement createPointPlacement(
double anchorX,
double anchorY,
double displacementX,
double displacementY,
double rotation) {
AnchorPoint anchorPoint = createAnchorPoint(anchorX, anchorY);
Displacement displacement = createDisplacement(displacementX, displacementY);
return sf.createPointPlacement(anchorPoint, displacement, literalExpression(rotation));
}
/**
* wrapper round Stylefactory Method
*
* @param anchorPoint - the anchor point of the label
* @param displacement - the displacement of the label
* @param rotation - an Expresson representing the rotation of the label
*
* @return the pointplacement created
*/
public PointPlacement createPointPlacement(
AnchorPoint anchorPoint,
Displacement displacement,
Expression rotation) {
return sf.createPointPlacement(anchorPoint, displacement, rotation);
}
/**
* wrapper round Stylefactory Method
*
* @param offset - the distance between the line and the label
*
* @return the LinePlacement created
*/
public LinePlacement createLinePlacement(double offset) {
return sf.createLinePlacement(literalExpression(offset));
}
/**
* wrapper round Stylefactory Method
*
* @param offset - an Expression representing the distance between the line and the label
*
* @return the LinePlacement created
*/
public LinePlacement createLinePlacement(Expression offset) {
return sf.createLinePlacement(offset);
}
/**
* create a geotools font object from a java font
*
* @param font - the font to be converted
*
* @return - the geotools font
*/
public Font createFont(java.awt.Font font) {
Expression family = literalExpression(font.getFamily());
Expression style;
Expression weight;
if (font.isBold()) {
weight = literalExpression(FONT_WEIGHT_BOLD);
} else {
weight = literalExpression(FONT_WEIGHT_NORMAL);
}
if (font.isItalic()) {
style = literalExpression(FONT_STYLE_ITALIC);
} else {
style = literalExpression(FONT_STYLE_NORMAL);
}
return sf.createFont(family, style, weight, literalExpression(font.getSize2D()));
}
/**
* create font of supplied family and size
*
* @param fontFamily - the font family
* @param fontSize - the size of the font in points
*
* @return the font object created
*/
public Font createFont(String fontFamily, double fontSize) {
Expression family = literalExpression(fontFamily);
Expression style = literalExpression(FONT_STYLE_NORMAL);
Expression weight = literalExpression(FONT_WEIGHT_NORMAL);
return sf.createFont(family, style, weight, literalExpression(fontSize));
}
/**
* create font of supplied family, size and weight/style
*
* @param fontFamily - the font family
* @param italic - should the font be italic?
* @param bold - should the font be bold?
* @param fontSize - the size of the font in points
*
* @return the new font object
*/
public Font createFont(String fontFamily, boolean italic, boolean bold, double fontSize) {
Expression family = literalExpression(fontFamily);
Expression style;
Expression weight;
if (bold) {
weight = literalExpression(FONT_WEIGHT_BOLD);
} else {
weight = literalExpression(FONT_WEIGHT_NORMAL);
}
if (italic) {
style = literalExpression(FONT_STYLE_ITALIC);
} else {
style = literalExpression(FONT_STYLE_NORMAL);
}
return sf.createFont(family, style, weight, literalExpression(fontSize));
}
/**
* wrapper round StyleFactory method
*
* @param fontFamily - Expression representing Font family
* @param fontStyle - Expression representing Font style
* @param fontWeight - Expression representing Font weight
* @param fontSize - Expression representing Font size
*
* @return the new font object
*/
public Font createFont(
Expression fontFamily,
Expression fontStyle,
Expression fontWeight,
Expression fontSize) {
return sf.createFont(fontFamily, fontStyle, fontWeight, fontSize);
}
/**
* wrapper round StyleFactory method to create default halo
*
* @return the new halo
*/
public Halo createHalo() {
return sf.createHalo(createFill(Color.WHITE), literalExpression(1));
}
/**
* wrapper round StyleFactory method to create halo
*
* @param color - the color of the halo
* @param radius - the width of the halo
*
* @return the new halo
*/
public Halo createHalo(Color color, double radius) {
return sf.createHalo(createFill(color), literalExpression(radius));
}
/**
* wrapper round StyleFactory method to create halo
*
* @param color - the color of the halo
* @param opacity - the opacity of the halo fill 0 - transparent 1 - solid
* @param radius - the width of the halo
*
* @return the new halo
*/
public Halo createHalo(Color color, double opacity, double radius) {
return sf.createHalo(createFill(color, opacity), literalExpression(radius));
}
/**
* wrapper round StyleFactory method to create halo
*
* @param fill - the fill of the halo
* @param radius - the width of the halo
*
* @return the new halo
*/
public Halo createHalo(Fill fill, double radius) {
return sf.createHalo(fill, literalExpression(radius));
}
/**
* wrapper round StyleFactory method to create halo
*
* @param fill - the fill of the halo
* @param radius - an Expression representing the width of the halo
*
* @return the new halo
*/
public Halo createHalo(Fill fill, Expression radius) {
return sf.createHalo(fill, radius);
}
/**
* create a default line symboliser
*
* @return the new line symbolizer
*/
public LineSymbolizer createLineSymbolizer() {
return sf.getDefaultLineSymbolizer();
}
/**
* create a new line symbolizer
*
* @param width the width of the line
*
* @return the new line symbolizer
*/
public LineSymbolizer createLineSymbolizer(double width) {
return createLineSymbolizer(createStroke(width), null);
}
/**
* create a LineSymbolizer
*
* @param color - the color of the line
*
* @return the new line symbolizer
*/
public LineSymbolizer createLineSymbolizer(Color color) {
return createLineSymbolizer(createStroke(color), null);
}
/**
* create a LineSymbolizer
*
* @param color - the color of the line
* @param width - the width of the line
*
* @return the new line symbolizer
*/
public LineSymbolizer createLineSymbolizer(Color color, double width) {
return createLineSymbolizer(createStroke(color, width), null);
}
/**
* create a LineSymbolizer
*
* @param color - the color of the line
* @param width - the width of the line
* @param geometryPropertyName - the name of the geometry to be drawn
*
* @return the new line symbolizer
*/
public LineSymbolizer createLineSymbolizer(
Color color,
double width,
String geometryPropertyName) {
return createLineSymbolizer(createStroke(color, width), geometryPropertyName);
}
/**
* create a LineSymbolizer
*
* @param stroke - the stroke to be used to draw the line
*
* @return the new line symbolizer
*/
public LineSymbolizer createLineSymbolizer(Stroke stroke) {
return sf.createLineSymbolizer(stroke, null);
}
/**
* create a LineSymbolizer
*
* @param stroke - the stroke to be used to draw the line
* @param geometryPropertyName - the name of the geometry to be drawn
*
* @return the new line symbolizer
*/
public LineSymbolizer createLineSymbolizer(Stroke stroke, String geometryPropertyName) {
return sf.createLineSymbolizer(stroke, geometryPropertyName);
}
/**
* create a default polygon symbolizer
*
* @return the new polygon symbolizer
*/
public PolygonSymbolizer createPolygonSymbolizer() {
PolygonSymbolizer ps = sf.createPolygonSymbolizer();
ps.setFill(createFill());
ps.setStroke(createStroke());
return ps;
}
/**
* create a polygon symbolizer
*
* @param fillColor - the color to fill the polygon
*
* @return the new polygon symbolizer
*/
public PolygonSymbolizer createPolygonSymbolizer(Color fillColor) {
return createPolygonSymbolizer(null, createFill(fillColor));
}
/**
* create a polygon symbolizer
*
* @param fillColor - the color to fill the polygon
* @param borderColor - the outline color of the polygon
* @param borderWidth - the width of the outline
*
* @return the new polygon symbolizer
*/
public PolygonSymbolizer createPolygonSymbolizer(
Color fillColor,
Color borderColor,
double borderWidth) {
return createPolygonSymbolizer(
createStroke(borderColor, borderWidth),
createFill(fillColor));
}
/**
* create a polygon symbolizer
*
* @param borderColor - the outline color of the polygon
* @param borderWidth - the width of the outline
*
* @return the new polygon symbolizer
*/
public PolygonSymbolizer createPolygonSymbolizer(Color borderColor, double borderWidth) {
return createPolygonSymbolizer(createStroke(borderColor, borderWidth), null);
}
/**
* create a polygon symbolizer
*
* @param stroke - the stroke to use to outline the polygon
* @param fill - the fill to use to color the polygon
*
* @return the new polygon symbolizer
*/
public PolygonSymbolizer createPolygonSymbolizer(Stroke stroke, Fill fill) {
return createPolygonSymbolizer(stroke, fill, null);
}
/**
* create a polygon symbolizer
*
* @param stroke - the stroke to use to outline the polygon
* @param fill - the fill to use to color the polygon
* @param geometryPropertyName - the name of the geometry to be drawn
*
* @return the new polygon symbolizer
*/
public PolygonSymbolizer createPolygonSymbolizer(
Stroke stroke,
Fill fill,
String geometryPropertyName) {
return sf.createPolygonSymbolizer(stroke, fill, geometryPropertyName);
}
/**
* create a default point symbolizer
*
* @return the new point symbolizer
*/
public PointSymbolizer createPointSymbolizer() {
return sf.getDefaultPointSymbolizer();
}
/**
* create a point symbolizer
*
* @param graphic - the graphic object to draw at the point
*
* @return the new point symbolizer
*/
public PointSymbolizer createPointSymbolizer(Graphic graphic) {
PointSymbolizer ps = sf.createPointSymbolizer();
ps.setGraphic(graphic);
return ps;
}
/**
* create a point symbolizer
*
* @param graphic - the graphic object to draw at the point
* @param geometryPropertyName - the name of the geometry to be drawn
*
* @return the new point symbolizer
*/
public PointSymbolizer createPointSymbolizer(Graphic graphic, String geometryPropertyName) {
return sf.createPointSymbolizer(graphic, geometryPropertyName);
}
/**
* Creates a default text symbolizer. Warning: there is no definition of a default text
* symbolizer in the SLD standard, this is provided just for convenience and uniformity with
* the other symbolizers
*
* @return the default text symbolizer
*/
public TextSymbolizer createTextSymbolizer() {
TextSymbolizer ts = sf.createTextSymbolizer();
ts.setFill(createFill(Color.BLACK));
ts.setLabel(literalExpression("Label"));
ts.setFonts(new Font[] { createFont("Lucida Sans", 10)});
return ts;
}
/**
* create a textsymbolizer
*
* @param color the color of the text
* @param font the font to use
* @param attributeName the attribute to use for the label
*
* @return the new textsymbolizer
*
* @throws org.geotools.filter.IllegalFilterException - if the attribute name does not exist
*/
public TextSymbolizer createTextSymbolizer(Color color, Font font, String attributeName)
throws org.geotools.filter.IllegalFilterException {
return createTextSymbolizer(
createFill(color),
new Font[] { font },
null,
attributeExpression(attributeName),
null,
null);
}
/**
* create a textsymbolizer
*
* @param color the color of the text
* @param fonts an array of fonts to use from the first to last
* @param attributeName the attribute to use for the label
*
* @return the new textsymbolizer
*
* @throws org.geotools.filter.IllegalFilterException - if the attribute name does not exist
*/
public TextSymbolizer createTextSymbolizer(Color color, Font[] fonts, String attributeName)
throws org.geotools.filter.IllegalFilterException {
return createTextSymbolizer(
createFill(color),
fonts,
null,
attributeExpression(attributeName),
null,
null);
}
/**
* create a textsymbolizer which doesn't change
*
* @param color the color of the text
* @param font the font to use
* @param label the label to use
*
* @return the new textsymbolizer
*/
public TextSymbolizer createStaticTextSymbolizer(Color color, Font font, String label) {
return createTextSymbolizer(
createFill(color),
new Font[] { font },
null,
literalExpression(label),
null,
null);
}
/**
* create a textsymbolizer which doesn't change
*
* @param color the color of the text
* @param fonts an array of fonts to use from the first to last
* @param label the label to use
*
* @return the new textsymbolizer
*/
public TextSymbolizer createStaticTextSymbolizer(Color color, Font[] fonts, String label) {
return createTextSymbolizer(
createFill(color),
fonts,
null,
literalExpression(label),
null,
null);
}
/**
* create a text symbolizer
*
* @param fill - the fill to color the text
* @param fonts - an array of fonts to use from the first to last
* @param halo - the halo to be applied to the text
* @param label - Expression representing the label
* @param labelPlacement - where to place the label
* @param geometryPropertyName - the name of the geometry to use
*
* @return the new textsymbolizer
*/
public TextSymbolizer createTextSymbolizer(
Fill fill,
Font[] fonts,
Halo halo,
Expression label,
LabelPlacement labelPlacement,
String geometryPropertyName) {
TextSymbolizer ts = sf.createTextSymbolizer();
if (fill != null) {
ts.setFill(fill);
}
if (halo != null) {
ts.setHalo(halo);
}
if (label != null) {
ts.setLabel(label);
}
if (labelPlacement != null) {
ts.setPlacement(labelPlacement);
}
if (geometryPropertyName != null) {
ts.setGeometryPropertyName(geometryPropertyName);
}
if (fonts != null) {
ts.setFonts(fonts);
}
return ts;
}
/**
* create a SimpleFeature type styler
*
* @param symbolizer - the symbolizer to use
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(Symbolizer symbolizer) {
return createFeatureTypeStyle(null, symbolizer, Double.NaN, Double.NaN);
}
/**
* create a simple styling rule
*
* @param symbolizer - the symbolizer to use
*
* @return the new rule
*/
public Rule createRule(Symbolizer symbolizer) {
return createRule(symbolizer, Double.NaN, Double.NaN);
}
/**
* reate a simple styling rule
*
* @param symbolizers - an array of symbolizers to use
*
* @return the new rule
*/
public Rule createRule(Symbolizer[] symbolizers) {
return createRule(symbolizers, Double.NaN, Double.NaN);
}
/**
* create a simple styling rule, see the SLD Spec for more details of scaleDenominators
*
* @param symbolizer - the symbolizer to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new rule
*/
public Rule createRule(
Symbolizer symbolizer,
double minScaleDenominator,
double maxScaleDenominator) {
return createRule(new Symbolizer[] { symbolizer }, Double.NaN, Double.NaN);
}
/**
* create a simple styling rule, see the SLD Spec for more details of scaleDenominators
*
* @param symbolizers - an array of symbolizers to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new rule
*/
public Rule createRule(
Symbolizer[] symbolizers,
double minScaleDenominator,
double maxScaleDenominator) {
Rule r = sf.createRule();
r.setSymbolizers(symbolizers);
if (!Double.isNaN(maxScaleDenominator)) {
r.setMaxScaleDenominator(maxScaleDenominator);
} else {
r.setMaxScaleDenominator(Double.POSITIVE_INFINITY);
}
if (!Double.isNaN(minScaleDenominator)) {
r.setMinScaleDenominator(minScaleDenominator);
} else {
r.setMinScaleDenominator(0.0);
}
return r;
}
/**
* create a SimpleFeature type styler see the SLD Spec for more details of scaleDenominators
*
* @param symbolizer - the symbolizer to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(
Symbolizer symbolizer,
double minScaleDenominator,
double maxScaleDenominator) {
return createFeatureTypeStyle(null, symbolizer, minScaleDenominator, maxScaleDenominator);
}
/**
* create a SimpleFeature type styler see the SLD Spec for more details of scaleDenominators
*
* @param symbolizers - an array of symbolizers to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(
Symbolizer[] symbolizers,
double minScaleDenominator,
double maxScaleDenominator) {
return createFeatureTypeStyle(null, symbolizers, minScaleDenominator, maxScaleDenominator);
}
/**
* create a SimpleFeature type styler
*
* @param featureTypeName - name of the feature type
* @param symbolizer - the symbolizer to use
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(
String featureTypeName,
Symbolizer symbolizer) {
return createFeatureTypeStyle(featureTypeName, symbolizer, Double.NaN, Double.NaN);
}
/**
* create a SimpleFeature type styler
*
* @param featureTypeName - name of the feature type
* @param symbolizers - an array of symbolizers to use
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(
String featureTypeName,
Symbolizer[] symbolizers) {
return createFeatureTypeStyle(featureTypeName, symbolizers, Double.NaN, Double.NaN);
}
/**
* create a SimpleFeature type styler see the SLD Spec for more details of scaleDenominators
*
* @param typeName - The feature typeName you want to draw (use "Feature" as a wild card to match all)
* @param symbolizer - the symbolizer to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(
String typeName,
Symbolizer symbolizer,
double minScaleDenominator,
double maxScaleDenominator) {
return createFeatureTypeStyle(
typeName,
new Symbolizer[] { symbolizer },
minScaleDenominator,
maxScaleDenominator);
}
/**
* create a SimpleFeature type styler see the SLD Spec for more details of scaleDenominators
*
* @param typeName - The feature typeName you want to draw (use "Feature" as a wild card to match all)
* @param symbolizers - an array of symbolizers to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(
String typeName,
Symbolizer[] symbolizers,
double minScaleDenominator,
double maxScaleDenominator) {
Rule r = createRule(symbolizers, minScaleDenominator, maxScaleDenominator);
// setup the feature type style
FeatureTypeStyle fts = sf.createFeatureTypeStyle();
fts.setRules(new Rule[] { r });
if (typeName != null) {
fts.setFeatureTypeName(typeName);
}
return fts;
}
/**
* create a SimpleFeature type styler
*
* @param typeName - The feature typeName you want to draw (use "Feature" as a wild card to match all)
* @param r - the rule that driver this feature typ style
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(String typeName, Rule r) {
// setup the feature type style
FeatureTypeStyle fts = sf.createFeatureTypeStyle();
fts.setRules(new Rule[] { r });
if (typeName != null) {
fts.setFeatureTypeName(typeName);
}
return fts;
}
/**
* create a SimpleFeature type styler see the SLD Spec for more details of scaleDenominators
*
* @param typeName - The feature typeName you want to draw (use "Feature" as a wild card to match all)
* @param rules - the rules that make up the FeatureTypeStyle
*
* @return the new feature type styler
*/
public FeatureTypeStyle createFeatureTypeStyle(String typeName, Rule[] rules) {
FeatureTypeStyle fts = sf.createFeatureTypeStyle();
fts.setRules(rules);
if (typeName != null) {
fts.setFeatureTypeName(typeName);
}
return fts;
}
/**
* create a new style
*
* @param symbolizer - the symbolizer to use
*
* @return the new style
*/
public Style createStyle(Symbolizer symbolizer) {
return createStyle(null, symbolizer, Double.NaN, Double.NaN);
}
/**
* create a new style
*
* @param symbolizer - the symbolizer to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new style
*/
public Style createStyle(
Symbolizer symbolizer,
double minScaleDenominator,
double maxScaleDenominator) {
return createStyle(null, symbolizer, minScaleDenominator, maxScaleDenominator);
}
/**
* create a new style
*
* @param typeName - The feature typeName you want to draw (use "Feature" as a wild card to match all)
* @param symbolizer - the symbolizer to use
*
* @return the new style
*/
public Style createStyle(String typeName, Symbolizer symbolizer) {
return createStyle(typeName, symbolizer, Double.NaN, Double.NaN);
}
/**
* create a new style
*
* @param typeName - The feature typeName you want to draw (use "Feature" as a wild card to match all)
* @param symbolizer - the symbolizer to use
* @param minScaleDenominator - the minimim scale to draw the feature at
* @param maxScaleDenominator - the maximum scale to draw the feature at
*
* @return the new style
*/
public Style createStyle(
String typeName,
Symbolizer symbolizer,
double minScaleDenominator,
double maxScaleDenominator) {
// create the feature type style
FeatureTypeStyle fts =
createFeatureTypeStyle(
typeName,
symbolizer,
minScaleDenominator,
maxScaleDenominator);
// and finally create the style
Style style = sf.createStyle();
style.addFeatureTypeStyle(fts);
return style;
}
/**
* create a new default style
*
* @return the new style
*/
public Style createStyle() {
return sf.createStyle();
}
/**
* convert an awt color in to a literal expression representing the color
*
* @param color the color to encode
*
* @return the expression
*/
public Expression colorExpression(Color color) {
if (color == null) {
return null;
}
String redCode = Integer.toHexString(color.getRed());
String greenCode = Integer.toHexString(color.getGreen());
String blueCode = Integer.toHexString(color.getBlue());
if (redCode.length() == 1) {
redCode = "0" + redCode;
}
if (greenCode.length() == 1) {
greenCode = "0" + greenCode;
}
if (blueCode.length() == 1) {
blueCode = "0" + blueCode;
}
String colorCode = "#" + redCode + greenCode + blueCode;
return ff.literal(colorCode.toUpperCase());
}
/**
* create a literal expression representing the value
*
* @param value the value to be encoded
*
* @return the expression
*/
public Expression literalExpression(double value) {
return ff.literal(value);
}
/**
* create a literal expression representing the value
*
* @param value the value to be encoded
*
* @return the expression
*/
public Expression literalExpression(int value) {
return ff.literal(value);
}
/**
* create a literal expression representing the value
*
* @param value the value to be encoded
*
* @return the expression
*/
public Expression literalExpression(String value) {
Expression result = null;
if (value != null) {
result = ff.literal(value);
}
return result;
}
/**
* create a literal expression representing the value
*
* @param value the value to be encoded
*
* @return the expression
*
* @throws IllegalFilterException DOCUMENT ME!
*/
public Expression literalExpression(Object value) throws IllegalFilterException {
Expression result = null;
if (value != null) {
result = ff.literal(value);
}
return result;
}
/**
* create an attribute expression
*
* @param attributeName the attribute to use
*
* @return the new expression
*
* @throws org.geotools.filter.IllegalFilterException if the attribute name does not exist
*/
public Expression attributeExpression(String attributeName)
throws org.geotools.filter.IllegalFilterException {
return ff.property( attributeName );
}
/**
* given a feature collection and an array of colours build a style with the given number of
* classes on the named column
*
* @param fc DOCUMENT ME!
* @param name DOCUMENT ME!
* @param colors DOCUMENT ME!
* @param schema DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws IllegalFilterException DOCUMENT ME!
*/
public Style buildClassifiedStyle(
FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
String name,
String[] colors,
SimpleFeatureType schema)
throws IllegalFilterException {
//grab attribute col
PropertyName value = ff.property(name);
String geomName = schema.getGeometryDescriptor().getLocalName();
double[] values = new double[fc.size()];
Iterator it = fc.iterator();
int count = 0;
while (it.hasNext()) {
SimpleFeature f = (SimpleFeature) it.next();
values[count++] = ((Number) f.getAttribute(name)).doubleValue();
}
//pass to classification algorithm
EqualClasses ec = new EqualClasses(colors.length, values);
//build style
double[] breaks = ec.getBreaks();
Style ret = createStyle();
// ret.setName(name);
Rule[] rules = new Rule[colors.length + 1];
PropertyIsLessThan cf1 = ff.less( value, ff.literal( breaks[0] ));
LOGGER.fine(cf1.toString());
rules[0] = sf.createRule();
rules[0].setFilter(cf1);
// rules[0].setName("lowest");
Color c = this.createColor(colors[0]);
PolygonSymbolizer symb1 = createPolygonSymbolizer(c, Color.black, 1.0);
//@todo: this should set the geometry name but currently this breaks the legend
// symb1.setGeometryPropertyName(geomName);
rules[0].setSymbolizers(new Symbolizer[] { symb1 });
LOGGER.fine("added low class " + breaks[0] + " " + colors[0]);
// LOGGER.fine(rules[0].toString());
for (int i = 1; i < (colors.length - 1); i++) {
rules[i] = sf.createRule();
Expression expr = value;
Expression lower = ff.literal(breaks[i - 1]);
Expression upper = ff.literal(breaks[i]);
PropertyIsBetween cf = ff.between(expr, lower, upper);
LOGGER.fine(cf.toString());
c = this.createColor(colors[i]);
LOGGER.fine("color " + c.toString());
PolygonSymbolizer symb = createPolygonSymbolizer(c, Color.black, 1.0);
// symb.setGeometryPropertyName(geomName);
rules[i].setSymbolizers(new Symbolizer[] { symb });
rules[i].setFilter(cf);
// rules[i].setName("class "+i);
LOGGER.fine("added class " + breaks[i - 1] + "->" + breaks[i] + " " + colors[i]);
}
PropertyIsGreaterThan cf2 = ff.greater( value, ff.literal(breaks[colors.length - 2]));
LOGGER.fine(cf2.toString());
rules[colors.length - 1] = sf.createRule();
rules[colors.length - 1].setFilter(cf2);
rules[colors.length - 1].setName(geomName);
c = this.createColor(colors[colors.length - 1]);
PolygonSymbolizer symb2 = createPolygonSymbolizer(c, Color.black, 1.0);
// symb2.setGeometryPropertyName(geomName);
rules[colors.length - 1].setSymbolizers(new Symbolizer[] { symb2 });
LOGGER.fine(
"added upper class " + breaks[colors.length - 2] + " " + colors[colors.length - 1]);
rules[colors.length] = sf.createRule();
PolygonSymbolizer elsePoly = createPolygonSymbolizer(Color.black, 1.0);
rules[colors.length].setSymbolizers(new Symbolizer[] { elsePoly });
rules[colors.length].setElseFilter(true);
FeatureTypeStyle ft = sf.createFeatureTypeStyle(rules);
ft.setFeatureTypeName("Feature");
ft.setName(name);
ret.addFeatureTypeStyle(ft);
return ret;
}
private Color createColor(String text) {
int i = Integer.decode("0x" + text).intValue();
return Color.decode("" + i);
}
/**
* Creates the default raster symbolizer
*/
public RasterSymbolizer createRasterSymbolizer() {
return sf.getDefaultRasterSymbolizer();
}
/**
* Creates a raster symbolizer
* @param colorMap The symbolizer color map
* @param opacity The whole layer opacity
*
*/
public RasterSymbolizer createRasterSymbolizer(ColorMap colorMap, double opacity) {
RasterSymbolizer rs = sf.getDefaultRasterSymbolizer();
rs.setColorMap(colorMap);
rs.setOpacity(literalExpression(opacity));
return rs;
}
/**
* Creates a color map based on fixed quantities and colors.
* @param quantities The values that begin a category, or break points in a ramp,
* or isolated values, according to the type of color map specified by Type
* @param colors The colors that will be associated to the categories, break points, or isolated values
* @param type Either @link ColorMap#TYPE_RAMP, @link ColorMap#TYPE_INTERVALS or @link ColorMap#TYPE_VALUES
*/
public ColorMap createColorMap(String[] labels, double[] quantities, Color[] colors, int type) {
ColorMap colorMap = sf.createColorMap();
colorMap.setType(type);
if ((labels == null) || (quantities == null) || (colors == null) || (labels.length != quantities.length) || (quantities.length != colors.length)) {
throw new IllegalArgumentException("Labels, quantities and colors arrays should be not null and have the same size");
}
for (int i = 0; i < colors.length; i++) {
colorMap.addColorMapEntry(createColorMapEntry(labels[i], quantities[i], colors[i]));
}
return colorMap;
}
/**
* Creates a simple color entity based on a fixed value and a color.<br>
* The color alpha will be used as the entry's opacity
* @param quantity The entry's quantity
* @param color The entry's color.
*/
private ColorMapEntry createColorMapEntry(String label, double quantity, Color color) {
ColorMapEntry entry = sf.createColorMapEntry();
entry.setQuantity(literalExpression(quantity));
entry.setColor(colorExpression(color));
entry.setOpacity(literalExpression(color.getAlpha() / 255.0));
entry.setLabel(label);
return entry;
}
public class EqualClasses {
int numberClasses;
double[] breaks;
double[] collection;
/**
* Creates a new instance of EqualClasses
*
* @param numberClasses
* @param fc
*/
public EqualClasses(int numberClasses, double[] fc) {
breaks = new double[numberClasses-1];
setCollection(fc);
setNumberClasses(numberClasses);
}
/** Getter for property numberClasses.
* @return Value of property numberClasses.
*
*/
public int getNumberClasses() {
return numberClasses;
}
/** Setter for property numberClasses.
* @param numberClasses New value of property numberClasses.
*
*/
public void setNumberClasses(int numberClasses) {
this.numberClasses = numberClasses;
if(breaks == null){
breaks = new double[numberClasses-1];
}
Arrays.sort(collection);
int step = collection.length/numberClasses;
for(int i=step,j=0;j<breaks.length;j++,i+=step){
breaks[j] = collection[i];
}
}
/**
* returns the the break points between the classes
* <b>Note</b> You get one less breaks than number of classes.
* @return Value of property breaks.
*
*/
public double[] getBreaks() {
return this.breaks;
}
/** Setter for property collection.
* @param collection New value of property collection.
*
*/
public void setCollection(double[] collection) {
this.collection = collection;
}
}
}