teichmann@5863: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5863: * Software engineering by Intevation GmbH teichmann@5863: * teichmann@5994: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5863: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5994: * documentation coming with Dive4Elements River for details. teichmann@5863: */ teichmann@5863: teichmann@5831: package org.dive4elements.river.artifacts.model.sq; sascha@3289: teichmann@7698: import java.io.FileWriter; teichmann@7698: import java.io.IOException; teichmann@7698: import java.text.SimpleDateFormat; teichmann@3992: import java.util.ArrayList; teichmann@4005: import java.util.Calendar; teichmann@4005: import java.util.Collections; teichmann@4004: import java.util.Date; teichmann@4008: import java.util.HashMap; sascha@3928: import java.util.List; teichmann@4008: import java.util.Map; teichmann@4001: import java.util.TreeMap; sascha@3928: teichmann@4066: import org.apache.log4j.Logger; teichmann@4066: sascha@3289: import org.hibernate.SQLQuery; sascha@3289: import org.hibernate.Session; sascha@3289: sascha@3289: import org.hibernate.transform.BasicTransformerAdapter; sascha@3289: sascha@3289: import org.hibernate.type.StandardBasicTypes; sascha@3289: teichmann@5831: import org.dive4elements.river.artifacts.model.DateRange; teichmann@4008: teichmann@5831: import org.dive4elements.river.backend.SedDBSessionHolder; andre@8684: import org.dive4elements.river.artifacts.model.RiverFactory; teichmann@4008: teichmann@7698: import au.com.bytecode.opencsv.CSVWriter; teichmann@7698: sascha@3289: public class MeasurementFactory sascha@3289: { teichmann@4066: private static final Logger log = teichmann@4066: Logger.getLogger(MeasurementFactory.class); teichmann@4066: tom@8856: public static final String MINFO_DUMP_SQ_SEDDB_PREFIX = tom@8856: "minfo.dump.sq.seddb.prefix"; teichmann@7698: teichmann@4008: public static final String SQL_TOTALS = teichmann@4008: "SELECT " + teichmann@4008: "m.Q_BPEGEL AS Q_BPEGEL,"+ teichmann@4008: "m.TSCHWEB AS TSCHWEB," + andre@8539: "m.TSAND AS TSAND, " + andre@8539: "m.DATUM AS DATUM " + teichmann@4008: "FROM MESSUNG m " + teichmann@4008: "JOIN STATION s ON m.STATIONID = s.STATIONID " + teichmann@4008: "JOIN GEWAESSER r ON s.GEWAESSERID = r.GEWAESSERID " + teichmann@4008: "WHERE " + teichmann@4008: "r.NAME = :river_name " + teichmann@4008: "AND m.Q_BPEGEL IS NOT NULL " + teichmann@4008: "AND s.KM BETWEEN :location - 0.001 AND :location + 0.001 " + teichmann@4008: "AND m.DATUM BETWEEN :from AND :to " + teichmann@4008: "AND m.DATUM IS NOT NULL"; sascha@3289: teichmann@4007: public static final String SQL_FACTIONS = teichmann@4008: "SELECT " + teichmann@4008: "m.datum AS DATUM," + teichmann@4008: "m.Q_BPEGEL AS Q_BPEGEL,"+ teichmann@4007: "g.GLOTRECHTEID AS GLOTRECHTEID," + teichmann@4007: "gp.LFDNR AS LFDNR," + teichmann@4007: "g.UFERABST AS UFERABST," + teichmann@4007: "g.UFERABLINKS AS UFERABLINKS," + aheinecke@6955: "COALESCE(m.TSCHWEB, 0) AS TSCHWEB," + aheinecke@6955: "COALESCE(m.TSAND, 0) AS TSAND," + aheinecke@6955: "COALESCE(gp.GTRIEB_F, 0) AS GTRIEB," + aheinecke@6955: "COALESCE(m.TGESCHIEBE, 0) AS TGESCHIEBE," + teichmann@7709: "si.SIEB01 AS SIEB01, si.SIEB02 AS SIEB02," + teichmann@7709: "si.SIEB03 AS SIEB03, si.SIEB04 AS SIEB04," + teichmann@7709: "si.SIEB05 AS SIEB05, si.SIEB06 AS SIEB06," + teichmann@7709: "si.SIEB07 AS SIEB07, si.SIEB08 AS SIEB08," + teichmann@7709: "si.SIEB09 AS SIEB09, si.SIEB10 AS SIEB10," + teichmann@7709: "si.SIEB11 AS SIEB11, si.SIEB12 AS SIEB12," + teichmann@7709: "si.SIEB13 AS SIEB13, si.SIEB14 AS SIEB14," + teichmann@7709: "si.SIEB15 AS SIEB15, si.SIEB16 AS SIEB16," + teichmann@7709: "si.SIEB17 AS SIEB17, si.SIEB18 AS SIEB18," + teichmann@7709: "si.SIEB19 AS SIEB19, si.SIEB20 AS SIEB20," + teichmann@7709: "si.SIEB21 AS SIEB21," + teichmann@7709: "gs.RSIEB01 AS RSIEB01, gs.RSIEB02 AS RSIEB02," + teichmann@7709: "gs.RSIEB03 AS RSIEB03, gs.RSIEB04 AS RSIEB04," + teichmann@7709: "gs.RSIEB05 AS RSIEB05, gs.RSIEB06 AS RSIEB06," + teichmann@7709: "gs.RSIEB07 AS RSIEB07, gs.RSIEB08 AS RSIEB08," + teichmann@7709: "gs.RSIEB09 AS RSIEB09, gs.RSIEB10 AS RSIEB10," + teichmann@7709: "gs.RSIEB11 AS RSIEB11, gs.RSIEB12 AS RSIEB12," + teichmann@7709: "gs.RSIEB13 AS RSIEB13, gs.RSIEB14 AS RSIEB14," + teichmann@7709: "gs.RSIEB15 AS RSIEB15, gs.RSIEB16 AS RSIEB16," + teichmann@7709: "gs.RSIEB17 AS RSIEB17, gs.RSIEB18 AS RSIEB18," + teichmann@7709: "gs.RSIEB19 AS RSIEB19, gs.RSIEB20 AS RSIEB20," + teichmann@7709: "gs.RSIEB21 AS RSIEB21, gs.REST AS REST " + sascha@3928: "FROM MESSUNG m " + sascha@3928: "JOIN STATION s ON m.STATIONID = s.STATIONID " + teichmann@4008: "JOIN GEWAESSER r ON s.GEWAESSERID = r.GEWAESSERID " + teichmann@4009: "JOIN GLOTRECHTE g ON m.MESSUNGID = g.MESSUNGID " + teichmann@4009: "JOIN GPROBE gp ON g.GLOTRECHTEID = gp.GLOTRECHTEID " + sascha@3928: "JOIN GSIEBUNG gs ON g.GLOTRECHTEID = gs.GLOTRECHTEID " + teichmann@4009: "JOIN GSIEBSATZ si ON m.GSIEBSATZID = si.GSIEBSATZID " + sascha@3310: "WHERE " + teichmann@4008: "r.NAME = :river_name " + sascha@3396: "AND m.Q_BPEGEL IS NOT NULL " + sascha@3928: "AND s.KM BETWEEN :location - 0.001 AND :location + 0.001 " + sascha@3928: "AND m.DATUM BETWEEN :from AND :to " + sascha@3928: "AND m.TGESCHIEBE IS NOT NULL " + teichmann@4004: "AND m.DATUM IS NOT NULL " + teichmann@3981: "AND (" + teichmann@3981: "COALESCE(gs.RSIEB01, 0) + COALESCE(gs.RSIEB02, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB03, 0) + COALESCE(gs.RSIEB04, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB05, 0) + COALESCE(gs.RSIEB06, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB07, 0) + COALESCE(gs.RSIEB08, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB09, 0) + COALESCE(gs.RSIEB10, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB11, 0) + COALESCE(gs.RSIEB12, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB13, 0) + COALESCE(gs.RSIEB14, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB15, 0) + COALESCE(gs.RSIEB16, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB17, 0) + COALESCE(gs.RSIEB18, 0) +" + teichmann@3981: "COALESCE(gs.RSIEB19, 0) + COALESCE(gs.RSIEB20, 0) +" + teichmann@7704: "COALESCE(gs.RSIEB21, 0) + COALESCE(gs.REST, 0)) > 0 " + teichmann@4008: "ORDER BY " + teichmann@4008: "m.DATUM, g.UFERABST, g.GLOTRECHTEID, gp.LFDNR"; teichmann@4008: teichmann@4007: private static final int index(String s) { teichmann@4007: return Integer.parseInt(s.substring(s.length()-2))-1; teichmann@4007: } teichmann@3992: tom@8856: public abstract static class CSVTransformer tom@8856: extends BasicTransformerAdapter tom@8856: { teichmann@7698: private static final long serialVersionUID = 1L; teichmann@4007: teichmann@7698: private CSVWriter rawWriter; teichmann@7698: private boolean metaDataWritten; teichmann@4007: teichmann@7698: public CSVTransformer() { teichmann@7698: this(null); teichmann@7698: } teichmann@7698: teichmann@7698: public CSVTransformer(CSVWriter rawWriter) { teichmann@7698: this.rawWriter = rawWriter; teichmann@7698: } teichmann@7698: teichmann@7698: protected void writeRaw(Object [] tuple, String [] aliases) { teichmann@7698: if (rawWriter == null) { teichmann@7698: return; teichmann@7698: } teichmann@7698: teichmann@7698: if (!metaDataWritten) { teichmann@7698: rawWriter.writeNext(aliases); teichmann@7698: metaDataWritten = true; teichmann@7698: } teichmann@7698: teichmann@7698: String [] nextLine = new String[tuple.length]; teichmann@7698: for (int i = 0; i < tuple.length; ++i) { teichmann@7698: nextLine[i] = tuple[i] != null ? tuple[i].toString() : ""; teichmann@7698: } teichmann@7698: rawWriter.writeNext(nextLine); teichmann@7698: } teichmann@7704: } // class CSVTransformer teichmann@7698: teichmann@7698: public static class FractionsTransformer extends CSVTransformer { teichmann@7698: teichmann@7698: private static final long serialVersionUID = 1L; teichmann@7698: teichmann@7698: public FractionsTransformer() { teichmann@7698: this(null); teichmann@7698: } teichmann@7698: teichmann@7698: public FractionsTransformer(CSVWriter rawWriter) { teichmann@7698: super(rawWriter); teichmann@7698: } teichmann@7698: teichmann@7698: @Override teichmann@7698: public Object transformTuple(Object [] tuple, String [] aliases) { teichmann@7698: teichmann@7698: writeRaw(tuple, aliases); teichmann@7698: teichmann@7698: Map map = new HashMap(); teichmann@7698: teichmann@7698: Sieve [] sieves = new Sieve[21]; teichmann@7698: teichmann@7698: List validSieves = new ArrayList(21); teichmann@7698: teichmann@7698: for (int i = 0; i < tuple.length; ++i) { teichmann@7698: Object value = tuple[i]; teichmann@7698: if (value == null) { teichmann@7698: continue; teichmann@7698: } teichmann@7698: String alias = aliases[i]; teichmann@7698: if (alias.startsWith("SIEB") teichmann@7698: || alias.startsWith("RSIEB")) { teichmann@7698: int idx = index(alias); teichmann@7698: Sieve s = sieves[idx]; teichmann@7698: double v = (Double)value; teichmann@7698: if (s == null) { teichmann@7698: s = new Sieve(); teichmann@7698: sieves[idx] = s; teichmann@4007: } teichmann@7698: if (alias.startsWith("SIEB")) { teichmann@7698: s.setDiameter(v); teichmann@3992: } teichmann@4007: else { teichmann@7698: s.setLoad(v); rrenkert@4789: } rrenkert@4789: } teichmann@7698: else if (alias.equals("REST")) { teichmann@7698: Sieve s = new Sieve(0d, (Double)value); teichmann@7698: validSieves.add(s); teichmann@7698: } teichmann@7698: else { teichmann@7698: map.put(alias, value); teichmann@7698: } teichmann@7698: sascha@3289: } teichmann@7698: for (Sieve s: sieves) { teichmann@7710: if (s != null && s.isValid()) { teichmann@7698: validSieves.add(s); teichmann@7698: } teichmann@7698: } teichmann@7698: return new Measurement(map, validSieves); teichmann@7698: } teichmann@7698: } // class FractionsTransformer teichmann@7698: teichmann@7698: public static class TotalsTransformer extends CSVTransformer { teichmann@7698: teichmann@7698: private static final long serialVersionUID = 1L; teichmann@7698: teichmann@7698: public TotalsTransformer() { teichmann@7698: this(null); teichmann@7698: } teichmann@7698: teichmann@7698: public TotalsTransformer(CSVWriter rawWriter) { teichmann@7698: super(rawWriter); teichmann@7698: } teichmann@7698: teichmann@7698: @Override teichmann@7698: public Object transformTuple(Object [] tuple, String [] aliases) { teichmann@7698: teichmann@7698: writeRaw(tuple, aliases); teichmann@7698: teichmann@7698: Map map = new HashMap(); teichmann@7698: for (int i = 0; i < tuple.length; ++i) { teichmann@7698: Object value = tuple[i]; teichmann@7698: if (value != null) { teichmann@7698: map.put(aliases[i], value); teichmann@7698: } teichmann@7698: } teichmann@7698: return new Measurement(map, Collections.emptyList()); teichmann@7698: } teichmann@7698: } // class TotalsTransformer sascha@3289: sascha@3289: private MeasurementFactory() { sascha@3289: } sascha@3289: teichmann@4008: public static Measurements getMeasurements( teichmann@6780: String river, teichmann@6780: double location, teichmann@6780: DateRange dateRange, teichmann@6780: SQ.Factory sqFactory teichmann@4008: ) { teichmann@4008: Session session = SedDBSessionHolder.HOLDER.get(); andre@8684: String seddbRiver = RiverFactory.getRiver(river).nameForSeddb(); andre@8684: andre@8566: List totals = loadTotals( andre@8684: session, seddbRiver, location, dateRange); teichmann@4008: andre@8566: List accumulated = loadFractions( andre@8684: session, seddbRiver, location, dateRange); teichmann@4008: andre@8566: return new Measurements(totals, accumulated, sqFactory); teichmann@4008: } teichmann@4008: teichmann@7698: @SuppressWarnings("unchecked") teichmann@4008: protected static List loadTotals( sascha@3289: Session session, sascha@3289: String river, sascha@3289: double location, sascha@3289: DateRange dateRange sascha@3289: ) { teichmann@4008: SQLQuery query = session.createSQLQuery(SQL_TOTALS) teichmann@4008: .addScalar("Q_BPEGEL", StandardBasicTypes.DOUBLE) teichmann@4008: .addScalar("TSCHWEB", StandardBasicTypes.DOUBLE) andre@8539: .addScalar("TSAND", StandardBasicTypes.DOUBLE) andre@8539: .addScalar("DATUM", StandardBasicTypes.DATE); sascha@3308: teichmann@4008: query.setString("river_name", river); teichmann@4008: query.setDouble("location", location); teichmann@4008: query.setDate("from", dateRange.getFrom()); teichmann@4008: query.setDate("to", dateRange.getTo()); sascha@3308: teichmann@7698: CSVWriter csvWriter = teichmann@7698: getCVSWriter("totals", river, location, dateRange); teichmann@4008: teichmann@7698: try { tom@8856: TotalsTransformer totalTransformer = tom@8856: new TotalsTransformer(csvWriter); teichmann@7698: query.setResultTransformer(totalTransformer); teichmann@7698: teichmann@7698: return (List)query.list(); teichmann@7698: } teichmann@7698: finally { teichmann@7698: closeGraceful(csvWriter); teichmann@7698: } teichmann@4008: } teichmann@4008: teichmann@7698: private static CSVWriter getCVSWriter( teichmann@7698: String type, teichmann@7698: String river, teichmann@7698: double location, teichmann@7698: DateRange dateRange teichmann@7698: ) { teichmann@7698: String dumpPrefix = System.getProperty(MINFO_DUMP_SQ_SEDDB_PREFIX); teichmann@7698: if (dumpPrefix == null) { teichmann@7698: return null; teichmann@7698: } teichmann@7698: teichmann@7698: SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-ddd"); teichmann@7698: StringBuilder sb = new StringBuilder(dumpPrefix); teichmann@7698: Date from = dateRange.getFrom(); teichmann@7698: Date to = dateRange.getTo(); teichmann@7698: teichmann@7698: sb.append(type) teichmann@7698: .append('-').append(df.format(new Date())) teichmann@7698: .append('-').append(river) teichmann@7698: .append('-').append(location) teichmann@7698: .append('-').append(from != null ? df.format(from) : "") teichmann@7698: .append('-').append(to != null ? df.format(to) : "") teichmann@7698: .append(".csv"); teichmann@7698: teichmann@7698: String fileName = sb.toString(); teichmann@7698: teichmann@7698: try { teichmann@7698: return new CSVWriter(new FileWriter(fileName), ';'); teichmann@7698: } teichmann@7698: catch (IOException ioe) { teichmann@7698: log.error("Cannot open '" + fileName + "' for writing.", ioe); teichmann@7698: } teichmann@7698: teichmann@7698: return null; teichmann@7698: } teichmann@7698: teichmann@7698: private static void closeGraceful(CSVWriter writer) { teichmann@7698: if (writer != null) { teichmann@7698: try { teichmann@7698: writer.flush(); teichmann@7698: writer.close(); teichmann@7698: } teichmann@7698: catch (IOException ioe) { teichmann@7698: log.error(ioe); teichmann@7698: } teichmann@7698: } teichmann@7698: } teichmann@7698: teichmann@7698: @SuppressWarnings("unchecked") teichmann@4008: protected static List loadFractions( teichmann@4008: Session session, teichmann@4008: String river, teichmann@4008: double location, teichmann@4008: DateRange dateRange teichmann@4008: ) { teichmann@4066: boolean debug = log.isDebugEnabled(); teichmann@4066: teichmann@4007: SQLQuery query = session.createSQLQuery(SQL_FACTIONS) sascha@3928: .addScalar("Q_BPEGEL", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("DATUM", StandardBasicTypes.DATE) teichmann@3981: .addScalar("GLOTRECHTEID", StandardBasicTypes.INTEGER) teichmann@3981: .addScalar("LFDNR", StandardBasicTypes.INTEGER) sascha@3928: .addScalar("UFERABST", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("UFERABLINKS", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("TSCHWEB", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("TSAND", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("GTRIEB", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("TGESCHIEBE", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB01", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB02", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB03", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB04", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB05", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB06", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB07", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB08", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB09", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB10", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB11", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB12", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB13", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB14", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB15", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB16", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB17", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB18", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB19", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB20", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("RSIEB21", StandardBasicTypes.DOUBLE) sascha@3928: .addScalar("REST", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB01", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB02", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB03", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB04", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB05", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB06", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB07", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB08", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB09", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB10", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB11", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB12", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB13", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB14", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB15", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB16", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB17", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB18", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB19", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB20", StandardBasicTypes.DOUBLE) teichmann@3981: .addScalar("SIEB21", StandardBasicTypes.DOUBLE); sascha@3292: sascha@3289: query.setString("river_name", river); sascha@3289: query.setDouble("location", location); sascha@3289: query.setDate("from", dateRange.getFrom()); sascha@3289: query.setDate("to", dateRange.getTo()); sascha@3289: teichmann@7698: List measuments; sascha@3289: teichmann@7698: CSVWriter csvWriter = teichmann@7698: getCVSWriter("fractions", river, location, dateRange); teichmann@7698: teichmann@7698: try { teichmann@7698: FractionsTransformer fractionsTransformer = teichmann@7698: new FractionsTransformer(csvWriter); teichmann@7698: teichmann@7698: query.setResultTransformer(fractionsTransformer); teichmann@7698: teichmann@7698: measuments = (List)query.list(); teichmann@7698: } teichmann@7698: finally { teichmann@7698: closeGraceful(csvWriter); teichmann@7698: } sascha@3928: teichmann@4066: if (debug) { teichmann@4066: log.debug("num fraction results: " + measuments.size()); teichmann@4066: } teichmann@4066: teichmann@4001: List same = new ArrayList(); teichmann@4001: teichmann@3981: Integer lastLR = null; teichmann@3981: teichmann@4001: List accumulated = new ArrayList(); teichmann@4001: teichmann@4001: for (Measurement m: measuments) { teichmann@3981: Integer currentLR = (Integer)m.getData("GLOTRECHTEID"); teichmann@3981: teichmann@3981: boolean newDS = lastLR == null teichmann@3981: || (currentLR != null && !lastLR.equals(currentLR)); teichmann@3981: teichmann@4001: if (newDS && !same.isEmpty()) { teichmann@4001: accumulated.add(accumulate(same)); teichmann@4001: same.clear(); teichmann@3981: } teichmann@3981: teichmann@4066: same.add(m); teichmann@4066: teichmann@3981: lastLR = currentLR; sascha@3928: } sascha@3928: teichmann@4001: if (!same.isEmpty()) { teichmann@4001: accumulated.add(accumulate(same)); teichmann@4001: } teichmann@4001: teichmann@4066: if (debug) { teichmann@4066: log.debug("Before date separation: " + accumulated.size()); teichmann@4066: } teichmann@4066: teichmann@4066: accumulated = separateByDate(accumulated); teichmann@4066: teichmann@4066: if (debug) { teichmann@4066: log.debug("After date separation: " + accumulated.size()); teichmann@4066: } teichmann@4066: teichmann@4066: return accumulated; teichmann@4001: } teichmann@4001: tom@8856: protected static List separateByDate( tom@8856: List measurements tom@8856: ) { teichmann@4004: List result = new ArrayList(); teichmann@4004: teichmann@4004: List same = new ArrayList(); teichmann@4004: teichmann@4004: Date lastDate = null; teichmann@4004: teichmann@4004: for (Measurement m: measurements) { teichmann@4004: Date currentDate = (Date)m.getData("DATUM"); teichmann@4004: if ((lastDate == null teichmann@4004: || !equalDate(currentDate, lastDate)) teichmann@4004: && !same.isEmpty() teichmann@4004: ) { teichmann@4004: result.add(processSameDate(same)); teichmann@4004: same.clear(); teichmann@4004: } teichmann@4004: same.add(m); teichmann@4004: lastDate = currentDate; teichmann@4004: } teichmann@4004: teichmann@4004: if (!same.isEmpty()) { teichmann@4004: result.add(processSameDate(same)); teichmann@4004: } teichmann@4004: teichmann@4004: return result; teichmann@4004: } teichmann@4004: teichmann@4005: tom@8856: protected static Measurement processSameDate( tom@8856: List measurements tom@8856: ) { teichmann@4004: int N = measurements.size(); teichmann@4842: teichmann@4842: boolean debug = log.isDebugEnabled(); teichmann@4842: if (debug && N > 0) { rrenkert@4837: log.debug("process same date for Q: " + measurements.get(0).Q()); rrenkert@4837: } teichmann@4004: if (N == 1) { teichmann@4004: Measurement current = measurements.get(0); teichmann@4004: double left = current.get("UFERABLINKS"); teichmann@4004: double right = current.get("UFERABST"); teichmann@4004: current.set("EFFWIDTH", left + right); teichmann@4004: } teichmann@4004: else { teichmann@4004: for (int i = 0; i < N; ++i) { teichmann@4004: Measurement current = measurements.get(i); teichmann@4004: teichmann@4004: if (i == 0) { teichmann@4004: Measurement next = measurements.get(i+1); teichmann@4004: double distCurrent = current.get("UFERABST"); teichmann@4004: double distNext = next.get("UFERABST"); teichmann@4004: current.set("EFFWIDTH", distNext - distCurrent); teichmann@4004: } teichmann@4004: else if (i == N-1) { teichmann@4004: Measurement prev = measurements.get(i-1); teichmann@4004: double distCurrent = current.get("UFERABST"); teichmann@4004: double distPrev = prev.get("UFERABST"); teichmann@4004: current.set("EFFWIDTH", distCurrent - distPrev); teichmann@4004: } teichmann@4004: else { teichmann@4004: Measurement prev = measurements.get(i-1); teichmann@4004: Measurement next = measurements.get(i+1); teichmann@4004: double distPrev = prev.get("UFERABST"); teichmann@4004: double distNext = next.get("UFERABST"); teichmann@4004: current.set("EFFWIDTH", 0.5*(distNext - distPrev)); teichmann@4004: } teichmann@4842: if (debug) { teichmann@4842: log.debug("effective width: " + current.get("EFFWIDTH")); teichmann@4842: } teichmann@4004: } teichmann@4004: } teichmann@4004: teichmann@4005: double sumSandF = 0d; teichmann@4005: double sumCoarseF = 0d; teichmann@4005: double sumGravelF = 0d; teichmann@4005: double sumNorm = 0d; teichmann@4005: teichmann@4005: for (Measurement m: measurements) { teichmann@4005: SieveArray sa = m.getSieveArray(); rrenkert@4837: if (sa.totalLoad() < SieveArray.EPSILON) { rrenkert@4837: continue; rrenkert@4837: } teichmann@4005: double sandF = sa.sandNormFraction(); teichmann@4005: double coarseF = sa.coarseNormFraction(); teichmann@4005: double gravelF = sa.gravelNormFraction(); teichmann@4005: double effWidth = m.get("EFFWIDTH"); teichmann@4005: double gt = m.get("GTRIEB"); teichmann@4005: double scale = effWidth*gt; teichmann@4005: sumSandF += scale*sandF; teichmann@4005: sumCoarseF += scale*coarseF; teichmann@4005: sumGravelF += scale*gravelF; teichmann@4005: sumNorm += scale; teichmann@4842: if (debug) { teichmann@4842: log.debug("fractions - s: " + teichmann@4842: sandF + " c: " + teichmann@5282: coarseF + " g: " + teichmann@4842: gravelF); teichmann@4842: log.debug("scale: " + scale + " = " + effWidth + " * " + gt); teichmann@4842: } teichmann@4005: } teichmann@4005: teichmann@4005: Map data = teichmann@4005: new HashMap(measurements.get(0).getData()); teichmann@4005: teichmann@4005: Measurement m = new Measurement(data, Collections.emptyList()); teichmann@4005: teichmann@4005: sumNorm = 1d/sumNorm; teichmann@4005: teichmann@4005: m.set("BL_S", sumNorm*sumSandF); teichmann@4005: m.set("BL_G", sumNorm*sumGravelF); teichmann@4005: m.set("BL_C", sumNorm*sumCoarseF); teichmann@4842: if (debug) { teichmann@4842: log.debug( teichmann@4842: "BL_S: " + m.get("BL_S") + teichmann@5282: " BL_G: " + m.get("BL_G") + teichmann@4842: " BL_C: " + m.get("BL_C")); teichmann@4842: } teichmann@4005: return m; teichmann@4004: } teichmann@4004: teichmann@4004: teichmann@4004: private static final boolean equalDate(Date a, Date b) { teichmann@4005: Calendar ca = Calendar.getInstance(); teichmann@4005: Calendar cb = Calendar.getInstance(); teichmann@4005: ca.setTime(a); teichmann@4005: cb.setTime(b); teichmann@4006: return ca.get(Calendar.YEAR) == cb.get(Calendar.YEAR) teichmann@4006: && ca.get(Calendar.MONTH) == cb.get(Calendar.MONTH) teichmann@4005: && ca.get(Calendar.DAY_OF_MONTH) == cb.get(Calendar.DAY_OF_MONTH); teichmann@4004: } teichmann@4004: teichmann@4004: teichmann@4001: protected static Measurement accumulate(List measuments) { teichmann@4001: teichmann@4001: int N = measuments.size(); teichmann@4001: if (N == 1) { teichmann@4001: return measuments.get(0); teichmann@4001: } teichmann@4001: TreeMap diameters = teichmann@4001: new TreeMap(Sieve.DIAMETER_CMP); teichmann@4001: rrenkert@4813: double sumGTrieb = 0d; teichmann@4001: for (Measurement m: measuments) { teichmann@4001: for (Sieve s: m.getSieves()) { teichmann@4001: Double key = s.getDiameter(); teichmann@4001: double [] sum = diameters.get(key); teichmann@4001: if (sum == null) { teichmann@4001: sum = new double[1]; teichmann@4001: diameters.put(key, sum); teichmann@4001: } teichmann@4001: sum[0] += s.getLoad(); teichmann@4001: } rrenkert@4813: // calculate 'Geschiebetrieb' rrenkert@4813: sumGTrieb += m.get("GTRIEB"); teichmann@4001: } teichmann@4001: List accumulatedSieves = new ArrayList(diameters.size()); teichmann@4001: for (Map.Entry entry: diameters.entrySet()) { teichmann@4001: accumulatedSieves.add( teichmann@4001: new Sieve(entry.getKey(), teichmann@4001: entry.getValue()[0]/N)); teichmann@4001: } teichmann@4001: Map data = teichmann@4001: new HashMap(measuments.get(0).getData()); teichmann@4001: rrenkert@4813: data.put("GTRIEB", sumGTrieb/N); rrenkert@4837: teichmann@4001: return new Measurement(data, accumulatedSieves); sascha@3289: } sascha@3289: } sascha@3289: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :