[Schmitzm-commits] r1949 - in trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools: . feature styling styling/chartsymbols

scm-commit at wald.intevation.org scm-commit at wald.intevation.org
Sun Apr 15 13:31:30 CEST 2012


Author: alfonx
Date: 2012-04-15 13:31:30 +0200 (Sun, 15 Apr 2012)
New Revision: 1949

Added:
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphic.java
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangeListener.java
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangedEvent.java
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicLegendVisitor.java
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicPreviewFixStyleVisitor.java
Modified:
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/LegendIconFeatureRenderer.java
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/feature/FeatureUtil.java
   trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/StyledLayerUtil.java
Log:
ChartGrapics as Symvols in AtlasStyler / GP now habe legends and therefor are beta - ready to testing and misses GP specific adaptinos (Translations etc.)

Modified: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/LegendIconFeatureRenderer.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/LegendIconFeatureRenderer.java	2012-04-15 11:02:04 UTC (rev 1948)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/LegendIconFeatureRenderer.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -64,7 +64,6 @@
 import org.geotools.styling.Symbolizer;
 import org.geotools.styling.TextSymbolizer;
 import org.geotools.util.NumberRange;
-import org.opengis.feature.IllegalAttributeException;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
 import org.opengis.feature.type.AttributeDescriptor;
@@ -76,9 +75,10 @@
 import com.vividsolutions.jts.geom.Polygon;
 
 import de.schmitzm.geotools.feature.FeatureUtil;
+import de.schmitzm.geotools.styling.StylingUtil;
 
 /**
- * Based on geoserver!
+ * Somehow based on an old geoserver <=2.0 version.
  * <hr>
  * <b>Changes by <a href="mailto:Martin.Schmitz at koeln.de">Martin Schmitz</a></b>
  * <li>07.02.2008:<br>
@@ -86,25 +86,18 @@
  * {@link FeatureUtil#getDefaultAttributeValues(SimpleFeatureType)} instead of
  * using {@link AttributeDescriptor#createDefaultValue()} directly, because the
  * latter returns {@code null} even though the attribut is not nillable.</li>
- * </ul>
- * 
- * @author Stefan A. Tzeggai (wikisquare.de) für CPA Systems GmbH Alfons Tzeggai
  */
 public class LegendIconFeatureRenderer {
-	// private static final Dimension SIZE = new Dimension(30,20);
 
 	Logger LOGGER = Logger.getLogger(LegendIconFeatureRenderer.class);
 
-	/**
-	 * This is a static class
-	 */
-	private LegendIconFeatureRenderer() {
+	public LegendIconFeatureRenderer() {
 	}
 
 	/**
 	 * We have to return new instances here. Otherwise the sample features are
-	 * not recreated and the sizes of the previews are locaked to the size of
-	 * the first request.
+	 * not recreated and the sizes of the previews are locked to the size of the
+	 * first request.
 	 */
 	public static LegendIconFeatureRenderer getInstance() {
 		return new LegendIconFeatureRenderer();
@@ -235,8 +228,6 @@
 	 *            {@link Style}
 	 * @param bg
 	 *            Background {@link Color} or <code>null</code>
-	 * 
-	 * @throws IllegalAttributeException
 	 */
 	public BufferedImage createImageForRule(Rule rule,
 			SimpleFeatureType featureType, Dimension size, Color bg) {
@@ -248,10 +239,10 @@
 		Graphics2D graphics = buffImage.createGraphics();
 
 		if (bg != null) {
-			// ****************************************************************************
-			// The following lines define the background color for the rendered
-			// images
-			// ****************************************************************************
+			/*
+			 * The following lines define the background color for the rendered
+			 * image
+			 */
 			graphics.setBackground(bg);
 			graphics.setColor(bg);
 			graphics.fillRect(0, 0, size.width, size.height);
@@ -269,15 +260,15 @@
 				Symbolizer symbolizer = symbolizers[sIdx];
 
 				if (symbolizer instanceof TextSymbolizer) {
+					// TextSymbolizers are not rendered in the Legend
 					continue;
 				}
-				
 
 				final SimpleFeature sampleFeature = FeatureUtil
 						.createSampleFeature(featureType);
-				
+
 				if (sampleFeature == null)
-					LOGGER.debug("sampleFeature " + sampleFeature);
+					LOGGER.warn("sampleFeature " + sampleFeature);
 
 				// The SLDStyleFactory has to be recreated, as it seams to cache
 				// some stuff.
@@ -301,16 +292,6 @@
 		return buffImage;
 	}
 
-	/**
-	 * Define Java2D and other Hints
-	 * 
-	 * @param hints
-	 * @author <a href="mailto:tzeggai at wikisquare.de">Stefan Alfons Tzeggai</a>
-	 */
-	public void setHints(Hints hints) {
-		getHints().add(hints);
-	}
-
 	private Hints getHints() {
 		if (hints == null) {
 			hints = GeoTools.getDefaultHints();
@@ -338,12 +319,22 @@
 	 *            Schema that describes the kind of the sample
 	 *            {@link SimpleFeature} that will be rendered with the
 	 *            {@link Style}
-	 * 
-	 * @throws IllegalAttributeException
 	 */
 	public BufferedImage createImageForRule(final Rule rule,
 			final SimpleFeatureType featureType, final Dimension size) {
 		return createImageForRule(rule, featureType, size, null);
 	}
 
+	/**
+	 * Creates a little BufferedImage that presents the Style/Symbols used by
+	 * the {@link MapLegend} to show a legend for the {@link SimpleFeatureType}
+	 */
+	public BufferedImage createImageForSymbolizer(final Symbolizer symbolizer,
+			final SimpleFeatureType featureType, final Dimension size) {
+
+		Rule rule = StylingUtil.STYLE_BUILDER.createRule(symbolizer);
+
+		return createImageForRule(rule, featureType, size, null);
+	}
+
 }

Modified: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/feature/FeatureUtil.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/feature/FeatureUtil.java	2012-04-15 11:02:04 UTC (rev 1948)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/feature/FeatureUtil.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -2131,8 +2131,6 @@
 	 * 
 	 * @param schema
 	 *            the schema for which to create a sample SimpleFeature instance
-	 * @author SK
-	 * @throws org.opengis.feature.IllegalAttributeException
 	 */
 	public static SimpleFeature createSampleFeature(SimpleFeatureType schema,
 			Object... values) {

Modified: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/StyledLayerUtil.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/StyledLayerUtil.java	2012-04-15 11:02:04 UTC (rev 1948)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/StyledLayerUtil.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -31,6 +31,7 @@
 
 import java.awt.Color;
 import java.awt.Dimension;
+import java.awt.Graphics;
 import java.awt.Graphics2D;
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
@@ -73,6 +74,7 @@
 import org.geotools.styling.ColorMap;
 import org.geotools.styling.ColorMapEntry;
 import org.geotools.styling.FeatureTypeStyle;
+import org.geotools.styling.PointSymbolizer;
 import org.geotools.styling.RasterSymbolizer;
 import org.geotools.styling.Rule;
 import org.geotools.styling.SelectedChannelType;
@@ -90,6 +92,7 @@
 import org.opengis.parameter.GeneralParameterValue;
 
 import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.Point;
 
 import de.schmitzm.geotools.GTUtil;
 import de.schmitzm.geotools.JTSUtil;
@@ -100,6 +103,7 @@
 import de.schmitzm.geotools.data.amd.AttributeMetadataMap;
 import de.schmitzm.geotools.data.rld.RasterLegendData;
 import de.schmitzm.geotools.feature.FeatureUtil;
+import de.schmitzm.geotools.styling.chartsymbols.ChartGraphic;
 import de.schmitzm.i18n.I18NUtil;
 import de.schmitzm.i18n.Translation;
 import de.schmitzm.io.IOUtil;
@@ -1070,31 +1074,87 @@
 						.size() == rule.getSymbolizers().length)
 					continue;
 
-				final BufferedImage imageForRule = LegendIconFeatureRenderer
-						.getInstance().createImageForRule(rule, featureType,
-								new Dimension(iconWidth, iconHeight));
+				if (ChartGraphic.isChart(rule.symbolizers().get(0))) {
 
-				final ImageIcon legendIcon = new ImageIcon(imageForRule);
+					/*
+					 * With ChartGraphics we habe ONE Icon that spans the full
+					 * width, and one additional row for every attribute.
+					 */
+					PointSymbolizer pointSymbolizer = (PointSymbolizer) rule
+							.symbolizers().get(0);
 
-				final JLabel iconLabel = new JLabel(legendIcon);
-				panel.add(iconLabel, "sgx1");
-				// hbox.setAlignmentX(0f);
-				// hbox.add(iconLabel);
-				// hbox.add(Box.createHorizontalStrut(3));
+					ChartGraphic cg = new ChartGraphic(
+							pointSymbolizer.getGraphic());
 
-				final Translation labelT = new Translation();
-				labelT.fromOneLine(GTUtil.descriptionTitle(rule
-						.getDescription()));
-				final JLabel classTitleLabel = new JLabel(labelT.toString());
+					{
+						// One bigger Icon to span over both columns
+						Symbolizer fixSymbolizer = ChartGraphic
+								.getFixDataLegendSymbolizer(pointSymbolizer);
 
-				panel.add(classTitleLabel, "sgx2");
-				classTitleLabel.setLabelFor(iconLabel);
+						SimpleFeatureType ftpoint = FeatureUtil
+								.createFeatureType(Point.class);
+						final BufferedImage chartImage = LegendIconFeatureRenderer
+								.getInstance().createImageForSymbolizer(
+										fixSymbolizer, ftpoint,
+										new Dimension(80, 80));
+
+						final JLabel iconLabel = new JLabel(new ImageIcon(
+								chartImage));
+						panel.add(iconLabel, "span 2");
+					}
+
+					for (String attName : cg.getAttributes()) {
+
+						final BufferedImage imageChartData = new BufferedImage(
+								iconWidth, (int) (iconHeight * 0.8),
+								BufferedImage.TYPE_INT_ARGB);
+						Graphics g2 = imageChartData.getGraphics();
+						g2.setColor(cg.getColor(attName));
+						g2.fillRect(0, 0, iconWidth, (int) (iconHeight * 0.8));
+						g2.dispose();
+
+						addRowToPanel(panel, imageChartData, attName);
+					}
+
+				} else {
+
+					/*
+					 * Normally there is ONE icon and ONE label per Rule
+					 */
+
+					final BufferedImage imageForRule = LegendIconFeatureRenderer
+							.getInstance().createImageForRule(rule,
+									featureType,
+									new Dimension(iconWidth, iconHeight));
+					String descriptionTitle = GTUtil.descriptionTitle(rule
+							.getDescription());
+
+					addRowToPanel(panel, imageForRule, descriptionTitle);
+				}
 			}
 		}
 
 		return panel;
 	}
 
+	private static void addRowToPanel(final JPanel panel,
+			final BufferedImage imageForRule, String descriptionTitle) {
+		final ImageIcon legendIcon = new ImageIcon(imageForRule);
+
+		final JLabel iconLabel = new JLabel(legendIcon);
+		panel.add(iconLabel, "sgx1");
+		// hbox.setAlignmentX(0f);
+		// hbox.add(iconLabel);
+		// hbox.add(Box.createHorizontalStrut(3));
+
+		final Translation labelT = new Translation();
+		labelT.fromOneLine(descriptionTitle);
+		final JLabel classTitleLabel = new JLabel(labelT.toString());
+
+		panel.add(classTitleLabel, "sgx2");
+		classTitleLabel.setLabelFor(iconLabel);
+	}
+
 	/**
 	 * Creates a {@link JComponent} that contains a legend for a given
 	 * {@link StyledRasterInterface} and a given {@link Style}.
@@ -1119,18 +1179,18 @@
 		// Schleife über alle Rules, auch wenn Sie aus mehreren FTS kommen:
 
 		StylingUtil.DUPLICATINGSTYLEVISITOR.visit(style);
-		style = (Style)StylingUtil.DUPLICATINGSTYLEVISITOR.getCopy();
-		List<FeatureTypeStyle> fts = new ArrayList<FeatureTypeStyle>( style.featureTypeStyles());
+		style = (Style) StylingUtil.DUPLICATINGSTYLEVISITOR.getCopy();
+		List<FeatureTypeStyle> fts = new ArrayList<FeatureTypeStyle>(
+				style.featureTypeStyles());
 		Collections.reverse(fts);
 		style.featureTypeStyles().clear();
 		style.featureTypeStyles().addAll(fts);
-		
+
 		style = StylingUtil.optimizeStyle(style, null);
 
 		fts = style.featureTypeStyles();
 		if (fts.size() == 0)
 			return panel;
-		
 
 		for (Rule r : fts.get(0).rules()) {
 
@@ -1315,12 +1375,10 @@
 					// er nur ein spezielles Band von mehreren darstellt,
 					// dann muss diese ChannelSelectino hier aufgehoiben
 					// werden, da die samleConverages nur ein Band haben.
-					rs.setChannelSelection(StylingUtil.STYLE_FACTORY
-							.createChannelSelection(new SelectedChannelType[] { StylingUtil.STYLE_FACTORY
-									.createSelectedChannelType(
-											"1",
-											StylingUtil.STYLE_FACTORY
-													.createContrastEnhancement()) }));
+					rs.setChannelSelection(StylingUtil.STYLE_FACTORY.createChannelSelection(new SelectedChannelType[] { StylingUtil.STYLE_FACTORY
+							.createSelectedChannelType("1",
+									StylingUtil.STYLE_FACTORY
+											.createContrastEnhancement()) }));
 
 					renderer.paint(graphics, sampleCov, rs);
 				} catch (final Exception ee) {

Added: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphic.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphic.java	                        (rev 0)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphic.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -0,0 +1,509 @@
+package de.schmitzm.geotools.styling.chartsymbols;
+
+import java.awt.Color;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.SwingUtilities;
+
+import org.apache.log4j.Logger;
+import org.geotools.styling.ExternalGraphic;
+import org.geotools.styling.Graphic;
+import org.geotools.styling.Symbolizer;
+import org.geotools.styling.visitor.DuplicatingStyleVisitor;
+import org.geotools.util.WeakHashSet;
+import org.opengis.style.GraphicalSymbol;
+
+import de.schmitzm.geotools.gui.GeotoolsGUIUtil;
+import de.schmitzm.geotools.styling.StylingUtil;
+import de.schmitzm.regex.RegexCache;
+import de.schmitzm.swing.SwingUtil;
+
+/**
+ * https://developers.google.com/chart/image/docs/chart_params
+ * https://developers.google.com/chart/image/docs/chart_playground
+ */
+public class ChartGraphic {
+
+	public enum ChartTyp {
+		p, p3, bhg, bvg, bhs, bvs, bvo, lc;
+
+		/**
+		 * @return a human-readable and translated Title
+		 */
+		public String getTitle() {
+			return GeotoolsGUIUtil.R("ChartTyp." + this.toString());
+		}
+	}
+
+	public ExternalGraphic getChartGraphic() {
+
+		StringBuffer url = new StringBuffer("http://chart?cht="
+				+ getChartType());
+
+		// StringBuffer url = new StringBuffer(
+		// "http://chart?cht=bvg&chs=50x100&chd=t:${MEAT}|${DEMSTAT}&chco=4D89F9,C6D9FD");
+		// Data
+		if (attributes.size() > 0) {
+
+			url.append("&chd=t:");
+			for (String att : attributes) {
+
+				if (chartType == ChartTyp.p || chartType == ChartTyp.p3
+						|| chartType == ChartTyp.lc) {
+
+					// Sum up all others in this "row" to 100
+					StringBuffer allOthers = new StringBuffer();
+
+					for (String a : attributes) {
+						allOthers.append(a);
+						allOthers.append("+");
+					}
+					allOthers.setLength(allOthers.length() - 1);
+
+					url.append("${" + att + " * 100 / (" + allOthers + ")}");
+
+				} else {
+
+					// For Barcharts scale all numbers so that maxValue equals
+					// 100.
+
+					url.append("${" + att + " * 100. / " + getMaxValue() + "}");
+
+				}
+
+				if (chartType == ChartTyp.p || chartType == ChartTyp.p3
+						|| chartType == ChartTyp.lc)
+					url.append(",");
+				else
+					url.append("|");
+			}
+			url.setLength(url.length() - 1);
+
+			// Write colors:
+			url.append("&chco=");
+			for (String att : attributes) {
+				url.append(SwingUtil.convertColorToHex(getColor(att), false,
+						false));
+				url.append(",");
+			}
+			url.setLength(url.length() - 1);
+
+		}
+
+		// Chart Background Color works: set it fully transparent here.
+		// backgrouds can be defined with other symbolizers
+		url.append("&chf=bg,s,FFFFFF00");
+
+		// url.append("&chdl=NASDAQ|FTSE100|DOW");
+
+		// System.err.println("&chf=bg,s," + getBackgroundColorString());
+
+		// Bar Chart Gaps don't seem to work :-/
+		// https://developers.google.com/chart/image/docs/gallery/bar_charts#chbh
+		// url.append("&chbh=a,5,15");
+		// // Chart Margins don't seem to work :-/
+		// //
+		// https://developers.google.com/chart/image/docs/chart_params#gcharts_chart_margins
+		// url.append("&chma=1,1,1,1");
+		//
+		// // Hiding chart axes don't seem to work :-/
+		// url.append("&chxt=");
+
+		int w = imageWidth == null ? DEFAULT_WIDTH : imageWidth;
+		int h = imageHeight == null ? DEFAULT_HEIGHT : imageHeight;
+		url.append("&chs=" + w + "x" + h);
+
+		System.err.println(url);
+
+		ExternalGraphic crt = StylingUtil.STYLE_BUILDER.createExternalGraphic(
+				url.toString(), "application/chart");
+
+		return crt;
+	}
+
+	/**
+	 * Mapping of the colors for the attributes
+	 */
+	HashMap<String, Color> colors = new HashMap<String, Color>();
+
+	/**
+	 * Returns <code>true</code> if the given Graphic is an ExternalGraphic with
+	 * a URL that starts with "http://chart?"
+	 */
+	public static boolean isChart(Symbolizer symbolizer) {
+		if (symbolizer == null)
+			return false;
+
+		final AtomicBoolean isChart = new AtomicBoolean(false);
+		DuplicatingStyleVisitor v = new DuplicatingStyleVisitor() {
+
+			@Override
+			public void visit(ExternalGraphic eg) {
+				super.visit(eg);
+				isChart.set(isChart(eg));
+			}
+		};
+		symbolizer.accept(v);
+
+		return isChart.get();
+	}
+
+	/**
+	 * Scale the data, so that his {@link #maxValue} is transformed to 100. -
+	 * which is by Eastwood-default the top of the value axis.
+	 */
+	private Double maxValue = 100.;
+
+	/**
+	 * Returns <code>true</code> if the given Graphic is an ExternalGraphic with
+	 * a URL that starts with "http://chart?"
+	 */
+	public static boolean isChart(Graphic graphic) {
+		if (graphic == null)
+			return false;
+		final AtomicBoolean isChart = new AtomicBoolean(false);
+		DuplicatingStyleVisitor v = new DuplicatingStyleVisitor() {
+
+			@Override
+			public void visit(ExternalGraphic eg) {
+				super.visit(eg);
+				isChart.set(isChart(eg));
+			}
+		};
+		graphic.accept(v);
+
+		return isChart.get();
+	}
+
+	public static boolean isChart(ExternalGraphic eg) {
+		try {
+			if (eg.getLocation() == null)
+				return false;
+			if (eg.getLocation().toString().toLowerCase()
+					.startsWith("http://chart?"))
+				return true;
+
+		} catch (MalformedURLException e) {
+		}
+		return false;
+	}
+
+	public ChartGraphic(Graphic importThis) {
+		importChartFromGraphic(importThis);
+	}
+
+	/**
+	 * Tries to find a gt-chart defined in this Graphic object. If a chart
+	 * definition can be found, its settings are stored in this
+	 * {@link ChartGraphic} object.
+	 */
+	private void importChartFromGraphic(Graphic importThis) {
+
+		if (importThis == null)
+			return;
+
+		for (GraphicalSymbol gs : importThis.graphicalSymbols()) {
+			if (gs instanceof ExternalGraphic) {
+
+				ExternalGraphic eg = (ExternalGraphic) gs;
+				try {
+					if (eg.getLocation() == null)
+						continue;
+					String url = eg.getLocation().toString();
+
+					/*
+					 * Parse the URL-Parameters, but do NOT CALL THE SETTERS!
+					 */
+
+					// Read the Chart-Type!
+					Pattern typePattern = RegexCache.getInstance().getPattern(
+							"cht=(.*?)(&.*|^)");
+					Matcher m = typePattern.matcher(url);
+					if (m.find() && m.groupCount() > 0) {
+						chartType = ChartTyp.valueOf(m.group(1));
+					}
+
+					// Read the ATTRIBUTE NAMES from the Style
+					Pattern nextAtt = RegexCache.getInstance().getPattern(
+							"\\$\\{([^ ]*?)( .*?|)\\}");
+					m = nextAtt.matcher(url);
+					while (m.find() && m.groupCount() > 0) {
+						attributes.add(m.group(1));
+					}
+
+					// Read the COLORS from the Style
+					Pattern colorPart = RegexCache.getInstance().getPattern(
+							"chco=([^&]*?)(&.*|$)");
+					m = colorPart.matcher(url);
+					if (m.find() && m.groupCount() == 2) {
+						String colorstr = m.group(1);
+						Pattern nextColor = RegexCache.getInstance()
+								.getPattern("([a-f,A-F,0-9]{6,6})(?:[&,]|$)?");
+						m = nextColor.matcher(colorstr);
+						int count = 0;
+						while (m.find() && m.groupCount() == 1) {
+							if (attributes.size() >= count + 1)
+								colors.put(attributes.get(count),
+										Color.decode("#" + m.group(1)));
+							count++;
+						}
+					}
+
+					// Read any size from the Style
+					Pattern sizePart = RegexCache.getInstance().getPattern(
+							"chs=(\\d+)x(\\d+)");
+					m = sizePart.matcher(url);
+					if (m.find() && m.groupCount() == 2) {
+						imageWidth = Integer.valueOf(m.group(1));
+						imageHeight = Integer.valueOf(m.group(2));
+					}
+
+					// Try to find a maxValue
+					Pattern maxValuePattern = RegexCache
+							.getInstance()
+							.getPattern(
+									"\\$\\{([^ \\*]*?) \\* 100\\. / ([^ \\*]*)\\}");
+					m = maxValuePattern.matcher(url);
+					if (m.find() && m.groupCount() == 2) {
+						maxValue = Double.valueOf(m.group(2));
+					}
+
+					break;
+
+				} catch (MalformedURLException e) {
+					LOGGER.warn(e, e);
+					continue;
+				}
+			}
+		}
+
+	}
+
+	public ChartGraphic() {
+		this(null);
+	}
+
+	private ChartTyp chartType = ChartTyp.bvg;
+
+	List<String> attributes = new ArrayList<String>();
+
+	/**
+	 * Value between 0 and 1 for the transparency of the background
+	 */
+	// private float opacity = 0f;
+	//
+	// private Color bgColor = Color.white;
+
+	// /**
+	// * Creates a Color string like FFFFFFTT, where the 4th Hex-Byte represents
+	// * transparenzy.
+	// */
+	// private String getBackgroundColorString() {
+	//
+	// return SwingUtil.convertColorToHex(
+	// new Color(getBgColor().getRed() / 255f,
+	// getBgColor().getGreen() / 255f,
+	// getBgColor().getBlue() / 255f, getOpacity()), true,
+	// false).toUpperCase();
+	// }
+
+	public void addAttribute(String att) {
+
+		if (attributes.contains(att))
+			return;
+
+		attributes.add(att);
+
+		fireEvents(new ChartGraphicChangedEvent());
+	}
+
+	public void setColor(int index, Color color) {
+
+		setColor(attributes.get(index), color);
+
+	}
+
+	public void setColor(String attName, Color color) {
+
+		if (color != colors.get(attName)) {
+			colors.put(attName, color);
+			fireEvents(new ChartGraphicChangedEvent());
+		}
+
+	}
+
+	public Color getColor(int index) {
+		return getColor(attributes.get(index));
+	}
+
+	public Color getColor(String attname) {
+		if (attname == null)
+			return null;
+		Color c = colors.get(attname);
+		if (c == null) {
+			c = Color.red;
+			colors.put(attname, c);
+		}
+		return c;
+	}
+
+	public void removeAttribute(int index) {
+		colors.remove(attributes.remove(index));
+		fireEvents(new ChartGraphicChangedEvent());
+	}
+
+	static final Logger LOGGER = Logger.getLogger(ChartGraphic.class);
+
+	public static final int DEFAULT_WIDTH = 60;
+	public static final int DEFAULT_HEIGHT = 60;
+
+	public static Symbolizer getFixDataSymbolizer(Symbolizer sym) {
+		ChartGraphicPreviewFixStyleVisitor visitor = new ChartGraphicPreviewFixStyleVisitor();
+		sym.accept(visitor);
+		return (Symbolizer) visitor.getCopy();
+	}
+
+	public static Symbolizer getFixDataLegendSymbolizer(Symbolizer sym) {
+		ChartGraphicLegendVisitor visitorLegend = new ChartGraphicLegendVisitor();
+		getFixDataSymbolizer(sym).accept(visitorLegend);
+		return (Symbolizer) visitorLegend.getCopy();
+	}
+
+	public static Graphic getFixDataSymbolizer(Graphic graphic) {
+
+		ChartGraphicPreviewFixStyleVisitor visitor = new ChartGraphicPreviewFixStyleVisitor();
+		graphic.accept(visitor);
+		return (Graphic) visitor.getCopy();
+	}
+
+	public List<String> getAttributes() {
+		return attributes;
+	}
+
+	/**
+	 * This is a WeakHashSet, so references to the listeners have to exist in
+	 * the classes adding the listeners. They shall not be anonymous instances.
+	 */
+	final WeakHashSet<ChartGraphicChangeListener> listeners = new WeakHashSet<ChartGraphicChangeListener>(
+			ChartGraphicChangeListener.class);
+
+	public void addListener(ChartGraphicChangeListener listener) {
+		listeners.add(listener);
+	}
+
+	public void clearListeners() {
+		listeners.clear();
+	}
+
+	public void fireEvents(final ChartGraphicChangedEvent cgce) {
+
+		for (final ChartGraphicChangeListener l : listeners) {
+			try {
+
+				SwingUtilities.invokeLater(new Runnable() {
+
+					@Override
+					public void run() {
+						l.changed(cgce);
+					}
+
+				});
+
+			} catch (Exception e) {
+				LOGGER.error("While fireEvents: " + cgce, e);
+			}
+		}
+	}
+
+	public ChartTyp getChartType() {
+		return chartType;
+	}
+
+	public void setChartType(ChartTyp chartType) {
+		if (this.chartType != chartType) {
+			this.chartType = chartType;
+			fireEvents(new ChartGraphicChangedEvent());
+		}
+	}
+
+	public Integer getImageWidth() {
+		return imageWidth;
+	}
+
+	public void setImageWidth(Integer imageWidth) {
+		if (this.imageWidth != imageWidth) {
+			this.imageWidth = imageWidth;
+			fireEvents(new ChartGraphicChangedEvent());
+		}
+
+	}
+
+	public Integer getImageHeight() {
+		return imageHeight;
+	}
+
+	public void setImageHeight(Integer imageHeight) {
+		if (this.imageHeight != imageHeight) {
+			this.imageHeight = imageHeight;
+			fireEvents(new ChartGraphicChangedEvent());
+		}
+	}
+
+	//
+	// public float getOpacity() {
+	// return opacity;
+	// }
+	//
+	// public void setOpacity(float opacity) {
+	//
+	// if (this.opacity != opacity) {
+	//
+	// if (opacity > 1f)
+	// opacity = 1f;
+	// if (opacity < 0f)
+	// opacity = 0f;
+	// this.opacity = opacity;
+	//
+	// fireEvents(new ChartGraphicChangedEvent());
+	// }
+	// }
+	//
+	// public Color getBgColor() {
+	// if (bgColor == null)
+	// return Color.white;
+	// return bgColor;
+	// }
+	//
+	// public void setBgColor(Color bgColor) {
+	// // Mit Absicht kein Check:
+	// if (this.bgColor != bgColor) {
+	// this.bgColor = bgColor;
+	// fireEvents(new ChartGraphicChangedEvent());
+	// }
+	// }
+
+	public Double getMaxValue() {
+		return maxValue;
+	}
+
+	public void setMaxValue(Double maxValue) {
+		if (this.maxValue != maxValue) {
+
+			if (maxValue == null || maxValue == 0)
+				maxValue = 100.;
+			this.maxValue = maxValue;
+
+			if (chartType != ChartTyp.p && chartType != ChartTyp.p3)
+				fireEvents(new ChartGraphicChangedEvent());
+		}
+	}
+
+	private Integer imageWidth;
+	private Integer imageHeight;
+}


Property changes on: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphic.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangeListener.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangeListener.java	                        (rev 0)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangeListener.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -0,0 +1,10 @@
+package de.schmitzm.geotools.styling.chartsymbols;
+
+
+public interface ChartGraphicChangeListener {
+	/**
+	 * Called when a Symbolization RL has changed.
+	 */
+
+	public abstract void changed(ChartGraphicChangedEvent e);
+}


Property changes on: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangeListener.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangedEvent.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangedEvent.java	                        (rev 0)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangedEvent.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -0,0 +1,5 @@
+package de.schmitzm.geotools.styling.chartsymbols;
+
+public class ChartGraphicChangedEvent {
+
+}


Property changes on: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicChangedEvent.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicLegendVisitor.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicLegendVisitor.java	                        (rev 0)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicLegendVisitor.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -0,0 +1,36 @@
+package de.schmitzm.geotools.styling.chartsymbols;
+
+import org.apache.log4j.Logger;
+import org.geotools.styling.Graphic;
+import org.geotools.styling.visitor.DuplicatingStyleVisitor;
+
+import de.schmitzm.geotools.styling.StylingUtil;
+
+/**
+ * When a dynamic Chart Symvol is previewed, the freemarker(?) expressions (like
+ * "${COUNTHOUSES}") are replaced with fixed values;
+ */
+public class ChartGraphicLegendVisitor extends DuplicatingStyleVisitor {
+
+	final static String regex = "\\$\\{.*?\\}";
+
+	@Override
+	public Graphic copy(Graphic g) {
+		if (!ChartGraphic.isChart(g)) {
+			return super.copy(g);
+		}
+
+		try {
+
+			g = super.copy(g);
+
+			g.setOpacity(StylingUtil.STYLE_BUILDER.literalExpression(1.));
+			g.setSize(StylingUtil.STYLE_BUILDER.literalExpression(90));
+
+		} catch (Exception e) {
+			Logger.getLogger(ChartGraphicLegendVisitor.class).error(e, e);
+		}
+		return g;
+
+	}
+}


Property changes on: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicLegendVisitor.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain

Added: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicPreviewFixStyleVisitor.java
===================================================================
--- trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicPreviewFixStyleVisitor.java	                        (rev 0)
+++ trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicPreviewFixStyleVisitor.java	2012-04-15 11:31:30 UTC (rev 1949)
@@ -0,0 +1,62 @@
+package de.schmitzm.geotools.styling.chartsymbols;
+
+import java.util.regex.Matcher;
+
+import org.apache.log4j.Logger;
+import org.geotools.styling.ExternalGraphic;
+import org.geotools.styling.visitor.DuplicatingStyleVisitor;
+
+import de.schmitzm.geotools.styling.StylingUtil;
+import de.schmitzm.regex.RegexCache;
+
+/**
+ * When a dynamic Chart Symvol is previewed, the freemarker(?) expressions (like
+ * "${COUNTHOUSES}") are replaced with fixed values;
+ */
+public class ChartGraphicPreviewFixStyleVisitor extends DuplicatingStyleVisitor {
+
+	final static String regex = "\\$\\{.*?\\}";
+
+	@Override
+	public ExternalGraphic copy(ExternalGraphic eg) {
+		if (!ChartGraphic.isChart(eg)) {
+			return super.copy(eg);
+		}
+
+		String url2;
+		try {
+			url2 = eg.getLocation().toString();
+
+			// Assume a Bar-Chart:
+			// Howmany placeholders to we have?
+
+			int count = 0;
+			Matcher m = RegexCache.getInstance().getPattern(regex).matcher(url2);
+			while (m
+					.find()) {
+				count++;
+			}
+			
+			int count2 = 0;
+			m = RegexCache.getInstance().getPattern(regex).matcher(url2);
+			while (m
+					.find()) {
+				count2++;
+				url2 = url2.replaceFirst(regex, (int) (100. / (double) count * count2)
+						+ "");
+				// url2 = url2.replaceFirst(regex, ((int) (Math.random() * 100))
+				// + "");
+			}
+
+			ExternalGraphic externalGraphic2 = StylingUtil.STYLE_BUILDER
+					.createExternalGraphic(url2, eg.getFormat());
+
+			return externalGraphic2;
+		} catch (Exception e) {
+			Logger.getLogger(ChartGraphicPreviewFixStyleVisitor.class).error(e,
+					e);
+			return eg;
+		}
+
+	}
+}


Property changes on: trunk/schmitzm-gt/src/main/java/de/schmitzm/geotools/styling/chartsymbols/ChartGraphicPreviewFixStyleVisitor.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain



More information about the Schmitzm-commits mailing list