diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java @ 938:bd3683453928

Debugged the water fill algorithm. flys-artifacts/trunk@2330 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Thu, 14 Jul 2011 14:11:29 +0000
parents 759808931a2e
children 111794adf285
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java	Thu Jul 14 11:27:01 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/charts/CrossSectionApp.java	Thu Jul 14 14:11:29 2011 +0000
@@ -9,6 +9,7 @@
 import javax.swing.JPanel;
 import javax.swing.JButton;
 import javax.swing.JComboBox;
+import javax.swing.JTextField;
 import javax.swing.DefaultComboBoxModel;
 
 import java.awt.event.ItemListener;
@@ -16,10 +17,14 @@
 import java.awt.event.ActionListener;
 import java.awt.event.ActionEvent;
 
+import java.awt.geom.Point2D;
+import java.awt.geom.Line2D;
+
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Comparator;
 import java.util.Collections;
+import java.util.Iterator;
 
 import java.io.File;
 import java.io.IOException;
@@ -32,11 +37,14 @@
 import org.jfree.chart.ChartFactory;
 
 import org.jfree.chart.plot.PlotOrientation;
+import org.jfree.chart.plot.XYPlot;
 
 import org.jfree.chart.ChartUtilities;
 import org.jfree.chart.JFreeChart;
 import org.jfree.chart.ChartPanel;
 
+import org.jfree.chart.axis.NumberAxis;
+
 import org.jfree.data.xy.XYDataset;
 import org.jfree.data.xy.DefaultXYDataset;
 
@@ -44,11 +52,14 @@
 import de.intevation.flys.model.CrossSectionLine;
 import de.intevation.flys.model.CrossSectionPoint;
 
+import de.intevation.flys.geom.Lines;
+
 import de.intevation.flys.backend.SessionFactoryProvider;
 
 import org.hibernate.Session;
 import org.hibernate.Query;
 
+import gnu.trove.TDoubleArrayList;
 
 public class CrossSectionApp
 extends      ApplicationFrame
@@ -58,7 +69,7 @@
     public static final double EPSILON   = 1e-4;
 
     public static final double TOO_SMALL = 0.2;
-    public static final double TOO_BIG   = 4000;
+    public static final double TOO_BIG   = 500;
 
     public static final Comparator<CrossSectionPoint> COL_POS_CMP =
         new Comparator<CrossSectionPoint>() {
@@ -83,9 +94,12 @@
 
     protected JComboBox crossSectionsCB;
     protected JComboBox crossSectionLinesCB;
+    protected JTextField waterlevelTF;
 
     protected ChartPanel chartPanel;
 
+    protected Double lastWaterLevel;
+
 
     public static class CrossSectionItem {
 
@@ -175,16 +189,21 @@
         crossSectionLinesCB.addItemListener(new ItemListener() {
             public void itemStateChanged(ItemEvent ie) {
                 if (ie.getStateChange() == ItemEvent.SELECTED) {
-                    updateCrossSectionLine(((CrossSectionLineItem)ie.getItem()).line);
+                    updateChart();
                 }
             }
         });
 
-        panel.add(nav, BorderLayout.SOUTH);
 
-        chartPanel = createChartPanel();
+        waterlevelTF = new JTextField(5);
 
-        panel.add(chartPanel, BorderLayout.CENTER);
+        waterlevelTF.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent ae) {
+                waterLevelChanged();
+            }
+        });
+
+        nav.add(waterlevelTF);
 
         JButton dump = new JButton("dump");
 
@@ -196,30 +215,51 @@
 
         nav.add(dump);
 
+        panel.add(nav, BorderLayout.SOUTH);
+
+        chartPanel = createChartPanel();
+
+        panel.add(chartPanel, BorderLayout.CENTER);
+
         return panel;
     }
 
+    protected void waterLevelChanged() {
+        String value = waterlevelTF.getText();
+        try {
+            lastWaterLevel = Double.parseDouble(value);
+        }
+        catch (NumberFormatException nfe) {
+            waterlevelTF.setText(
+                lastWaterLevel != null ? lastWaterLevel.toString() : "");
+            return;
+        }
+        updateChart();
+    }
+
+    protected void updateChart() {
+
+        CrossSectionLineItem csli =
+            (CrossSectionLineItem)crossSectionLinesCB.getSelectedItem();
+
+        JFreeChart chart = createChart(csli == null
+            ? new DefaultXYDataset()
+            : generateDataset(csli.line, lastWaterLevel));
+
+        chartPanel.setChart(chart);
+    }
+
     protected ChartPanel createChartPanel() {
         CrossSectionLineItem csli =
             (CrossSectionLineItem)crossSectionLinesCB.getSelectedItem();
 
-        if (csli == null) {
-            return new ChartPanel(null);
-        }
-
-        XYDataset dataset = crossSectionPoints(csli.line);
-
-        JFreeChart chart = createChart(dataset);
+        JFreeChart chart = createChart(csli == null
+            ? new DefaultXYDataset()
+            : generateDataset(csli.line, lastWaterLevel));
 
         return new ChartPanel(chart);
     }
 
-    protected void updateCrossSectionLine(CrossSectionLine line) {
-        XYDataset dataset = crossSectionPoints(line);
-        JFreeChart chart = createChart(dataset);
-        chartPanel.setChart(chart);
-    }
-
     protected void dumpData() {
 
         CrossSectionLineItem csli =
@@ -272,18 +312,27 @@
         }
     }
 
-    protected XYDataset crossSectionPoints(CrossSectionLine line) {
+    protected XYDataset generateDataset(
+        CrossSectionLine line,
+        Double           waterlevel
+    ) {
         DefaultXYDataset dataset = new DefaultXYDataset();
 
         List<CrossSectionPoint> ps = line.getPoints();
 
-        List<CrossSectionPoint> points =
-            new ArrayList<CrossSectionPoint>(ps.size());
+        if (ps.isEmpty()) {
+            return dataset;
+        }
+
+        Collections.sort(ps, COL_POS_CMP);
+
+        List<Point2D> points = new ArrayList<Point2D>(ps.size());
 
         for (CrossSectionPoint p: ps) {
-            if (isValid(p.getX().doubleValue())
-            &&  isValid(p.getY().doubleValue())) {
-                points.add(p);
+            double x = p.getX().doubleValue();
+            double y = p.getY().doubleValue();
+            if (isValid(x) && isValid(y)) {
+                points.add(new Point2D.Double(x, y));
             }
         }
 
@@ -291,21 +340,16 @@
             return dataset;
         }
 
-        Collections.sort(points, COL_POS_CMP);
-
         double [] xs = new double[points.size()];
         double [] ys = new double[xs.length];
 
-        double x = points.get(0).getX().doubleValue();
-        double y = points.get(0).getY().doubleValue();
-
-        xs[0] = x;
-        ys[0] = y;
+        xs[0] = points.get(0).getX();
+        ys[0] = points.get(0).getY();
 
         for (int i = 1; i < xs.length; ++i) {
-            CrossSectionPoint p = points.get(i);
-            x = p.getX().doubleValue();
-            y = p.getY().doubleValue();
+            Point2D p = points.get(i);
+            double x = p.getX();
+            double y = p.getY();
 
             if (x <= xs[i-1]) {
                 x = xs[i-1] + EPSILON;
@@ -314,6 +358,11 @@
             ys[i] = y;
         }
 
+        if (waterlevel != null) {
+            double [][] data = createWaterLines(points, waterlevel);
+            dataset.addSeries(String.valueOf(waterlevel), data);
+        }
+
         CrossSection cs = line.getCrossSection();
 
         String legend = (cs != null ? cs.getDescription() : "???")
@@ -324,6 +373,32 @@
         return dataset;
     }
 
+    protected static double [][] createWaterLines(
+        List<Point2D> points,
+        double        waterlevel
+    ) {
+        List<Line2D> lines = Lines.fillWater(points, waterlevel);
+
+        TDoubleArrayList lxs = new TDoubleArrayList();
+        TDoubleArrayList lys = new TDoubleArrayList();
+
+        for (Iterator<Line2D> iter = lines.iterator(); iter.hasNext();) {
+            Line2D  l  = iter.next();
+            Point2D p1 = l.getP1();
+            Point2D p2 = l.getP2();
+            lxs.add(p1.getX());
+            lys.add(p1.getY());
+            lxs.add(p2.getX());
+            lys.add(p2.getY());
+            if (iter.hasNext()) {
+                lxs.add(Double.NaN);
+                lys.add(Double.NaN);
+            }
+        }
+
+        return new double [][] { lxs.toNativeArray(), lys.toNativeArray() };
+    }
+
     protected void updateCrossSection(CrossSection crossSection) {
         Object [] cslis = createCrossSectionLineItems(crossSection);
         DefaultComboBoxModel dcbm = new DefaultComboBoxModel(cslis);
@@ -334,8 +409,8 @@
         if (cslis.length > 0) {
             CrossSectionLine line =
                 ((CrossSectionLineItem)cslis[0]).line;
-            updateCrossSectionLine(line);
         }
+        updateChart();
     }
 
     protected Object [] createCrossSectionLineItems(CrossSection cs) {
@@ -367,6 +442,11 @@
             true,
             true,
             false);
+
+        XYPlot plot = chart.getXYPlot();
+        NumberAxis yAxis = (NumberAxis)plot.getRangeAxis();
+        yAxis.setAutoRangeIncludesZero(false);
+
         ChartUtilities.applyCurrentTheme(chart);
         return chart;
     }

http://dive4elements.wald.intevation.org