changeset 446:f5a041000357

Connected vertical cross section with chart generation. gnv-artifacts/trunk@494 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Fri, 01 Jan 2010 12:08:05 +0000
parents f42ed4f10b79
children 92b7ccbf6163
files gnv-artifacts/ChangeLog gnv-artifacts/doc/conf/conf.xml gnv-artifacts/src/main/java/de/intevation/gnv/chart/Chart.java gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation3D.java gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java
diffstat 10 files changed, 285 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/gnv-artifacts/ChangeLog	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/ChangeLog	Fri Jan 01 12:08:05 2010 +0000
@@ -1,3 +1,45 @@
+2010-01-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* doc/conf/conf.xml: Deactivated gauss filter because
+	  it blurs no data areas too.  Moreover gauss filtering does not 
+	  seem to be necessary at all. Possible TODO: Mask the no data
+	  areas while filtering.
+
+	* src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java:
+	  Added generation of polygon data suitable for PolygonPlot.
+
+	* src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java:
+	  Some hacks to display the new Chart. XXX: This class is
+	  a real mess ... but I've said that before.
+
+	* src/main/java/de/intevation/gnv/chart/Chart.java: Made it
+	  serializable.
+
+	* src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java:
+	  New. Chart for vertical cross sections. Mainly a copy of
+	  Ingo's prototype implementation. TODO: parameter based i18n.
+
+	* src/main/java/de/intevation/gnv/math/Interpolation3D.java: Code
+	  simplification. Made it Serializable to be cachable persistently.
+	
+	* src/main/java/de/intevation/gnv/math/AttributedXYColumns.java:
+	  Added fields for the interpolation and the generated PolygonDataset.
+	  Its used as the data carrying object in cache now.
+
+	* src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java:
+	  Removed println debug code.
+
+	* src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java:
+	  Added a little hack to draw the polygons of the interpolation.
+	  The values are in y-direction all below zero (depth is given
+	  by negative values) so the drawing is mirrored along y axis.
+	  This special behavior is determined by the position of data 
+	  bounding box. At first I suspected a ccw issue here but some
+	  initial tests falsified this hypothesis. We need to have a
+	  deeper look at this but till than it works.
+
+	* ChangeLog: Fixed some typos.
+
 2009-12-30	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* doc/conf/conf.xml: Fixed defect XML
@@ -151,7 +193,7 @@
 
 	  Iso line generation is a bit more sophisticated than pure
 	  region tracing. Along a border of a region there could
-	  be more than one type neighborhood. This is due to quantification
+	  be more than one type of neighborhood. This is due to quantification
 	  errors introduced by the fact that steep value gradients
 	  are sampled to less points. The only ways out would be an
 	  increase of the sample resolution or an other algorithm
--- a/gnv-artifacts/doc/conf/conf.xml	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/doc/conf/conf.xml	Fri Jan 01 12:08:05 2010 +0000
@@ -419,11 +419,13 @@
         <vertical-cross-section>
             <!-- This section configures the "Profilschnitt" -->
             <samples width="1024" height="768"/>
+            <!--
             <filters>
                 <filter factory="de.intevation.gnv.raster.KernelFilter$GaussFactory" 
                         sigma="1"
                         radius="5"/>
             </filters>
+            -->
         </vertical-cross-section>
     </gnv>
     <ehcache>
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/chart/Chart.java	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/Chart.java	Fri Jan 01 12:08:05 2010 +0000
@@ -2,11 +2,14 @@
 
 import org.jfree.chart.JFreeChart;
 
+import java.io.Serializable;
+
 
 /**
  * @author Ingo Weinzierl <ingo.weinzierl@intevation.de>
  */
