changeset 2562:ba35dfb7c09a

FixingsOverview: Construct the Q sectors once. flys-artifacts/trunk@4088 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 20 Feb 2012 14:36:28 +0000
parents b3f6d49cdc80
children 59c920e73d8a
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java
diffstat 2 files changed, 180 insertions(+), 105 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Sun Feb 19 17:14:39 2012 +0000
+++ b/flys-artifacts/ChangeLog	Mon Feb 20 14:36:28 2012 +0000
@@ -1,3 +1,10 @@
+2012-02-20  Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java:
+	  Refactored to build the Q sectors once at construction time and not
+	  every time output is generated.
+	  This will ease the job of applying filters to the Overview.
+
 2012-02-19  Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	  Service to generate the data needed to build the "Fixerungen pro Fluss Uebersicht"
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Sun Feb 19 17:14:39 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FixingsOverview.java	Mon Feb 20 14:36:28 2012 +0000
@@ -119,7 +119,7 @@
         "    MAX(position) AS stop_km " +
         "FROM" +
         "    wst_column_values " +
-        "WHERE " +
+        "WHERE" +
         "    wst_column_id = :column_id";
 
     public static class Range implements Serializable {
@@ -135,10 +135,22 @@
             this.end   = end;
         }
 
+        public double getStart() {
+            return start;
+        }
+
+        public double getEnd() {
+            return end;
+        }
+
         public boolean disjoint(Range other) {
             return start > other.end || other.start > end;
         }
 
+        public boolean intersects(Range other) {
+            return !disjoint(other);
+        }
+
         public boolean clip(Range other) {
             if (disjoint(other)) return false;
 
@@ -229,6 +241,91 @@
         }
     } // class GaugeRange
 
+    public static class GaugeFinder {
+
+        protected List<GaugeRange> gauges;
+        protected boolean          isKmUp;
+
+        public GaugeFinder(List<GaugeRange> gauges) {
+            this(gauges, true);
+        }
+
+        public GaugeFinder(
+            List<GaugeRange> gauges,
+            boolean          isKmUp
+        ) {
+            this.gauges = gauges;
+            this.isKmUp = isKmUp;
+        }
+
+        public boolean getIsKmUp() {
+            return isKmUp;
+        }
+
+        public void setIsKmUp(boolean isKmUp) {
+            this.isKmUp = isKmUp;
+        }
+
+        public GaugeRange find(Range range) {
+            double km = isKmUp ? range.start : range.end;
+            for (GaugeRange gauge: gauges) {
+                if (gauge.inside(km)) {
+                    return gauge;
+                }
+            }
+            return null;
+        }
+
+        public GaugeRange find(int gaugeId) {
+            for (GaugeRange gauge: gauges) {
+                if (gauge.gaugeId == gaugeId) {
+                    return gauge;
+                }
+            }
+            return null;
+        }
+
+        public boolean loadDischargeSectors(Session session, int riverId) {
+
+            SQLQuery query = session.createSQLQuery(SQL_DISCHARGE_SECTORS)
+                .addScalar("gauge_id", StandardBasicTypes.INTEGER)
+                .addScalar("name",     StandardBasicTypes.STRING)
+                .addScalar("value",    StandardBasicTypes.DOUBLE);
+
+            query.setInteger("river_id", riverId);
+
+            List<Object []> list = query.list();
+
+            if (list.isEmpty()) {
+                log.warn("River " + riverId + " has no discharge sectors.");
+                return false;
+            }
+
+            GaugeRange gauge = null;
+
+            for (Object [] row: list) {
+                int    gaugeId = (Integer)row[0];
+                String label   = (String) row[1];
+                Double value   = (Double) row[2];
+
+                if (gauge == null || gauge.gaugeId != gaugeId) {
+                    if ((gauge = find(gaugeId)) == null) {
+                        log.warn("Cannot find gauge for id " + gaugeId + ".");
+                        continue;
+                    }
+                }
+
+                gauge.addMainValue(label, value);
+            }
+
+            for (GaugeRange g: gauges) {
+                g.buildClasses();
+            }
+
+            return true;
+        }
+    } // class GaugeFinder
+
     public static class QRange extends Range {
 
         protected double q;
@@ -249,11 +346,21 @@
         public SectorRange() {
         }
 
+        public SectorRange(SectorRange other) {
+            start  = other.start;
+            end    = other.end;
+            sector = other.sector;
+        }
+
         public SectorRange(double start, double end, int sector) {
             super(start, end);
             this.sector = sector;
         }
 
+        public int getSector() {
+            return sector;
+        }
+
         public boolean enlarge(SectorRange other) {
             if (sector == other.sector
             && Math.abs(end-other.start) < EPSILON2) {
@@ -280,7 +387,7 @@
             protected Date   startTime;
             protected String name;
 
-            protected List<QRange> qRanges;
+            protected List<SectorRange> sectors;
 
             public Column() {
             }
@@ -290,16 +397,18 @@
                 this.startTime = startTime;
                 this.name      = name;
                 
-                qRanges = new ArrayList<QRange>();
+                sectors = new ArrayList<SectorRange>();
             }
 
             public Fixing getFixing() {
                 return Fixing.this;
             }
 
-            public List<SectorRange> classify(GaugeRange gauge) {
+            public List<SectorRange> getSectors() {
+                return sectors;
+            }
 
-                List<SectorRange> sectors = new ArrayList<SectorRange>();
+            public void buildSectors(GaugeRange gauge, List<QRange> qRanges) {
 
                 for (QRange qRange: qRanges) {
                     SectorRange sector = new SectorRange(
@@ -310,8 +419,6 @@
                         sectors.add(sector);
                     }
                 }
-
-                return sectors;
             }
 
             public void loadKmRange(SQLQuery query) {
@@ -329,10 +436,15 @@
                 }
             }
 
-            public void loadQRanges(SQLQuery query) {
+            public void loadQRanges(
+                SQLQuery    query,
+                GaugeFinder gaugeFinder
+            ) {
                 query.setInteger("column_id", columnId);
                 List<Object []> list = query.list();
 
+                List<QRange> qRanges = new ArrayList<QRange>(list.size());
+
                 for (Object [] row: list) {
                     double q     = (Double)row[0];
                     double start = (Double)row[1];
@@ -342,11 +454,20 @@
                         qRanges.add(qRange);
                     }
                 }
+
+                GaugeRange gauge = gaugeFinder.find(this);
+
+                if (gauge != null) {
+                    buildSectors(gauge, qRanges);
+                }
+                else {
+                    log.warn("No gauge found for column " + columnId + ".");
+                }
             }
         } // class Column
 
-        protected int                wstId;
-        protected String             description;
+        protected int          wstId;
+        protected String       description;
         protected List<Column> columns;
 
         public Fixing() {
@@ -375,27 +496,32 @@
             }
         }
 
-        public void loadColumnsQRanges(SQLQuery query) {
+        public void loadColumnsQRanges(
+            SQLQuery    query,
+            GaugeFinder gaugeFinder
+        ) {
             for (Column column: columns) {
-                column.loadQRanges(query);
+                column.loadQRanges(query, gaugeFinder);
             }
         }
 
-        public void addAllColumns(List<Column> allColumns) {
-            allColumns.addAll(columns);
+        public void addAllColumns(List<Column> allColumns, Range range) {
+            for (Column column: columns) {
+                if (column.intersects(range)) { 
+                    allColumns.add(column);
+                }
+            }
         }
     } // class Fixing
 
 
-    protected String           riverName;
-    protected int              riverId;
-    protected boolean          isKmUp;
-    protected List<GaugeRange> gauges;
-    protected List<Fixing>     fixings;
-    protected Range            extent;
+    protected String       riverName;
+    protected int          riverId;
+    protected boolean      isKmUp;
+    protected List<Fixing> fixings;
+    protected Range        extent;
 
     public FixingsOverview() {
-        gauges  = new ArrayList<GaugeRange>();
         fixings = new ArrayList<Fixing>();
     }
 
@@ -446,8 +572,7 @@
         return true;
     }
 
-
-    protected boolean loadGauges(Session session) {
+    protected GaugeFinder loadGauges(Session session) {
         SQLQuery query = session.createSQLQuery(SQL_GAUGES)
             .addScalar("gauge_id", StandardBasicTypes.INTEGER)
             .addScalar("a",        StandardBasicTypes.DOUBLE)
@@ -459,9 +584,11 @@
 
         if (list.isEmpty()) {
             log.warn("River " + riverId + " has no gauges.");
-            return false;
+            return null;
         }
 
+        List<GaugeRange> gauges = new ArrayList<GaugeRange>();
+
         for (Object [] row: list) {
             int    gaugeId = (Integer)row[0];
             double start   = (Double) row[1];
@@ -470,66 +597,9 @@
             gauges.add(gauge);
         }
 
-        return true;
-    }
-
-    protected GaugeRange findGaugeById(int gaugeId) {
-        for (GaugeRange gauge: gauges) {
-            if (gauge.gaugeId == gaugeId) {
-                return gauge;
-            }
-        }
-        return null;
-    }
-
-    protected GaugeRange findGaugeByKm(double km) {
-        for (GaugeRange gauge: gauges) {
-            if (gauge.inside(km)) {
-                return gauge;
-            }
-        }
-        return null;
+        return new GaugeFinder(gauges, isKmUp);
     }
 
-    protected boolean loadDischargeSectors(Session session) {
-
-        SQLQuery query = session.createSQLQuery(SQL_DISCHARGE_SECTORS)
-            .addScalar("gauge_id", StandardBasicTypes.INTEGER)
-            .addScalar("name",     StandardBasicTypes.STRING)
-            .addScalar("value",    StandardBasicTypes.DOUBLE);
-
-        query.setInteger("river_id", riverId);
-
-        List<Object []> list = query.list();
-
-        if (list.isEmpty()) {
-            log.warn("River " + riverId + " has no discharge sectors.");
-            return false;
-        }
-
-        GaugeRange gauge = null;
-
-        for (Object [] row: list) {
-            int    gaugeId = (Integer)row[0];
-            String label   = (String) row[1];
-            Double value   = (Double) row[2];
-
-            if (gauge == null || gauge.gaugeId != gaugeId) {
-                if ((gauge = findGaugeById(gaugeId)) == null) {
-                    log.warn("Cannot find gauge for id " + gaugeId + ".");
-                    continue;
-                }
-            }
-
-            gauge.addMainValue(label, value);
-        }
-
-        for (GaugeRange g: gauges) {
-            g.buildClasses();
-        }
-
-        return true;
-    }
 
     protected void loadFixings(Session session) {
         SQLQuery query = session.createSQLQuery(SQL_FIXINGS)
@@ -574,49 +644,55 @@
         }
     }
 
