# HG changeset patch # User Sascha L. Teichmann # Date 1262347685 0 # Node ID f5a0410003575635b47e440090b1dd49cd47676b # Parent f42ed4f10b798325c686acb2e930006732084266 Connected vertical cross section with chart generation. gnv-artifacts/trunk@494 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/ChangeLog --- 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 + + * 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 * 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 diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/doc/conf/conf.xml --- 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 @@ + diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/chart/Chart.java --- 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 */ -public interface Chart { - +public interface Chart +extends Serializable +{ public JFreeChart generateChart(); } diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalCrossSectionChart.java --- /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 : diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonPlot.java --- 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."); } diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonRenderer.java --- 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); diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java --- 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 columns; protected Map attributes; + protected Interpolation3D interpolation; + protected PolygonDataset dataset; public AttributedXYColumns() { } @@ -47,5 +51,21 @@ public void setXYColumns(List 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: diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/math/Interpolation3D.java --- 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; diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java --- 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 getFilterFactories(CallContext callContext) { + private static List getFilterFactories( + CallContext callContext + ) { GNVArtifactContext context = (GNVArtifactContext)callContext.globalContext(); List factories = (List)context.get( @@ -245,8 +248,7 @@ List 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 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; } diff -r f42ed4f10b79 -r f5a041000357 gnv-artifacts/src/main/java/de/intevation/gnv/state/timeseries/TimeSeriesOutputState.java --- 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 chartResult = - (Collection) getChartResult(uuid, callContext); - Collection parameters = - this.getParameters(uuid); - Collection measurements = - this.getMeasurements(uuid); - Collection dates = - this.getDates(uuid); - Collection statistics = - s.calculateStatistics(chartResult, - parameters, - measurements, - dates); + + Collection statistics; + + Object result = getChartResult(uuid, callContext); + + if (result instanceof Collection) { + Collection chartResult = + (Collection) result; + Collection parameters = + this.getParameters(uuid); + Collection measurements = + this.getMeasurements(uuid); + Collection dates = + this.getDates(uuid); + statistics = s.calculateStatistics( + chartResult, + parameters, + measurements, + dates); + } + else { + statistics = new ArrayList(); + } + 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,