Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | b98d1adee7a6 |
children | 79401c871da4 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java Fri Sep 28 12:13:53 2012 +0200 @@ -0,0 +1,323 @@ +package de.intevation.gnv.chart; + +import java.util.Collection; +import java.util.Locale; +import java.util.Map; + +import com.vividsolutions.jts.geom.Point; +import com.vividsolutions.jts.io.WKTReader; +import com.vividsolutions.jts.io.ParseException; + +import org.apache.log4j.Logger; + +import org.jfree.chart.ChartTheme; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.data.general.Series; +import org.jfree.data.xy.XYSeries; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.utils.DistanceCalculator; + + +/** + * @author Ingo Weinzierl <ingo.weinzierl@intevation.de> + */ +public class HorizontalProfileChart +extends VerticalProfileChart +{ + private static Logger log = Logger.getLogger(HorizontalProfileChart.class); + + private static WKTReader wktReader = new WKTReader(); + private Point firstPoint; + + public HorizontalProfileChart( + ChartLabels labels, + ChartTheme theme, + Collection parameters, + Collection measurements, + Collection dates, + Collection result, + Collection timeGaps, + Locale locale, + boolean linesVisible, + boolean shapesVisible + ) { + super( + labels, + theme, + parameters, + measurements, + dates, + result, + timeGaps, + locale, + linesVisible, + shapesVisible + ); + this.PLOT_ORIENTATION = PlotOrientation.VERTICAL; + } + + + @Override + protected Object getValue(Result row) { + try { + return (Point) wktReader.read(row.getString("SHAPE")); + } + catch(ParseException pe) { + log.warn("No data found while parsing."); + return null; + } + } + + + protected void gapDetection( + Result[] results, + Series series, + int startPos, + int endPos + ) { + log.debug("Start gap detection."); + try { + Point startValue = getPoint(results[startPos]); + Point endValue = getPoint(results[endPos-1]); + if (results[0].getInteger("DATAID") == 2) + addGapsOnGrid(results, series, startPos, endPos); + else + addGaps( + results, + series, + startValue, + endValue, + startPos, + endPos + ); + } + catch (ParseException pe) { + log.warn( + "Error while parsing points for gap detection. " + + "No gaps for current series will be detected." + ); + } + + log.debug("Gap detection finished."); + } + + + protected void addValue(Result row, Series series) { + double distance = 0; + + try { + Point point = (Point) wktReader.read(row.getString("SHAPE")); + if (firstPoint != null) { + distance = DistanceCalculator.calculateDistance( + firstPoint, point + ); + } + else { + firstPoint = point; + } + + ((XYSeries) series).add( + distance, + row.getDouble("YORDINATE") + ); + } + catch(ParseException pe) { + log.warn("No data found while parsing."); + } + } + + + protected void addSeries(Series series, String label, int idx) { + super.addSeries(series, label, idx); + + // reset firstPoint for next series + firstPoint = null; + } + + + @Override + protected void prepareRangeAxis(String seriesKey, int idx) { + return; + // do nothing here + } + + + @Override + protected void storeMaxValue(Map values, Object value, String parameter) { + return; + // do nothing here + } + + + protected String createSeriesName( + String breakPoint1, + String breakPoint2, + String breakPoint3 + ) { + log.debug("create seriesname of horizontalprofile chart"); + return super.createSeriesName( + breakPoint1, + breakPoint2, + breakPoint3) + + " " + + findValueTitle(dates, breakPoint3); + } + + + protected void addGapsOnGrid( + Result[] results, + Series series, + int startPos, + int endPos + ) { + String axis = getDependendAxisName( + results[startPos], + results[startPos+1] + ); + + int last = 0; + int current = 0; + Point lastPoint = null; + Point currentPoint = null; + + try { + firstPoint = getPoint(results[0]); + } + catch (ParseException pe) { + log.error("Unable to parse start point for gap detection."); + return; + } + + for (int i = startPos+1; i < endPos; i++) { + try { + last = results[i-1].getInteger(axis); + lastPoint = getPoint(results[i-1]); + current = results[i].getInteger(axis); + currentPoint = getPoint(results[i]); + double distance = DistanceCalculator.calculateDistance( + firstPoint, + currentPoint); + double distanceOld = DistanceCalculator.calculateDistance( + firstPoint, + lastPoint); + + boolean detected = gridDetection(last, current); + + if (log.isDebugEnabled()) { + log.debug("Last point: " + lastPoint.toString()); + log.debug("Current point: " + currentPoint.toString()); + log.debug("Current distance from start: " + distance); + } + + if (detected) { + log.info( + "Gap detected on grid between " + distanceOld + + " and " + distance); + + ((XYSeries) series).add(distance-1d, null); + ((XYSeries) series).add(distanceOld+1d, null); + } + } + catch (ParseException pe) { + log.warn("Error while parsing point for gap detection.", pe); + } + } + } + + + protected void addGaps( + Result[] results, + Series series, + Point startValue, + Point endValue, + int startPos, + int endPos + ) { + double range = 0; + Point last = null; + Point now = null; + + for (int i = startPos+1; i < endPos; i++) { + boolean detected = false; + + try { + last = (Point) getPoint(results[i-1]); + now = (Point) getPoint(results[i]); + + // gap detection for more than GAP_MAX_VALUES values + if (results.length > GAP_MAX_VALUES) + detected = simpleDetection(startValue, endValue, last, now); + // gap detection for less than GAP_MAX_VALUES values + else + detected = specialDetection( + startValue, + endValue, + last, + now, + results.length + ); + + // gap detected, insert null value to break line + if (detected) { + log.info("Gap after " + range); + double x = range + 0.0001; + + ((XYSeries)series).add(x, null); + } + + range += DistanceCalculator.calculateDistance(last,now); + } + catch (ParseException pe) { + log.warn("Error while parsing point."); + } + + } + } + + + protected boolean simpleDetection( + Point start, + Point end, + Point last, + Point current + ) { + double delta = DistanceCalculator.calculateDistance(start, end); + double deltaSmall = DistanceCalculator.calculateDistance(last,current); + + return (deltaSmall > (delta / 100 * PERCENTAGE)); + } + + + protected boolean specialDetection( + Point start, + Point end, + Point last, + Point current, + int count + ) { + double delta = Math.abs( + DistanceCalculator.calculateDistance(end, start) + ); + double smallDelta = Math.abs( + DistanceCalculator.calculateDistance(current, last) + ); + + return (smallDelta > (3.0 / (count - 1) * delta)); + } + + @Override + protected String getDependendAxisName(Result first, Result second) { + if (first.getInteger("IPOSITION") == second.getInteger("IPOSITION")) + return "JPOSITION"; + + return "IPOSITION"; + } + + private Point getPoint(Result result) + throws ParseException + { + return (Point) wktReader.read(result.getString("SHAPE")); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :