changeset 4521:71e6fe870c1d

Added objects and factory for sediment densities.
author Raimund Renkert <rrenkert@intevation.de>
date Wed, 14 Nov 2012 17:17:02 +0100
parents 0b330ed218f6
children a9753f717b3d
files flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensity.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensityFactory.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensityValue.java
diffstat 3 files changed, 296 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensity.java	Wed Nov 14 17:17:02 2012 +0100
@@ -0,0 +1,160 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.jfree.util.Log;
+
+
+public class SedimentDensity
+{
+    private static final Logger logger = Logger
+        .getLogger(SedimentDensity.class);
+
+    private Map<Integer, List<SedimentDensityValue>> densities;
+    private List<Integer> years;
+
+    public SedimentDensity() {
+        this.densities = new HashMap<Integer, List<SedimentDensityValue>>();
+        this.years = new ArrayList<Integer>();
+    }
+
+    public Map<Integer, List<SedimentDensityValue>> getDensities() {
+        return densities;
+    }
+
+    public void setDensities(Map<Integer, List<SedimentDensityValue>> densities) {
+        this.densities = densities;
+    }
+
+    public void addDensity(double km, double density, int year) {
+        logger.debug("adding " + year);
+        if (this.densities.containsKey(year)) {
+            List<SedimentDensityValue> list = this.densities.get(year);
+            list.add(new SedimentDensityValue(km, density, year));
+        }
+        else {
+            List<SedimentDensityValue> list =
+                new ArrayList<SedimentDensityValue>();
+            list.add(new SedimentDensityValue(km, density, year));
+            densities.put(year, list);
+        }
+        if (!this.years.contains(new Integer(year))) {
+            logger.debug("new year");
+            years.add(new Integer(year));
+        }
+    }
+
+    public List<Integer> getYears() {
+        return years;
+    }
+
+    public void setYears(List<Integer> years) {
+        this.years = years;
+    }
+
+    public double getDensity(double km, int year) {
+        Collections.sort(this.years);
+        if (this.years.size() == 1) {
+            return getDensityAtKm(densities.get(year), km);
+        }
+        else {
+            for (int i = 0; i < years.size() -1; i++) {
+                int y1 = years.get(i);
+                int y2 = years.get(i + 1);
+                int mid = Math.round((y1 + y2) / 2);
+                if (year < mid) {
+                    return getDensityAtKm(densities.get(y1), km);
+                }
+                else if (i == years.size() -1) {
+                    continue;
+                }
+                else {
+                    return getDensityAtKm(densities.get(y2), km);
+                }
+            }
+        }
+        return -1d;
+    }
+
+    private double getDensityAtKm(
+        List<SedimentDensityValue> values,
+        double km
+    ) {
+        boolean found = true;
+        SedimentDensityValue prev = null;
+        SedimentDensityValue next = null;
+        for (SedimentDensityValue sdv: values) {
+logger.debug("year: " + sdv.getYear());
+            if (sdv.getKm() == km) {
+                prev = sdv;
+                found = true;
+                break;
+            }
+            if (sdv.getKm() > km) {
+                next = sdv;
+                break;
+            }
+            prev = sdv;
+        }
+        if (found) {
+            return prev.getDensity();
+        }
+        else {
+            return spline(prev, next, km);
+        }
+    }
+
+    private double spline(
+        SedimentDensityValue prev,
+        SedimentDensityValue next,
+        double km
+    ) {
+        double lower = prev.getKm();
+        double upper = next.getKm();
+        double upperDensity = next.getDensity();
+        double lowerDensity = prev.getDensity();
+
+        double m =(upperDensity - lowerDensity)/(upper - lower) * km;
+        double b = lowerDensity -
+            ((upperDensity - lowerDensity)/(upper - lower) * lower);
+        return (m * km) + b;
+    }
+
+    public void cleanUp() {
+        Set<Integer> keys = densities.keySet();
+        for (Integer key : keys) {
+            List<SedimentDensityValue> list = densities.get(key);
+            if (list.size() == 0) {
+                return;
+            }
+            List<SedimentDensityValue> cleaned =
+                new ArrayList<SedimentDensityValue>();
+            double prevkm = list.get(0).getKm();
+            int counter = 0;
+            double sum = 0d;
+            for (SedimentDensityValue value : list) {
+                if (value.getKm() == prevkm) {
+                    sum += value.getDensity();
+                    counter++;
+                }
+                else {
+                    cleaned.add(new SedimentDensityValue(
+                        prevkm,
+                        sum / counter,
+                        value.getYear()));
+                    sum = value.getDensity();
+                    counter = 1;
+                }
+                prevkm = value.getKm();
+            }
+            this.densities.put(key, cleaned);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensityFactory.java	Wed Nov 14 17:17:02 2012 +0100
@@ -0,0 +1,90 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+import java.util.List;
+
+import net.sf.ehcache.Cache;
+import net.sf.ehcache.Element;
+
+import org.apache.log4j.Logger;
+import org.hibernate.SQLQuery;
+import org.hibernate.Session;
+import org.hibernate.type.StandardBasicTypes;
+
+import de.intevation.flys.artifacts.cache.CacheFactory;
+import de.intevation.flys.backend.SessionHolder;
+
+
+public class SedimentDensityFactory
+{
+    /** Private logger to use here. */
+    private static Logger log = Logger.getLogger(SedimentDensityFactory.class);
+
+    private static final String DENSITY_CACHE_NAME = "sedimentdensity";
+
+    /**Query to get sediment density values and kms. */
+    private static final String SQL_SELECT_DENSITY =
+        "SELECT sdv.station AS km, " +
+        "       sdv.density AS density," +
+        "       sdv.year AS year " +
+        "   FROM sediment_density sd" +
+        "       JOIN rivers r ON sd.river_id = r.id " +
+        "       JOIN sediment_density_values sdv ON sd.id = sdv.sediment_density_id" +
+        "   WHERE r.name = :name";
+
+    private SedimentDensityFactory() {}
+
+    public static SedimentDensity getSedimentDensity(
+        String river,
+        double startKm,
+        double endKm,
+        int year
+    ) {
+        log.debug("getSedimentDensity");
+        Cache cache = CacheFactory.getCache(DENSITY_CACHE_NAME);
+
+        if (cache == null) {
+            log.debug("Cache not configured.");
+            return getSedimentDensityUncached(river, startKm, endKm, year);
+        }
+
+        String key = river + startKm + endKm;
+        Element element = cache.get(key);
+        if (element != null) {
+            log.debug("SedimentDensity found in cache!");
+            return (SedimentDensity)element.getValue();
+        }
+        SedimentDensity value =
+            getSedimentDensityUncached(river, startKm, endKm, year);
+
+        if (value != null && key != null) {
+            log.debug("Store sediment density values in cache.");
+            element = new Element(key, value);
+            cache.put(element);
+        }
+        return value;
+    }
+
+    private static SedimentDensity getSedimentDensityUncached(
+        String river,
+        double startKm,
+        double endKm,
+        int year
+    ) {
+        log.debug("getSedimentDensityUncached");
+        List<Object[]> results = null;
+        Session session = SessionHolder.HOLDER.get();
+        SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_DENSITY)
+            .addScalar("km", StandardBasicTypes.DOUBLE)
+            .addScalar("density", StandardBasicTypes.DOUBLE)
+            .addScalar("year", StandardBasicTypes.INTEGER);
+        sqlQuery.setString("name", river);
+        results = sqlQuery.list();
+        SedimentDensity density = new SedimentDensity();
+        for (Object[] row : results) {
+            density.addDensity((Double)row[0], (Double)row[1], (Integer)row[2]);
+        }
+
+        density.cleanUp();
+        return density;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensityValue.java	Wed Nov 14 17:17:02 2012 +0100
@@ -0,0 +1,46 @@
+package de.intevation.flys.artifacts.model.minfo;
+
+
+public class SedimentDensityValue
+{
+
+    private double km;
+    private double density;
+    private int year;
+
+    public SedimentDensityValue() {
+        this.km = 0d;
+        this.density = 0d;
+        this.year = 0;
+    }
+
+    public SedimentDensityValue(double km, double density, int year) {
+        this.km = km;
+        this.density = density;
+        this.year = year;
+    }
+
+    public double getKm() {
+        return km;
+    }
+
+    public void setKm(double km) {
+        this.km = km;
+    }
+
+    public double getDensity() {
+        return density;
+    }
+
+    public void setDensity(double density) {
+        this.density = density;
+    }
+
+    public int getYear() {
+        return year;
+    }
+
+    public void setYear(int year) {
+        this.year = year;
+    }
+}

http://dive4elements.wald.intevation.org