# HG changeset patch # User Raimund Renkert # Date 1352909822 -3600 # Node ID 71e6fe870c1dac0e00be148d679cf748401e6021 # Parent 0b330ed218f67eaef35b375295366b366e0d4265 Added objects and factory for sediment densities. diff -r 0b330ed218f6 -r 71e6fe870c1d flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensity.java --- /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> densities; + private List years; + + public SedimentDensity() { + this.densities = new HashMap>(); + this.years = new ArrayList(); + } + + public Map> getDensities() { + return densities; + } + + public void setDensities(Map> densities) { + this.densities = densities; + } + + public void addDensity(double km, double density, int year) { + logger.debug("adding " + year); + if (this.densities.containsKey(year)) { + List list = this.densities.get(year); + list.add(new SedimentDensityValue(km, density, year)); + } + else { + List list = + new ArrayList(); + 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 getYears() { + return years; + } + + public void setYears(List 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 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 keys = densities.keySet(); + for (Integer key : keys) { + List list = densities.get(key); + if (list.size() == 0) { + return; + } + List cleaned = + new ArrayList(); + 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); + } + } +} diff -r 0b330ed218f6 -r 71e6fe870c1d flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensityFactory.java --- /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 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; + } +} diff -r 0b330ed218f6 -r 71e6fe870c1d flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentDensityValue.java --- /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; + } +}