changeset 925:0cb1a70b8b92

Added the math needed to calculate "W-Differenzen" in "Laengsschnitten" flys-artifacts/trunk@2277 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 03 Jul 2011 15:33:33 +0000
parents f7761914f745
children 659608128823
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/WKmsOperation.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/NamedObject.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/NamedObjectImpl.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKms.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKmsImpl.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQ.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKms.java flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java
diffstat 10 files changed, 299 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri Jul 01 14:46:13 2011 +0000
+++ b/flys-artifacts/ChangeLog	Sun Jul 03 15:33:33 2011 +0000
@@ -1,3 +1,42 @@
+2011-07-03  Sascha L. Teichmann <sascha.teichmann@intevation.de>
+
+	Added the math needed to calculate "W-Differenzen" in "Laengsschnitten".
+	Needs testing!
+
+	* src/main/java/de/intevation/flys/artifacts/model/NamedObject.java:
+	  Made it an interface to be usable in more than one inheritance chain.
+
+	* src/main/java/de/intevation/flys/artifacts/model/NamedObjectImpl.java:
+	  Implements the NamedObject interface and is the new base class of
+	  WQ and WKmsImpl.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WKms.java:
+	  New. Interface to associate kms with ws.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WQKms.java:
+	  Changed the base class to NamedObjectImpl. Renamed getKms(int)
+	  to getKm(int) to make clear it return a single scalar value
+	  and fullfil the WKms interface.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WKmsImpl.java:
+	  New. Implements the WKms interface. Intended to be a lightweight
+	  datastore for "zusaetzliche Laengsschnitte" and as results
+	  of the WKmsOperations.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WQ.java:
+	  Changed base class to NamedObjectImpl.
+
+	* src/main/java/de/intevation/flys/artifacts/math/WKmsOperation.java:
+	  New. Operations on WKms data.
+	  Currently only the SUBTRACTION operation is implemented. This
+	  one is needed to calculate the "W-Differenzen". The operation
+	  is insensitive about the km directions of the datasets. Missing
+	  values are interpolated linear.
+
+	* src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java,
+	  src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java:
+	  Adjusted to satisfy the signature change of WQKMs.
+
 2011-07-01  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/exports/StyledXYSeries.java: New. This
@@ -96,7 +135,7 @@
 	* pom.xml: Downgraded Trove to 1.1-beta-5, because the new
 	  later ones are removed from the maven repos.
 
-	  The functionality we need is in 1.1 so this downgrad should
+	  The functionality we need is in 1.1 so this downgrade should
 	  cause no problems.
 
 	  Would be nice if we would support the maintainers of trove to 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/WKmsOperation.java	Sun Jul 03 15:33:33 2011 +0000
