[Schmitzm-commits] r1174 - in trunk: src/schmitzm/geotools/styling src_junit/schmitzm/lang
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Tue Oct 26 12:00:34 CEST 2010
Author: alfonx
Date: 2010-10-26 12:00:34 +0200 (Tue, 26 Oct 2010)
New Revision: 1174
Modified:
trunk/src/schmitzm/geotools/styling/StylingUtil.java
trunk/src_junit/schmitzm/lang/ResourceProviderTest.java
Log:
Added comments and sorted StylingUtil.java
Modified: trunk/src/schmitzm/geotools/styling/StylingUtil.java
===================================================================
--- trunk/src/schmitzm/geotools/styling/StylingUtil.java 2010-10-26 10:00:10 UTC (rev 1173)
+++ trunk/src/schmitzm/geotools/styling/StylingUtil.java 2010-10-26 10:00:34 UTC (rev 1174)
@@ -88,7 +88,6 @@
import org.geotools.resources.i18n.VocabularyKeys;
import org.geotools.styling.ColorMap;
import org.geotools.styling.ColorMapEntry;
-import org.geotools.styling.ColorMapEntryImpl;
import org.geotools.styling.ColorMapImpl;
import org.geotools.styling.ExternalGraphic;
import org.geotools.styling.FeatureTypeStyle;
@@ -116,6 +115,7 @@
import org.geotools.util.NumberRange;
import org.jdom.Element;
import org.jdom.output.XMLOutputter;
+import org.jfree.util.Log;
import org.opengis.coverage.grid.Grid;
import org.opengis.coverage.grid.GridCoverage;
import org.opengis.feature.simple.SimpleFeature;
@@ -131,7 +131,6 @@
import org.opengis.filter.expression.Literal;
import org.opengis.filter.expression.PropertyName;
-import schmitzm.data.DataUtil;
import schmitzm.geotools.FilterUtil;
import schmitzm.geotools.feature.FeatureUtil;
import schmitzm.geotools.feature.FeatureUtil.GeometryForm;
@@ -160,16 +159,13 @@
* @version 1.1
*/
public class StylingUtil {
- private static final FilterFactory FILTER_FACTORY = FeatureUtil.FILTER_FACTORY;
private static final Logger LOGGER = Logger.getLogger(StylingUtil.class);
- /** transparent color */
- public static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);
- /** Standard-Instanz eines {@link StyleBuilder}. */
- public static final StyleBuilder STYLE_BUILDER = new StyleBuilder();
+ static final Literal zeroLit = FeatureUtil.FILTER_FACTORY2.literal(0);
/** Standard-Instanz eines {@link SLDTransformer}. */
public final static SLDTransformer SLDTRANSFORMER = new SLDTransformer();
+
static {
SLDTRANSFORMER.setEncoding(Charset.defaultCharset());
}
@@ -178,19 +174,38 @@
public static final StyleFactory STYLE_FACTORY = CommonFactoryFinder
.getStyleFactory(GeoTools.getDefaultHints());
+ /** Standard-Instanz eines {@link StyleBuilder}. */
+ public static final StyleBuilder STYLE_BUILDER = new StyleBuilder(
+ STYLE_FACTORY);
+
/**
- * TODO SK The following constants are used to speed up
- * {@link #createSelectionStyle(Object)}. I will "redo" them soon and also
- * document them. This is still under construction. TODO SK
+ * Lists a few predefined {@link Style}s usefull to mark selected features.
*/
+ public enum SelectionStylesTypes {
+ LeftTop2RightBottom_lines, LeftTop2RightBottom_lines_biggaps, LeftTop2RightBottom_lines_smallgaps, Outline_only, RightTop2LeftBottom_lines, RightTop2LeftBottom_lines_biggaps, RightTop2LeftBottom_lines_smallgaps
+ }
+ /**
+ * RegEx Patter to read palette information from gdalinfo output, for images
+ * wir <code>RGB</code>, @see {@link #parseColormapToSld(URL)} @see
+ * {@link #parseColormapToSld(File)}
+ **/
+ public static final Pattern GDALINFO_COLORMAP_RGB = Pattern
+ .compile("^.*(\\d+): (\\d+),(\\d+),(\\d+).*$");
+
+ /**
+ * RegEx Patter to read palette information from gdalinfo output, for images
+ * wir <code>RGBA</code> @see {@link #parseColormapToSld(URL)} @see
+ * {@link #parseColormapToSld(File)}
+ **/
+ public static final Pattern GDALINFO_COLORMAP_RGBA = Pattern
+ .compile("^.*(\\d+): (\\d+),(\\d+),(\\d+),(\\d+).*$");
+
+ static final Literal halfLit = FeatureUtil.FILTER_FACTORY2.literal(.5);
static final Literal size0 = FeatureUtil.FILTER_FACTORY2.literal(26);
-
static final Literal size1 = FeatureUtil.FILTER_FACTORY2.literal(9);
static final Literal size2 = FeatureUtil.FILTER_FACTORY2.literal(7);
static final Literal size3 = FeatureUtil.FILTER_FACTORY2.literal(3);
- static final Literal zeroLit = FeatureUtil.FILTER_FACTORY2.literal(0);
- static final Literal halfLit = FeatureUtil.FILTER_FACTORY2.literal(.5);
static final Graphic SELECTION_GRAPHIC1 = STYLE_FACTORY.createGraphic(
new ExternalGraphic[0], new Mark[] { STYLE_FACTORY.createMark(
@@ -200,14 +215,6 @@
new org.geotools.styling.Symbol[0], FeatureUtil.FILTER_FACTORY2
.literal(1), size1, zeroLit);
- static final Graphic BLINK_GRAPHIC1 = STYLE_FACTORY.createGraphic(
- new ExternalGraphic[0], new Mark[] { STYLE_FACTORY.createMark(
- FeatureUtil.FILTER_FACTORY2.literal("circle"), null,
- STYLE_FACTORY.createFill(STYLE_BUILDER
- .colorExpression(Color.WHITE)), size0, halfLit) },
- new org.geotools.styling.Symbol[0], FeatureUtil.FILTER_FACTORY2
- .literal(1), size0, zeroLit);
-
static final Graphic SELECTION_GRAPHIC2 = STYLE_FACTORY.createGraphic(
new ExternalGraphic[0], new Mark[] { STYLE_FACTORY.createMark(
FeatureUtil.FILTER_FACTORY2.literal("circle"), null,
@@ -215,7 +222,6 @@
.colorExpression(Color.BLACK)), size2, zeroLit) },
new org.geotools.styling.Symbol[0], FeatureUtil.FILTER_FACTORY2
.literal(1), size2, zeroLit);
-
static final Graphic SELECTION_GRAPHIC3 = STYLE_FACTORY.createGraphic(
new ExternalGraphic[0], new Mark[] { STYLE_FACTORY.createMark(
FeatureUtil.FILTER_FACTORY2.literal("circle"), null,
@@ -224,231 +230,40 @@
zeroLit) }, new org.geotools.styling.Symbol[0],
FeatureUtil.FILTER_FACTORY2.literal(1), size3, zeroLit);
+ static final Graphic BLINK_GRAPHIC1 = STYLE_FACTORY.createGraphic(
+ new ExternalGraphic[0], new Mark[] { STYLE_FACTORY.createMark(
+ FeatureUtil.FILTER_FACTORY2.literal("circle"), null,
+ STYLE_FACTORY.createFill(STYLE_BUILDER
+ .colorExpression(Color.WHITE)), size0, halfLit) },
+ new org.geotools.styling.Symbol[0], FeatureUtil.FILTER_FACTORY2
+ .literal(1), size0, zeroLit);
+ private static final FilterFactory FILTER_FACTORY = FeatureUtil.FILTER_FACTORY;
+
/**
* THis string is set as the Name of the Rules that describe selected
* features
**/
public static final String SELECTION_RULE_ID = "SelectionRule";
+//
+// /** transparent color */
+// public static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0);
/**
- * Erstellt einen Default-Style fuer die Klassen/Interfaces:
- * StyledFeaturesInterface, GridCoverage2D, FeatureCollection, FeatureSource
- * und GeometryAttributeType.
+ * Unless {@link ColorMap} is not sorted automatically, this method calls
+ * {@link #sortColorMap(ColorMap)} after inserting the color map entry.
*
- * @param object
- * {@link GridCoverage2D},
- * {@link org.geotools.coverage.grid.io.AbstractGridCoverage2DReader}
- * oder {@link FeatureCollection}
- * @return {@code null} falls kein Style generiert werden kann
- *
- * @Deprectated Use FeatureUtil.createDefaultStyle and
- * FeatureUtil.getGeometryForm
- */
- public static Style createDefaultStyle(Object object) {
- Style style = STYLE_BUILDER.createStyle(); // SK.. nicer default than
- // null !
-
- if (object instanceof StyledFeaturesInterface)
- style = FeatureUtil
- .createDefaultStyle(((StyledFeaturesInterface<?>) object)
- .getSchema().getGeometryDescriptor());
-
- if (object instanceof GridCoverage2D
- || object instanceof AbstractGridCoverage2DReader
- || object instanceof StyledRasterInterface)
- style = GridUtil.createDefaultStyle();
-
- if (object instanceof FeatureCollection)
- style = FeatureUtil
- .createDefaultStyle((FeatureCollection<SimpleFeatureType, SimpleFeature>) object);
-
- if (object instanceof FeatureSource)
- style = FeatureUtil.createDefaultStyle(((FeatureSource) object)
- .getSchema().getGeometryDescriptor());
-
- if (object instanceof GeometryAttributeType)
- style = FeatureUtil
- .createDefaultStyle((GeometryAttributeType) object);
-
- return style;
- }
-
- /**
- * Erzeugt eine {@link Category} fuer die NoData-Werte transparent
- * dargestellt werden.
- *
- * @param geoValue
- * Geo-Wert, der NoData repraesentiert
- */
- public static Category createNoDataCategory(double geoValue) {
- return createNoDataCategory(0, geoValue);
- }
-
- /**
- * Erzeugt eine {@link Category} fuer die NoData-Werte transparent
- * dargestellt werden.
- *
- * @param value
- * Sample-Wert der Category
- * @param geoValue
- * Geo-Wert, der NoData repraesentiert
- */
- public static Category createNoDataCategory(int value, double geoValue) {
- return new Category(
- Vocabulary.formatInternational(VocabularyKeys.NODATA),
- new Color[] { new Color(0, 0, 0, 0) }, new NumberRange(value,
- value), new NumberRange(geoValue, geoValue));
- }
-
- /**
- * Erzeugt eine {@link GridSampleDimension} aus einer {@link ColorMap}.
- *
- * @param name
- * Name fuer die {@link GridSampleDimension}
* @param colorMap
- * fuer jeden Eintrag der {@link ColorMap} wird eine
- * {@link Category} erzeugt
- * @param noDataValues
- * Werte fuer die zusaetzliche {@link Category Categorys}
- * erstellt werden, welche die transparent dargestellt werden
- * (wenn {@code null} wird keine zusaetzliche {@link Category}
- * erstellt)
- * @param unit
- * Einheit der Werte in der {@link GridSampleDimension} (kann
- * {@code null} sein)
+ * the color map to extend
+ * @param colorMapEntry
+ * the new entry
*/
- public static GridSampleDimension createDiscreteGridSampleDimension(
- String name, ColorMap colorMap, double[] noDataValues, Unit<?> unit) {
- if (colorMap.getColorMapEntries().length == 0)
- return null;
-
- SortedMap<Integer, Category> categories = new TreeMap<Integer, Category>();
- if (noDataValues == null)
- noDataValues = new double[0];
-
- // Create a (discrete) Category for each ColorMapEntry
- int colorMapMin = Integer.MAX_VALUE;
- int colorMapMax = Integer.MIN_VALUE;
- for (ColorMapEntry cme : colorMap.getColorMapEntries()) {
- String label = cme.getLabel();
- Color color = getColorFromColorMapEntry(cme);
- double value = getQuantityFromColorMapEntry(cme);
- int intValue = (int) Math.round(value);
- colorMapMin = Math.min(colorMapMin, intValue);
- colorMapMax = Math.max(colorMapMax, intValue);
- // if ( label == null || label.trim().equals("") )
- // label = String.valueOf(intValue);
- if (label == null)
- label = "";
- categories.put(intValue, new Category(label, new Color[] { color },
- new NumberRange(intValue, intValue), new NumberRange(
- intValue, intValue)));
- }
-
- // If NoData-Value is set, create an additional Category
- for (double noDataValue : noDataValues) {
- int value = categories.lastKey() + 10; // value not already used
- categories.put(value, createNoDataCategory(value, noDataValue));
- colorMapMin = Math.min(colorMapMin, (int) noDataValue);
- colorMapMax = Math.max(colorMapMax, (int) noDataValue);
- }
-
- // Declare "all" values smaller/greater the color map values
- // automatically as NoData
- // int colorMapRange = colorMapMax - colorMapMin;
- // double lowerStart = colorMapMin - 10000*colorMapRange;
- // double higherEnd = colorMapMax + 10000*colorMapRange;
- final int lowerStart = Integer.MIN_VALUE;
- final int higherEnd = Integer.MAX_VALUE;
- categories.put(colorMapMax + 10, new Category("_autoNoData1_",
- new Color[] { new Color(0, 0, 0, 0) }, new NumberRange(
- colorMapMax + 1, colorMapMax + 2), new NumberRange(
- colorMapMax + 1, higherEnd)));
- if (colorMapMin < colorMapMax)
- categories.put(colorMapMin - 10, new Category("_autoNoData2_",
- new Color[] { new Color(0, 0, 0, 0) },
- // new NumberRange(colorMapMin-2, colorMapMin-1), //
- // logischer, aber klappt nicht!?
- NumberRange.create(colorMapMax + 3, colorMapMax + 4),
- // new NumberRange(colorMapMax + 3, colorMapMax + 4),
- NumberRange.create(lowerStart, colorMapMin - 1)
- // new NumberRange(lowerStart, colorMapMin - 1)
- ));
-
- // Create the GridSampleDimension
- GridSampleDimension gsd = new GridSampleDimension(name, categories
- .values().toArray(new Category[0]), unit).geophysics(true);
-
- for (Category c : (List<Category>) gsd.getCategories())
- LOGGER.debug(c.toString());
-
- return gsd;
+ public static ColorMap addColorMapEntryAndSort(ColorMap colorMap,
+ ColorMapEntry colorMapEntry) {
+ colorMap.addColorMapEntry(colorMapEntry);
+ return sortColorMap(colorMap);
}
/**
- * Liefert die Farbpalette zu einem Style, wenn der Style aus einem
- * {@link RasterSymbolizer} erzeugt wurde.
- *
- * @param style
- * Style Wenn <code>null</code>, dann wird style auf
- * {@link GridUtil}.createDefaultStyle() gesetzt
- * @return <code>null</code> wenn der Style nicht auf einem
- * {@link RasterSymbolizer} basiert.
- */
- public static ColorMap getColorMapFromStyle(final Style style) {
- final List<ColorMap> colorMapsFromStyle = getColorMapsFromStyle(style);
- if (colorMapsFromStyle.size() > 0)
- return colorMapsFromStyle.get(0);
- else
- return null;
-
- }
-
- /**
- * Liefert alle Farbpaletten aus einem Style, wenn irgendo
- * {@link RasterSymbolizer} enthalten sind.
- *
- * @param style
- * Style Wenn <code>null</code>, dann wird style auf
- * {@link GridUtil}.createDefaultStyle() gesetzt
- * @return Leere Liste wenn keine RasterSymbolizer enthalten ist.
- */
- public static List<ColorMap> getColorMapsFromStyle(Style style) {
-
- if (style == null)
- style = GridUtil.createDefaultStyle();
-
- final List<RasterSymbolizer> rasterSymbolizers = getRasterSymbolizers(style);
-
- final List<ColorMap> colorMaps = new ArrayList<ColorMap>();
-
- for (final RasterSymbolizer rs : rasterSymbolizers) {
- if (rs.getColorMap() != null) {
- colorMaps.add(rs.getColorMap());
- }
- }
-
- return colorMaps;
- }
-
- /**
- * Ermittelt fuer einen Wert den {@link ColorMapEntry} aus einer
- * {@link ColorMap}.
- *
- * @param value
- * Wert
- * @return {@code null}, wenn in der {@link ColorMap} kein expliziter
- * Eintrag fuer den Wert hinterlegt ist
- */
- public static ColorMapEntry findColorMapEntry(ColorMap colorMap,
- double value) {
- for (ColorMapEntry entry : colorMap.getColorMapEntries())
- if (value == getQuantityFromColorMapEntry(entry))
- return entry;
- return null;
- }
-
- /**
* Applies general properties (color map type and extended colors) to a
* {@link ColorMap}.
*
@@ -466,121 +281,53 @@
}
/**
- * Unless {@link ColorMap} has no methods to remove an entry this method
- * creates a new {@link ColorMap} with the identical entries except the one
- * to remove.
+ * Removes all label information from the {@link ColorMapEntry}s of the
+ * given {@link ColorMap}
*
- * @param colorMap
- * the color map to remove entries from
- * @param idx
- * the entry index to remove
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static ColorMap removeColorMapEntry(ColorMap colorMap, int idx) {
- ColorMap newColorMap = new ColorMapImpl();
- applyColorMapProperties(colorMap, newColorMap);
-
- ColorMapEntry[] entry = colorMap.getColorMapEntries();
- for (int i = 0; i < entry.length; i++)
- if (i != idx)
- newColorMap.addColorMapEntry(entry[i]);
-
- return newColorMap;
+ public static ColorMap clearColorMapLabels(ColorMap colorMap) {
+ for (ColorMapEntry cme : colorMap.getColorMapEntries()) {
+ cme.setLabel(null);
+ }
+ return colorMap;
}
/**
- * Unless {@link ColorMap} has no methods to remove an entry this method
- * creates a new {@link ColorMap} with the identical entries except the one
- * to remove.
+ * Clons a {@link Graphic} element
*
- * @param colorMap
- * the color map to remove entries from
- * @param colorMapEntry
- * the entry to remove
+ * @param graphicFill
+ * @return
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static ColorMap removeColorMapEntry(ColorMap colorMap,
- ColorMapEntry colorMapEntry) {
- ColorMap newColorMap = new ColorMapImpl();
- applyColorMapProperties(colorMap, newColorMap);
-
- ColorMapEntry[] entry = colorMap.getColorMapEntries();
- for (int i = 0; i < entry.length; i++)
- if (entry[i] != colorMapEntry)
- newColorMap.addColorMapEntry(entry[i]);
-
- return newColorMap;
+ public static Graphic clone(Graphic graphic) {
+ DuplicatingStyleVisitor duplicatingStyleVisitor = new DuplicatingStyleVisitor();
+ graphic.accept(duplicatingStyleVisitor);
+ return (Graphic) duplicatingStyleVisitor.getCopy();
}
/**
- * Unless {@link ColorMap} is not sorted automatically, this method calls
- * {@link #sortColorMap(ColorMap)} after inserting the color map entry.
+ * Clones a Style by converting it to XML and reading it back in.
*
- * @param colorMap
- * the color map to extend
- * @param colorMapEntry
- * the new entry
+ * @param style
+ * the {@link Style} to be copied.
*/
- public static ColorMap addColorMapEntryAndSort(ColorMap colorMap,
- ColorMapEntry colorMapEntry) {
- colorMap.addColorMapEntry(colorMapEntry);
- return sortColorMap(colorMap);
+ public static Style clone(Style style) {
+ DuplicatingStyleVisitor duplicatingStyleVisitor = new DuplicatingStyleVisitor();
+ style.accept(duplicatingStyleVisitor);
+ return (Style) duplicatingStyleVisitor.getCopy();
}
/**
- * Sorts a {@link ColorMap} according to the value of its entries.
- *
- * @param colorMap
- * the color map to sort
+ * Clones a {@link Symbolizer} using the {@link DuplicatingStyleVisitor}.
*/
- public static ColorMap sortColorMap(ColorMap colorMap) {
- ColorMap newColorMap = new ColorMapImpl();
- applyColorMapProperties(colorMap, newColorMap);
-
- // Put all color map entries in a sorted map (with
- // collision lists!)
- SortedMap<Double, Vector<ColorMapEntry>> sortedEntries = new TreeMap<Double, Vector<ColorMapEntry>>();
- for (ColorMapEntry entry : colorMap.getColorMapEntries()) {
- double quantity = getQuantityFromColorMapEntry(entry);
- Vector<ColorMapEntry> collisionList = sortedEntries.get(quantity);
- if (collisionList == null) {
- collisionList = new Vector<ColorMapEntry>();
- sortedEntries.put(quantity, collisionList);
- }
- collisionList.add(entry);
- }
-
- // According to the order of the sorted map, put all
- // color map entries to the new ColorMap
- for (Vector<ColorMapEntry> collisionList : sortedEntries.values())
- for (ColorMapEntry entry : collisionList)
- newColorMap.addColorMapEntry(entry);
-
- return newColorMap;
+ public static Symbolizer clone(Symbolizer sym) {
+ DuplicatingStyleVisitor duplicatingStyleVisitor = new DuplicatingStyleVisitor();
+ sym.accept(duplicatingStyleVisitor);
+ return (Symbolizer) duplicatingStyleVisitor.getCopy();
}
/**
- * Returns the color map type specified by a given string.
- *
- * @param typeStr
- * a string
- * @see ColorMap#getType()
- */
- public static int getColorMapType(String typeStr) {
- if (typeStr == null)
- throw new IllegalArgumentException("Unknown color map type: "
- + typeStr);
-
- typeStr = typeStr.trim().toLowerCase();
- if (typeStr.equals("ramp") || typeStr.equals("type_ramp"))
- return ColorMap.TYPE_RAMP;
- if (typeStr.equals("intervals") || typeStr.equals("type_intervals"))
- return ColorMap.TYPE_INTERVALS;
- if (typeStr.equals("values") || typeStr.equals("type_values"))
- return ColorMap.TYPE_VALUES;
-
- throw new IllegalArgumentException("Unknown color map type: " + typeStr);
- }
-
- /**
* Kopiert eine {@link ColorMap}.
*
* @return <code>null</code> wenn die uebergebene ColorMap <code>null</code>
@@ -600,7 +347,8 @@
if (colorMap == null)
return null;
ColorMapEntry[] entry = colorMap.getColorMapEntries();
- ColorMap newColorMap = new ColorMapImpl();
+// ColorMap newColorMap = new ColorMapImpl();
+ ColorMap newColorMap = STYLE_FACTORY.createColorMap();
newColorMap.setType(colorMap.getType());
for (int i = 0; i < entry.length; i++)
newColorMap.addColorMapEntry(cloneColorMapEntry(entry[i]));
@@ -624,33 +372,6 @@
}
/**
- * Prueft, ob zwei {@link ColorMap}-Instanzen gleich sind.
- *
- * @param cm1
- * eine Farbpalette
- * @param cm2
- * eine andere Farbpalette
- */
- public static boolean colorMapsEqual(ColorMap cm1, ColorMap cm2) {
- if (cm1 == null ^ cm2 == null)
- return false;
- if (cm1 == cm2)
- return true;
-
- ColorMapEntry[] cme1 = cm1.getColorMapEntries();
- ColorMapEntry[] cme2 = cm2.getColorMapEntries();
- if (cme1.length != cme2.length)
- return false;
-
- // Farbpaletten-Eintraege muessen gleich sein und in gleicher
- // Reihenfolge vorliegen!
- for (int i = 0; i < cme1.length; i++)
- if (!colorMapEntriesEqual(cme1[i], cme2[i]))
- return false;
- return true;
- }
-
- /**
* Prueft, ob zwei {@link ColorMapEntry}-Instanzen gleich sind. Dies ist der
* Fall, wenn ihnen der gleiche Wert, die gleiche Farbe, die gleiche
* Transparenz und das gleiche Label zugeordnet ist.
@@ -692,31 +413,6 @@
}
/**
- * Erzeugt einen {@link ColorMapEntry}.
- *
- * @param label
- * Label fuer den Farbpaletten-Eintrag
- * @param quantity
- * Wert fuer den Farbpaletten-Eintrag
- * @param color
- * Farbe fuer den Farbpaletten-Eintrag
- * @param opacity
- * Transparenz fuer die Farbe des Farbpaletten-Eintrag
- */
- public static ColorMapEntry createColorMapEntry(String label,
- Double quantity, Color color, double opacity) {
- ColorMapEntry newEntry = new ColorMapEntryImpl();
- try {
- newEntry.setLabel(label);
- newEntry.setColor(STYLE_BUILDER.colorExpression(color));
- newEntry.setOpacity(STYLE_BUILDER.literalExpression(opacity));
- newEntry.setQuantity(STYLE_BUILDER.literalExpression(quantity));
- } catch (Exception err) {
- }
- return newEntry;
- }
-
- /**
* Kopiert einen {@link ColorMapEntry}.
*
* @return <code>null</code> wenn der uebergebene ColorMapEntry
@@ -737,957 +433,565 @@
}
/**
- * Liefert den Wert eines Farbpaletten-Eintrag.
+ * Prueft, ob zwei {@link ColorMap}-Instanzen gleich sind.
*
- * @param expression
- * Expression, die einen String oder einen Double liefert
- * @return {@code null}, wenn <code>null</code> uebergeben wird
+ * @param cm1
+ * eine Farbpalette
+ * @param cm2
+ * eine andere Farbpalette
*/
- public static Double getQuantityFromExpression(Expression expression) {
- // gt2-2.3.4:
- // if ( expression == null || expression.getValue(null) == null )
- // return null
- // Object exprValue = evaluate.getValue(null);
- // gt2-2.3.4:
- if (expression == null || expression.evaluate(null) == null)
- return null;
- Object exprValue = expression.evaluate(null);
+ public static boolean colorMapsEqual(ColorMap cm1, ColorMap cm2) {
+ if (cm1 == null ^ cm2 == null)
+ return false;
+ if (cm1 == cm2)
+ return true;
- return (exprValue instanceof String) ? Double
- .valueOf((String) exprValue) : ((Number) exprValue)
- .doubleValue();
- }
+ ColorMapEntry[] cme1 = cm1.getColorMapEntries();
+ ColorMapEntry[] cme2 = cm2.getColorMapEntries();
+ if (cme1.length != cme2.length)
+ return false;
- /**
- * Liefert den Wert eines Farbpaletten-Eintrag.
- *
- * @param entry
- * Farbpaletten-Eintrag
- * @return {@code null}, wenn <code>null</code> uebergeben wird
- */
- public static Double getQuantityFromColorMapEntry(ColorMapEntry entry) {
- if (entry == null)
- return null;
- return getQuantityFromExpression(entry.getQuantity());
+ // Farbpaletten-Eintraege muessen gleich sein und in gleicher
+ // Reihenfolge vorliegen!
+ for (int i = 0; i < cme1.length; i++)
+ if (!colorMapEntriesEqual(cme1[i], cme2[i]))
+ return false;
+ return true;
}
- /**
- * Setzt den Wert eines Farbpaletten-Eintrag.
+ /***************************************************************************
+ * Copies all Values from one {@link TextSymbolizer} to another
+ * {@link TextSymbolizer}
*
- * @param entry
- * Farbpaletten-Eintrag
- * @param quantity
- * neuer Wert
- */
- public static void setQuantityForColorMapEntry(ColorMapEntry entry,
- double quantity) {
- if (entry != null)
- entry.setQuantity(STYLE_BUILDER.literalExpression(quantity));
- }
-
- /**
- * Liefert die Transparenz eines Farbpaletten-Eintrag.
+ * @param from
+ * {@link TextSymbolizer} source
+ * @param to
+ * {@link TextSymbolizer} target. May not be <code>null</code>.
*
- * @param expression
- * Expression, die einen String oder einen Double liefert
- * @return 1.0, wenn <code>null</code> uebergeben wird
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static Double getOpacityFromExpression(Expression expression) {
- // gt2-2.3.4:
- // if ( expression == null || expression.getValue(null) == null )
- // return 1.0
- // Object exprValue = evaluate.getValue(null);
- // gt2-2.3.4:
- if (expression == null || expression.evaluate(null) == null)
- return 1.0;
- Object exprValue = expression.evaluate(null);
+ public static void copyAllValues(final TextSymbolizer from,
+ final TextSymbolizer to) {
+ to.setLabel(from.getLabel());
+ to.setPriority(from.getPriority());
- return (exprValue instanceof String) ? Double
- .valueOf((String) exprValue) : ((Number) exprValue)
- .doubleValue();
- }
+ // TODO Does not copy all that has to be copied!
- /**
- * Liefert die Transparenz eines Farbpaletten-Eintrag.
- *
- * @param entry
- * Farbpaletten-Eintrag
- * @return 1.0, wenn <code>null</code> uebergeben wird
- */
- public static Double getOpacityFromColorMapEntry(ColorMapEntry entry) {
- if (entry == null)
- return 1.0;
- return getOpacityFromExpression(entry.getOpacity());
+ final FilterFactory2 ff2 = FeatureUtil.FILTER_FACTORY2;
+
+ to.getFonts()[0].setFontFamily(ff2.literal(from.getFonts()[0]
+ .getFontFamily().toString()));
+ to.getFonts()[0].setFontSize(ff2.literal(from.getFonts()[0]
+ .getFontSize().toString()));
+ to.getFonts()[0].setFontWeight(ff2.literal(from.getFonts()[0]
+ .getFontWeight().toString()));
+ to.getFonts()[0].setFontStyle(ff2.literal(from.getFonts()[0]
+ .getFontStyle().toString()));
}
/**
- * Setzt die Transparenz eines Farbpaletten-Eintrag.
+ * Since GT2.6, the AttributeNames are case sensitive. Also the raster
+ * Styles need GeometryProperty set to "geom" to work. This method checks
+ * all referenced AttributeNames.
*
- * @param entry
- * Farbpaletten-Eintrag
- * @param opacity
- * Transparenzwert
+ * @param Schema
+ * may be <code>null</code>, e.g. for raster layers
+ *
+ * TODO Rename to correctStye
*/
- public static void setOpacityForColorMapEntry(ColorMapEntry entry,
- double opacity) {
- if (entry != null)
- entry.setOpacity(STYLE_BUILDER.literalExpression(opacity));
+ public static Style correctPropertyNames(Style style) {
+ return correctPropertyNames(style, null);
}
/**
- * Liefert die Farbe eines Farbpaletten-Eintrag.
+ * Since GT2.6, the AttributeNames are case sensitive. Also the raster
+ * Styles need GeometryProperty set to "geom" to work. This method checks
+ * all referenced AttributeNames and checks them against the schema.
*
- * @param expression
- * Expression, die einen String liefert
+ * @param Schema
+ * may be <code>null</code>, e.g. for raster layers
+ *
+ * TODO Rename to correctStye
*/
- public static Color getColorFromExpression(Expression expression) {
- if (expression == null)
- return null;
+ public static Style correctPropertyNames(Style style,
+ final SimpleFeatureType schema) {
- if (expression instanceof ConstantExpression) {
- ConstantExpression a = (ConstantExpression) expression;
- Object obj = a.getValue();
- if (obj instanceof Color) {
- return (Color) obj;
- }
- }
+ DuplicatingStyleVisitor dsv = new DuplicatingStyleVisitor() {
+ @Override
+ public Expression copy(Expression expression) {
+ if (expression instanceof FilterFunction_strConcat) {
+ FilterFunction_strConcat strConcat = (FilterFunction_strConcat) expression;
- return Color.decode(expression.toString());
+ List<Expression> children = strConcat.getParameters();
+ List<Expression> correctedChildren = new ArrayList<Expression>();
+ for (Expression o : children) {
+ correctedChildren.add(copy(o));
+ }
+ strConcat.setParameters(correctedChildren);
- // Old way Martin did it:
- // return Color.decode((String) expression.evaluate(null));
+ } else if (expression instanceof DivideImpl) {
+ DivideImpl divFilter = (DivideImpl) expression;
+ divFilter.setExpression1(copy(divFilter.getExpression1()));
+ divFilter.setExpression2(copy(divFilter.getExpression2()));
+ } else if (expression instanceof PropertyName) {
+ PropertyName pName = (PropertyName) expression;
- }
+ Name correctedName = FeatureUtil
+ .findBestMatchingAttributeFallBackFirst(schema,
+ pName.getPropertyName());
- /**
- * Liefert die Farbe eines Farbpaletten-Eintrag.
- *
- * @param entry
- * Farbpaletten-Eintrag
- */
- public static Color getColorFromColorMapEntry(ColorMapEntry entry) {
- // if ( entry == null || entry.getColor() == null ||
- // entry.getColor().getValue(null) == null ) // gt2-2.3.4
- if (entry == null || entry.getColor() == null
- || entry.getColor().evaluate(null) == null) // gt2-2-4-2
- return null;
+ return ff.property(correctedName);
+ }
+ return super.copy(expression);
+ };
- // // Transparenz
- // Double opacity = getOpacityFromColorMapEntry(entry);
+ @Override
+ protected Filter copy(Filter filter) {
+ if (filter instanceof DivideImpl) {
+ DivideImpl divFilter = (DivideImpl) filter;
+ divFilter.setExpression1(copy(divFilter.getExpression1()));
+ divFilter.setExpression2(copy(divFilter.getExpression2()));
+ } else if (filter instanceof IsNullImpl) {
+ IsNullImpl isNullFilter = (IsNullImpl) filter;
+ isNullFilter.setExpression1(copy(isNullFilter
+ .getExpression1()));
+ } else if (filter instanceof NotImpl) {
+ NotImpl notFilter = (NotImpl) filter;
+ List<Filter> children = notFilter.getChildren();
+ List<Filter> correctedChildren = new ArrayList<Filter>();
+ for (Filter ex : children) {
+ correctedChildren.add(copy(ex));
+ }
+ notFilter.setChildren(correctedChildren);
+ } else if (filter instanceof OrImpl) {
+ OrImpl notFilter = (OrImpl) filter;
+ List<Filter> children = notFilter.getChildren();
+ List<Filter> correctedChildren = new ArrayList<Filter>();
+ for (Filter ex : children) {
+ correctedChildren.add(copy(ex));
+ }
+ notFilter.setChildren(correctedChildren);
+ } else if (filter instanceof AndImpl) {
+ AndImpl andFilter = (AndImpl) filter;
+ List<Filter> children = andFilter.getChildren();
+ List<Filter> correctedChildren = new ArrayList<Filter>();
+ for (Filter ex : children) {
+ correctedChildren.add(copy(ex));
+ }
+ andFilter.setChildren(correctedChildren);
+ } else if (filter instanceof BinaryComparisonAbstract) {
+ BinaryComparisonAbstract binFilter = (BinaryComparisonAbstract) filter;
+ binFilter.setExpression1(copy(binFilter.getExpression1()));
+ binFilter.setExpression2(copy(binFilter.getExpression2()));
- return getColorFromExpression(entry.getColor());
- }
+ // TODO noch viel mehr faelle!!
+ if (filter instanceof IsBetweenImpl) {
+ IsBetweenImpl isbetween = (IsBetweenImpl) filter;
+ isbetween
+ .setExpression(copy(isbetween.getExpression()));
+ }
- /**
- * Setzt die Farbe eines Farbpaletten-Eintrag.
- *
- * @param entry
- * Farbpaletten-Eintrag
- * @param color
- * eine Farbe
- */
- public static void setColorForColorMapEntry(ColorMapEntry entry, Color color) {
- if (entry != null)
- entry.setColor(STYLE_BUILDER.colorExpression(color));
- }
+ }
+ return (Filter) super.copy(filter);
+ };
- /**
- * Erzeugt einen {@link Style} aus einem {@linkplain Element JDOM-Element},
- * des eine SLD-Definition enthaelt
- *
- * @param element
- * Element mit SLD-Definition
- */
- public static Style createStyleFromSLD(Element element) {
- String xmlDefinition = new XMLOutputter().outputString(element);
- // TODO: Workaround, because gt2-2.6.x has problems when the
- // ColorMapEntries are not in the ascending order according to
- // their values
- // --> maybe we can bring the XML-Elements to an ascending order
- // prior to interprete the XML
+ @Override
+ public void visit(ColorMap cm) {
+ super.visit(sortColorMap(cm));
+ }
- ByteArrayInputStream inputStream = null;
- try {
- inputStream = new ByteArrayInputStream(xmlDefinition.getBytes());
- Style[] style = loadSLD(inputStream);
- return style == null || style.length == 0 ? null : style[0];
- } finally {
- IOUtils.closeQuietly(inputStream);
- }
- }
+ @Override
+ public void visit(LineSymbolizer sym) {
+ sym.setGeometryPropertyName(FeatureUtil
+ .findBestMatchingAttributeFallBackFirst(schema,
+ sym.getGeometryPropertyName()).getLocalPart());
+ super.visit(sym);
+ }
- /**
- * Creates a {@link Style} for a {@link Grid} layer from a {@link ColorMap}
- *
- * @param colorMap
- * If null, then defaultStyle for Grid will be used
- * @param name
- * The name to give to the Style. null will result in name=
- * {@link GridUtil#UNNAMED_RASTER_STYLE_NAME} or
- * GridUtil#DEFAULT_RASTER_STYLE_NAME} (if no colorMap is given).
- *
- * @param title
- * The Title to give to the Style. null will result in title=
- * {@link GridUtil#UNTITLED_RASTER_STYLE_TITLE} or
- * {@link GridUtil#DEFAULT_RASTER_STYLE_TITLE} (if no colorMap is
- * given)
- *
- * @return Always a {@link Style} that you can be applyed to a
- * {@link GridCoverage}.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static Style createStyleFromColorMap(ColorMap colorMap, String name,
- String title) {
- if (colorMap == null)
- return GridUtil.createDefaultStyle();
+ @Override
+ public void visit(PointSymbolizer sym) {
+ sym.setGeometryPropertyName(FeatureUtil
+ .findBestMatchingAttributeFallBackFirst(schema,
+ sym.getGeometryPropertyName()).getLocalPart());
+ super.visit(sym);
+ }
- if (name == null)
- // A colorMap was provided, but no name.
- name = GridUtil.UNNAMED_RASTER_STYLE_NAME;
+ @Override
+ public void visit(PolygonSymbolizer sym) {
+ sym.setGeometryPropertyName(FeatureUtil
+ .findBestMatchingAttributeFallBackFirst(schema,
+ sym.getGeometryPropertyName()).getLocalPart());
+ super.visit(sym);
+ }
- if (title == null)
- // A colorMap was provided, but no title.
- title = GridUtil.UNTITLED_RASTER_STYLE_TITLE;
+ public void visit(RasterSymbolizer sym) {
+ sym.setGeometryPropertyName("geom");
+ super.visit(sym);
+ }
- RasterSymbolizerImpl rasterSymbolizerImpl = new RasterSymbolizerImpl();
+ @Override
+ public void visit(TextSymbolizer sym) {
+ sym.setGeometryPropertyName(FeatureUtil
+ .findBestMatchingAttributeFallBackFirst(schema,
+ sym.getGeometryPropertyName()).getLocalPart());
+ if (sym.getLabel() != null)
+ sym.setLabel(copy(sym.getLabel()));
- // MS: In GT-2.6.1 the attribute for the raster style is "grid",
- // not "raster". Setting the geometry to NULL causes that
- // the grid attribute is determined dynamically during rendering
- rasterSymbolizerImpl.setGeometry(null);// new
- // AttributeExpressionImpl("grid"));
+ if (sym.getPriority() != null)
+ sym.setPriority(copy(sym.getPriority()));
- // Entferne alle label informationen
- clearColorMapLabels(colorMap);
-
- rasterSymbolizerImpl.setColorMap(colorMap);
- Symbolizer[] symbolizers = { rasterSymbolizerImpl };
- RuleImpl ruleImpl = new RuleImpl(symbolizers) {
+ super.visit(sym);
+ }
};
- Rule[] rules = { ruleImpl };
- FeatureTypeStyleImpl featureTypeStyleImpl = new FeatureTypeStyleImpl(
- rules) {
- };
- Style style = STYLE_FACTORY.createStyle();
- style.setName(name);
- style.getDescription().setTitle(title);
- style.featureTypeStyles().add(featureTypeStyleImpl);
- return style;
- }
+ dsv.visit(style);
- /**
- * Removes all label information from the {@link ColorMapEntry}s of the
- * given {@link ColorMap}
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static ColorMap clearColorMapLabels(ColorMap colorMap) {
- for (ColorMapEntry cme : colorMap.getColorMapEntries()) {
- cme.setLabel(null);
- }
- return colorMap;
+ Style copiedCleanStyle = (Style) dsv.getCopy();
+ return copiedCleanStyle;
}
/**
- * Creates a {@link Style} for a {@link Grid} layer from a {@link ColorMap}
- * Title will be set to {@link GridUtil#UNTITLED_RASTER_STYLE_TITLE}
- *
- * @param colorMap
- * If null, then defaultStyle for Grid will be used
- * @param name
- * The name to give to the Style. null will result in name
- * {@link GridUtil#UNTITLED_RASTER_STYLE_TITLE}
- *
- * @return Always a Style that you can apply to a {@link GridCoverage}.
- * Style has name {@link GridUtil#DEFAULT_RASTER_STYLE_NAME} if no
- * colormap was provided.
- *
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @return A {@link FeatureTypeStyle} that can be used style the given
+ * geoObject during a blink or highlight process.
*/
- public static Style createStyleFromColorMap(ColorMap colorMap, String name) {
- return createStyleFromColorMap(colorMap, name, null);
- }
-
- /**
- * Loads {@link Style}s from a SLD {@link InputStream}
- *
- * @param url
- * {@link URL} to read the SLD from
- *
- * @return An {@link Array} of {@link Style}s, can be length==0 if no
- * UserStyles in SLD file. null if file not exists
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static Style[] loadSLD(URL url) {
- InputStream openStream = null;
- try {
- openStream = url.openStream();
- return loadSLD(openStream);
- } catch (IOException e) {
- return null;
- } finally {
- IOUtils.closeQuietly(openStream);
+ public static FeatureTypeStyle createBlinkFeatureTypeStyle(Object geoObject) {
+ if (geoObject instanceof GridCoverage2D
+ || geoObject instanceof org.geotools.coverage.grid.io.AbstractGridCoverage2DReader) {
+ // Wenn irgendwann mal selection für raster möglich ist, dann hier
+ // einen schöneren style erstellen.
+ return GridUtil.createDefaultStyle().featureTypeStyles().get(0);
}
- }
- /**
- * Loads {@link Style}s from a SLD {@link InputStream}
- *
- * @param inputStream
- * {@link InputStream} to read the SLD from
- *
- * @return An {@link Array} of {@link Style}s, can be length==0. null if
- * file not exists
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static Style[] loadSLD(InputStream inputStream) {
-
- Style[] styles = null;
- try {
- SLDParser stylereader = new SLDParser(StylingUtil.STYLE_FACTORY,
- inputStream);
- styles = stylereader.readXML();
- return styles;
- } catch (Exception e) {
- LOGGER.warn(
- " ... no styles recognized. Return 'new Style[] { null }' ",
- e);
- return new Style[] { null };
+ // We have vector-data. Now let's determine the type...
+ GeometryForm geometryForm = null;
+ if (geoObject instanceof FeatureCollection) {
+ geometryForm = FeatureUtil
+ .getGeometryForm((FeatureCollection<SimpleFeatureType, SimpleFeature>) geoObject);
+ } else if (geoObject instanceof GeometryAttributeType) {
+ geometryForm = FeatureUtil
+ .getGeometryForm((GeometryAttributeType) geoObject);
+ } else if (geoObject instanceof FeatureSource) {
+ geometryForm = FeatureUtil
+ .getGeometryForm((FeatureSource<SimpleFeatureType, SimpleFeature>) geoObject);
}
- }
+ Symbolizer[] symbolizers = new Symbolizer[0];
- /**
- * Loads {@link Style}s from a SLD {@link File}
- *
- * @param sldFile
- * {@link File} to read the SLD from
- *
- * @return An {@link Array} of {@link Style}s, can be length==0
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static Style[] loadSLD(File sldFile) throws FileNotFoundException {
+ Graphic bg2;
+ switch (geometryForm) {
- FileInputStream inputStream = null;
- try {
- inputStream = new FileInputStream(sldFile);
- final Style[] loadedSLD = loadSLD(inputStream);
- return loadedSLD;
- } finally {
- IOUtils.closeQuietly(inputStream);
- }
- }
+ case POINT:
- /**
- * Saves the {@link Style} to OGC SLD. Overwrites any existing file. If a
- * FeatureTypeStyle for selection is used, it is automatically removed. This
- * method also checks, whether the style is actually differing from any
- * existing style in the {@link File}. If there is no difference, the file
- * is not saved again (that is more svn friendly).
- *
- * @param origStyle
- * {@link Style} to save. Any selectino related FeatureTypeStyle
- * will be removed.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- *
- * @return <code>true</code> if the file was really written.
- * <code>false</code> means, that the existing file already was
- * equals.
- * @throws IOException
- * @throws TransformerException
- */
- public static final boolean saveStyleToSLD(Style origStyle, File exportFile)
- throws TransformerException, IOException {
+ Literal size0 = FeatureUtil.FILTER_FACTORY2.literal(26);
+ Literal size1 = FeatureUtil.FILTER_FACTORY2.literal(28);
- // Wenn Datei nicht mit .sld endet, die Dateierweiterung
- // anhängen
- exportFile = IOUtil.appendFileExt(exportFile, ".sld");
+ Graphic bg1 = STYLE_FACTORY.createGraphic(new ExternalGraphic[0],
+ new Mark[] { STYLE_FACTORY.createMark(
+ FeatureUtil.FILTER_FACTORY2.literal("circle"),
+ STYLE_BUILDER.createStroke(Color.red, 2.), null,
+ size1, halfLit) },
+ new org.geotools.styling.Symbol[0],
+ FeatureUtil.FILTER_FACTORY2.literal(1), size1, zeroLit);
- SLDTRANSFORMER.setIndentation(2);
+ PointSymbolizer ps1 = STYLE_FACTORY.createPointSymbolizer();
+ ps1.setGraphic(bg1);
+ symbolizers = LangUtil.extendArray(symbolizers, ps1);
- Style exportStyle = removeSelectionFeatureTypeStyle(origStyle);
+ bg2 = STYLE_FACTORY.createGraphic(new ExternalGraphic[0],
+ new Mark[] { STYLE_FACTORY.createMark(
+ FeatureUtil.FILTER_FACTORY2.literal("circle"),
+ STYLE_BUILDER.createStroke(Color.black, 2.),
+ STYLE_BUILDER.createFill(Color.WHITE, 0.3), size0,
+ halfLit) }, new org.geotools.styling.Symbol[0],
+ FeatureUtil.FILTER_FACTORY2.literal(1), size0, zeroLit);
- // Nur in Datei speichern, wenn
- if (!isStyleDifferent(exportStyle, exportFile)) {
- return false;
- }
+ PointSymbolizer ps2 = STYLE_FACTORY.createPointSymbolizer();
+ ps2.setGraphic(bg2);
- SLDTRANSFORMER.transform(exportStyle, new FileWriter(exportFile));
- return true;
- }
+ symbolizers = LangUtil.extendArray(symbolizers, ps2);
+ break;
+ case POLYGON:
- /**
- * Exports the {@link Style} to OGC SLD. If a FeatureTypeStyle for selection
- * is used, it is automatically removed.
- *
- * @param style
- * {@link Style} to save. Any selectino related FeatureTypeStyle
- * will be removed.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- * @throws TransformerException
- */
- public static final void saveStyleToSLD(Style style,
- OutputStream exportStream) throws TransformerException {
- SLDTRANSFORMER.setIndentation(2);
- SLDTRANSFORMER.transform(style, exportStream);
- }
+ PolygonSymbolizer pol1 = STYLE_BUILDER.createPolygonSymbolizer(
+ STYLE_BUILDER.createStroke(Color.red, 4), null);
+ symbolizers = LangUtil.extendArray(symbolizers, pol1);
- /**
- * Creates a copy of the given {@link Style}, removing any
- * {@link FeatureTypeStyle}s that are only SELECTION related.
- *
- * @see {@link FeatureMapLayerSelectionSynchronizer#SELECTION_STYLING_FTS_NAME}
- */
- public static Style removeSelectionFeatureTypeStyle(final Style style) {
+ PolygonSymbolizer pol2 = STYLE_BUILDER.createPolygonSymbolizer(
+ STYLE_BUILDER.createStroke(Color.black, 2),
+ STYLE_BUILDER.createFill(Color.WHITE, .5));
+ symbolizers = LangUtil.extendArray(symbolizers, pol2);
- // Create a copy of the style
- DuplicatingStyleVisitor duplVisitor = new DuplicatingStyleVisitor();
- duplVisitor.visit(style);
- Style cleanStyle = (Style) duplVisitor.getCopy();
+ break;
- // Remove any selection-FeatureTypeStyle from the new Style
- for (int ii = 0; ii < style.featureTypeStyles().size(); ii++) {
+ case LINE:
- FeatureTypeStyle fts = style.featureTypeStyles().get(ii);
+ LineSymbolizer ls = STYLE_BUILDER.createLineSymbolizer(Color.red,
+ 6.);
+ symbolizers = LangUtil.extendArray(symbolizers, ls);
- if (fts.getName() != null
- && fts.getName()
- .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME)) {
- cleanStyle.featureTypeStyles().remove(ii);
- break;
- }
- }
+ LineSymbolizer ls2 = STYLE_BUILDER.createLineSymbolizer(
+ Color.black, 4.);
+ symbolizers = LangUtil.extendArray(symbolizers, ls2);
- return cleanStyle;
- }
+ LineSymbolizer ls3 = STYLE_BUILDER.createLineSymbolizer(
+ Color.white, 2.);
+ symbolizers = LangUtil.extendArray(symbolizers, ls3);
+ break;
- /**
- * Returns <code>null</code> or any {@link FeatureTypeStyle} contained in
- * the given {@link Style} that is SELECTION related.
- *
- * @see {@link FeatureMapLayerSelectionSynchronizer#SELECTION_STYLING_FTS_NAME}
- */
- public static FeatureTypeStyle getSelectionFeatureTypeStyle(
- final Style style) {
-
- if (style == null)
- return null;
-
- // Remove any selection-FeatureTypeStyle from the new Style
- for (int ii = 0; ii < style.featureTypeStyles().size(); ii++) {
-
- FeatureTypeStyle fts = style.featureTypeStyles().get(ii);
-
- if (fts.getName() != null
- && fts.getName()
- .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME)) {
- return style.featureTypeStyles().get(ii);
- }
+ default:
+ throw new IllegalArgumentException("Provide a suitable object.");
}
- return null;
+ return STYLE_BUILDER.createFeatureTypeStyle(symbolizers, Double.NaN,
+ Double.NaN);
}
/**
- * Compares a given Style and a {@link File} containg a {@link Style}.
+ * Creates a new {@link BrewerPalette} with only one scheme (which includes
+ * all colors). The suitablity of the palette is set to "unknown" for all
+ * viewer types.
*
- * @param style1
- * The first {@link Style}
- * @param style2file
- * A {@link File} pointing to the second {@link Style}
- * @return <code>true</code> is they are different, ignoring any XML
- * fomatting.
+ * @param name
+ * name for the palette (also the description is set to this
+ * value)
+ * @param colors
+ * colors for the palette
*/
- public static boolean isStyleDifferent(Style style1, File style2file) {
- SLDTRANSFORMER.setIndentation(2);
+ public static BrewerPalette createBrewerPalette(String name, Color[] colors) {
+ BrewerPalette palette = new BrewerPalette();
+ palette.setColors(colors);
+ palette.setName(name);
+ palette.setDescription(name);
+ // set suitability to UNKNOWN for all viewers
+ PaletteSuitability suitability = new PaletteSuitability();
try {
+ suitability.setSuitability(colors.length, new String[] { "?", "?",
+ "?", "?", "?", "?" });
+ palette.setPaletteSuitability(suitability);
+ } catch (IOException e) {
+ LOGGER.error(
+ "Unabel to PaletteSuitability.setSuitablility for colors.length="
+ + colors, e);
+ }
- if (!style2file.exists())
- return true;
+ // Create the trivial scheme for the palette (requested colors equals
+ // number of colors)
+ int[] schema = new int[colors.length];
+ for (int j = 0; j < colors.length; j++)
+ schema[j] = j;
+ SampleScheme sampleScheme = new SampleScheme();
- Style style2 = loadSLD(style2file)[0];
+ // set the trivial scheme for all schemas
+ for (int j = 2; j < schema.length; j++) {
+ sampleScheme.setSampleScheme(j, schema);
+ // sampleScheme.setSampleScheme(schema.length, schema);
+ }
- return isStyleDifferent(style1, style2);
+ palette.setColorScheme(sampleScheme);
- } catch (Exception e) {
- LOGGER.debug("Comparing styles " + style1 + " and " + style2file
- + " failed. So we assume they are different.", e);
- return true;
- }
+ return palette;
}
/**
- * Compares a given Style and a {@link File} containg a {@link Style}.
+ * Erzeugt einen {@link ColorMapEntry}.
*
- * @param style1
- * The first {@link Style}
- * @param style2
- * The second {@link Style} to compare to
- * @return <code>true</code> is they are different, ignoring any XML
- * fomatting.
+ * @param label
+ * Label fuer den Farbpaletten-Eintrag
+ * @param quantity
+ * Wert fuer den Farbpaletten-Eintrag
+ * @param color
+ * Farbe fuer den Farbpaletten-Eintrag
+ * @param opacity
+ * Transparenz fuer die Farbe des Farbpaletten-Eintrag
*/
- public static boolean isStyleDifferent(Style style1, Style style2) {
+ public static ColorMapEntry createColorMapEntry(String label,
+ Double quantity, Color color, double opacity) {
+ ColorMapEntry newEntry = STYLE_FACTORY.createColorMapEntry();
try {
- // SLDTRANSFORMER.setEncoding(Charset.forName("UTF-8"));
- // Transforming style2 to an XML String
- String style1string = SLDTRANSFORMER.transform(style1);
- String style2string = SLDTRANSFORMER.transform(style2);
-
- return !style1string.equals(style2string);
-
- } catch (Exception e) {
- LOGGER.debug("Compating styles " + style1 + " and " + style2
- + " failed. So we assume they are different.", e);
- return true;
+ newEntry.setLabel(label);
+ newEntry.setColor(STYLE_BUILDER.colorExpression(color));
+ newEntry.setOpacity(STYLE_BUILDER.literalExpression(opacity));
+ newEntry.setQuantity(STYLE_BUILDER.literalExpression(quantity));
+ } catch (Exception err) {
}
+ return newEntry;
}
/**
- * SLD Rules können die Paramter MinScaleDenominator und MaxScaleDenominator
- * enthalten. Dadurch können Elemente für manche Zoom-Stufen deaktiviert
- * werden.
+ * Erstellt einen Default-Style fuer die Klassen/Interfaces:
+ * StyledFeaturesInterface, GridCoverage2D, FeatureCollection, FeatureSource
+ * und GeometryAttributeType.
*
- * Kommentar: "Sichtbarkeit" bezieht es nicht darauf, ob die Elemente auf
- * dem Kartenausschnitt sichtbar sind, sondern um die SLD Regeln, welche das
- * SimpleFeature evt. nur Scalenabhängig zeichnen.<br/>
- * SK 19.6.2009:Bei einem {@link PolygonSymbolizer} zählt nicht der Rand,
- * sondern nur ob eine Füllung vorhanden ist! Man kann dann zwar leider
- * nicht auf ein Rand eines Polygons ohne Fill klicken, aber dafür kann man
- * durch die ungefüllte Fläche klicken.
+ * @param object
+ * {@link GridCoverage2D},
+ * {@link org.geotools.coverage.grid.io.AbstractGridCoverage2DReader}
+ * oder {@link FeatureCollection}
+ * @return {@code null} falls kein Style generiert werden kann
*
- * @param fc
- * Die zu filternde FeatureCollection. Diese wird nicht
- * verändert.
- * @param style
- * Der Style, mit dem die Features gerendert werden (z.b.
- * layer.getStyle() )
- *
- * @param scaleDenominator
- * Der aktuelle ScaleDenomitor für den die Sichtbarkeit ermittelt
- * wird.
- *
- * @see RendererUtilities.calculateOGCScale
- *
- * @return Eine FeatureCollection in welcher nur die Features enthalten
- * sind, welche bei aktuellen Scale mit dem übergebenen Style
- * gerendert werden.
- *
- * TODO Was ist mit raster?!
- *
- * TODO Das sollte man besser machen: Zuerst die FIlter der
- * sichtbaren regeln raussuchen, und dann direkt am anfang damitmit
- * mitfiltern...
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @Deprectated Use FeatureUtil.createDefaultStyle and
+ * FeatureUtil.getGeometryForm
*/
- public static MemoryFeatureCollection filterSLDVisibleOnly(
- final FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
- final Style style, final Double scaleDenominator) {
+ public static Style createDefaultStyle(Object object) {
+ Style style = STYLE_BUILDER.createStyle(); // SK.. nicer default than
+ // null !
- // Eine im Speicher gehaltene FeatureCollection der sichtbaren
- final MemoryFeatureCollection fcVisible = new MemoryFeatureCollection(
- fc.getSchema());
+ if (object instanceof StyledFeaturesInterface)
+ style = FeatureUtil
+ .createDefaultStyle(((StyledFeaturesInterface<?>) object)
+ .getSchema().getGeometryDescriptor());
- // Prüfen aller Features in der Collection
- final Iterator<SimpleFeature> fcIt = fc.iterator();
+ if (object instanceof GridCoverage2D
+ || object instanceof AbstractGridCoverage2DReader
+ || object instanceof StyledRasterInterface)
+ style = GridUtil.createDefaultStyle();
- try {
+ if (object instanceof FeatureCollection)
+ style = FeatureUtil
+ .createDefaultStyle((FeatureCollection<SimpleFeatureType, SimpleFeature>) object);
- while (fcIt.hasNext()) {
- final SimpleFeature feature = fcIt.next();
+ if (object instanceof FeatureSource)
+ style = FeatureUtil.createDefaultStyle(((FeatureSource) object)
+ .getSchema().getGeometryDescriptor());
- for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
+ if (object instanceof GeometryAttributeType)
+ style = FeatureUtil
+ .createDefaultStyle((GeometryAttributeType) object);
- // Leave out FTSs that are selection related
- if (fts.getName() != null
- && fts.getName()
- .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME))
- continue;
-
- final List<Rule> rules = fts.rules();
-
- for (final Rule rule : rules) {
- final double maxScaleDenominator = rule
- .getMaxScaleDenominator();
- final double minScaleDenominator = rule
- .getMinScaleDenominator();
-
- // 1. Check: Trifft die Rule auf den aktuellen Scale der
- // JMapPane?
- if ((minScaleDenominator > scaleDenominator)
- || (scaleDenominator > maxScaleDenominator)) {
- continue;
- }
-
- // 2. Check: Eine Rule ist gülrig, aber trifft der
- // Filter für dieses SimpleFeature?
- final Filter rFilter = rule.getFilter();
- if ((rFilter != null) && (!rFilter.evaluate(feature)))
- continue;
-
- // 3. Check: Passt einer der Symbolizer dieser Rule zu
- // dem
- // SimpleFeature? Dieser Check wird in
- // "real world" meistens klappen, es sei denn, ein
- // Hansel
- // gibt einen LineSymbolizer für ein PointLayer an.
- boolean passt = false;
- for (final Symbolizer symb : rule.getSymbolizers()) {
-
- final Geometry geom = (Geometry) feature
- .getDefaultGeometry();
-
- if ((geom instanceof MultiPoint)
- || (geom instanceof com.vividsolutions.jts.geom.Point)) {
- if (symb instanceof PointSymbolizer) {
- if (((PointSymbolizer) symb).getGraphic() != null)
- passt = true;
- break;
- }
- } else if ((geom instanceof MultiLineString)
- || (geom instanceof LineString)) {
- if (symb instanceof LineSymbolizer) {
- if (((LineSymbolizer) symb).getStroke() != null)
- passt = true;
- break;
- }
- } else if ((geom instanceof MultiPolygon)
- || (geom instanceof Polygon)) {
-
- if (symb instanceof PolygonSymbolizer) {
- if (((PolygonSymbolizer) symb).getFill() != null)
- passt = true;
- break;
- }
-
- if (symb instanceof PointSymbolizer) {
- // This is a special case and not handles
- // 100% correct yet. Polygons visualized
- // with Pointsymbolizers should also have
- // different Filters when they are selected
- if (((PointSymbolizer) symb).getGraphic() != null)
- passt = true;
- break;
- }
- } else {
- LOGGER.warn("Unbekannter geom Typ! Gehe von sichbar aus!");
- passt = true;
- }
- }
- if (!passt)
- continue;
-
- // Nun sollte das feature wiklich sichtbar sein
- fcVisible.add(feature);
- }
- }
- }
- } catch (final java.lang.IllegalStateException e) {
- LOGGER.error("Iterating over the features", e);
- /**
- * SK: 14.Apri 2009. It happened a few time to that fcIt.hasNext
- * suddenly threw an exception for the "africa countries.shp":
- * Exception in thread "AWT-EventQueue-0"
- * java.lang.IllegalStateException: ShapeType changed illegally from
- * Polygon to Undefined at org.geotools.
- * data.shapefile.shp.ShapefileReader.nextRecord(ShapefileReader
- * .java:452) at org.geotools.data.shapefile.indexed.
- * IndexedShapefileDataStore$Reader
- * .next(IndexedShapefileDataStore.java:1272) at
- * org.geotools.data.FIDFeatureReader.next(FIDFeatureReader.java:92)
- * at org .geotools.data.FilteringFeatureReader.hasNext(
- * FilteringFeatureReader .java:125) at
- * org.geotools.data.store.FeatureReaderIterator.hasNext(
- * FeatureReaderIterator.java:44) at
- * schmitzm.geotools.feature.FeatureUtil
- * .filterSLDVisibleOnly(FeatureUtil.java:216) *
- *
- */
- }
-
- // LOGGER.info("filterSLDVisibleOnly removed "+ (fc.size() -
- // fcVisible.size()) + " features.");
-
- return fcVisible;
+ return style;
}
/**
- * @param style
- * A {@link Style} to search for the first {@link TextSymbolizer}
- * that will be used for the given {@link SimpleFeature}.
+ * Erzeugt eine {@link GridSampleDimension} aus einer {@link ColorMap}.
*
- * @author Stefan A. Tzeggai
- *
- * @return <code>null</code> or the first {@link TextSymbolizer} found in
- * the style that applies to the {@link SimpleFeature}.
+ * @param name
+ * Name fuer die {@link GridSampleDimension}
+ * @param colorMap
+ * fuer jeden Eintrag der {@link ColorMap} wird eine
+ * {@link Category} erzeugt
+ * @param noDataValues
+ * Werte fuer die zusaetzliche {@link Category Categorys}
+ * erstellt werden, welche die transparent dargestellt werden
+ * (wenn {@code null} wird keine zusaetzliche {@link Category}
+ * erstellt)
+ * @param unit
+ * Einheit der Werte in der {@link GridSampleDimension} (kann
+ * {@code null} sein)
*/
- public static TextSymbolizer getTextSymbolizer(final Style style,
- final SimpleFeature f) {
- if (f == null)
+ public static GridSampleDimension createDiscreteGridSampleDimension(
+ String name, ColorMap colorMap, double[] noDataValues, Unit<?> unit) {
+ if (colorMap.getColorMapEntries().length == 0)
return null;
- try {
- if (style != null) {
- for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
- for (final Rule r : fts.rules()) {
+ SortedMap<Integer, Category> categories = new TreeMap<Integer, Category>();
+ if (noDataValues == null)
+ noDataValues = new double[0];
- final Filter filter = r.getFilter();
-
- if (filter != null && (!filter.evaluate(f))) {
- continue;
- }
-
- for (final Symbolizer symb : r.getSymbolizers()) {
- if (symb instanceof TextSymbolizer) {
- return (TextSymbolizer) symb;
- }
- }
-
- }
- }
-
- }
-
- } catch (final Exception e) {
- LOGGER.error("error - filter API stuff?", e);
- return null;
+ // Create a (discrete) Category for each ColorMapEntry
+ int colorMapMin = Integer.MAX_VALUE;
+ int colorMapMax = Integer.MIN_VALUE;
+ for (ColorMapEntry cme : colorMap.getColorMapEntries()) {
+ String label = cme.getLabel();
+ Color color = getColorFromColorMapEntry(cme);
+ double value = getQuantityFromColorMapEntry(cme);
+ int intValue = (int) Math.round(value);
+ colorMapMin = Math.min(colorMapMin, intValue);
+ colorMapMax = Math.max(colorMapMax, intValue);
+ // if ( label == null || label.trim().equals("") )
+ // label = String.valueOf(intValue);
+ if (label == null)
+ label = "";
+ categories.put(intValue, new Category(label, new Color[] { color },
+ new NumberRange(intValue, intValue), new NumberRange(
+ intValue, intValue)));
}
- return null;
- }
- /**
- * @param style
- * A {@link Style} to search for all {@link TextSymbolizer}s . No
- * guarantee, that any one of them will ever be used for any
- * feature (think about filters).
- *
- * @author Stefan A. Tzeggai
- *
- * @return {@link List} or all {@link TextSymbolizer}s found in the
- * {@link Style}.
- */
- public static List<TextSymbolizer> getVisibleTextSymbolizers(
- final Style style) {
- List<TextSymbolizer> results = new ArrayList<TextSymbolizer>();
- try {
- if (style != null) {
-
- for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
- for (final Rule r : fts.rules()) {
-
- if (r.getFilter() != null) {
-
- /*
- * We are comparing it to AsUtil.alwaysfalsefilter
- *
- * public static final PropertyIsEqualTo
- * allwaysFalseFilter = ff2.equals(ff2
- * .literal("1"), ff2.literal("2"));
- */
- try {
-
- Filter f = r.getFilter();
- if (f instanceof And) {
- And and = (And) f;
- if (and.getChildren() != null) {
- Filter candidateF = and.getChildren()
- .get(0);
- if (candidateF instanceof PropertyIsEqualTo) {
- final PropertyIsEqualTo compare = (PropertyIsEqualTo) candidateF;
- if (compare.getExpression1() instanceof Literal
- && compare.getExpression2() instanceof Literal) {
- Literal test1 = (Literal) compare
- .getExpression1();
- Literal test2 = (Literal) compare
- .getExpression2();
- if (test1.toString()
- .equals("1")
- && test2.toString()
- .equals("2")) {
- // This TextSymbolizer is
- // disabled using
- // ASUtil.allwaysFalseFilter
- // LOGGER.debug("Ignoring Rule "+
- // r
- // +" because the filter is "+f);
- continue;
- }
- }
- }
- }
- }
- } catch (Exception e) {
- LOGGER.debug(
- "Checking for textSymbolizer allwaysFalseFilter",
- e);
- }
- }
-
- results.addAll(getTextSymbolizers(r.getSymbolizers()));
- }
- }
-
- }
-
- } catch (final Exception e) {
- LOGGER.error("error - filter API stuff?", e);
- return results;
+ // If NoData-Value is set, create an additional Category
+ for (double noDataValue : noDataValues) {
+ int value = categories.lastKey() + 10; // value not already used
+ categories.put(value, createNoDataCategory(value, noDataValue));
+ colorMapMin = Math.min(colorMapMin, (int) noDataValue);
+ colorMapMax = Math.max(colorMapMax, (int) noDataValue);
}
- return results;
- }
- /**
- * @param style
- * A {@link Style} to search for all {@link TextSymbolizer}s . No
- * guarantee, that any one of them will ever be used for any
- * feature (think about filters).
- *
- * @author Stefan A. Tzeggai
- *
- * @return {@link List} or all {@link TextSymbolizer}s found in the
- * {@link Style}.
- */
- public static List<TextSymbolizer> getTextSymbolizers(final Style style) {
- List<TextSymbolizer> results = new ArrayList<TextSymbolizer>();
- try {
- if (style != null) {
+ // Declare "all" values smaller/greater the color map values
+ // automatically as NoData
+ // int colorMapRange = colorMapMax - colorMapMin;
+ // double lowerStart = colorMapMin - 10000*colorMapRange;
+ // double higherEnd = colorMapMax + 10000*colorMapRange;
+ final int lowerStart = Integer.MIN_VALUE;
+ final int higherEnd = Integer.MAX_VALUE;
+ categories.put(colorMapMax + 10, new Category("_autoNoData1_",
+ new Color[] { new Color(0, 0, 0, 0) }, new NumberRange(
+ colorMapMax + 1, colorMapMax + 2), new NumberRange(
+ colorMapMax + 1, higherEnd)));
+ if (colorMapMin < colorMapMax)
+ categories.put(colorMapMin - 10, new Category("_autoNoData2_",
+ new Color[] { new Color(0, 0, 0, 0) },
+ // new NumberRange(colorMapMin-2, colorMapMin-1), //
+ // logischer, aber klappt nicht!?
+ NumberRange.create(colorMapMax + 3, colorMapMax + 4),
+ // new NumberRange(colorMapMax + 3, colorMapMax + 4),
+ NumberRange.create(lowerStart, colorMapMin - 1)
+ // new NumberRange(lowerStart, colorMapMin - 1)
+ ));
- for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
- for (final Rule r : fts.rules()) {
- results.addAll(getTextSymbolizers(r.getSymbolizers()));
- }
- }
+ // Create the GridSampleDimension
+ GridSampleDimension gsd = new GridSampleDimension(name, categories
+ .values().toArray(new Category[0]), unit).geophysics(true);
- }
+ for (Category c : (List<Category>) gsd.getCategories())
+ LOGGER.debug(c.toString());
- } catch (final Exception e) {
- LOGGER.error("error - filter API stuff?", e);
- return results;
- }
- return results;
+ return gsd;
}
/**
- * @param symbolizers
- * List of Symbolizers to search for all {@link TextSymbolizer}s
- * . No guarantee, that any one of them will ever be used for any
- * feature (think about filters).
+ * Erzeugt eine {@link Category} fuer die NoData-Werte transparent
+ * dargestellt werden.
*
- * @author Stefan A. Tzeggai
- *
- * @return {@link List} or all {@link TextSymbolizer}s found in the given
- * symbolizers.
+ * @param geoValue
+ * Geo-Wert, der NoData repraesentiert
*/
- public static List<TextSymbolizer> getTextSymbolizers(
- Symbolizer[] symbolizers) {
- List<TextSymbolizer> results = new ArrayList<TextSymbolizer>();
- try {
- if (symbolizers != null) {
-
- for (final Symbolizer symb : symbolizers) {
- if (symb instanceof TextSymbolizer) {
- results.add((TextSymbolizer) symb);
- }
- }
-
- }
-
- } catch (final Exception e) {
- LOGGER.error("error - filter API stuff?", e);
- return results;
- }
- return results;
+ public static Category createNoDataCategory(double geoValue) {
+ return createNoDataCategory(0, geoValue);
}
/**
- * Clones a Style by converting it to XML and reading it back in.
+ * Erzeugt eine {@link Category} fuer die NoData-Werte transparent
+ * dargestellt werden.
*
- * @param style
- * the {@link Style} to be copied.
+ * @param value
+ * Sample-Wert der Category
+ * @param geoValue
+ * Geo-Wert, der NoData repraesentiert
*/
- public static Style clone(Style style) {
- DuplicatingStyleVisitor duplicatingStyleVisitor = new DuplicatingStyleVisitor();
- style.accept(duplicatingStyleVisitor);
- return (Style) duplicatingStyleVisitor.getCopy();
+ public static Category createNoDataCategory(int value, double geoValue) {
+ return new Category(
+ Vocabulary.formatInternational(VocabularyKeys.NODATA),
+ new Color[] { new Color(0, 0, 0, 0) }, new NumberRange(value,
+ value), new NumberRange(geoValue, geoValue));
}
/**
- * Clones a {@link Symbolizer} using the {@link DuplicatingStyleVisitor}.
- */
- public static Symbolizer clone(Symbolizer sym) {
- DuplicatingStyleVisitor duplicatingStyleVisitor = new DuplicatingStyleVisitor();
- sym.accept(duplicatingStyleVisitor);
- return (Symbolizer) duplicatingStyleVisitor.getCopy();
- }
-
- /**
- * Clons a {@link Graphic} element
+ * @param geoObject
+ * the {@link GeometryForm} the selection style shall be created
+ * for.
+ * @param type
+ * define the look of the selection style by choosing a constant
+ * from {@link SelectionStylesTypes}
*
- * @param graphicFill
- * @return
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @return a {@link Style} that is suitable to identify features of the
+ * given type as selected items.
*/
- public static Graphic clone(Graphic graphic) {
- DuplicatingStyleVisitor duplicatingStyleVisitor = new DuplicatingStyleVisitor();
- graphic.accept(duplicatingStyleVisitor);
- return (Graphic) duplicatingStyleVisitor.getCopy();
- }
+ public static FeatureTypeStyle createSelectionFTStyle(
+ GeometryForm geometryForm, SelectionStylesTypes type) {
+ Symbolizer[] symbolizers = createSelectionSymbolizers(geometryForm,
+ type);
- /**
- * Creates a new {@link BrewerPalette} with only one scheme (which includes
- * all colors). The suitablity of the palette is set to "unknown" for all
- * viewer types.
- *
- * @param name
- * name for the palette (also the description is set to this
- * value)
- * @param colors
- * colors for the palette
- */
- public static BrewerPalette createBrewerPalette(String name, Color[] colors) {
- BrewerPalette palette = new BrewerPalette();
- palette.setColors(colors);
- palette.setName(name);
- palette.setDescription(name);
-
- // set suitability to UNKNOWN for all viewers
- PaletteSuitability suitability = new PaletteSuitability();
- try {
- suitability.setSuitability(colors.length, new String[] { "?", "?",
- "?", "?", "?", "?" });
- palette.setPaletteSuitability(suitability);
- } catch (IOException e) {
- LOGGER.error(
- "Unabel to PaletteSuitability.setSuitablility for colors.length="
- + colors, e);
- }
-
- // Create the trivial scheme for the palette (requested colors equals
- // number of colors)
- int[] schema = new int[colors.length];
- for (int j = 0; j < colors.length; j++)
- schema[j] = j;
- SampleScheme sampleScheme = new SampleScheme();
-
- // set the trivial scheme for all schemas
- for (int j = 2; j < schema.length; j++) {
- sampleScheme.setSampleScheme(j, schema);
- // sampleScheme.setSampleScheme(schema.length, schema);
- }
-
- palette.setColorScheme(sampleScheme);
-
- return palette;
+ return STYLE_BUILDER.createFeatureTypeStyle(symbolizers, 0.0,
+ Double.POSITIVE_INFINITY);
}
/**
@@ -1737,41 +1041,7 @@
}
- public static Style createSelectionStyle(Object geoObject,
- SelectionStylesTypes type) {
- FeatureTypeStyle fts = createSelectionFTStyle(geoObject, type);
- Style style = STYLE_FACTORY.createStyle();
- style.featureTypeStyles().clear();
- style.featureTypeStyles().add(fts);
- return style;
-
- }
-
/**
- * @param geoObject
- * the {@link GeometryForm} the selection style shall be created
- * for.
- * @param type
- * define the look of the selection style by choosing a constant
- * from {@link SelectionStylesTypes}
- *
- * @return a {@link Style} that is suitable to identify features of the
- * given type as selected items.
- */
- public static FeatureTypeStyle createSelectionFTStyle(
- GeometryForm geometryForm, SelectionStylesTypes type) {
- Symbolizer[] symbolizers = createSelectionSymbolizers(geometryForm,
- type);
-
- return STYLE_BUILDER.createFeatureTypeStyle(symbolizers, 0.0,
- Double.POSITIVE_INFINITY);
- }
-
- public enum SelectionStylesTypes {
- LeftTop2RightBottom_lines, RightTop2LeftBottom_lines, Outline_only, LeftTop2RightBottom_lines_biggaps, RightTop2LeftBottom_lines_biggaps, RightTop2LeftBottom_lines_smallgaps, LeftTop2RightBottom_lines_smallgaps
- }
-
- /**
* Creates a rule which paints features as selected.
*
* @param geometryForm
@@ -1818,15 +1088,19 @@
return rule;
}
+ public static Style createSelectionStyle(Object geoObject,
+ SelectionStylesTypes type) {
+ FeatureTypeStyle fts = createSelectionFTStyle(geoObject, type);
+ Style style = STYLE_FACTORY.createStyle();
+ style.featureTypeStyles().clear();
+ style.featureTypeStyles().add(fts);
+ return style;
+
+ }
+
public static Symbolizer[] createSelectionSymbolizers(
GeometryForm geometryForm, SelectionStylesTypes type) {
Symbolizer[] symbolizers = new Symbolizer[0];
- //
- // // TODO Not a good idea to put the 500 here as constant!
- // final Function offsetFunction = FilterUtil.FILTER_FAC2.function(
- // "offset", FilterUtil.FILTER_FAC2.property("the_geom"),
- // FilterUtil.FILTER_FAC2.literal(-500), FilterUtil.FILTER_FAC2
- // .literal(500));
double size = 15.;
if (type == SelectionStylesTypes.RightTop2LeftBottom_lines_smallgaps
@@ -1933,6 +1207,113 @@
return symbolizers;
}
+ /**
+ * Creates a {@link Style} for a {@link Grid} layer from a {@link ColorMap}
+ * Title will be set to {@link GridUtil#UNTITLED_RASTER_STYLE_TITLE}
+ *
+ * @param colorMap
+ * If null, then defaultStyle for Grid will be used
+ * @param name
+ * The name to give to the Style. null will result in name
+ * {@link GridUtil#UNTITLED_RASTER_STYLE_TITLE}
+ *
+ * @return Always a Style that you can apply to a {@link GridCoverage}.
+ * Style has name {@link GridUtil#DEFAULT_RASTER_STYLE_NAME} if no
+ * colormap was provided.
+ *
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static Style createStyleFromColorMap(ColorMap colorMap, String name) {
+ return createStyleFromColorMap(colorMap, name, null);
+ }
+
+ /**
+ * Creates a {@link Style} for a {@link Grid} layer from a {@link ColorMap}
+ *
+ * @param colorMap
+ * If null, then defaultStyle for Grid will be used
+ * @param name
+ * The name to give to the Style. null will result in name=
+ * {@link GridUtil#UNNAMED_RASTER_STYLE_NAME} or
+ * GridUtil#DEFAULT_RASTER_STYLE_NAME} (if no colorMap is given).
+ *
+ * @param title
+ * The Title to give to the Style. null will result in title=
+ * {@link GridUtil#UNTITLED_RASTER_STYLE_TITLE} or
+ * {@link GridUtil#DEFAULT_RASTER_STYLE_TITLE} (if no colorMap is
+ * given)
+ *
+ * @return Always a {@link Style} that you can be applyed to a
+ * {@link GridCoverage}.
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static Style createStyleFromColorMap(ColorMap colorMap, String name,
+ String title) {
+ if (colorMap == null)
+ return GridUtil.createDefaultStyle();
+
+ if (name == null)
+ // A colorMap was provided, but no name.
+ name = GridUtil.UNNAMED_RASTER_STYLE_NAME;
+
+ if (title == null)
+ // A colorMap was provided, but no title.
+ title = GridUtil.UNTITLED_RASTER_STYLE_TITLE;
+
+ RasterSymbolizerImpl rasterSymbolizerImpl = new RasterSymbolizerImpl();
+
+ // MS: In GT-2.6.1 the attribute for the raster style is "grid",
+ // not "raster". Setting the geometry to NULL causes that
+ // the grid attribute is determined dynamically during rendering
+ rasterSymbolizerImpl.setGeometry(null);// new
+ // AttributeExpressionImpl("grid"));
+
+ // Entferne alle label informationen
+ clearColorMapLabels(colorMap);
+
+ rasterSymbolizerImpl.setColorMap(colorMap);
+ Symbolizer[] symbolizers = { rasterSymbolizerImpl };
+ RuleImpl ruleImpl = new RuleImpl(symbolizers) {
+ };
+ Rule[] rules = { ruleImpl };
+ FeatureTypeStyleImpl featureTypeStyleImpl = new FeatureTypeStyleImpl(
+ rules) {
+ };
+
+ Style style = STYLE_FACTORY.createStyle();
+ style.setName(name);
+ style.getDescription().setTitle(title);
+ style.featureTypeStyles().add(featureTypeStyleImpl);
+ return style;
+ }
+
+ /**
+ * Erzeugt einen {@link Style} aus einem {@linkplain Element JDOM-Element},
+ * des eine SLD-Definition enthaelt
+ *
+ * @param element
+ * Element mit SLD-Definition
+ */
+ public static Style createStyleFromSLD(Element element) {
+ String xmlDefinition = new XMLOutputter().outputString(element);
+ // TODO: Workaround, because gt2-2.6.x has problems when the
+ // ColorMapEntries are not in the ascending order according to
+ // their values
+ // --> maybe we can bring the XML-Elements to an ascending order
+ // prior to interprete the XML
+
+ ByteArrayInputStream inputStream = null;
+ try {
+ inputStream = new ByteArrayInputStream(xmlDefinition.getBytes());
+ Style[] style = loadSLD(inputStream);
+ return style == null || style.length == 0 ? null : style[0];
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+
public static Style createStyleSimple(Object geoObject, Color color,
Color color2) {
if (geoObject instanceof GridCoverage2D
@@ -2006,238 +1387,337 @@
return style;
}
- //
- // /**
- // * Doubles the number of palettes by adding the reverse palette to every
- // * palette. The name of the reverse palette is the name of the original
- // * palette plus the letter R.
- // *
- // * @author SK
- // * @param palettes The original list of {@link BrewerPalette
- // BrewerPalettes}
- // */
- // public static BrewerPalette[] addReversePalettes(BrewerPalette[]
- // palettes) {
- // BrewerPalette[] newPalettes = new BrewerPalette[palettes.length * 2];
- //
- // int pos = 0;
- // for (BrewerPalette bp : palettes) {
- // newPalettes[pos] = bp;
- // pos++;
- // Color[] newColors = new Color[bp.getMaxColors()];
- //
- // List<Color> colorList =
- // java.util.Arrays.asList(bp.getColors(bp.getMaxColors()));
- // Collections.reverse(colorList);
- // colorList.toArray(newColors);
- //
- // try {
- // newPalettes[pos] = StylingUtil.createBrewerPalette(bp.getName()
- // + "R", newColors);
- // newPalettes[pos].setPaletteSuitability(bp
- // .getPaletteSuitability());
- // newPalettes[pos].setDescription(bp.getDescription()+" reversed");
- // newPalettes[pos].setType(bp.getType());
- // newPalettes[pos].setColorScheme(bp.getColorScheme());
- // } catch (IOException e) {
- // LOGGER.error("",e);
- // newPalettes[pos] = bp;
- // }
- //
- // pos++;
- // }
- //
- // return newPalettes;
- // }
-
/**
- * Replaces the "main" color in a given {@link Symbolizer} element
+ * SLD Rules können die Paramter MinScaleDenominator und MaxScaleDenominator
+ * enthalten. Dadurch können Elemente für manche Zoom-Stufen deaktiviert
+ * werden.
*
+ * Kommentar: "Sichtbarkeit" bezieht es nicht darauf, ob die Elemente auf
+ * dem Kartenausschnitt sichtbar sind, sondern um die SLD Regeln, welche das
+ * SimpleFeature evt. nur Scalenabhängig zeichnen.<br/>
+ * SK 19.6.2009:Bei einem {@link PolygonSymbolizer} zählt nicht der Rand,
+ * sondern nur ob eine Füllung vorhanden ist! Man kann dann zwar leider
+ * nicht auf ein Rand eines Polygons ohne Fill klicken, aber dafür kann man
+ * durch die ungefüllte Fläche klicken.
+ *
+ * @param fc
+ * Die zu filternde FeatureCollection. Diese wird nicht
+ * verändert.
+ * @param style
+ * Der Style, mit dem die Features gerendert werden (z.b.
+ * layer.getStyle() )
+ *
+ * @param scaleDenominator
+ * Der aktuelle ScaleDenomitor für den die Sichtbarkeit ermittelt
+ * wird.
+ *
+ * @see RendererUtilities.calculateOGCScale
+ *
+ * @return Eine FeatureCollection in welcher nur die Features enthalten
+ * sind, welche bei aktuellen Scale mit dem übergebenen Style
+ * gerendert werden.
+ *
+ * TODO Was ist mit raster?!
+ *
+ * TODO Das sollte man besser machen: Zuerst die FIlter der
+ * sichtbaren regeln raussuchen, und dann direkt am anfang damitmit
+ * mitfiltern...
+ *
* @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static void replaceSymbolizerColor(Symbolizer symb, Color oldColor,
- Color newColor) {
- if (symb == null)
- return;
+ public static MemoryFeatureCollection filterSLDVisibleOnly(
+ final FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
+ final Style style, final Double scaleDenominator) {
- if (symb instanceof PointSymbolizer) {
- PointSymbolizer ps = (PointSymbolizer) symb;
- replacePointSymbolizerColor(ps, oldColor, newColor);
- }
+ // Eine im Speicher gehaltene FeatureCollection der sichtbaren
+ final MemoryFeatureCollection fcVisible = new MemoryFeatureCollection(
+ fc.getSchema());
- if (symb instanceof PolygonSymbolizer) {
- PolygonSymbolizer ps = (PolygonSymbolizer) symb;
- replacePolygonSymbolizerColor(ps, oldColor, newColor);
- }
+ // Prüfen aller Features in der Collection
+ final Iterator<SimpleFeature> fcIt = fc.iterator();
- if (symb instanceof LineSymbolizer) {
- LineSymbolizer ps = (LineSymbolizer) symb;
- replaceLineSymbolizerColor(ps, oldColor, newColor);
+ try {
+
+ while (fcIt.hasNext()) {
+ final SimpleFeature feature = fcIt.next();
+
+ for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
+
+ // Leave out FTSs that are selection related
+ if (fts.getName() != null
+ && fts.getName()
+ .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME))
+ continue;
+
+ final List<Rule> rules = fts.rules();
+
+ for (final Rule rule : rules) {
+ final double maxScaleDenominator = rule
+ .getMaxScaleDenominator();
+ final double minScaleDenominator = rule
+ .getMinScaleDenominator();
+
+ // 1. Check: Trifft die Rule auf den aktuellen Scale der
+ // JMapPane?
+ if ((minScaleDenominator > scaleDenominator)
+ || (scaleDenominator > maxScaleDenominator)) {
+ continue;
+ }
+
+ // 2. Check: Eine Rule ist gülrig, aber trifft der
+ // Filter für dieses SimpleFeature?
+ final Filter rFilter = rule.getFilter();
+ if ((rFilter != null) && (!rFilter.evaluate(feature)))
+ continue;
+
+ // 3. Check: Passt einer der Symbolizer dieser Rule zu
+ // dem
+ // SimpleFeature? Dieser Check wird in
+ // "real world" meistens klappen, es sei denn, ein
+ // Hansel
+ // gibt einen LineSymbolizer für ein PointLayer an.
+ boolean passt = false;
+ for (final Symbolizer symb : rule.getSymbolizers()) {
+
+ final Geometry geom = (Geometry) feature
+ .getDefaultGeometry();
+
+ if ((geom instanceof MultiPoint)
+ || (geom instanceof com.vividsolutions.jts.geom.Point)) {
+ if (symb instanceof PointSymbolizer) {
+ if (((PointSymbolizer) symb).getGraphic() != null)
+ passt = true;
+ break;
+ }
+ } else if ((geom instanceof MultiLineString)
+ || (geom instanceof LineString)) {
+ if (symb instanceof LineSymbolizer) {
+ if (((LineSymbolizer) symb).getStroke() != null)
+ passt = true;
+ break;
+ }
+ } else if ((geom instanceof MultiPolygon)
+ || (geom instanceof Polygon)) {
+
+ if (symb instanceof PolygonSymbolizer) {
+ if (((PolygonSymbolizer) symb).getFill() != null)
+ passt = true;
+ break;
+ }
+
+ if (symb instanceof PointSymbolizer) {
+ // This is a special case and not handles
+ // 100% correct yet. Polygons visualized
+ // with Pointsymbolizers should also have
+ // different Filters when they are selected
+ if (((PointSymbolizer) symb).getGraphic() != null)
+ passt = true;
+ break;
+ }
+ } else {
+ LOGGER.warn("Unbekannter geom Typ! Gehe von sichbar aus!");
+ passt = true;
+ }
+ }
+ if (!passt)
+ continue;
+
+ // Nun sollte das feature wiklich sichtbar sein
+ fcVisible.add(feature);
+ }
+ }
+ }
+ } catch (final java.lang.IllegalStateException e) {
+ LOGGER.error("Iterating over the features", e);
+ /**
+ * SK: 14.Apri 2009. It happened a few time to that fcIt.hasNext
+ * suddenly threw an exception for the "africa countries.shp":
+ * Exception in thread "AWT-EventQueue-0"
+ * java.lang.IllegalStateException: ShapeType changed illegally from
+ * Polygon to Undefined at org.geotools.
+ * data.shapefile.shp.ShapefileReader.nextRecord(ShapefileReader
+ * .java:452) at org.geotools.data.shapefile.indexed.
+ * IndexedShapefileDataStore$Reader
+ * .next(IndexedShapefileDataStore.java:1272) at
+ * org.geotools.data.FIDFeatureReader.next(FIDFeatureReader.java:92)
+ * at org .geotools.data.FilteringFeatureReader.hasNext(
+ * FilteringFeatureReader .java:125) at
+ * org.geotools.data.store.FeatureReaderIterator.hasNext(
+ * FeatureReaderIterator.java:44) at
+ * schmitzm.geotools.feature.FeatureUtil
+ * .filterSLDVisibleOnly(FeatureUtil.java:216) *
+ *
+ */
}
+ // LOGGER.info("filterSLDVisibleOnly removed "+ (fc.size() -
+ // fcVisible.size()) + " features.");
+
+ return fcVisible;
}
/**
- * Replaces the "main" color in a given {@link LineSymbolizer} element
+ * SLD Rules können die Paramter MinScaleDenominator und MaxScaleDenominator
+ * enthalten. Dadurch können Elemente für manche Zoom-Stufen deaktiviert
+ * werden.
*
+ * @param fc
+ * Die zu filternde FeatureCollection. Diese wird nicht
+ * verändert.
+ * @param style
+ * Der Style, mit dem die Features gerendert werden (z.b.
+ * layer.getStyle() )
+ *
+ * @return Eine FeatureCollection in welcher nur die Features enthalten
+ * sind, welche bei aktuellen Scale mit dem übergebenen Style
+ * gerendert werden.
+ *
* @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static void replaceLineSymbolizerColor(LineSymbolizer ps,
- Color oldColor, Color newColor) {
- if (ps == null)
- return;
+ public static FeatureCollection<SimpleFeatureType, SimpleFeature> filterSLDVisibleOnly(
+ final FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
+ final Style style, XMapPane xMapPane) {
- replaceStrokeColor(ps.getStroke(), oldColor, newColor);
- }
+ if (xMapPane == null || style == null)
+ return new EmptyFeatureCollection(fc.getSchema());
- /**
- * Replaces the "main" color in a given {@link PointSymbolizer} element
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static void replacePointSymbolizerColor(PointSymbolizer ps,
- Color oldColor, Color newColor) {
- if (ps == null)
- return;
+ // Der "scaleDenominator" der aktuellen JMapPane
+ Double scaleDenominator = RendererUtilities.calculateOGCScale(
+ new ReferencedEnvelope(xMapPane.getMapArea(), xMapPane
+ .getMapContext().getCoordinateReferenceSystem()),
+ xMapPane.getBounds().width, null);
- replaceGraphicColor(ps.getGraphic(), oldColor, newColor);
+ return filterSLDVisibleOnly(fc, style, scaleDenominator);
}
/**
- * Replaces the "main" color in a given {@link PolygonSymbolizer} element
+ * Ermittelt fuer einen Wert den {@link ColorMapEntry} aus einer
+ * {@link ColorMap}.
*
- * @param oldColor
- * @param newColor
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- * @param ps
+ * @param value
+ * Wert
+ * @return {@code null}, wenn in der {@link ColorMap} kein expliziter
+ * Eintrag fuer den Wert hinterlegt ist
*/
- public static void replacePolygonSymbolizerColor(PolygonSymbolizer ps,
- Color oldColor, Color newColor) {
- replaceFillColor(ps.getFill(), oldColor, newColor);
- replaceStrokeColor(ps.getStroke(), oldColor, newColor);
+ public static ColorMapEntry findColorMapEntry(ColorMap colorMap,
+ double value) {
+ for (ColorMapEntry entry : colorMap.getColorMapEntries())
+ if (value == getQuantityFromColorMapEntry(entry))
+ return entry;
+ return null;
}
/**
- * Replaces the "main" color in a given {@link Stroke} element
+ * Liefert die Farbe eines Farbpaletten-Eintrag.
*
- * @param stroke
- * @param oldColor
- * @param newColor
+ * @param entry
+ * Farbpaletten-Eintrag
*/
- public static void replaceStrokeColor(Stroke stroke, Color oldColor,
- Color newColor) {
- if (stroke == null)
- return;
+ public static Color getColorFromColorMapEntry(ColorMapEntry entry) {
+ // if ( entry == null || entry.getColor() == null ||
+ // entry.getColor().getValue(null) == null ) // gt2-2.3.4
+ if (entry == null || entry.getColor() == null
+ || entry.getColor().evaluate(null) == null) // gt2-2-4-2
+ return null;
- if ((stroke.getColor() != null)
- && (StylingUtil.getColorFromExpression(stroke.getColor())
- .equals(oldColor)))
- stroke.setColor(StylingUtil.STYLE_BUILDER.colorExpression(newColor));
+ // // Transparenz
+ // Double opacity = getOpacityFromColorMapEntry(entry);
- replaceGraphicColor(stroke.getGraphicFill(), oldColor, newColor);
-
- replaceGraphicColor(stroke.getGraphicStroke(), oldColor, newColor);
-
+ return getColorFromExpression(entry.getColor());
}
/**
- * Replaces the "main" color in a given {@link Fill} element
+ * Liefert die Farbe eines Farbpaletten-Eintrag.
*
- * @param fill
- * @param oldColor
- * @param newColor
+ * @param expression
+ * Expression, die einen String liefert
*/
- public static void replaceFillColor(Fill fill, Color oldColor,
- Color newColor) {
- if (fill == null)
- return;
+ public static Color getColorFromExpression(Expression expression) {
+ if (expression == null)
+ return null;
- if ((fill.getColor() != null)
- && (getColorFromExpression(fill.getColor()).equals(oldColor)))
- fill.setColor(STYLE_BUILDER.colorExpression(newColor));
+ if (expression instanceof ConstantExpression) {
+ ConstantExpression a = (ConstantExpression) expression;
+ Object obj = a.getValue();
+ if (obj instanceof Color) {
+ return (Color) obj;
+ }
+ }
- replaceGraphicColor(fill.getGraphicFill(), oldColor, newColor);
- //
- // if ((fill.getBackgroundColor() != null)
- // && (getColorFromExpression(fill.getBackgroundColor())
- // .equals(oldColor)))
- // fill.setBackgroundColor(STYLE_BUILDER.colorExpression(newColor));
+ return Color.decode(expression.toString());
+
+ // Old way Martin did it:
+ // return Color.decode((String) expression.evaluate(null));
+
}
/**
- * Replaces the "main" color in a given {@link Graphic} element
+ * Liefert die Farbpalette zu einem Style, wenn der Style aus einem
+ * {@link RasterSymbolizer} erzeugt wurde.
*
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @param style
+ * Style Wenn <code>null</code>, dann wird style auf
+ * {@link GridUtil}.createDefaultStyle() gesetzt
+ * @return <code>null</code> wenn der Style nicht auf einem
+ * {@link RasterSymbolizer} basiert.
*/
- public static void replaceGraphicColor(Graphic graphic, Color oldColor,
- Color newColor) {
- if (graphic == null)
- return;
+ public static ColorMap getColorMapFromStyle(final Style style) {
+ final List<ColorMap> colorMapsFromStyle = getColorMapsFromStyle(style);
+ if (colorMapsFromStyle.size() > 0)
+ return colorMapsFromStyle.get(0);
+ else
+ return null;
- if ((graphic.getMarks() != null) && (graphic.getMarks().length > 0)) {
-
- // Checking for Colors in Marks...
- for (Mark m : graphic.getMarks()) {
-
- replaceFillColor(m.getFill(), oldColor, newColor);
-
- replaceStrokeColor(m.getStroke(), oldColor, newColor);
-
- }
- }
}
/**
- * @return the {@link Color} used in the {@link Graphic} or null, if an
- * {@link ExternalGraphic} is used.
+ * Liefert alle Farbpaletten aus einem Style, wenn irgendo
+ * {@link RasterSymbolizer} enthalten sind.
*
- * @param graphic
- * If <code>null</code> returns <code>null</code>
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @param style
+ * Style Wenn <code>null</code>, dann wird style auf
+ * {@link GridUtil}.createDefaultStyle() gesetzt
+ * @return Leere Liste wenn keine RasterSymbolizer enthalten ist.
*/
- public static Color getGraphicColor(Graphic graphic) {
- if (graphic == null)
- return null;
+ public static List<ColorMap> getColorMapsFromStyle(Style style) {
- Color foundColor = null;
+ if (style == null)
+ style = GridUtil.createDefaultStyle();
- if ((graphic.getMarks() != null) && (graphic.getMarks().length > 0)) {
+ final List<RasterSymbolizer> rasterSymbolizers = getRasterSymbolizers(style);
- // Checking for Colors in Marks...
- for (Mark m : graphic.getMarks()) {
+ final List<ColorMap> colorMaps = new ArrayList<ColorMap>();
- if (foundColor == null)
- foundColor = getFillColor(m.getFill());
-
- if (foundColor == null)
- foundColor = getStrokeColor(m.getStroke());
+ for (final RasterSymbolizer rs : rasterSymbolizers) {
+ if (rs.getColorMap() != null) {
+ colorMaps.add(rs.getColorMap());
}
-
}
- return foundColor;
+ return colorMaps;
}
/**
- * @return the first {@link Color} used in a {@link Stroke}.
+ * Returns the color map type specified by a given string.
*
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @param typeStr
+ * a string
+ * @see ColorMap#getType()
*/
- public static Color getStrokeColor(Stroke stroke) {
- if (stroke == null)
- return null;
+ public static int getColorMapType(String typeStr) {
+ if (typeStr == null)
+ throw new IllegalArgumentException("Unknown color map type: "
+ + typeStr);
- if (stroke.getColor() != null)
- return StylingUtil.getColorFromExpression(stroke.getColor());
+ typeStr = typeStr.trim().toLowerCase();
+ if (typeStr.equals("ramp") || typeStr.equals("type_ramp"))
+ return ColorMap.TYPE_RAMP;
+ if (typeStr.equals("intervals") || typeStr.equals("type_intervals"))
+ return ColorMap.TYPE_INTERVALS;
+ if (typeStr.equals("values") || typeStr.equals("type_values"))
+ return ColorMap.TYPE_VALUES;
- if (getGraphicColor(stroke.getGraphicStroke()) != null)
- return getGraphicColor(stroke.getGraphicStroke());
-
- if (getGraphicColor(stroke.getGraphicFill()) != null)
- return getGraphicColor(stroke.getGraphicFill());
-
- return null;
+ throw new IllegalArgumentException("Unknown color map type: " + typeStr);
}
/**
@@ -2261,139 +1741,119 @@
}
/**
- * @return the first {@link Color} used in a {@link Symbolizer}.
+ * Geopublisher allows to use one or two attributes for labelling, like
*
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * <code>
+
+ <sld:Label>
+ <ogc:PropertyName>ORTSRATSBE</ogc:PropertyName>: <ogc:PropertyName>ORB_SCHLUE</ogc:PropertyName>
+ </sld:Label>
+
+ </code>
+ *
+ * Returns the first attribute found in the label expression of the given
+ * {@link TextSymbolizer}. If non is found for some reason, the method tries
+ * to return the first attribute from the schema. We expect the layer to
+ * have some attributes, because otherwise AS shouldn't even create the
+ * LabellingTab.
*/
- public static Color getSymbolizerColor(Symbolizer symb) {
- if (symb == null)
- return null;
+ public static PropertyName getFirstPropertyName(final SimpleFeatureType ft,
+ final TextSymbolizer textSymbolizer) {
+ final Expression labelExpression = textSymbolizer.getLabel();
+ try {
+ if (labelExpression instanceof PropertyName) {
+ // There is no second property
+ return (PropertyName) labelExpression;
+ } else if (labelExpression instanceof Function) {
+ final Function filterExpression = (Function) labelExpression;
+ final FilterAttributeExtractor attExVid = new FilterAttributeExtractor(
+ ft);
- if (symb instanceof PointSymbolizer) {
- PointSymbolizer ps = (PointSymbolizer) symb;
- return getPointSymbolizerColor(ps);
- }
+ attExVid.visit(filterExpression, null);
- if (symb instanceof PolygonSymbolizer) {
- PolygonSymbolizer ps = (PolygonSymbolizer) symb;
- return getPolygonSymbolizerColor(ps);
- }
+ final String[] attributeNames = attExVid.getAttributeNames();
- if (symb instanceof LineSymbolizer) {
- LineSymbolizer ps = (LineSymbolizer) symb;
- return getLineSymbolizerColor(ps);
+ if (attributeNames.length == 0)
+ return null;
+
+ String prop1 = null;
+ if (attributeNames.length == 1) {
+ // Easy
+ prop1 = attributeNames[0];
+ } else {
+
+ if (filterExpression.toString().indexOf(attributeNames[0]) < filterExpression
+ .toString().indexOf(attributeNames[1])) {
+ prop1 = attributeNames[0];
+ // prop2 = attributeNames[1];
+ } else {
+ prop1 = attributeNames[1];
+ // prop2 = attributeNames[0];
+ }
+
+ }
+ return FilterUtil.FILTER_FAC2.property(prop1);
+ }
+ } catch (final Exception e) {
+ LOGGER.error("Reading the second property for labelling failed", e);
+ return null;
}
- return null;
+ // TODO this is not rockhard.. could NPE
+ return FilterUtil.FILTER_FAC2.property(ft.getAttributeDescriptors()
+ .get(1).getLocalName());
}
/**
- * @return the first {@link Color} used in a {@link LineSymbolizer}.
+ * @return the {@link Color} used in the {@link Graphic} or null, if an
+ * {@link ExternalGraphic} is used.
*
+ * @param graphic
+ * If <code>null</code> returns <code>null</code>
+ *
* @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static Color getLineSymbolizerColor(LineSymbolizer ps) {
- if (ps == null)
+ public static Color getGraphicColor(Graphic graphic) {
+ if (graphic == null)
return null;
Color foundColor = null;
- if (foundColor == null)
- foundColor = getStrokeColor(ps.getStroke());
+ if ((graphic.getMarks() != null) && (graphic.getMarks().length > 0)) {
+ // Checking for Colors in Marks...
+ for (Mark m : graphic.getMarks()) {
+
+ if (foundColor == null)
+ foundColor = getFillColor(m.getFill());
+
+ if (foundColor == null)
+ foundColor = getStrokeColor(m.getStroke());
+ }
+
+ }
+
return foundColor;
}
/**
- * @return the first {@link Color} used in a {@link PolygonSymbolizer}.
+ * @return the first {@link Color} used in a {@link LineSymbolizer}.
*
* @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static Color getPolygonSymbolizerColor(PolygonSymbolizer ps) {
+ public static Color getLineSymbolizerColor(LineSymbolizer ps) {
if (ps == null)
return null;
Color foundColor = null;
if (foundColor == null)
- foundColor = getFillColor(ps.getFill());
-
- if (foundColor == null)
foundColor = getStrokeColor(ps.getStroke());
return foundColor;
}
/**
- * @return the first {@link Color} used in a {@link PointSymbolizer}.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static Color getPointSymbolizerColor(PointSymbolizer ps) {
- if (ps == null)
- return null;
-
- return getGraphicColor(ps.getGraphic());
- }
-
- /***************************************************************************
- * Copies all Values from one {@link TextSymbolizer} to another
- * {@link TextSymbolizer}
- *
- * @param from
- * {@link TextSymbolizer} source
- * @param to
- * {@link TextSymbolizer} target. May not be <code>null</code>.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
- */
- public static void copyAllValues(final TextSymbolizer from,
- final TextSymbolizer to) {
- to.setLabel(from.getLabel());
- to.setPriority(from.getPriority());
-
- // TODO Does not copy all that has to be copied!
-
- final FilterFactory2 ff2 = FeatureUtil.FILTER_FACTORY2;
-
- to.getFonts()[0].setFontFamily(ff2.literal(from.getFonts()[0]
- .getFontFamily().toString()));
- to.getFonts()[0].setFontSize(ff2.literal(from.getFonts()[0]
- .getFontSize().toString()));
- to.getFonts()[0].setFontWeight(ff2.literal(from.getFonts()[0]
- .getFontWeight().toString()));
- to.getFonts()[0].setFontStyle(ff2.literal(from.getFonts()[0]
- .getFontStyle().toString()));
- }
-
- /**
- * Returns all {@link RasterSymbolizer} that are contained in a
- * {@link Style}. {@link RasterSymbolizer} from {@link FeatureTypeStyle}s
- * that are selection related are ignored.
- */
- public static List<RasterSymbolizer> getRasterSymbolizers(Style style) {
- final List<RasterSymbolizer> rsList = new ArrayList<RasterSymbolizer>();
- for (FeatureTypeStyle fts : style.featureTypeStyles()) {
-
- // Leave out FTSs that are selection related
- if (fts.getName() != null
- && fts.getName()
- .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME))
- continue;
-
- for (Rule r : fts.rules()) {
- for (Symbolizer symb : r.getSymbolizers()) {
- if (symb instanceof RasterSymbolizer) {
- rsList.add((RasterSymbolizer) symb);
- }
- }
- }
- }
-
- return rsList;
- }
-
- /**
* Super smart metod ;-) Needs to be extended to look at the graphic width
* and Geometry type.
*
@@ -2451,198 +1911,132 @@
}
/**
- * SLD Rules können die Paramter MinScaleDenominator und MaxScaleDenominator
- * enthalten. Dadurch können Elemente für manche Zoom-Stufen deaktiviert
- * werden.
+ * Liefert die Transparenz eines Farbpaletten-Eintrag.
*
- * @param fc
- * Die zu filternde FeatureCollection. Diese wird nicht
- * verändert.
- * @param style
- * Der Style, mit dem die Features gerendert werden (z.b.
- * layer.getStyle() )
+ * @param entry
+ * Farbpaletten-Eintrag
+ * @return 1.0, wenn <code>null</code> uebergeben wird
+ */
+ public static Double getOpacityFromColorMapEntry(ColorMapEntry entry) {
+ if (entry == null)
+ return 1.0;
+ return getOpacityFromExpression(entry.getOpacity());
+ }
+
+ /**
+ * Liefert die Transparenz eines Farbpaletten-Eintrag.
*
- * @return Eine FeatureCollection in welcher nur die Features enthalten
- * sind, welche bei aktuellen Scale mit dem übergebenen Style
- * gerendert werden.
- *
- * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @param expression
+ * Expression, die einen String oder einen Double liefert
+ * @return 1.0, wenn <code>null</code> uebergeben wird
*/
- public static FeatureCollection<SimpleFeatureType, SimpleFeature> filterSLDVisibleOnly(
- final FeatureCollection<SimpleFeatureType, SimpleFeature> fc,
- final Style style, XMapPane xMapPane) {
+ public static Double getOpacityFromExpression(Expression expression) {
+ // gt2-2.3.4:
+ // if ( expression == null || expression.getValue(null) == null )
+ // return 1.0
+ // Object exprValue = evaluate.getValue(null);
+ // gt2-2.3.4:
+ if (expression == null || expression.evaluate(null) == null)
+ return 1.0;
+ Object exprValue = expression.evaluate(null);
- if (xMapPane == null || style == null)
- return new EmptyFeatureCollection(fc.getSchema());
-
- // Der "scaleDenominator" der aktuellen JMapPane
- Double scaleDenominator = RendererUtilities.calculateOGCScale(
- new ReferencedEnvelope(xMapPane.getMapArea(), xMapPane
- .getMapContext().getCoordinateReferenceSystem()),
- xMapPane.getBounds().width, null);
-
- return filterSLDVisibleOnly(fc, style, scaleDenominator);
+ return (exprValue instanceof String) ? Double
+ .valueOf((String) exprValue) : ((Number) exprValue)
+ .doubleValue();
}
/**
- * Since GT2.6, the AttributeNames are case sensitive. Also the raster
- * Styles need GeometryProperty set to "geom" to work. This method checks
- * all referenced AttributeNames.
+ * @return the first {@link Color} used in a {@link PointSymbolizer}.
*
- * @param Schema
- * may be <code>null</code>, e.g. for raster layers
- *
- * TODO Rename to correctStye
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static Style correctPropertyNames(Style style) {
- return correctPropertyNames(style, null);
+ public static Color getPointSymbolizerColor(PointSymbolizer ps) {
+ if (ps == null)
+ return null;
+
+ return getGraphicColor(ps.getGraphic());
}
/**
- * Since GT2.6, the AttributeNames are case sensitive. Also the raster
- * Styles need GeometryProperty set to "geom" to work. This method checks
- * all referenced AttributeNames and checks them against the schema.
+ * @return the first {@link Color} used in a {@link PolygonSymbolizer}.
*
- * @param Schema
- * may be <code>null</code>, e.g. for raster layers
- *
- * TODO Rename to correctStye
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static Style correctPropertyNames(Style style,
- final SimpleFeatureType schema) {
+ public static Color getPolygonSymbolizerColor(PolygonSymbolizer ps) {
+ if (ps == null)
+ return null;
- DuplicatingStyleVisitor dsv = new DuplicatingStyleVisitor() {
- public void visit(RasterSymbolizer sym) {
- sym.setGeometryPropertyName("geom");
- super.visit(sym);
- };
+ Color foundColor = null;
- @Override
- public void visit(ColorMap cm) {
- super.visit(sortColorMap(cm));
- };
+ if (foundColor == null)
+ foundColor = getFillColor(ps.getFill());
- @Override
- public void visit(LineSymbolizer sym) {
- sym.setGeometryPropertyName(FeatureUtil
- .findBestMatchingAttributeFallBackFirst(schema,
- sym.getGeometryPropertyName()).getLocalPart());
- super.visit(sym);
- }
+ if (foundColor == null)
+ foundColor = getStrokeColor(ps.getStroke());
- @Override
- public void visit(PolygonSymbolizer sym) {
- sym.setGeometryPropertyName(FeatureUtil
- .findBestMatchingAttributeFallBackFirst(schema,
- sym.getGeometryPropertyName()).getLocalPart());
- super.visit(sym);
- }
+ return foundColor;
+ }
- @Override
- public void visit(PointSymbolizer sym) {
- sym.setGeometryPropertyName(FeatureUtil
- .findBestMatchingAttributeFallBackFirst(schema,
- sym.getGeometryPropertyName()).getLocalPart());
- super.visit(sym);
- }
+ /**
+ * Liefert den Wert eines Farbpaletten-Eintrag.
+ *
+ * @param entry
+ * Farbpaletten-Eintrag
+ * @return {@code null}, wenn <code>null</code> uebergeben wird
+ */
+ public static Double getQuantityFromColorMapEntry(ColorMapEntry entry) {
+ if (entry == null)
+ return null;
+ return getQuantityFromExpression(entry.getQuantity());
+ }
- @Override
- public void visit(TextSymbolizer sym) {
- sym.setGeometryPropertyName(FeatureUtil
- .findBestMatchingAttributeFallBackFirst(schema,
- sym.getGeometryPropertyName()).getLocalPart());
- if (sym.getLabel() != null)
- sym.setLabel(copy(sym.getLabel()));
+ /**
+ * Liefert den Wert eines Farbpaletten-Eintrag.
+ *
+ * @param expression
+ * Expression, die einen String oder einen Double liefert
+ * @return {@code null}, wenn <code>null</code> uebergeben wird
+ */
+ public static Double getQuantityFromExpression(Expression expression) {
+ // gt2-2.3.4:
+ // if ( expression == null || expression.getValue(null) == null )
+ // return null
+ // Object exprValue = evaluate.getValue(null);
+ // gt2-2.3.4:
+ if (expression == null || expression.evaluate(null) == null)
+ return null;
+ Object exprValue = expression.evaluate(null);
- if (sym.getPriority() != null)
- sym.setPriority(copy(sym.getPriority()));
+ return (exprValue instanceof String) ? Double
+ .valueOf((String) exprValue) : ((Number) exprValue)
+ .doubleValue();
+ }
- super.visit(sym);
- }
+ /**
+ * Returns all {@link RasterSymbolizer} that are contained in a
+ * {@link Style}. {@link RasterSymbolizer} from {@link FeatureTypeStyle}s
+ * that are selection related are ignored.
+ */
+ public static List<RasterSymbolizer> getRasterSymbolizers(Style style) {
+ final List<RasterSymbolizer> rsList = new ArrayList<RasterSymbolizer>();
+ for (FeatureTypeStyle fts : style.featureTypeStyles()) {
- @Override
- public Expression copy(Expression expression) {
- if (expression instanceof FilterFunction_strConcat) {
- FilterFunction_strConcat strConcat = (FilterFunction_strConcat) expression;
+ // Leave out FTSs that are selection related
+ if (fts.getName() != null
+ && fts.getName()
+ .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME))
+ continue;
- List<Expression> children = strConcat.getParameters();
- List<Expression> correctedChildren = new ArrayList<Expression>();
- for (Expression o : children) {
- correctedChildren.add(copy(o));
+ for (Rule r : fts.rules()) {
+ for (Symbolizer symb : r.getSymbolizers()) {
+ if (symb instanceof RasterSymbolizer) {
+ rsList.add((RasterSymbolizer) symb);
}
- strConcat.setParameters(correctedChildren);
-
- } else if (expression instanceof DivideImpl) {
- DivideImpl divFilter = (DivideImpl) expression;
- divFilter.setExpression1(copy(divFilter.getExpression1()));
- divFilter.setExpression2(copy(divFilter.getExpression2()));
- } else if (expression instanceof PropertyName) {
- PropertyName pName = (PropertyName) expression;
-
- Name correctedName = FeatureUtil
- .findBestMatchingAttributeFallBackFirst(schema,
- pName.getPropertyName());
-
- return ff.property(correctedName);
}
- return super.copy(expression);
}
+ }
- @Override
- protected Filter copy(Filter filter) {
- if (filter instanceof DivideImpl) {
- DivideImpl divFilter = (DivideImpl) filter;
- divFilter.setExpression1(copy(divFilter.getExpression1()));
- divFilter.setExpression2(copy(divFilter.getExpression2()));
- } else if (filter instanceof IsNullImpl) {
- IsNullImpl isNullFilter = (IsNullImpl) filter;
- isNullFilter.setExpression1(copy(isNullFilter
- .getExpression1()));
- } else if (filter instanceof NotImpl) {
- NotImpl notFilter = (NotImpl) filter;
- List<Filter> children = notFilter.getChildren();
- List<Filter> correctedChildren = new ArrayList<Filter>();
- for (Filter ex : children) {
- correctedChildren.add(copy(ex));
- }
- notFilter.setChildren(correctedChildren);
- } else if (filter instanceof OrImpl) {
- OrImpl notFilter = (OrImpl) filter;
- List<Filter> children = notFilter.getChildren();
- List<Filter> correctedChildren = new ArrayList<Filter>();
- for (Filter ex : children) {
- correctedChildren.add(copy(ex));
- }
- notFilter.setChildren(correctedChildren);
- } else if (filter instanceof AndImpl) {
- AndImpl andFilter = (AndImpl) filter;
- List<Filter> children = andFilter.getChildren();
- List<Filter> correctedChildren = new ArrayList<Filter>();
- for (Filter ex : children) {
- correctedChildren.add(copy(ex));
- }
- andFilter.setChildren(correctedChildren);
- } else if (filter instanceof BinaryComparisonAbstract) {
- BinaryComparisonAbstract binFilter = (BinaryComparisonAbstract) filter;
- binFilter.setExpression1(copy(binFilter.getExpression1()));
- binFilter.setExpression2(copy(binFilter.getExpression2()));
-
- // TODO noch viel mehr faelle!!
- if (filter instanceof IsBetweenImpl) {
- IsBetweenImpl isbetween = (IsBetweenImpl) filter;
- isbetween
- .setExpression(copy(isbetween.getExpression()));
- }
-
- }
- return (Filter) super.copy(filter);
- }
- };
-
- dsv.visit(style);
-
- Style copiedCleanStyle = (Style) dsv.getCopy();
- return copiedCleanStyle;
+ return rsList;
}
/**
@@ -2691,199 +2085,447 @@
}
/**
- * Geopublisher allows to use one or two attributes for labelling, like
+ * Returns <code>null</code> or any {@link FeatureTypeStyle} contained in
+ * the given {@link Style} that is SELECTION related.
*
- * <code>
-
- <sld:Label>
- <ogc:PropertyName>ORTSRATSBE</ogc:PropertyName>: <ogc:PropertyName>ORB_SCHLUE</ogc:PropertyName>
- </sld:Label>
+ * @see {@link FeatureMapLayerSelectionSynchronizer#SELECTION_STYLING_FTS_NAME}
+ */
+ public static FeatureTypeStyle getSelectionFeatureTypeStyle(
+ final Style style) {
- </code>
+ if (style == null)
+ return null;
+
+ // Remove any selection-FeatureTypeStyle from the new Style
+ for (int ii = 0; ii < style.featureTypeStyles().size(); ii++) {
+
+ FeatureTypeStyle fts = style.featureTypeStyles().get(ii);
+
+ if (fts.getName() != null
+ && fts.getName()
+ .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME)) {
+ return style.featureTypeStyles().get(ii);
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * @return the first {@link Color} used in a {@link Stroke}.
*
- * Returns the first attribute found in the label expression of the given
- * {@link TextSymbolizer}. If non is found for some reason, the method tries
- * to return the first attribute from the schema. We expect the layer to
- * have some attributes, because otherwise AS shouldn't even create the
- * LabellingTab.
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
*/
- public static PropertyName getFirstPropertyName(final SimpleFeatureType ft,
- final TextSymbolizer textSymbolizer) {
- final Expression labelExpression = textSymbolizer.getLabel();
+ public static Color getStrokeColor(Stroke stroke) {
+ if (stroke == null)
+ return null;
+
+ if (stroke.getColor() != null)
+ return StylingUtil.getColorFromExpression(stroke.getColor());
+
+ if (getGraphicColor(stroke.getGraphicStroke()) != null)
+ return getGraphicColor(stroke.getGraphicStroke());
+
+ if (getGraphicColor(stroke.getGraphicFill()) != null)
+ return getGraphicColor(stroke.getGraphicFill());
+
+ return null;
+ }
+
+ //
+ // /**
+ // * Doubles the number of palettes by adding the reverse palette to every
+ // * palette. The name of the reverse palette is the name of the original
+ // * palette plus the letter R.
+ // *
+ // * @author SK
+ // * @param palettes The original list of {@link BrewerPalette
+ // BrewerPalettes}
+ // */
+ // public static BrewerPalette[] addReversePalettes(BrewerPalette[]
+ // palettes) {
+ // BrewerPalette[] newPalettes = new BrewerPalette[palettes.length * 2];
+ //
+ // int pos = 0;
+ // for (BrewerPalette bp : palettes) {
+ // newPalettes[pos] = bp;
+ // pos++;
+ // Color[] newColors = new Color[bp.getMaxColors()];
+ //
+ // List<Color> colorList =
+ // java.util.Arrays.asList(bp.getColors(bp.getMaxColors()));
+ // Collections.reverse(colorList);
+ // colorList.toArray(newColors);
+ //
+ // try {
+ // newPalettes[pos] = StylingUtil.createBrewerPalette(bp.getName()
+ // + "R", newColors);
+ // newPalettes[pos].setPaletteSuitability(bp
+ // .getPaletteSuitability());
+ // newPalettes[pos].setDescription(bp.getDescription()+" reversed");
+ // newPalettes[pos].setType(bp.getType());
+ // newPalettes[pos].setColorScheme(bp.getColorScheme());
+ // } catch (IOException e) {
+ // LOGGER.error("",e);
+ // newPalettes[pos] = bp;
+ // }
+ //
+ // pos++;
+ // }
+ //
+ // return newPalettes;
+ // }
+
+ /**
+ * @return the first {@link Color} used in a {@link Symbolizer}.
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static Color getSymbolizerColor(Symbolizer symb) {
+ if (symb == null)
+ return null;
+
+ if (symb instanceof PointSymbolizer) {
+ PointSymbolizer ps = (PointSymbolizer) symb;
+ return getPointSymbolizerColor(ps);
+ }
+
+ if (symb instanceof PolygonSymbolizer) {
+ PolygonSymbolizer ps = (PolygonSymbolizer) symb;
+ return getPolygonSymbolizerColor(ps);
+ }
+
+ if (symb instanceof LineSymbolizer) {
+ LineSymbolizer ps = (LineSymbolizer) symb;
+ return getLineSymbolizerColor(ps);
+ }
+
+ return null;
+ }
+
+ /**
+ * @param style
+ * A {@link Style} to search for the first {@link TextSymbolizer}
+ * that will be used for the given {@link SimpleFeature}.
+ *
+ * @author Stefan A. Tzeggai
+ *
+ * @return <code>null</code> or the first {@link TextSymbolizer} found in
+ * the style that applies to the {@link SimpleFeature}.
+ */
+ public static TextSymbolizer getTextSymbolizer(final Style style,
+ final SimpleFeature f) {
+ if (f == null)
+ return null;
try {
- if (labelExpression instanceof PropertyName) {
- // There is no second property
- return (PropertyName) labelExpression;
- } else if (labelExpression instanceof Function) {
- final Function filterExpression = (Function) labelExpression;
- final FilterAttributeExtractor attExVid = new FilterAttributeExtractor(
- ft);
+ if (style != null) {
- attExVid.visit(filterExpression, null);
+ for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
+ for (final Rule r : fts.rules()) {
- final String[] attributeNames = attExVid.getAttributeNames();
+ final Filter filter = r.getFilter();
- if (attributeNames.length == 0)
- return null;
+ if (filter != null && (!filter.evaluate(f))) {
+ continue;
+ }
- String prop1 = null;
- if (attributeNames.length == 1) {
- // Easy
- prop1 = attributeNames[0];
- } else {
+ for (final Symbolizer symb : r.getSymbolizers()) {
+ if (symb instanceof TextSymbolizer) {
+ return (TextSymbolizer) symb;
+ }
+ }
- if (filterExpression.toString().indexOf(attributeNames[0]) < filterExpression
- .toString().indexOf(attributeNames[1])) {
- prop1 = attributeNames[0];
- // prop2 = attributeNames[1];
- } else {
- prop1 = attributeNames[1];
- // prop2 = attributeNames[0];
}
+ }
- }
- return FilterUtil.FILTER_FAC2.property(prop1);
}
+
} catch (final Exception e) {
- LOGGER.error("Reading the second property for labelling failed", e);
+ LOGGER.error("error - filter API stuff?", e);
return null;
}
-
- // TODO this is not rockhard.. could NPE
- return FilterUtil.FILTER_FAC2.property(ft.getAttributeDescriptors()
- .get(1).getLocalName());
+ return null;
}
/**
- * AtlasStyler has a fixed system that allows to use one or two label
- * attributes. If two are used, the are seperated by ": ". This mehtod stes
- * one or two ProperybaName fields.
+ * @param style
+ * A {@link Style} to search for all {@link TextSymbolizer}s . No
+ * guarantee, that any one of them will ever be used for any
+ * feature (think about filters).
*
- * @param symbolizer
- * the {@link TextSymbolizer} to call setLabel(Expression) on.
- * @param literalLabelField1
- * may not be null!
- * @param literalLabelField2
- * may be <code>null</code>
+ * @author Stefan A. Tzeggai
+ *
+ * @return {@link List} or all {@link TextSymbolizer}s found in the
+ * {@link Style}.
*/
- public static void setDoublePropertyName(final TextSymbolizer symbolizer,
- final PropertyName literalLabelField1,
- final PropertyName literalLabelField2) {
- if (literalLabelField2 != null
- && !literalLabelField2.toString().equalsIgnoreCase("-")) {
- final Literal trenner = FilterUtil.FILTER_FAC2.literal(": ");
- final Function f3 = FilterUtil.FILTER_FAC2.function("strConcat",
- trenner, literalLabelField2);
- final Function bothExpression = FilterUtil.FILTER_FAC2.function(
- "strConcat", literalLabelField1, f3);
- LOGGER.debug("Extended label expression is now: " + bothExpression);
- symbolizer.setLabel(bothExpression);
- } else {
- symbolizer.setLabel(literalLabelField1);
+ public static List<TextSymbolizer> getTextSymbolizers(final Style style) {
+ List<TextSymbolizer> results = new ArrayList<TextSymbolizer>();
+ try {
+ if (style != null) {
+
+ for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
+ for (final Rule r : fts.rules()) {
+ results.addAll(getTextSymbolizers(r.getSymbolizers()));
+ }
+ }
+
+ }
+
+ } catch (final Exception e) {
+ LOGGER.error("error - filter API stuff?", e);
+ return results;
}
+ return results;
}
/**
- * @return A {@link FeatureTypeStyle} that can be used style the given
- * geoObject during a blink or highlight process.
+ * @param symbolizers
+ * List of Symbolizers to search for all {@link TextSymbolizer}s
+ * . No guarantee, that any one of them will ever be used for any
+ * feature (think about filters).
+ *
+ * @author Stefan A. Tzeggai
+ *
+ * @return {@link List} or all {@link TextSymbolizer}s found in the given
+ * symbolizers.
*/
- public static FeatureTypeStyle createBlinkFeatureTypeStyle(Object geoObject) {
- if (geoObject instanceof GridCoverage2D
- || geoObject instanceof org.geotools.coverage.grid.io.AbstractGridCoverage2DReader) {
- // Wenn irgendwann mal selection für raster möglich ist, dann hier
- // einen schöneren style erstellen.
- return GridUtil.createDefaultStyle().featureTypeStyles().get(0);
- }
+ public static List<TextSymbolizer> getTextSymbolizers(
+ Symbolizer[] symbolizers) {
+ List<TextSymbolizer> results = new ArrayList<TextSymbolizer>();
+ try {
+ if (symbolizers != null) {
- // We have vector-data. Now let's determine the type...
- GeometryForm geometryForm = null;
- if (geoObject instanceof FeatureCollection) {
- geometryForm = FeatureUtil
- .getGeometryForm((FeatureCollection<SimpleFeatureType, SimpleFeature>) geoObject);
- } else if (geoObject instanceof GeometryAttributeType) {
- geometryForm = FeatureUtil
- .getGeometryForm((GeometryAttributeType) geoObject);
- } else if (geoObject instanceof FeatureSource) {
- geometryForm = FeatureUtil
- .getGeometryForm((FeatureSource<SimpleFeatureType, SimpleFeature>) geoObject);
+ for (final Symbolizer symb : symbolizers) {
+ if (symb instanceof TextSymbolizer) {
+ results.add((TextSymbolizer) symb);
+ }
+ }
+
+ }
+
+ } catch (final Exception e) {
+ LOGGER.error("error - filter API stuff?", e);
+ return results;
}
+ return results;
+ }
- Symbolizer[] symbolizers = new Symbolizer[0];
+ /**
+ * @param style
+ * A {@link Style} to search for all {@link TextSymbolizer}s . No
+ * guarantee, that any one of them will ever be used for any
+ * feature (think about filters).
+ *
+ * @author Stefan A. Tzeggai
+ *
+ * @return {@link List} or all {@link TextSymbolizer}s found in the
+ * {@link Style}.
+ */
+ public static List<TextSymbolizer> getVisibleTextSymbolizers(
+ final Style style) {
+ List<TextSymbolizer> results = new ArrayList<TextSymbolizer>();
+ try {
+ if (style != null) {
- Graphic bg2;
- switch (geometryForm) {
+ for (final FeatureTypeStyle fts : style.featureTypeStyles()) {
+ for (final Rule r : fts.rules()) {
- case POINT:
+ if (r.getFilter() != null) {
- Literal size0 = FeatureUtil.FILTER_FACTORY2.literal(26);
- Literal size1 = FeatureUtil.FILTER_FACTORY2.literal(28);
+ /*
+ * We are comparing it to AsUtil.alwaysfalsefilter
+ *
+ * public static final PropertyIsEqualTo
+ * allwaysFalseFilter = ff2.equals(ff2
+ * .literal("1"), ff2.literal("2"));
+ */
+ try {
- Graphic bg1 = STYLE_FACTORY.createGraphic(new ExternalGraphic[0],
- new Mark[] { STYLE_FACTORY.createMark(
- FeatureUtil.FILTER_FACTORY2.literal("circle"),
- STYLE_BUILDER.createStroke(Color.red, 2.), null,
- size1, halfLit) },
- new org.geotools.styling.Symbol[0],
- FeatureUtil.FILTER_FACTORY2.literal(1), size1, zeroLit);
+ Filter f = r.getFilter();
+ if (f instanceof And) {
+ And and = (And) f;
+ if (and.getChildren() != null) {
+ Filter candidateF = and.getChildren()
+ .get(0);
+ if (candidateF instanceof PropertyIsEqualTo) {
+ final PropertyIsEqualTo compare = (PropertyIsEqualTo) candidateF;
+ if (compare.getExpression1() instanceof Literal
+ && compare.getExpression2() instanceof Literal) {
+ Literal test1 = (Literal) compare
+ .getExpression1();
+ Literal test2 = (Literal) compare
+ .getExpression2();
+ if (test1.toString()
+ .equals("1")
+ && test2.toString()
+ .equals("2")) {
+ // This TextSymbolizer is
+ // disabled using
+ // ASUtil.allwaysFalseFilter
+ // LOGGER.debug("Ignoring Rule "+
+ // r
+ // +" because the filter is "+f);
+ continue;
+ }
+ }
+ }
+ }
+ }
+ } catch (Exception e) {
+ LOGGER.debug(
+ "Checking for textSymbolizer allwaysFalseFilter",
+ e);
+ }
+ }
- PointSymbolizer ps1 = STYLE_FACTORY.createPointSymbolizer();
- ps1.setGraphic(bg1);
- symbolizers = LangUtil.extendArray(symbolizers, ps1);
+ results.addAll(getTextSymbolizers(r.getSymbolizers()));
+ }
+ }
- bg2 = STYLE_FACTORY.createGraphic(new ExternalGraphic[0],
- new Mark[] { STYLE_FACTORY.createMark(
- FeatureUtil.FILTER_FACTORY2.literal("circle"),
- STYLE_BUILDER.createStroke(Color.black, 2.),
- STYLE_BUILDER.createFill(Color.WHITE, 0.3), size0,
- halfLit) }, new org.geotools.styling.Symbol[0],
- FeatureUtil.FILTER_FACTORY2.literal(1), size0, zeroLit);
+ }
- PointSymbolizer ps2 = STYLE_FACTORY.createPointSymbolizer();
- ps2.setGraphic(bg2);
+ } catch (final Exception e) {
+ LOGGER.error("error - filter API stuff?", e);
+ return results;
+ }
+ return results;
+ }
- symbolizers = LangUtil.extendArray(symbolizers, ps2);
- break;
- case POLYGON:
+ /**
+ * Compares a given Style and a {@link File} containg a {@link Style}.
+ *
+ * @param style1
+ * The first {@link Style}
+ * @param style2file
+ * A {@link File} pointing to the second {@link Style}
+ * @return <code>true</code> is they are different, ignoring any XML
+ * fomatting.
+ */
+ public static boolean isStyleDifferent(Style style1, File style2file) {
+ SLDTRANSFORMER.setIndentation(2);
- PolygonSymbolizer pol1 = STYLE_BUILDER.createPolygonSymbolizer(
- STYLE_BUILDER.createStroke(Color.red, 4), null);
- symbolizers = LangUtil.extendArray(symbolizers, pol1);
+ try {
- PolygonSymbolizer pol2 = STYLE_BUILDER.createPolygonSymbolizer(
- STYLE_BUILDER.createStroke(Color.black, 2),
- STYLE_BUILDER.createFill(Color.WHITE, .5));
- symbolizers = LangUtil.extendArray(symbolizers, pol2);
+ if (!style2file.exists())
+ return true;
- break;
+ Style style2 = loadSLD(style2file)[0];
- case LINE:
+ return isStyleDifferent(style1, style2);
- LineSymbolizer ls = STYLE_BUILDER.createLineSymbolizer(Color.red,
- 6.);
- symbolizers = LangUtil.extendArray(symbolizers, ls);
+ } catch (Exception e) {
+ LOGGER.debug("Comparing styles " + style1 + " and " + style2file
+ + " failed. So we assume they are different.", e);
+ return true;
+ }
+ }
- LineSymbolizer ls2 = STYLE_BUILDER.createLineSymbolizer(
- Color.black, 4.);
- symbolizers = LangUtil.extendArray(symbolizers, ls2);
+ /**
+ * Compares a given Style and a {@link File} containg a {@link Style}.
+ *
+ * @param style1
+ * The first {@link Style}
+ * @param style2
+ * The second {@link Style} to compare to
+ * @return <code>true</code> is they are different, ignoring any XML
+ * fomatting.
+ */
+ public static boolean isStyleDifferent(Style style1, Style style2) {
+ try {
+ // SLDTRANSFORMER.setEncoding(Charset.forName("UTF-8"));
+ // Transforming style2 to an XML String
+ String style1string = SLDTRANSFORMER.transform(style1);
+ String style2string = SLDTRANSFORMER.transform(style2);
- LineSymbolizer ls3 = STYLE_BUILDER.createLineSymbolizer(
- Color.white, 2.);
- symbolizers = LangUtil.extendArray(symbolizers, ls3);
- break;
+ return !style1string.equals(style2string);
- default:
- throw new IllegalArgumentException("Provide a suitable object.");
+ } catch (Exception e) {
+ LOGGER.debug("Compating styles " + style1 + " and " + style2
+ + " failed. So we assume they are different.", e);
+ return true;
}
- return STYLE_BUILDER.createFeatureTypeStyle(symbolizers, Double.NaN,
- Double.NaN);
}
- public static StyledLayerDescriptor loadStyledLayerDescriptor(Reader reader) {
+ /**
+ * Loads {@link Style}s from a SLD {@link File}
+ *
+ * @param sldFile
+ * {@link File} to read the SLD from
+ *
+ * @return An {@link Array} of {@link Style}s, can be length==0
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static Style[] loadSLD(File sldFile) throws FileNotFoundException {
+
+ FileInputStream inputStream = null;
+ try {
+ inputStream = new FileInputStream(sldFile);
+ final Style[] loadedSLD = loadSLD(inputStream);
+ return loadedSLD;
+ } finally {
+ IOUtils.closeQuietly(inputStream);
+ }
+ }
+
+ /**
+ * Loads {@link Style}s from a SLD {@link InputStream}
+ *
+ * @param inputStream
+ * {@link InputStream} to read the SLD from
+ *
+ * @return An {@link Array} of {@link Style}s, can be length==0. null if
+ * file not exists
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static Style[] loadSLD(InputStream inputStream) {
+
+ Style[] styles = null;
+ try {
+ SLDParser stylereader = new SLDParser(StylingUtil.STYLE_FACTORY,
+ inputStream);
+ styles = stylereader.readXML();
+ return styles;
+ } catch (Exception e) {
+ LOGGER.warn(
+ " ... no styles recognized. Return 'new Style[] { null }' ",
+ e);
+ return new Style[] { null };
+ }
+
+ }
+
+ /**
+ * Loads {@link Style}s from a SLD {@link InputStream}
+ *
+ * @param url
+ * {@link URL} to read the SLD from
+ *
+ * @return An {@link Array} of {@link Style}s, can be length==0 if no
+ * UserStyles in SLD file. null if file not exists
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static Style[] loadSLD(URL url) {
+ InputStream openStream = null;
+ try {
+ openStream = url.openStream();
+ return loadSLD(openStream);
+ } catch (IOException e) {
+ return null;
+ } finally {
+ IOUtils.closeQuietly(openStream);
+ }
+ }
+
+ public static StyledLayerDescriptor loadStyledLayerDescriptor(
+ InputStream inputStream) {
StyledLayerDescriptor sld = null;
try {
SLDParser stylereader = new SLDParser(StylingUtil.STYLE_FACTORY,
- reader);
+ inputStream);
sld = stylereader.parseSLD();
return sld;
} catch (Exception e) {
@@ -2894,12 +2536,11 @@
}
}
- public static StyledLayerDescriptor loadStyledLayerDescriptor(
- InputStream inputStream) {
+ public static StyledLayerDescriptor loadStyledLayerDescriptor(Reader reader) {
StyledLayerDescriptor sld = null;
try {
SLDParser stylereader = new SLDParser(StylingUtil.STYLE_FACTORY,
- inputStream);
+ reader);
sld = stylereader.parseSLD();
return sld;
} catch (Exception e) {
@@ -2910,47 +2551,80 @@
}
}
+ static public ColorMap parseColormapToSld(File colormapFile)
+ throws IOException {
+ return parseColormapToSld(DataUtilities.fileToURL(colormapFile));
+ }
+
/**
- * Converts a {@link StyledLayerDescriptor} or any of it's subcomponents to
- * XML
+ * Creates a Geotools Colormap containing all the Color Palette definitions
+ * defined in the File. The File may have different formats. Supported
+ * formats are<br/>
+ * <ul>
+ * <li>gdalinfo output</li>
+ * </ul>
*
- * @throws TransformerException
+ * <br/>
+ * The returned {@link ColorMap} is of type {@link ColorMap#TYPE_VALUES}.
+ *
+ * TODO Stefan Tzeggai Support gdal xml.aux format!
+ *
+ * @see http
+ * ://osgeo-org.1803224.n2.nabble.com/gdal-dev-Color-palette-file-for
+ * -use-in-rgb2pct-td4493744.html
*/
- public static String toXMLString(Object sld) throws TransformerException {
- SLDTRANSFORMER.setIndentation(1);
- return SLDTRANSFORMER.transform(sld);
- }
-
- static public ColorMap parseColormapToSld(URL colormapUrl)
- throws IOException {
- return parseColormapToSld(DataUtilities.urlToFile(colormapUrl));
- }
-
- static Pattern GDALCOLORMAP_4 = Pattern
- .compile("(\\d+): (\\d+),(\\d+),(\\d+),(\\d+).*$");
-
- static public ColorMap parseColormapToSld(File file) throws IOException {
+ static public ColorMap parseColormapToSld(URL url) throws IOException {
String[] labels = new String[0];
double[] quantities = new double[0];
Color[] colors = new Color[0];
- String readFileAsString = IOUtil.readFileAsString(file);
+ String readFileAsString = IOUtil.readURLasString(url);
for (String line : readFileAsString.split("\\n")) {
- Matcher matcher = GDALCOLORMAP_4.matcher(line);
- if (matcher.find()) {
- String q = matcher.group(1);
- String r = matcher.group(2);
- String g = matcher.group(3);
- String b = matcher.group(4);
- String o = matcher.group(5);
-
- Color color = new Color(Integer.valueOf(r), Integer.valueOf(g),Integer.valueOf(b), Integer.valueOf(o));
-
- // Arrays verlängern
- labels = LangUtil.extendArray(labels, "");
- colors = LangUtil.extendArray(colors, color);
- quantities = LangUtil.extendArray(quantities, Double.valueOf(q));
+
+ try {
+
+ Matcher matcher = GDALINFO_COLORMAP_RGBA.matcher(line);
+ if (matcher.find()) {
+ Color color = new Color(Integer.valueOf(matcher.group(2)),
+ Integer.valueOf(matcher.group(3)),
+ Integer.valueOf(matcher.group(4)),
+ Integer.valueOf(matcher.group(5)));
+
+ // Arrays verlängern
+ labels = LangUtil.extendArray(labels, "");
+ colors = LangUtil.extendArray(colors, color);
+ quantities = LangUtil.extendArray(quantities,
+ Double.valueOf(matcher.group(1)));
+
+ // Zur nächsten Zeile springen
+ continue;
+ }
+ } catch (Exception e) {
+ Log.warn("Error parsing a line to ColorMapEntry. Line = '"
+ + line + "'. Skipped.", e);
}
+
+ try {
+ Matcher matcher = GDALINFO_COLORMAP_RGB.matcher(line);
+ if (matcher.find()) {
+ Color color = new Color(Integer.valueOf(matcher.group(2)),
+ Integer.valueOf(matcher.group(3)),
+ Integer.valueOf(matcher.group(4)));
+
+ // Arrays verlängern
+ labels = LangUtil.extendArray(labels, "");
+ colors = LangUtil.extendArray(colors, color);
+ quantities = LangUtil.extendArray(quantities,
+ Double.valueOf(matcher.group(1)));
+
+ // Zur nächsten Zeile springen
+ continue;
+
+ }
+ } catch (Exception e) {
+ Log.warn("Error parsing a line to ColorMapEntry. Line = '"
+ + line + "'. Skipped.", e);
+ }
}
int type = ColorMap.TYPE_VALUES;
@@ -2959,4 +2633,383 @@
return createColorMap;
}
+ /**
+ * Unless {@link ColorMap} has no methods to remove an entry this method
+ * creates a new {@link ColorMap} with the identical entries except the one
+ * to remove.
+ *
+ * @param colorMap
+ * the color map to remove entries from
+ * @param colorMapEntry
+ * the entry to remove
+ */
+ public static ColorMap removeColorMapEntry(ColorMap colorMap,
+ ColorMapEntry colorMapEntry) {
+ ColorMap newColorMap = new ColorMapImpl();
+ applyColorMapProperties(colorMap, newColorMap);
+
+ ColorMapEntry[] entry = colorMap.getColorMapEntries();
+ for (int i = 0; i < entry.length; i++)
+ if (entry[i] != colorMapEntry)
+ newColorMap.addColorMapEntry(entry[i]);
+
+ return newColorMap;
+ }
+
+ /**
+ * Unless {@link ColorMap} has no methods to remove an entry this method
+ * creates a new {@link ColorMap} with the identical entries except the one
+ * to remove.
+ *
+ * @param colorMap
+ * the color map to remove entries from
+ * @param idx
+ * the entry index to remove
+ */
+ public static ColorMap removeColorMapEntry(ColorMap colorMap, int idx) {
+ ColorMap newColorMap = new ColorMapImpl();
+ applyColorMapProperties(colorMap, newColorMap);
+
+ ColorMapEntry[] entry = colorMap.getColorMapEntries();
+ for (int i = 0; i < entry.length; i++)
+ if (i != idx)
+ newColorMap.addColorMapEntry(entry[i]);
+
+ return newColorMap;
+ }
+
+ /**
+ * Creates a copy of the given {@link Style}, removing any
+ * {@link FeatureTypeStyle}s that are only SELECTION related.
+ *
+ * @see {@link FeatureMapLayerSelectionSynchronizer#SELECTION_STYLING_FTS_NAME}
+ */
+ public static Style removeSelectionFeatureTypeStyle(final Style style) {
+
+ // Create a copy of the style
+ DuplicatingStyleVisitor duplVisitor = new DuplicatingStyleVisitor();
+ duplVisitor.visit(style);
+ Style cleanStyle = (Style) duplVisitor.getCopy();
+
+ // Remove any selection-FeatureTypeStyle from the new Style
+ for (int ii = 0; ii < style.featureTypeStyles().size(); ii++) {
+
+ FeatureTypeStyle fts = style.featureTypeStyles().get(ii);
+
+ if (fts.getName() != null
+ && fts.getName()
+ .equals(FeatureMapLayerSelectionSynchronizer.SELECTION_STYLING_FTS_NAME)) {
+ cleanStyle.featureTypeStyles().remove(ii);
+ break;
+ }
+ }
+
+ return cleanStyle;
+ }
+
+ /**
+ * Replaces the "main" color in a given {@link Fill} element
+ *
+ * @param fill
+ * @param oldColor
+ * @param newColor
+ */
+ public static void replaceFillColor(Fill fill, Color oldColor,
+ Color newColor) {
+ if (fill == null)
+ return;
+
+ if ((fill.getColor() != null)
+ && (getColorFromExpression(fill.getColor()).equals(oldColor)))
+ fill.setColor(STYLE_BUILDER.colorExpression(newColor));
+
+ replaceGraphicColor(fill.getGraphicFill(), oldColor, newColor);
+ //
+ // if ((fill.getBackgroundColor() != null)
+ // && (getColorFromExpression(fill.getBackgroundColor())
+ // .equals(oldColor)))
+ // fill.setBackgroundColor(STYLE_BUILDER.colorExpression(newColor));
+ }
+
+ /**
+ * Replaces the "main" color in a given {@link Graphic} element
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static void replaceGraphicColor(Graphic graphic, Color oldColor,
+ Color newColor) {
+ if (graphic == null)
+ return;
+
+ if ((graphic.getMarks() != null) && (graphic.getMarks().length > 0)) {
+
+ // Checking for Colors in Marks...
+ for (Mark m : graphic.getMarks()) {
+
+ replaceFillColor(m.getFill(), oldColor, newColor);
+
+ replaceStrokeColor(m.getStroke(), oldColor, newColor);
+
+ }
+ }
+ }
+
+ /**
+ * Replaces the "main" color in a given {@link LineSymbolizer} element
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static void replaceLineSymbolizerColor(LineSymbolizer ps,
+ Color oldColor, Color newColor) {
+ if (ps == null)
+ return;
+
+ replaceStrokeColor(ps.getStroke(), oldColor, newColor);
+ }
+
+ /**
+ * Replaces the "main" color in a given {@link PointSymbolizer} element
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static void replacePointSymbolizerColor(PointSymbolizer ps,
+ Color oldColor, Color newColor) {
+ if (ps == null)
+ return;
+
+ replaceGraphicColor(ps.getGraphic(), oldColor, newColor);
+ }
+
+ /**
+ * Replaces the "main" color in a given {@link PolygonSymbolizer} element
+ *
+ * @param oldColor
+ * @param newColor
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @param ps
+ */
+ public static void replacePolygonSymbolizerColor(PolygonSymbolizer ps,
+ Color oldColor, Color newColor) {
+ replaceFillColor(ps.getFill(), oldColor, newColor);
+ replaceStrokeColor(ps.getStroke(), oldColor, newColor);
+ }
+
+ /**
+ * Replaces the "main" color in a given {@link Stroke} element
+ *
+ * @param stroke
+ * @param oldColor
+ * @param newColor
+ */
+ public static void replaceStrokeColor(Stroke stroke, Color oldColor,
+ Color newColor) {
+ if (stroke == null)
+ return;
+
+ if ((stroke.getColor() != null)
+ && (StylingUtil.getColorFromExpression(stroke.getColor())
+ .equals(oldColor)))
+ stroke.setColor(StylingUtil.STYLE_BUILDER.colorExpression(newColor));
+
+ replaceGraphicColor(stroke.getGraphicFill(), oldColor, newColor);
+
+ replaceGraphicColor(stroke.getGraphicStroke(), oldColor, newColor);
+
+ }
+
+ /**
+ * Replaces the "main" color in a given {@link Symbolizer} element
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ */
+ public static void replaceSymbolizerColor(Symbolizer symb, Color oldColor,
+ Color newColor) {
+ if (symb == null)
+ return;
+
+ if (symb instanceof PointSymbolizer) {
+ PointSymbolizer ps = (PointSymbolizer) symb;
+ replacePointSymbolizerColor(ps, oldColor, newColor);
+ }
+
+ if (symb instanceof PolygonSymbolizer) {
+ PolygonSymbolizer ps = (PolygonSymbolizer) symb;
+ replacePolygonSymbolizerColor(ps, oldColor, newColor);
+ }
+
+ if (symb instanceof LineSymbolizer) {
+ LineSymbolizer ps = (LineSymbolizer) symb;
+ replaceLineSymbolizerColor(ps, oldColor, newColor);
+ }
+
+ }
+
+ /**
+ * Saves the {@link Style} to OGC SLD. Overwrites any existing file. If a
+ * FeatureTypeStyle for selection is used, it is automatically removed. This
+ * method also checks, whether the style is actually differing from any
+ * existing style in the {@link File}. If there is no difference, the file
+ * is not saved again (that is more svn friendly).
+ *
+ * @param origStyle
+ * {@link Style} to save. Any selectino related FeatureTypeStyle
+ * will be removed.
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ *
+ * @return <code>true</code> if the file was really written.
+ * <code>false</code> means, that the existing file already was
+ * equals.
+ * @throws IOException
+ * @throws TransformerException
+ */
+ public static final boolean saveStyleToSLD(Style origStyle, File exportFile)
+ throws TransformerException, IOException {
+
+ // Wenn Datei nicht mit .sld endet, die Dateierweiterung
+ // anhängen
+ exportFile = IOUtil.appendFileExt(exportFile, ".sld");
+
+ SLDTRANSFORMER.setIndentation(2);
+
+ Style exportStyle = removeSelectionFeatureTypeStyle(origStyle);
+
+ // Nur in Datei speichern, wenn
+ if (!isStyleDifferent(exportStyle, exportFile)) {
+ return false;
+ }
+
+ SLDTRANSFORMER.transform(exportStyle, new FileWriter(exportFile));
+ return true;
+ }
+
+ /**
+ * Exports the {@link Style} to OGC SLD. If a FeatureTypeStyle for selection
+ * is used, it is automatically removed.
+ *
+ * @param style
+ * {@link Style} to save. Any selectino related FeatureTypeStyle
+ * will be removed.
+ *
+ * @author <a href="mailto:skpublic at wikisquare.de">Stefan Alfons Tzeggai</a>
+ * @throws TransformerException
+ */
+ public static final void saveStyleToSLD(Style style,
+ OutputStream exportStream) throws TransformerException {
+ SLDTRANSFORMER.setIndentation(2);
+ SLDTRANSFORMER.transform(style, exportStream);
+ }
+
+ /**
+ * Setzt die Farbe eines Farbpaletten-Eintrag.
+ *
+ * @param entry
+ * Farbpaletten-Eintrag
+ * @param color
+ * eine Farbe
+ */
+ public static void setColorForColorMapEntry(ColorMapEntry entry, Color color) {
+ if (entry != null)
+ entry.setColor(STYLE_BUILDER.colorExpression(color));
+ }
+
+ /**
+ * AtlasStyler has a fixed system that allows to use one or two label
+ * attributes. If two are used, the are seperated by ": ". This mehtod stes
+ * one or two ProperybaName fields.
+ *
+ * @param symbolizer
+ * the {@link TextSymbolizer} to call setLabel(Expression) on.
+ * @param literalLabelField1
+ * may not be null!
+ * @param literalLabelField2
+ * may be <code>null</code>
+ */
+ public static void setDoublePropertyName(final TextSymbolizer symbolizer,
+ final PropertyName literalLabelField1,
+ final PropertyName literalLabelField2) {
+ if (literalLabelField2 != null
+ && !literalLabelField2.toString().equalsIgnoreCase("-")) {
+ final Literal trenner = FilterUtil.FILTER_FAC2.literal(": ");
+ final Function f3 = FilterUtil.FILTER_FAC2.function("strConcat",
+ trenner, literalLabelField2);
+ final Function bothExpression = FilterUtil.FILTER_FAC2.function(
+ "strConcat", literalLabelField1, f3);
+ LOGGER.debug("Extended label expression is now: " + bothExpression);
+ symbolizer.setLabel(bothExpression);
+ } else {
+ symbolizer.setLabel(literalLabelField1);
+ }
+ }
+
+ /**
+ * Setzt die Transparenz eines Farbpaletten-Eintrag.
+ *
+ * @param entry
+ * Farbpaletten-Eintrag
+ * @param opacity
+ * Transparenzwert
+ */
+ public static void setOpacityForColorMapEntry(ColorMapEntry entry,
+ double opacity) {
+ if (entry != null)
+ entry.setOpacity(STYLE_BUILDER.literalExpression(opacity));
+ }
+
+ /**
+ * Setzt den Wert eines Farbpaletten-Eintrag.
+ *
+ * @param entry
+ * Farbpaletten-Eintrag
+ * @param quantity
+ * neuer Wert
+ */
+ public static void setQuantityForColorMapEntry(ColorMapEntry entry,
+ double quantity) {
+ if (entry != null)
+ entry.setQuantity(STYLE_BUILDER.literalExpression(quantity));
+ }
+
+ /**
+ * Sorts a {@link ColorMap} according to the value of its entries.
+ *
+ * @param colorMap
+ * the color map to sort
+ */
+ public static ColorMap sortColorMap(ColorMap colorMap) {
+ ColorMap newColorMap = new ColorMapImpl();
+ applyColorMapProperties(colorMap, newColorMap);
+
+ // Put all color map entries in a sorted map (with
+ // collision lists!)
+ SortedMap<Double, Vector<ColorMapEntry>> sortedEntries = new TreeMap<Double, Vector<ColorMapEntry>>();
+ for (ColorMapEntry entry : colorMap.getColorMapEntries()) {
+ double quantity = getQuantityFromColorMapEntry(entry);
+ Vector<ColorMapEntry> collisionList = sortedEntries.get(quantity);
+ if (collisionList == null) {
+ collisionList = new Vector<ColorMapEntry>();
+ sortedEntries.put(quantity, collisionList);
+ }
+ collisionList.add(entry);
+ }
+
+ // According to the order of the sorted map, put all
+ // color map entries to the new ColorMap
+ for (Vector<ColorMapEntry> collisionList : sortedEntries.values())
+ for (ColorMapEntry entry : collisionList)
+ newColorMap.addColorMapEntry(entry);
+
+ return newColorMap;
+ }
+
+ /**
+ * Converts a {@link StyledLayerDescriptor} or any of it's subcomponents to
+ * XML
+ *
+ * @throws TransformerException
+ */
+ public static String toXMLString(Object sld) throws TransformerException {
+ SLDTRANSFORMER.setIndentation(1);
+ return SLDTRANSFORMER.transform(sld);
+ }
}
Modified: trunk/src_junit/schmitzm/lang/ResourceProviderTest.java
===================================================================
--- trunk/src_junit/schmitzm/lang/ResourceProviderTest.java 2010-10-26 10:00:10 UTC (rev 1173)
+++ trunk/src_junit/schmitzm/lang/ResourceProviderTest.java 2010-10-26 10:00:34 UTC (rev 1174)
@@ -54,6 +54,10 @@
@Test
public void testCreatePropertyFile() {
+
+ // TODO Martin Schmitzm MS + Stefan Tzeggai
+
+ // TODO Test schreiben, dass das etwas sinnvolles exportiert.
String before = "A\nB\nC";
String after = before.replaceAll("\\n", "\\\\n");
assertFalse(before.equals(after));
More information about the Schmitzm-commits
mailing list