changeset 5423:f4fd64a4d502

Fix Wstcalculation for non monotonous values. Patch written and provided by Sascha Teichmann
author Andre Heinecke <aheinecke@intevation.de>
date Tue, 26 Mar 2013 11:39:03 +0100
parents eb7a3f58bdd6
children 657392b30bb4
files flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java
diffstat 2 files changed, 80 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Tue Mar 26 11:29:25 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Tue Mar 26 11:39:03 2013 +0100
@@ -269,6 +269,26 @@
         return parent;
     }
 
+    public double averageQ() {
+        double sum = 0d;
+        int n = 0;
+        for (Node node = head(); node != null; node = node.next) {
+            sum += node.q;
+            ++n;
+        }
+        return sum/n;
+    }
+
+    public double maxQ() {
+        double max = -Double.MAX_VALUE;
+        for (Node node = head(); node != null; node = node.next) {
+            if (node.q > max) {
+                max = node.q;
+            }
+        }
+        return max;
+    }
+
     public double findQ(double pos) {
         return root != null ? root.findQ(pos) : Double.NaN;
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java	Tue Mar 26 11:29:25 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java	Tue Mar 26 11:39:03 2013 +0100
@@ -98,8 +98,8 @@
         // Fetch data for one column only.
 
         WstValueTable.Column [] columns = loadColumns(session, wst_id);
-        loadQRanges(session, columns, wst_id);
-        List<WstValueTable.Row> rows = loadRows(session, wst_id, columns.length);
+        int [] map = loadQRangesMap(session, columns, wst_id);
+        List<WstValueTable.Row> rows = loadRows(session, wst_id, columns.length, map);
 
         WstValueTable valueTable = new WstValueTable(columns, rows);
 
@@ -204,9 +204,10 @@
 
         WstValueTable.Column [] columns = loadColumns(session, wst);
 
-        loadQRanges(session, columns, wst);
+        int map [] = loadQRangesMap(session, columns, wst);
 
-        List<WstValueTable.Row> rows = loadRows(session, wst, columns.length);
+        List<WstValueTable.Row> rows =
+            loadRows(session, wst.getId(), columns.length, map);
 
         return new WstValueTable(columns, rows);
     }
@@ -274,6 +275,15 @@
         int     wst_id,
         int     numColumns
     ) {
+        return loadRows(session, wst_id, numColumns, null);
+    }
+
+    protected static List<WstValueTable.Row> loadRows(
+        Session session,
+        int     wst_id,
+        int     numColumns,
+        int []  map
+    ) {
         SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_WS)
             .addScalar("km",         StandardBasicTypes.DOUBLE)
             .addScalar("w",          StandardBasicTypes.DOUBLE)
@@ -298,7 +308,8 @@
                 rows.add(row);
             }
             Double w = (Double)result[1];
-            ws[column] = w != null ? w : Double.NaN;
+            int index = map != null ? map[column] : column;
+            ws[index] = w != null ? w : Double.NaN;
             lastColumn = column;
         }
 
@@ -387,7 +398,7 @@
         columns[0].setQRangeTree(qRangeTree);
     }
 
-    protected static void loadQRanges(
+    protected static int [] loadQRangesMap(
         Session                 session,
         WstValueTable.Column [] columns,
         int                     wst_id
@@ -426,6 +437,8 @@
             columns[lastColumn].setQRangeTree(qRangeTree);
         }
 
+        return sortColumnsByAverageQ(columns);
+
         /* This is debug code to visualize the q ranges trees
 
         java.io.PrintWriter out = null;
@@ -454,15 +467,53 @@
             }
         }
         */
-
     }
 
-    protected static void loadQRanges(
+    private static final class QIndex implements Comparable<QIndex> {
+        double q;
+        int    index;
+
+        QIndex(double q, int index) {
+            this.q     = q;
+            this.index = index;
+        }
+
+        @Override
+        public int compareTo(QIndex other) {
+            double diff = q - other.q;
+            if (diff < 0d) return -1;
+            if (diff > 0d) return +1;
+            return 0;
+        }
+    } // class QIndex
+
+    /** Ensure that the q colums are sorted in ascending order. */
+    protected static int [] sortColumnsByAverageQ(WstValueTable.Column [] columns) {
+        QIndex [] order = new QIndex[columns.length];
+        for (int i = 0; i < order.length; ++i) {
+            QRangeTree tree = columns[i].getQRangeTree();
+            double avg = tree.averageQ();
+            double max = tree.maxQ();
+            double q   = (avg+max)*0.5d;
+            order[i] = new QIndex(q, i);
+        }
+        Arrays.sort(order);
+        WstValueTable.Column [] copy = new WstValueTable.Column[order.length];
+        int [] map = new int[order.length];
+        for (int i = 0; i < copy.length; ++i) {
+            copy[i] = columns[order[i].index];
+            map[order[i].index] = i;
+        }
+        System.arraycopy(copy, 0, columns, 0, order.length);
+        return map;
+    }
+
+    protected static int [] loadQRangesMap(
         Session                 session,
         WstValueTable.Column [] columns,
         Wst                     wst
     ) {
-        loadQRanges(session, columns, wst.getId());
+        return loadQRangesMap(session, columns, wst.getId());
     }
 
 }

http://dive4elements.wald.intevation.org