changeset 340:07a64cfafdf1

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
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 09 Dec 2009 10:22:20 +0000
parents 02c71ea5c9c8
children 8937fd620e55
files gnv-artifacts/src/main/java/de/intevation/gnv/chart/HorizontalProfileChart.java gnv-artifacts/src/main/java/de/intevation/gnv/chart/VerticalProfileChart.java
diffstat 2 files changed, 315 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- 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 :
--- 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 :

http://dive4elements.wald.intevation.org