changeset 7604:05549a84ee83

(issue1620) Add export of official lines in WST as specified
author Andre Heinecke <aheinecke@intevation.de>
date Wed, 27 Nov 2013 16:21:00 +0100
parents 25bce6e8beea
children f51c943c707a
files artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstLine.java artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java artifacts/src/main/java/org/dive4elements/river/exports/WstWriter.java
diffstat 3 files changed, 88 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstLine.java	Mon Nov 25 17:40:47 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/WstLine.java	Wed Nov 27 16:21:00 2013 +0100
@@ -73,6 +73,16 @@
         return ws.size() > idx ? ws.get(idx) : -1d;
     }
 
+    /**
+     * Returns the W value at index <i>idx</i> of this line.
+     *
+     * @param idx The position of the desired W value.
+     *
+     * @return the W at position <i>idx</i>.
+     */
+    public double getQ(int idx) {
+        return qs.size() > idx ? qs.get(idx) : -1d;
+    }
 
     /**
      * Returns the Q values of this line.
--- a/artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java	Mon Nov 25 17:40:47 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/WaterlevelExporter.java	Wed Nov 27 16:21:00 2013 +0100
@@ -25,6 +25,13 @@
 
 import au.com.bytecode.opencsv.CSVWriter;
 
+import gnu.trove.TDoubleArrayList;
+
+import org.apache.commons.math.FunctionEvaluationException;
+import org.apache.commons.math.analysis.UnivariateRealFunction;
+
+import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
+
 import org.dive4elements.river.artifacts.model.ConstantWQKms;
 
 import net.sf.jasperreports.engine.JasperExportManager;
@@ -48,6 +55,7 @@
 import org.dive4elements.river.artifacts.model.Segment;
 import org.dive4elements.river.artifacts.model.WQCKms;
 import org.dive4elements.river.artifacts.model.WQKms;
+import org.dive4elements.river.artifacts.model.WstLine;
 import org.dive4elements.river.artifacts.model.WKmsJRDataSource;
 import org.dive4elements.river.artifacts.model.WQKmsResult;
 import org.dive4elements.river.artifacts.resources.Resources;
@@ -761,7 +769,7 @@
     {
         logger.info("WaterlevelExporter.generateWST");
 
-        int cols = data.get(0).length;
+        int cols = data.get(0).length + officalFixings.size();
         WstWriter writer = new WstWriter(cols);
 
         writeWSTData(writer);
@@ -801,6 +809,67 @@
                 }
             }
         }
+
+        // Append the official fixing interpolated to the calculation steps
+        //
+        // There was some confusion how to implement this. see flys/issue1620
+        // for details.
+        for (WQKms wqkms: officalFixings) {
+            // To add some spaces here or to add them in the writer,..
+            writer.addColumn("   " + getDesc(wqkms, true));
+
+            // Get all lines from the calculation
+            Map <Double, WstLine> calcLines = writer.getLines();
+
+            // All KM values where we have a point for
+            TDoubleArrayList officialKms = wqkms.allKms();
+
+            for (Map.Entry<Double, WstLine> entry : calcLines.entrySet()) {
+                // Bad for perfomance but the user can wait a bit for WST
+                // so lets not spend time optimizing too much,.. *hides*
+                double km = entry.getKey().doubleValue();
+                int idx = officialKms.indexOf(km);
+                if (idx != -1) {
+                    entry.getValue().add(wqkms.getW(idx), entry.getValue().getQ(0));
+                }
+            }
+
+            /* Variant: Interpolate the values
+            // Now get the lines for the of the calculation
+            Map <Double, WstLine> calcLines = writer.getLines();
+
+            // Create an interpolater for the official KM -> W relation
+            UnivariateRealFunction wFunc = new LinearInterpolator(
+                    ).interpolate(wqkms.allKms().toNativeArray(),
+                        wqkms.allWs().toNativeArray());
+
+            // Now for each calculated point add the interpolated official
+            for (Map.Entry<Double, WstLine> entry : calcLines.entrySet()) {
+                try {
+                    double wVal = wFunc.value(entry.getKey().doubleValue());
+                    // Matching Q's are guranteed otherwise we would
+                    // not have an official line
+                    entry.getValue().add(wVal, entry.getValue().getQ(0));
+                }
+                catch (FunctionEvaluationException aode) {
+                    // should not happen
+                    logger.error("spline interpolation failed", aode);
+                    // entry.getValue().add(Double.NaN, entry.getValue().getQ(0));
+                }
+            }*/
+
+             /* Variant: Add all official fixings
+                // Warning the WSTWriter does not handle this properly
+                // as it writes the points for which only a calculation
+                // exists in the first column
+                int size = wqkms.size();
+                result = new double[4];
+                for (int i = 0; i < size; i++) {
+                    result = wqkms.get(i, result);
+                    writer.add(result);
+                }
+            */
+        }
     }
 
 
--- a/artifacts/src/main/java/org/dive4elements/river/exports/WstWriter.java	Mon Nov 25 17:40:47 2013 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/exports/WstWriter.java	Wed Nov 27 16:21:00 2013 +0100
@@ -230,7 +230,7 @@
      */
     protected boolean dischargesChanged(double[] newQs) {
         // XXX maybe there is a way to do this faster
-        for (int i = 0; i < cols; i++) {
+        for (int i = 0; i < cols && i < qs.length && i < newQs.length; i++) {
             if (Math.abs(newQs[i] - qs[i]) >= 0.001) {
                 return true;
             }
@@ -238,5 +238,12 @@
 
         return false;
     }
+
+    /**
+     * Get the lines that have alreay been added to this writer
+     * lines are a map with km as the key and a wstline as value */
+    public Map<Double, WstLine> getLines() {
+        return lines;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org