@@ -0,0 +1,144 @@
+package de.intevation.flys.artifacts.math;
+
+import de.intevation.flys.artifacts.model.WKms;
+import de.intevation.flys.artifacts.model.WKmsImpl;
+
+import java.util.Arrays;
+
+public abstract class WKmsOperation
+{
+    public static final double EPSILON = 1e-6;
+
+    public static final class KmW 
+    implements                Comparable<KmW>
+    {
+        protected double km;
+        protected double w;
+
+        public KmW(double km, double w) {
+            this.km = km;
+            this.w  = w;
+        }
+
+        public int compareTo(KmW other) {
+            return km < other.km
+                ? -1
+                : km > other.km ? +1 : 0;
+        }
+
+        public boolean kmEquals(KmW other) {
+            return Math.abs(km - other.km) < EPSILON;
+        }
+
+        public double subtract(KmW other) {
+            return w - other.w;
+        }
+    } // class KmW
+
+    public static final WKmsOperation SUBTRACTION = new WKmsOperation() {
+
+        @Override
+        public WKms operate(WKms a, WKms b) {
+            return subtract(a, b);
+        }
+    };
+
+    protected WKmsOperation() {
+    }
+
+    public abstract WKms operate(WKms a, WKms b);
+
+    public static WKms subtract(WKms minuend, WKms subtrahend) {
+
+        int M = minuend   .size();
+        int S = subtrahend.size();
+
+        // Don't subtract empty sets
+        if (M < 1 || S < 1) {
+            return new WKmsImpl();
+        }
+
+        KmW [] ms = new KmW[M];
+        KmW [] ss = new KmW[S];
+
+        for (int i = 0; i < M; ++i) {
+            ms[i] = new KmW(minuend.getKm(i), minuend.getW(i));
+        }
+
+        for (int i = 0; i < S; ++i) {
+            ss[i] = new KmW(subtrahend.getKm(i), subtrahend.getW(i));
+        }
+
+        Arrays.sort(ms);
+        Arrays.sort(ss);
+
+        // no overlap -> empty result set
+        if (ms[0].km > ss[S-1].km || ss[0].km > ms[M-1].km) {
+            return new WKmsImpl();
+        }
+
+        WKmsImpl result = new WKmsImpl();
+
+        int mi = 0;
+        int si = 0;
+
+        OUT: while (mi < M && si < S) {
+            KmW m = ms[mi];
+            KmW s = ss[si];
+
+            if (m.km + EPSILON < s.km) {
+                // minuend is before subtrahend
+
+                while (ms[mi].km + EPSILON < s.km) {
+                    if (++mi >= M) {
+                        break OUT;
+                    }
+                }
+
+                if (ms[mi].km + EPSILON > s.km) {
+                    double mw = Linear.linear(
+                        s.km,
+                        ms[mi-1].km, ms[mi].km,
+                        ms[mi-1].w,  ms[mi].w);
+                    result.add(s.km, mw - s.w);
+                    ++si;
+                }
+                else { // s.km == ms[mi].km
+                    result.add(s.km, ms[mi].subtract(s));
+                    ++mi;
+                    ++si;
+                }
+            }
+            else if (m.km > s.km + EPSILON) {
+                // subtrahend is before minuend
+
+                while (m.km > ss[si].km + EPSILON) {
+                    if (++si >= S) {
+                        break OUT;
+                    }
+                }
+
+                if (ss[si].km + EPSILON > m.km) {
+                    double sw = Linear.linear(
+                        m.km,
+                        ss[si-1].km, ss[si].km,
+                        ss[si-1].w,  ss[si].w);
+                    result.add(m.km, m.w - sw);
+                }
+                else { // ss[si].km == m.km
+                    result.add(m.km, m.subtract(ss[si]));
+                    ++mi;
+                    ++si;
+                }
+            }
+            else { // m.km == s.km
+                result.add(s.km, m.subtract(s));
+                ++mi;
+                ++si;
+            }
+        }
+
+        return result;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/NamedObject.java	Fri Jul 01 14:46:13 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/NamedObject.java	Sun Jul 03 15:33:33 2011 +0000
@@ -9,26 +9,11 @@
  *
  * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
  */
-public class NamedObject implements Serializable {
-
-    /** The name of this object.*/
-    protected String name;
-
-    public NamedObject() {
-    }
+public interface NamedObject
+extends          Serializable
+{
+    void setName(String name);
 
-    public NamedObject(String name) {
-        this.name = name;
-    }
-
-
-    public void setName(String name) {
-        this.name = name;
-    }
-
-
-    public String getName() {
-        return name;
-    }
+    String getName();
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/NamedObjectImpl.java	Sun Jul 03 15:33:33 2011 +0000
@@ -0,0 +1,28 @@
+package de.intevation.flys.artifacts.model;
+
+public class NamedObjectImpl
+implements   NamedObject
+{
+    /** The name of this object.*/
+    protected String name;
+
+    public NamedObjectImpl() {
+    }
+
+    public NamedObjectImpl(String name) {
+        this.name = name;
+    }
+
+
+    @Override
+    public void setName(String name) {
+        this.name = name;
+    }
+
+
+    @Override
+    public String getName() {
+        return name;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKms.java	Sun Jul 03 15:33:33 2011 +0000
@@ -0,0 +1,12 @@
+package de.intevation.flys.artifacts.model;
+
+public interface WKms
+extends          NamedObject
+{
+    int size();
+
+    double getKm(int index);
+
+    double getW(int index);
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WKmsImpl.java	Sun Jul 03 15:33:33 2011 +0000
@@ -0,0 +1,55 @@
+package de.intevation.flys.artifacts.model;
+
+import gnu.trove.TDoubleArrayList;
+
+public class WKmsImpl
+extends      NamedObjectImpl
+implements   WKms
+{
+    protected TDoubleArrayList kms;
+    protected TDoubleArrayList ws;
+
+    public WKmsImpl() {
+        super("");
+        kms = new TDoubleArrayList();
+        ws  = new TDoubleArrayList();
+    }
+
+    public WKmsImpl(int capacity) {
+        super("");
+        kms = new TDoubleArrayList(capacity);
+        ws  = new TDoubleArrayList(capacity);
+    }
+
+    public WKmsImpl(TDoubleArrayList kms, TDoubleArrayList ws) {
+        this(kms, ws, "");
+    }
+
+    public WKmsImpl(
+        TDoubleArrayList kms,
+        TDoubleArrayList ws,
+        String           name
+    ) {
+        super(name);
+        this.kms = kms;
+        this.ws  = ws;
+    }
+
+    public void add(double km, double w) {
+        kms.add(km);
+        ws .add(w);
+    }
+
+    public double getW(int index) {
+        return ws.getQuick(index);
+    }
+
+    public double getKm(int index) {
+        return kms.getQuick(index);
+    }
+
+    public int size() {
+        return kms.size();
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQ.java	Fri Jul 01 14:46:13 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQ.java	Sun Jul 03 15:33:33 2011 +0000
@@ -5,10 +5,12 @@
 import java.util.Random;
 
 public class WQ
-extends      NamedObject
+extends      NamedObjectImpl
 {
+    // TODO: s/w/ws/g
     protected TDoubleArrayList w;
 
+    // TODO: s/q/qs/g
     protected TDoubleArrayList q;
 
     public WQ() {
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKms.java	Fri Jul 01 14:46:13 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WQKms.java	Sun Jul 03 15:33:33 2011 +0000
@@ -13,6 +13,7 @@
  */
 public class WQKms
 extends      WQ
+implements   WKms
 {
     private static Logger logger = Logger.getLogger(WQKms.class);
 
@@ -84,7 +85,8 @@
         return dst;
     }
 
-    public double getKms(int idx) {
+    @Override
+    public double getKm(int idx) {
         return kms.getQuick(idx);
     }
 
@@ -98,8 +100,8 @@
      * @return a string that consist of the first and last kilometer.
      */
     public String toString() {
-        double from = getKms(0);
-        double to   = getKms(size()-1);
+        double from = getKm(0);
+        double to   = getKm(size()-1);
         return from + " - " + to;
     }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java	Fri Jul 01 14:46:13 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/DischargeLongitudinalSectionGenerator.java	Sun Jul 03 15:33:33 2011 +0000
@@ -82,7 +82,7 @@
                 theme);
 
             for (int i = 0; i < size; i++) {
-                series.add(wqckms.getKms(i), wqckms.getC(i));
+                series.add(wqckms.getKm(i), wqckms.getC(i));
             }
 
             addFirstAxisSeries(series);
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Fri Jul 01 14:46:13 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/LongitudinalSectionGenerator.java	Sun Jul 03 15:33:33 2011 +0000
@@ -190,14 +190,14 @@
         if (logger.isDebugEnabled()) {
             if (wqkms.size() > 0) {
                 logger.debug("Generate series: " + series.getKey());
-                logger.debug("Start km: " + wqkms.getKms(0));
-                logger.debug("End   km: " + wqkms.getKms(size-1));
+                logger.debug("Start km: " + wqkms.getKm(0));
+                logger.debug("End   km: " + wqkms.getKm(size-1));
                 logger.debug("Values  : " + size);
             }
         }
 
         for (int i = 0; i < size; i++) {
-            series.add(wqkms.getKms(i), wqkms.getW(i));
+            series.add(wqkms.getKm(i), wqkms.getW(i));
         }
 
         addFirstAxisSeries(series);
@@ -224,14 +224,14 @@
         if (logger.isDebugEnabled()) {
             if (wqkms.size() > 0) {
                 logger.debug("Generate series: " + series.getKey());
-                logger.debug("Start km: " + wqkms.getKms(0));
-                logger.debug("End   km: " + wqkms.getKms(size-1));
+                logger.debug("Start km: " + wqkms.getKm(0));
+                logger.debug("End   km: " + wqkms.getKm(size-1));
                 logger.debug("Values  : " + size);
             }
         }
 
         for (int i = 0; i < size; i++) {
-            series.add(wqkms.getKms(i), wqkms.getQ(i));
+            series.add(wqkms.getKm(i), wqkms.getQ(i));
         }
 
         addSecondAxisSeries(series);

http://dive4elements.wald.intevation.org