-public interface Chart {
-    
+public interface Chart
+extends          Serializable
+{
     public JFreeChart generateChart();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java	Fri Jan 01 12:08:05 2010 +0000
@@ -0,0 +1,142 @@
+package de.intevation.gnv.chart;
+
+import java.util.Locale;
+
+import java.awt.Color;
+import java.awt.Paint;
+
+import de.intevation.gnv.math.AttributedXYColumns;
+
+import de.intevation.gnv.jfreechart.PolygonDataset;
+import de.intevation.gnv.jfreechart.PolygonPlot;
+import de.intevation.gnv.jfreechart.PolygonRenderer;
+
+import de.intevation.gnv.raster.Palette;
+
+import org.jfree.chart.JFreeChart;
+
+import org.jfree.chart.plot.PlotOrientation;
+
+import org.jfree.chart.axis.ValueAxis;
+import org.jfree.chart.axis.NumberAxis;
+import org.jfree.chart.axis.SymbolAxis;
+
+import org.jfree.chart.title.PaintScaleLegend;
+
+import org.jfree.chart.renderer.LookupPaintScale;
+
+import org.jfree.ui.RectangleEdge;
+import org.jfree.ui.RectangleInsets;
+
+/**
+ * @author Ingo Weinzierl      (ingo.weinzierl@intevation.de)
+ * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
+ */
+public class VerticalCrossSectionChart
+implements   Chart
+{
+    public static final class PalettePaintLookup
+    implements PolygonRenderer.PaintLookup
+    {
+        private Palette palette;
+
+        public PalettePaintLookup(Palette palette) {
+            this.palette = palette;
+        }
+
+        public Paint getPaint(int index) {
+            return index < 0
+                ? Color.black
+                : palette.getColor(index);
+        }
+    } // class PalettePaintLookup
+
+    protected JFreeChart chart;
+
+    protected AttributedXYColumns columns;
+    protected Palette             palette;
+    protected Locale              locale;
+
+    public VerticalCrossSectionChart() {
+    }
+
+    public VerticalCrossSectionChart(
+        AttributedXYColumns columns,
+        Palette             palette,
+        Locale              locale
+    ) {
+        this.columns = columns;
+        this.palette = palette;
+        this.locale  = locale;
+    }
+
+    protected JFreeChart createChart() {
+
+        String title        = "Neues 2D-Diagramm";
+        String xAxis        = "x-Achse des Diagramms";
+        String yAxis        = "y-Achse des Diagramms";
+        boolean legendB     = false;
+        boolean tooltips    = false;
+        boolean urls        = false;
+
+        PlotOrientation po  = PlotOrientation.HORIZONTAL;
+        PolygonDataset data = columns.getPolygonDataset();
+
+        PolygonRenderer renderer = new PolygonRenderer(
+            new PalettePaintLookup(palette));
+
+        ValueAxis domainAxis = new NumberAxis(xAxis);
+        ValueAxis rangeAxis  = new NumberAxis(yAxis);
+
+        PolygonPlot plot = new PolygonPlot(
+            data,
+            renderer,
+            domainAxis,
+            rangeAxis,
+            null);
+
+        int colors = palette.getSize();
+        LookupPaintScale lookupPaint =
+            new LookupPaintScale(-0.5d, colors-0.5d, Color.white);
+
+        Color color = null;
+
+        String [] labels = new String[colors];
+        for (int i = 0; i < colors; i++) {
+            color     = palette.getColor(colors-1-i);
+            labels[i] = palette.getEntryByIndex(colors-1-i).getDescription();
+            lookupPaint.add(i-0.5d, color);
+        }
+
+        JFreeChart chart = new JFreeChart(
+            title,
+            JFreeChart.DEFAULT_TITLE_FONT,
+            plot,
+            legendB);
+
+        chart.removeLegend();
+
+        SymbolAxis scale = new SymbolAxis("Temperatur", labels);
+        scale.setRange(-1.5d, colors+0.5d);
+        scale.setGridBandsVisible(false);
+        scale.setPlot(plot);
+
+        PaintScaleLegend legend = new PaintScaleLegend(
+            lookupPaint, scale);
+        legend.setMargin(new RectangleInsets(3d, 10d, 3d, 10d));
+        legend.setPosition(RectangleEdge.LEFT);
+        legend.setAxisOffset(5d);
+
+        chart.addSubtitle(legend);
+
+        return chart;
+    }
+
+    public JFreeChart generateChart() {
+        if (chart == null) {
+            chart = createChart();
+        }
+        return chart;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java	Fri Jan 01 12:08:05 2010 +0000
@@ -161,8 +161,6 @@
         PlotState         parentState,
         PlotRenderingInfo info
     ) {
-        System.out.println("Start drawing plot.");
-
         Graphics2D  savedG2       = g2;
         Rectangle2D savedDataArea = area;
 
@@ -197,8 +195,6 @@
 
         g2.setClip(savedClip);
         g2.setComposite(originalComposite);
-
-        System.out.println("Finished drawing plot.");
     }
 
 
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java	Fri Jan 01 12:08:05 2010 +0000
@@ -53,6 +53,12 @@
         double tx = rectangle.getMinX();
         double ty = rectangle.getMinY();
 
+        // XXX: Little hack to draw correctly if data is
+        // below 0 in y direction.
+        if (bbox.getMinY() <= 0d && bbox.getMaxY() <= 0d) {
+            sy = -sy; // mirror
+        }
+
         graphics.translate(tx, ty);
         graphics.scale(sx, sy);
 
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java	Fri Jan 01 12:08:05 2010 +0000
@@ -6,6 +6,8 @@
 
 import java.io.Serializable;
 
+import de.intevation.gnv.jfreechart.PolygonDataset; 
+
 /**
  *  @author Ingo Weinzierl
  *  @author Sascha L. Teichmann
@@ -15,6 +17,8 @@
 {
     protected List<? extends XYColumn> columns;
     protected Map                      attributes;
+    protected Interpolation3D          interpolation;
+    protected PolygonDataset           dataset;
 
     public AttributedXYColumns() {
     }
@@ -47,5 +51,21 @@
     public void setXYColumns(List<? extends XYColumn> columns) {
         this.columns = columns;
     }
+
+    public void setInterpolation(Interpolation3D interpolation) {
+        this.interpolation = interpolation;
+    }
+
+    public Interpolation3D getInterpolation() {
+        return interpolation;
+    }
+
+    public void setPolygonDataset(PolygonDataset dataset) {
+        this.dataset = dataset;
+    }
+
+    public PolygonDataset getPolygonDataset() {
+        return dataset;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation3D.java	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation3D.java	Fri Jan 01 12:08:05 2010 +0000
@@ -2,7 +2,6 @@
 
 import java.util.List;
 import java.util.Arrays;
-import java.util.ArrayList;
 import java.util.Collections;
 
 import java.io.Serializable;
@@ -65,8 +64,9 @@
     public double getMaxDepth() {
         double maxDepth = Double.MAX_VALUE;
         for (int i = depths!=null?depths.length-1:0; i >= 0; --i) {
-            if (!Double.isNaN(depths[i]) && depths[i] < maxDepth) {
-                maxDepth = depths[i];
+            double d = depths[i];
+            if (!Double.isNaN(d) && d < maxDepth) {
+                maxDepth = d;
             }
         }
         return maxDepth;
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java	Fri Jan 01 12:08:05 2010 +0000
@@ -39,6 +39,7 @@
 import de.intevation.gnv.chart.Chart;
 import de.intevation.gnv.chart.ChartLabels;
 import de.intevation.gnv.chart.ChartStyle;
+import de.intevation.gnv.chart.VerticalCrossSectionChart;
 
 import de.intevation.gnv.chart.exception.TechnicalChartException;
 
@@ -187,7 +188,9 @@
             : GNVArtifactContext.DEFAULT_VERTICAL_CROSS_SECTION_SAMPLES;
     }
 
-    private static List<Filter.Factory> getFilterFactories(CallContext callContext) {
+    private static List<Filter.Factory> getFilterFactories(
+        CallContext callContext
+    ) {
         GNVArtifactContext context = 
             (GNVArtifactContext)callContext.globalContext();
         List<Filter.Factory> factories = (List<Filter.Factory>)context.get(
@@ -245,8 +248,7 @@
         List<Filter.Factory> filterFactories = getFilterFactories(callContext);
         Interpolation3D      interpolation   = new Interpolation3D(rasterSize);
 
-        double distance = WKTUtils.toKM(
-            DistanceCalculator.calculateDistance(path));
+        double distance = DistanceCalculator.calculateDistance(path);
 
         if (distance < EPSILON) {
             log.warn("distance too short for interpolation");
@@ -259,7 +261,7 @@
             0d,
             distance,
             LinearMetrics.INSTANCE,
-            new ConstantXYDepth(-42d)); // TODO: Use DEM here!!
+            new ConstantXYDepth(-75d)); // TODO: Use DEM here!!
 
         if (!success) {
             log.warn("interpolation failed");
@@ -299,6 +301,8 @@
 
         int numRegions = vectorizer.process(pdsp);
 
+        vectorizer = null; intRaster = null; // help gc
+
         PolygonDataset pds = pdsp.getPolygonDataset();
 
         if (debug) {
@@ -306,7 +310,10 @@
             log.debug("number of series: " + pds.getSeriesCount());
         }
 
-        return null;
+        columns.setInterpolation(interpolation);
+        columns.setPolygonDataset(pds);
+
+        return columns;
     }
 
 
@@ -401,24 +408,38 @@
 
         log.info("Chart not in cache yet.");
 
-        log.warn("This sort of chart is not implemented yet.");
-        /* TODO Implement a special chart for this sort of charts.
-        chart = new VerticalProfileChart(
-            chartLables,
-            chartTheme,
-            parameters,
-            measurements,
-            result,
-            dates,
-            locale
-        );
+        AttributedXYColumns columns =
+            (AttributedXYColumns)result;
+
+        Integer parameterId =
+            (Integer)columns.getAttribute("GROUP1"); // XXX: hardcoded
+
+        if (parameterId == null) {
+            log.error("missing parameter id");
+            return null;
+        }
+
+        Map<Integer, PaletteManager> paletteManagers =
+            getPalettes(callContext);
+
+        PaletteManager paletteManager = paletteManagers.get(parameterId);
+
+        if (paletteManager == null) {
+            log.error("no palette found for parameter id " + parameterId);
+            return null;
+        }
+
+        chart = new VerticalCrossSectionChart(
+            columns,
+            paletteManager.getBase(),
+            locale);
+
         chart.generateChart();
 
         if (CACHE_CHART) {
             log.info("Put chart into cache.");
             purifyChart(chart, uuid);
         }
-        */
 
         return chart;
     }
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java	Wed Dec 30 23:02:10 2009 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java	Fri Jan 01 12:08:05 2010 +0000
@@ -358,20 +358,32 @@
                 this.createCSV(outputStream, chartResult);
             } else if (outputMode.equalsIgnoreCase("statistics")) {
                 log.debug("Statistics will be generated.");
+
                 Statistics s = getStatisticsGenerator();
-                Collection<Result> chartResult =
-                    (Collection<Result>) getChartResult(uuid, callContext);
-                Collection<KeyValueDescibeData> parameters = 
-                                                this.getParameters(uuid);
-                Collection<KeyValueDescibeData> measurements = 
-                                                this.getMeasurements(uuid);
-                Collection<KeyValueDescibeData> dates = 
-                                                this.getDates(uuid);
-                Collection<StatisticSet> statistics = 
-                                      s.calculateStatistics(chartResult,
-                                                            parameters,
-                                                            measurements,
-                                                            dates);
+
+                Collection<StatisticSet> statistics;
+
+                Object result = getChartResult(uuid, callContext);
+
+                if (result instanceof Collection) {
+                    Collection<Result> chartResult =
+                        (Collection<Result>) result;
+                    Collection<KeyValueDescibeData> parameters = 
+                                                    this.getParameters(uuid);
+                    Collection<KeyValueDescibeData> measurements = 
+                                                    this.getMeasurements(uuid);
+                    Collection<KeyValueDescibeData> dates = 
+                                                    this.getDates(uuid);
+                    statistics = s.calculateStatistics(
+                        chartResult,
+                        parameters,
+                        measurements,
+                        dates);
+                }
+                else {
+                    statistics = new ArrayList<StatisticSet>();
+                }
+
                 Document doc = this.writeStatistics2XML(statistics);
                 this.writeDocument2OutputStream(doc, outputStream);
             } else if (outputMode.equalsIgnoreCase("odv")) {
@@ -691,7 +703,7 @@
             parameters,
             measurements,
             dates,
-            (Collection) getChartResult(uuid, callContext),
+            getChartResult(uuid, callContext),
             locale,
             uuid,
             linesVisible,

http://dive4elements.wald.intevation.org