Mercurial > dive4elements > river
view flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/DischargeTables.java @ 704:eab5e5089d77
Merged revisions 2127-2133,2136-2137,2140,2143-2144,2146,2150-2151,2153-2154 via svnmerge from
svn+ssh://teichmann@thoe/home/projects/Geospatial/bsh-generischer-viewer/Material/SVN/flys-artifacts/branches/facets-slt
........
r2127 | ingo | 2011-06-16 09:50:56 +0200 (Do, 16 Jun 2011) | 1 line
Added a compute() method to WINFOArtifact which acts as a dispatcher for different computations. It triggers a calculation based on ComputeCallbacks that are generated by the current states.
........
r2128 | ingo | 2011-06-16 10:25:06 +0200 (Do, 16 Jun 2011) | 1 line
Moved Waterlevel state into the correct package.
........
r2129 | ingo | 2011-06-16 10:43:58 +0200 (Do, 16 Jun 2011) | 1 line
Added two more compute() methods to ComputeCallback to distinguish between different phases of the artifact.
........
r2130 | ingo | 2011-06-16 10:57:05 +0200 (Do, 16 Jun 2011) | 1 line
Use enums to dispatch computeFeed() and computeAdvance().
........
r2131 | ingo | 2011-06-16 11:04:59 +0200 (Do, 16 Jun 2011) | 1 line
Store facets for each state.
........
r2132 | ingo | 2011-06-16 12:05:44 +0200 (Do, 16 Jun 2011) | 1 line
Generated facets for each output aspect.
........
r2133 | ingo | 2011-06-16 15:24:00 +0200 (Do, 16 Jun 2011) | 1 line
Write computed facets into artifacts describe document.
........
r2136 | ingo | 2011-06-16 16:10:49 +0200 (Do, 16 Jun 2011) | 1 line
Add index and description of facets to collections describe document.
........
r2137 | ingo | 2011-06-16 16:31:41 +0200 (Do, 16 Jun 2011) | 1 line
OutGenerators doOut() takes a facet object now instead of just its name.
........
r2140 | ingo | 2011-06-17 11:19:43 +0200 (Fr, 17 Jun 2011) | 1 line
OutGenerators use now facets to fetch necessary data.
........
r2143 | teichmann | 2011-06-17 12:40:54 +0200 (Fr, 17 Jun 2011) | 1 line
Removed ComputeCallback because this was thought too complicated. Fixed issue with facets not be re-generated if same state is entered again.
........
r2144 | teichmann | 2011-06-17 13:08:31 +0200 (Fr, 17 Jun 2011) | 1 line
make getGauges() more robust
........
r2146 | teichmann | 2011-06-17 13:23:57 +0200 (Fr, 17 Jun 2011) | 1 line
mico opt: inter cmps are faster than str cmps.
........
r2150 | teichmann | 2011-06-17 15:10:20 +0200 (Fr, 17 Jun 2011) | 1 line
call computeAdvance() if we want to advance.
........
r2151 | teichmann | 2011-06-17 15:45:50 +0200 (Fr, 17 Jun 2011) | 1 line
Base WST/CSV exports on facets. TODO: generate the facets.
........
r2153 | teichmann | 2011-06-17 16:03:29 +0200 (Fr, 17 Jun 2011) | 1 line
Add facet to access raw computed data.
........
r2154 | teichmann | 2011-06-17 16:37:09 +0200 (Fr, 17 Jun 2011) | 1 line
Generate data facets for the computed states.
........
flys-artifacts/trunk@2156 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 17 Jun 2011 16:17:03 +0000 |
parents | 20c3a5b36434 |
children | db68806e6563 |
line wrap: on
line source
package de.intevation.flys.artifacts.model; import java.util.List; import java.util.Map; import java.util.HashMap; import java.util.Arrays; import java.util.Comparator; import java.io.Serializable; import org.hibernate.Session; import org.hibernate.Query; import org.apache.log4j.Logger; import de.intevation.flys.backend.SessionHolder; import de.intevation.flys.model.Gauge; import de.intevation.flys.model.DischargeTable; import de.intevation.flys.model.DischargeTableValue; public class DischargeTables implements Serializable { private static Logger log = Logger.getLogger(DischargeTables.class); public static final double DEFAULT_SCALE = 100.0; public static final int MASTER = 0; protected List<String> gaugeNames; protected String riverName; protected double scale; protected int kind; protected Map<String, double [][]> values; public DischargeTables() { } public DischargeTables(String riverName, String gaugeName) { this(riverName, gaugeName, MASTER); } public DischargeTables(String riverName, String gaugeName, int kind) { this(riverName, new String [] { gaugeName }, kind); } public DischargeTables(String riverName, String [] gaugeNames) { this(riverName, gaugeNames, MASTER); } public DischargeTables(String riverName, String [] gaugeNames, int kind) { this(riverName, Arrays.asList(gaugeNames), kind); } public DischargeTables( String riverName, List<String> gaugeNames, int kind ) { scale = Double.NaN; this.kind = kind; this.riverName = riverName; this.gaugeNames = gaugeNames; } public double [][] getFirstTable() { return getFirstTable(DEFAULT_SCALE); } public double [][] getFirstTable(double scale) { Map<String, double [][]> values = getValues(scale); for (double [][] table: values.values()) { return table; } return null; } public Map<String, double [][]> getValues() { return getValues(DEFAULT_SCALE); } public Map<String, double [][]> getValues(double scale) { if (values == null || scale != this.scale) { values = loadValues(scale); this.scale = scale; } return values; } protected Map<String, double [][]> loadValues(double scale) { Map<String, double [][]> values = new HashMap<String, double [][]>(); Session session = SessionHolder.HOLDER.get(); Query gaugeQuery = session.createQuery( "from Gauge where name=:gauge and river.name=:river"); gaugeQuery.setParameter("river", riverName); for (String gaugeName: gaugeNames) { gaugeQuery.setParameter("gauge", gaugeName); List<Gauge> gauges = gaugeQuery.list(); if (gauges.isEmpty()) { log.warn( "no gauge '"+gaugeName+"' at river '"+riverName+"'"); continue; } Gauge gauge = gauges.get(0); List<DischargeTable> tables = gauge.getDischargeTables(); if (tables.isEmpty()) { log.warn( "no discharge table for gauge '" + gaugeName + "'"); continue; } // TODO: Filter by time interval DischargeTable table = tables.get(0); List<DischargeTableValue> dtvs = table.getDischargeTableValues(); final double [][] vs = new double[2][dtvs.size()]; boolean qSorted = true; double lastQ = -Double.MAX_VALUE; int idx = 0; for (DischargeTableValue dtv: dtvs) { double q = dtv.getQ().doubleValue(); vs[0][idx] = q * scale; vs[1][idx] = dtv.getW().doubleValue() * scale; ++idx; if (qSorted && lastQ > q) { qSorted = false; } lastQ = q; } if (!qSorted) { log.debug("need to sort by q values"); // TODO: Do this db level. // XXX: This is so ugly :-( Integer [] indices = new Integer[vs[0].length]; for (int i = 0; i < indices.length; ++i) { indices[i] = i; } Arrays.sort(indices, new Comparator<Integer>() { public int compare(Integer a, Integer b) { double va = vs[1][a]; double vb = vs[1][b]; double d = va - vb; if (d < 0.0) return -1; if (d > 0.0) return +1; return 0; } }); double [][] vs2 = new double[2][vs[0].length]; for (int i = 0; i < indices.length; ++i) { vs2[0][i] = vs[0][indices[i]]; vs2[1][i] = vs[1][indices[i]]; } values.put(gaugeName, vs2); } else { values.put(gaugeName, vs); } } return values; } public static double getQForW(double [][] values, double w) { boolean debug = log.isDebugEnabled(); if (debug) { log.debug("calculating getQForW(" + w + ")"); } int index = Arrays.binarySearch(values[0], w); if (index >= 0) { return values[0][index]; } index = -index - 1; // insert position if (index < 1 || index >= values[0].length) { // do not extraploate if (debug) { log.debug("we do not extrapolate: NaN"); } return Double.NaN; } double w1 = values[0][index-1]; double w2 = values[0][index ]; double q1 = values[1][index-1]; double q2 = values[1][index ]; // q1 = m*w1 + b // q2 = m*w2 + b // q2 - q1 = m*(w2 - w1) // m = (q2 - q1)/(w2 - w1) # w2 != w1 // b = q1 - m*w1 double q; if (w1 == w2) { q = 0.5*(q1 + q2); if (debug) { log.debug("same w1 and w1: " + w1); } } else { double m = (q2 - q1)/(w2 - w1); double b = q1 - m*w1; q = w*m + b; } if (debug) { log.debug("Q(" + w + ") = " + q); } return q; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :