Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java @ 517:96a1e92e7ed2
If the number of data points to generate a "Horizontalschnitt"
is above a given threshold, they are culled against an 5% extented
bounding box of the interpolation area.
gnv-artifacts/trunk@611 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Sat, 23 Jan 2010 17:42:04 +0000 |
parents | 04a242c67fe6 |
children | d2c68f2f619b |
line wrap: on
line source
package de.intevation.gnv.chart; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Locale; import org.apache.log4j.Logger; import org.jfree.chart.ChartTheme; import org.jfree.chart.axis.Axis; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.plot.PlotOrientation; import org.jfree.data.xy.XYSeries; import org.jfree.data.general.Series; import org.jfree.data.xy.XYSeriesCollection; import de.intevation.gnv.geobackend.base.Result; import de.intevation.gnv.state.describedata.KeyValueDescibeData; /** * @author Ingo Weinzierl <ingo.weinzierl@intevation.de> */ public class VerticalProfileChart extends AbstractXYLineChart { private static Logger log = Logger.getLogger(VerticalProfileChart.class); protected final double PERCENTAGE = 5.0; protected final double GAP_MAX_LEVEL = Math.sqrt(2.0); protected final int GAP_MAX_VALUES = 60; public VerticalProfileChart( ChartLabels labels, ChartTheme theme, Collection parameters, Collection measurements, Collection dates, Collection result, Collection timeGaps, Locale locale, boolean linesVisible, boolean shapesVisible ) { this.labels = labels; this.theme = theme; this.parameters = parameters; this.measurements = measurements; this.dates = dates; this.resultSet = result; this.timeGaps = timeGaps; this.locale = locale; this.PLOT_ORIENTATION = PlotOrientation.HORIZONTAL; this.linesVisible = linesVisible; this.shapesVisible = shapesVisible; this.datasets = new HashMap(); this.ranges = new HashMap(); } protected void initData() { log.debug("init data for VerticalProfileChart"); String breakPoint1 = null; String breakPoint2 = null; String breakPoint3 = null; Iterator iter = resultSet.iterator(); Result row = null; String seriesName = null; String parameter = null; XYSeries series = null; int idx = 0; int startPos = 0; int endPos = 0; double startValue = 0; double endValue = 0; Result[] results = (Result[]) resultSet.toArray(new Result[resultSet.size()]); while (iter.hasNext()) { row = (Result) iter.next(); // add current data to plot and prepare for next one if (!row.getString("GROUP1").equals(breakPoint1) || !row.getString("GROUP2").equals(breakPoint2) || !row.getString("GROUP3").equals(breakPoint3) ) { log.debug("prepare data/plot for next dataset"); if(series != null) { gapDetection(results, series, startPos, endPos); addSeries(series, parameter, idx); startPos = endPos +1; } // prepare variables for next plot breakPoint1 = row.getString("GROUP1"); breakPoint2 = row.getString("GROUP2"); breakPoint3 = row.getString("GROUP3"); seriesName = createSeriesName( breakPoint1, breakPoint2, breakPoint3 ); parameter = findParameter(seriesName); log.debug("next dataset is '" + seriesName + "'"); series = new XYSeries(seriesName); } addValue(row, series); Double value = row.getDouble("YORDINATE"); if (value != null) storeMaxRange(value, parameter); endPos++; } if (results.length == 0) return; gapDetection(results, series, startPos, endPos); addSeries(series, parameter, idx); addDatasets(); } protected void gapDetection( Result[] results, Series series, int startPos, int endPos ) { double startValue = results[startPos].getDouble("XORDINATE"); double endValue = results[endPos-1].getDouble("XORDINATE"); if (results[0].getInteger("DATAID") == 2) addGapsOnGrid(results, series, startPos, endPos); else addGaps(results, series, startValue, endValue, startPos, endPos); } protected void addValue(Result row, Series series) { ((XYSeries) series).add( row.getDouble("XORDINATE"), row.getDouble("YORDINATE") ); } protected void addSeries(Series series, String parameter, int idx) { log.debug("add series (" + parameter + ")to chart"); if (series == null) { log.warn("no data to add"); return; } XYSeriesCollection xysc = null; if (datasets.containsKey(parameter)) xysc = (XYSeriesCollection) datasets.get(parameter); else xysc = new XYSeriesCollection(); xysc.addSeries((XYSeries) series); datasets.put(parameter, xysc); } protected void addDatasets() { Iterator iter = parameters.iterator(); XYPlot plot = chart.getXYPlot(); int idx = 0; XYSeriesCollection xysc = null; KeyValueDescibeData data = null; String key = null; while (iter.hasNext()) { data = (KeyValueDescibeData) iter.next(); key = data.getValue(); if (datasets.containsKey(key)) { xysc = (XYSeriesCollection)datasets.get(key); plot.setDataset(idx, xysc ); log.debug("Added " + key + " parameter to plot."); prepareAxis(key, idx); adjustRenderer( idx++, xysc.getSeriesCount(), linesVisible, shapesVisible ); } } } protected void localizeDomainAxis(Axis axis, Locale locale) { // call localizeRangeAxis from superclass which formats NumberAxis super.localizeRangeAxis(axis, locale); } protected String createSeriesName( String breakPoint1, String breakPoint2, String breakPoint3 ) { log.debug("create seriesname of verticalprofile chart"); return findValueTitle(parameters, breakPoint1) + " " + findValueTitle(measurements, breakPoint2) + "m"; } protected void addGapsOnGrid( Result[] results, Series series, int startPos, int endPos ) { String axis = getDependendAxisName( results[startPos], results[startPos+1] ); double range = 0; int last = 0; int current = 0; for (int i = startPos+1; i < endPos; i++) { last = results[i-1].getInteger(axis); current = results[i].getInteger(axis); boolean detected = gridDetection(last, current); if (detected) { double xOld = results[i-1].getDouble("XORDINATE"); double xNow = results[i].getDouble("XORDINATE"); log.debug("Gap detected on grid between "+ xOld +" and "+ xNow); ((XYSeries) series).add(xOld+0.0001, null); } } } protected void addGaps( Result[] results, Series series, double startValue, double endValue, int startPos, int endPos ) { double last = 0; double current = 0; int num = results.length; for (int i = startPos+1; i < endPos; i++) { boolean detected = false; last = results[i-1].getDouble("YORDINATE"); current = results[i].getDouble("YORDINATE"); // gap detection for more than GAP_MAX_VALUES values if (num > GAP_MAX_VALUES) detected = simpleDetection(startValue, endValue, last, current); // gap detection for less than GAP_MAX_VALUES values else detected = specialDetection( startValue, endValue, last, current, num ); if (detected) { log.info("Gap between " + last + " and " + current); ((XYSeries) series).add((last+current)/2, null); } } } protected boolean simpleDetection( double start, double end, double last, double current ) { double delta = Math.abs(end - start); double smallDelta = Math.abs(current - last); return (smallDelta > delta / 100 * PERCENTAGE); } protected boolean specialDetection( double start, double end, double last, double current, int count ) { double delta = Math.abs(end - start); double smallDelta = Math.abs(current - last); return (smallDelta > (3.0 / (count - 1) * delta)); } protected boolean gridDetection(double last, double current) { return (Math.abs(current - last) > GAP_MAX_LEVEL); } protected String getDependendAxisName(Result first, Result second) { return "KPOSITION"; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :