diff artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java @ 8901:0a900d605d52

S-INFO Flowdepth work on TKH calculation
author mschaefer
date Thu, 22 Feb 2018 17:04:06 +0100
parents 89f3c5462a16
children 37ff7f435912
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java	Thu Feb 22 14:11:19 2018 +0100
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/sinfo/flowdepth/BedQualityD50KmValueFinder.java	Thu Feb 22 17:04:06 2018 +0100
@@ -18,15 +18,22 @@
 import org.apache.commons.math.analysis.interpolation.LinearInterpolator;
 import org.apache.commons.math.analysis.polynomials.PolynomialSplineFunction;
 import org.apache.log4j.Logger;
+import org.dive4elements.river.artifacts.math.Utils;
 import org.dive4elements.river.artifacts.model.DateRange;
 import org.dive4elements.river.backend.SedDBSessionHolder;
 import org.dive4elements.river.model.River;
+import org.dive4elements.river.utils.DoubleUtil;
 import org.hibernate.SQLQuery;
 import org.hibernate.Session;
 import org.hibernate.type.StandardBasicTypes;
 
+import gnu.trove.TDoubleArrayList;
+
 /**
- * Searchable sorted km array with parallel bed measurements value array and linear interpolation for km and d50 between the array elements.
+ * Searchable sorted km array with parallel bed measurements value array and linear interpolation for km and d50 between the array elements.<br />
+ * <br />
+ * See comment of SQL command on how the values are filtered and aggregated.
+ * 
  * @author Matthias Schäfer
  *
  */
@@ -154,18 +161,35 @@
     private static final String[] SQL_BED_D50_SELECT_ALIAS = {"km", "mindate", "maxdate", "cnt", "mindepth", "maxdepth", "d50"};
 
     /**
-     * Real linear interpolator for kms and d50 values
+     * Kms of the loaded river range
      */
-    private PolynomialSplineFunction interpolator;
+    private TDoubleArrayList kms;
+    
+    /**
+     * D50 for each km in kms 
+     */
+    private TDoubleArrayList values;
+
     
     /***** METHODS *****/
     
     /**
      * Returns the d50 value interpolated according to a km
-     * @throws ArgumentOutsideDomainException
+     * @return d50 (mm) of the km, or NaN
      */
     public double findD50(double km) throws ArgumentOutsideDomainException {
-        return interpolator.value(km);
+        if ((kms == null) || (kms.size() == 0))
+            return Double.NaN;
+        int i = kms.binarySearch(km);
+        if (i >= 0)
+            return values.get(i);
+        i = -i - 1;
+        if ((i - 1 >= 0) && Utils.epsilonEquals(km, kms.get(i - 1), 0.0001))
+            return values.get(i - 1);
+        else if ((i >= 0) && (i <= kms.size() - 1) && Utils.epsilonEquals(km, kms.get(i), 0.0001))
+            return values.get(i);
+        else
+            return Double.NaN;
     }
     
     /**
@@ -191,18 +215,15 @@
         sqlQuery.setDate("todate", dateRange.getTo());
         @SuppressWarnings("unchecked")
         final List<Object[]> rows = sqlQuery.list();
-        final double[] kms = new double[rows.size()];
-        final double[] values = new double[rows.size()];
+        kms = new TDoubleArrayList();
+        values = new TDoubleArrayList();
         D50Measurement measurement;
-        int i = -1;
         for (Object[] row : rows) {
             measurement = new D50Measurement(row, SQL_BED_D50_SELECT_ALIAS);
-            i++;
-            kms[i] = measurement.getKm();
-            values[i] = measurement.getD50();
-            log.debug(String.format("loadValues km %.3f d50(mm) %.1f count %d", kms[i], values[i], measurement.getCnt()));
+            kms.add(measurement.getKm());
+            values.add(measurement.getD50());
+            log.debug(String.format("loadValues km %.3f d50(mm) %.1f count %d", kms.get(kms.size()-1), values.get(values.size()-1), measurement.getCnt()));
         }
-        interpolator = new LinearInterpolator().interpolate(kms, values);
         return true;
     }
 

http://dive4elements.wald.intevation.org