-    protected void loadFixingsColumnsQRanges(Session session) {
+    protected void loadFixingsColumnsQRanges(
+        Session     session,
+        GaugeFinder gaugeFinder
+    ) {
         SQLQuery query = session.createSQLQuery(SQL_FIXING_COLUMN_Q_RANGES)
             .addScalar("q",        StandardBasicTypes.DOUBLE)
             .addScalar("start_km", StandardBasicTypes.DOUBLE)
             .addScalar("stop_km",  StandardBasicTypes.DOUBLE);
 
         for (Fixing fixing: fixings) {
-            fixing.loadColumnsQRanges(query);
+            fixing.loadColumnsQRanges(query, gaugeFinder);
         }
     }
 
     public boolean load(Session session) {
 
-        if (!loadRiver(session)) {
+        if (!loadRiver(session)
+        ||  !loadRiverExtent(session)) {
             return false;
         }
 
-        if (!loadRiverExtent(session)) {
-            return false;
-        }
+        GaugeFinder gaugeFinder = loadGauges(session);
 
-        if (!loadGauges(session)) {
-            return false;
-        }
-
-        if (!loadDischargeSectors(session)) {
+        if (gaugeFinder == null
+        || !gaugeFinder.loadDischargeSectors(session, riverId)) {
             return false;
         }
 
         loadFixings(session);
         loadFixingsColumns(session);
         loadFixingsColumnsKmRange(session);
-        loadFixingsColumnsQRanges(session);
+        loadFixingsColumnsQRanges(session, gaugeFinder);
 
         return true;
     }
 
+    private static final Range FULL_EXTENT =
+        new Range(-Double.MAX_VALUE, Double.MAX_VALUE);
+
     public void generateOverview(Document document) {
+        generateOverview(document, FULL_EXTENT);
+    }
+
+    public void generateOverview(Document document, Range range) {
 
         List<Fixing.Column> allColumns = new ArrayList<Fixing.Column>();
 
         for (Fixing fixing: fixings) {
-            fixing.addAllColumns(allColumns);
+            fixing.addAllColumns(allColumns, range);
         }
 
         Collections.sort(allColumns, Fixing.DATE_CMP);
@@ -637,16 +713,8 @@
 
         for (Fixing.Column column: allColumns) {
 
-            double km = isKmUp ? column.start : column.end;
-
-            GaugeRange gauge = findGaugeByKm(km);
-
-            if (gauge == null) {
-                log.warn("Cannot find gauge for km " + km + ".");
-                continue;
-            }
-
-            List<SectorRange> sectors = column.classify(gauge);
+            // TODO: Apply additional filters here.
+            List<SectorRange> sectors = column.getSectors();
 
             if (!sectors.isEmpty()) {
                 Element eE = document.createElement("event");

http://dive4elements.wald.intevation.org