# HG changeset patch # User Ingo Weinzierl # Date 1260354140 0 # Node ID 07a64cfafdf14d5e8bc0d025d139e9ba4977d888 # Parent 02c71ea5c9c80c5a7327b42eee079cada0f99219 Added gap detection in horizontal and vertical profile charts. Distinguish between meshes and other data sources. gnv-artifacts/trunk@406 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 02c71ea5c9c8 -r 07a64cfafdf1 gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java Wed Dec 09 09:47:10 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java Wed Dec 09 10:22:20 2009 +0000 @@ -60,8 +60,40 @@ } + 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) { - // TODO look for gaps between two values try { Point point = (Point) wktReader.read(row.getString("SHAPE")); if (lastPoint != null) @@ -103,5 +135,142 @@ " " + findValueTitle(dates, breakPoint3); } + + + protected void addGapsOnGrid( + Result[] results, + Series series, + int startPos, + int endPos + ) { + String axis = getDependendAxisName( + results[startPos], + results[startPos+1] + ); + + double range = 0; + double distance = 0; + int last = 0; + int current = 0; + Point lastPoint = null; + Point currentPoint = null; + + 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]); + distance = DistanceCalculator.calculateDistance( + lastPoint, + currentPoint + ); + + boolean detected = gridDetection(last, current); + + if (detected) { + log.debug( + "Gap detected on grid between " + range + + " and " + (range+distance) + ); + + ((XYSeries) series).add(range+0.0001, null); + } + + range += distance; + } + 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)); + } + + + 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 : diff -r 02c71ea5c9c8 -r 07a64cfafdf1 gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java Wed Dec 09 09:47:10 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java Wed Dec 09 10:22:20 2009 +0000 @@ -27,6 +27,10 @@ { 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, @@ -67,7 +71,14 @@ String seriesName = null; XYSeries series = null; - int idx = 0; + 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(); @@ -80,7 +91,10 @@ log.debug("prepare data/plot for next dataset"); if(series != null) { + gapDetection(results, series, startPos, endPos); addSeries(series, seriesName, idx); + + startPos = endPos +1; } // prepare variables for next plot @@ -99,16 +113,35 @@ } addValue(row, series); + endPos++; } + if (results.length == 0) + return; + + gapDetection(results, series, startPos, endPos); addSeries(series, seriesName, 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) { - // TODO look for gaps between two values ((XYSeries) series).add( row.getDouble("XORDINATE"), row.getDouble("YORDINATE") @@ -182,5 +215,115 @@ 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) { + if (first.getInteger("IPOSITION") == second.getInteger("IPOSITION")) + return "JPOSITION"; + + return "IPOSITION"; + } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :