# HG changeset patch # User Andre Heinecke # Date 1364294343 -3600 # Node ID f4fd64a4d502ece4f1244d44e1d20c33769aed20 # Parent eb7a3f58bdd644b14933537780aee82afe280ba3 Fix Wstcalculation for non monotonous values. Patch written and provided by Sascha Teichmann diff -r eb7a3f58bdd6 -r f4fd64a4d502 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java --- 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; } diff -r eb7a3f58bdd6 -r f4fd64a4d502 flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTableFactory.java --- 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 rows = loadRows(session, wst_id, columns.length); + int [] map = loadQRangesMap(session, columns, wst_id); + List 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 rows = loadRows(session, wst, columns.length); + List 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 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 { + 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()); } }