Mercurial > dive4elements > river
view artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadFactory.java @ 6510:1e6bd2831280
artifacts: Desktop-FLYS conform official line messages in error reports.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Fri, 28 Jun 2013 20:20:14 +0200 |
parents | d1502b8dd091 |
children | b24dc0320b75 |
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde * Software engineering by Intevation GmbH * * This file is Free Software under the GNU AGPL (>=v3) * and comes with ABSOLUTELY NO WARRANTY! Check out the * documentation coming with Dive4Elements River for details. */ package org.dive4elements.river.artifacts.model.minfo; import gnu.trove.TDoubleArrayList; import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.TreeMap; import net.sf.ehcache.Cache; import net.sf.ehcache.Element; import org.apache.log4j.Logger; import org.dive4elements.river.artifacts.cache.CacheFactory; import org.dive4elements.river.artifacts.model.Range; import org.dive4elements.river.artifacts.model.RiverFactory; import org.dive4elements.river.artifacts.model.StaticSedimentLoadCacheKey; import org.dive4elements.river.backend.SessionHolder; import org.dive4elements.river.model.MeasurementStation; import org.hibernate.SQLQuery; import org.hibernate.Session; import org.hibernate.type.StandardBasicTypes; /** Pull Sediment Loads out of db. */ public class SedimentLoadFactory { /** Private logger to use here. */ private static Logger log = Logger.getLogger(SedimentLoadFactory.class); public static final String LOADS_CACHE_NAME = "sedimentloads"; public static final String LOAD_DATA_CACHE_NAME = "sedimentload-data"; /** Query to get km and ws for wst_id and column_pos. */ public static final String SQL_SELECT_SINGLES = "SELECT DISTINCT " + " sy.description AS description, " + " ti.start_time AS year " + " FROM sediment_yield sy " + " JOIN rivers r ON sy.river_id = r.id " + " JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " + " JOIN time_intervals ti ON sy.time_interval_id = ti.id " + " WHERE r.name = :name " + " AND ti.stop_time IS NULL " + " AND syv.station BETWEEN :startKm AND :endKm"; /** Query to get name for wst_id and column_pos. */ public static final String SQL_SELECT_EPOCHS = "SELECT DISTINCT " + " sy.description AS description, " + " ti.start_time AS startYear, " + " ti.stop_time AS end, " + " u.name AS unit" + " FROM sediment_yield sy " + " JOIN rivers r ON sy.river_id = r.id " + " JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " + " JOIN time_intervals ti ON sy.time_interval_id = ti.id " + " JOIN units u ON u.id = sy.unit_id " + " WHERE r.name = :name " + " AND ti.stop_time IS NOT NULL " + " AND syv.station BETWEEN :startKm AND :endKm"; public static final String SQL_SELECT_SINGLES_DATA = "SELECT" + " sy.description AS description, " + " ti.start_time AS year, " + " syv.value AS load, " + " syv.station AS km, " + " u.name AS unit " + " FROM sediment_yield sy " + " JOIN rivers r ON sy.river_id = r.id " + " JOIN time_intervals ti ON sy.time_interval_id = ti.id " + " JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " + " JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id " + " JOIN units u ON u.id = sy.unit_id" + " WHERE r.name = :name " + " AND ti.start_time BETWEEN :begin AND :end " + " AND ti.stop_time IS NULL " + " AND gf.name = :grain " + " AND syv.station BETWEEN :startKm AND :endKm " + " ORDER BY syv.station"; public static final String SQL_SELECT_UNKNOWN_DATA = "SELECT" + " sy.description AS description, " + " ti.start_time AS startYear, " + " ti.stop_time AS end, " + " syv.value AS load, " + " syv.station AS km, " + " u.name AS unit " + " FROM sediment_yield sy " + " JOIN rivers r ON sy.river_id = r.id " + " JOIN time_intervals ti ON sy.time_interval_id = ti.id " + " JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " + " JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id " + " JOIN units u ON u.id = sy.unit_id" + " WHERE r.name = :name " + " AND sy.description = :descr " + " AND gf.name = 'unknown' " + " ORDER BY syv.station"; public static final String SQL_SELECT_UNKNOWN = "SELECT DISTINCT " + " sy.description AS description, " + " ti.start_time AS startYear, " + " ti.stop_time AS end " + "FROM sediment_yield sy " + " JOIN rivers r ON sy.river_id = r.id " + " JOIN time_intervals ti ON sy.time_interval_id = ti.id " + " JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id " + "WHERE r.name = :river" + " AND gf.name = 'unknown'"; public static final String SQL_SELECT_EPOCHS_DATA = "SELECT" + " sy.description AS description, " + " ti.start_time AS startYear, " + " syv.value AS load, " + " syv.station AS km," + " ti.stop_time AS endYear, " + " u.name AS unit" + " FROM sediment_yield sy " + " JOIN rivers r ON sy.river_id = r.id " + " JOIN time_intervals ti ON sy.time_interval_id = ti.id " + " JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " + " JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id " + " JOIN units u ON u.id = sy.unit_id " + " WHERE r.name = :name " + " AND ti.start_time BETWEEN :sbegin AND :send " + " AND ti.stop_time BETWEEN :ebegin AND :eend " + " AND gf.name = :grain " + " AND syv.station BETWEEN :startKm AND :endKm " + " ORDER BY syv.station"; private SedimentLoadFactory() { } /** * */ public static SedimentLoad[] getLoads( String river, String type, double startKm, double endKm ) { log.debug("SedimentLoadFactory.getLoads"); Cache cache = CacheFactory.getCache(LOADS_CACHE_NAME); if (cache == null) { log.debug("Cache not configured."); return getSedimentLoadsUncached(river, type, startKm, endKm); } StaticSedimentLoadCacheKey key = new StaticSedimentLoadCacheKey(river, startKm, endKm, 0, 0); Element element = cache.get(key); if (element != null) { log.debug("SedimentLoad found in cache"); return (SedimentLoad[])element.getValue(); } SedimentLoad[] values = getSedimentLoadsUncached(river, type, startKm, endKm); if (values != null && key != null) { log.debug("Store static sediment load values in cache."); element = new Element(key, values); cache.put(element); } return values; } public static SedimentLoad getLoadWithData( String river, String type, double startKm, double endKm, int syear, int eyear ) { log.debug("SedimentLoadFactory.getLoadWithData"); Cache cache = CacheFactory.getCache(LOAD_DATA_CACHE_NAME); if (cache == null) { log.debug("Cache not configured."); return getSedimentLoadWithDataUncached( river, type, startKm, endKm, syear, eyear); } StaticSedimentLoadCacheKey key = new StaticSedimentLoadCacheKey(river, startKm, endKm, syear, eyear); Element element = cache.get(key); if (element != null) { log.debug("SedimentLoad found in cache"); return (SedimentLoad)element.getValue(); } SedimentLoad values = getSedimentLoadWithDataUncached( river, type, startKm, endKm, syear, eyear); if (values != null && key != null) { log.debug("Store static bed height values in cache."); element = new Element(key, values); cache.put(element); } return values; } /** * Get sediment loads from db. * @param river the river * @param type the sediment load type (year or epoch) * @return according sediment loads. */ public static SedimentLoad[] getSedimentLoadsUncached( String river, String type, double startKm, double endKm ) { log.debug("SedimentLoadFactory.getSedimentLoadsUncached"); Session session = SessionHolder.HOLDER.get(); SQLQuery sqlQuery = null; if (type.equals("single")) { sqlQuery = session.createSQLQuery(SQL_SELECT_SINGLES) .addScalar("description", StandardBasicTypes.STRING) .addScalar("year", StandardBasicTypes.DATE); sqlQuery.setString("name", river); sqlQuery.setDouble("startKm", startKm); sqlQuery.setDouble("endKm", endKm); List<Object []> results = sqlQuery.list(); SedimentLoad[] loads = new SedimentLoad[results.size()]; for (int i = 0; i < results.size(); i++) { Object[] row = results.get(i); loads[i] = new SedimentLoad( (String) row[0], (Date) row[1], null, false, ""); } return loads; } else if (type.equals("epoch")) { sqlQuery = session.createSQLQuery(SQL_SELECT_EPOCHS) .addScalar("description", StandardBasicTypes.STRING) .addScalar("startYear", StandardBasicTypes.DATE) .addScalar("end", StandardBasicTypes.DATE); sqlQuery.setString("name", river); sqlQuery.setDouble("startKm", startKm); sqlQuery.setDouble("endKm", endKm); List<Object []> results = sqlQuery.list(); SedimentLoad[] loads = new SedimentLoad[results.size()]; for (int i = 0; i < results.size(); i++) { Object[] row = results.get(i); loads[i] = new SedimentLoad( (String) row[0], (Date) row[1], (Date) row[2], true, ""); } return loads; } return new SedimentLoad[0]; } /** * Get sediment loads from db. * @param river the river * @param type the sediment load type (year or epoch) * @return according sediment loads. */ public static SedimentLoad getSedimentLoadWithDataUncached( String river, String type, double startKm, double endKm, int syear, int eyear ) { log.debug("SedimentLoadFactory.getSedimentLoadWithDataUncached"); Session session = SessionHolder.HOLDER.get(); SQLQuery sqlQuery = null; List<MeasurementStation> allStations = RiverFactory.getRiver(river).getMeasurementStations(); TreeMap<Double,MeasurementStation> floatStations = new TreeMap<Double, MeasurementStation>(); TreeMap<Double,MeasurementStation> suspStations = new TreeMap<Double, MeasurementStation>(); for (MeasurementStation measurementStation: allStations) { if (measurementStation.getMeasurementType() == null || measurementStation.getRange() == null) { continue; } if (measurementStation.getMeasurementType().equals("Schwebstoff")) { suspStations.put(measurementStation.getRange().getA().doubleValue(), measurementStation); } else if (measurementStation.getMeasurementType().equals("Geschiebe")) { floatStations.put(measurementStation.getRange().getA().doubleValue(), measurementStation); } } Calendar start = Calendar.getInstance(); start.set(syear - 1, 11, 31); Calendar end = Calendar.getInstance(); end.set(syear, 11, 30); if (type.equals("year") || type.equals("epoch")) { sqlQuery = session.createSQLQuery(SQL_SELECT_SINGLES_DATA) .addScalar("description", StandardBasicTypes.STRING) .addScalar("year", StandardBasicTypes.DATE) .addScalar("load", StandardBasicTypes.DOUBLE) .addScalar("km", StandardBasicTypes.DOUBLE) .addScalar("unit", StandardBasicTypes.STRING); sqlQuery.setString("name", river); sqlQuery.setDouble("startKm", startKm); sqlQuery.setDouble("endKm", endKm); sqlQuery.setDate("begin", start.getTime()); sqlQuery.setDate("end", end.getTime()); sqlQuery.setString("grain", "total"); List<Object []> results = sqlQuery.list(); SedimentLoad load = new SedimentLoad(); Object[] row = results.get(0); load = new SedimentLoad( (String) row[0], (Date) row[1], null, false, (String) row[4]); getValues("coarse", sqlQuery, load, floatStations); getValues("fine_middle", sqlQuery, load, floatStations); getValues("sand", sqlQuery, load, floatStations); getValues("suspended_sediment", sqlQuery, load, suspStations); getValues("susp_sand_bed", sqlQuery, load, floatStations); getValues("susp_sand", sqlQuery, load, floatStations); return load; } else if (type.equals("off_epoch")) { Calendar toStart = Calendar.getInstance(); toStart.set(eyear - 1, 11, 31); Calendar toEnd = Calendar.getInstance(); toEnd.set(eyear, 11, 30); sqlQuery = session.createSQLQuery(SQL_SELECT_EPOCHS_DATA) .addScalar("description", StandardBasicTypes.STRING) .addScalar("startYear", StandardBasicTypes.DATE) .addScalar("load", StandardBasicTypes.DOUBLE) .addScalar("km", StandardBasicTypes.DOUBLE) .addScalar("endYear", StandardBasicTypes.DATE) .addScalar("unit", StandardBasicTypes.STRING); sqlQuery.setString("name", river); sqlQuery.setDouble("startKm", startKm); sqlQuery.setDouble("endKm", endKm); sqlQuery.setDate("sbegin", start.getTime()); sqlQuery.setDate("send", end.getTime()); sqlQuery.setDate("ebegin",toStart.getTime()); sqlQuery.setDate("eend", toEnd.getTime()); sqlQuery.setString("grain", "total"); List<Object[]> results = null; results = sqlQuery.list(); SedimentLoad load = new SedimentLoad(); Object[] row = results.get(0); load = new SedimentLoad( (String) row[0], (Date) row[1], (Date) row[4], true, (String)row[5]); TDoubleArrayList kms = new TDoubleArrayList(); for (int i = 0; i < results.size(); i++) { row = results.get(i); kms.add((Double)row[3]); load.setLoadTotal((Double)row[3], (Double)row[2]); } getValues("coarse", sqlQuery, load, floatStations); getValues("fine_middle", sqlQuery, load, floatStations); getValues("sand", sqlQuery, load, floatStations); getValues("suspended_sediment", sqlQuery, load, suspStations); getValues("susp_sand_bed", sqlQuery, load, floatStations); getValues("susp_sand", sqlQuery, load, floatStations); return load; } return new SedimentLoad(); } /** * Run query with grain parameter set to fraction, feed result into * load. * @param fraction value to set 'grain' parameter in query to. * @param query query in which to set 'grain' parameter and run. * @param load[out] SedimentLoad which to populate with values. */ protected static void getValues ( String fraction, SQLQuery query, SedimentLoad load, TreeMap<Double, MeasurementStation> stations ) { query.setString("grain", fraction); List<Object[]> results = query.list(); for (int i = 0; i < results.size(); i++) { Object[] row = results.get(i); double km = (Double)row[3]; MeasurementStation station = stations.get(km); MeasurementStation nextStation = null; if (stations.ceilingEntry(km + 0.1d) != null) { nextStation = stations.ceilingEntry(km + 0.1d).getValue(); } Range range = null; if (station == null) { log.warn("No measurement station for " + fraction + " km " + km); } else { if (nextStation != null) range = new Range(station.getRange().getA().doubleValue(), nextStation.getRange().getA().doubleValue()); else { // TODO end-of-river instead of B. range = new Range(station.getRange().getA().doubleValue(), station.getRange().getB().doubleValue()); } } double v = -1; if (row[2] != null) { v = ((Double)row[2]).doubleValue(); } if (fraction.equals("coarse")) { load.setCoarse(km, v, range); } else if (fraction.equals("sand")) { load.setSand(km, v, range); } else if (fraction.equals("fine_middle")) { load.setFineMiddle(km, v, range); } else if (fraction.equals("suspended_sediment")) { load.setSuspSediment(km, v, range); } else if (fraction.equals("susp_sand")) { load.setSuspSand(km, v, range); } else if (fraction.equals("susp_sand_bed")) { load.setSuspSandBed(km, v, range); } } } public static SedimentLoad getLoadUnknown( String river, String description ) { log.debug("SedimentLoadFactory.getLoadWithData"); Cache cache = CacheFactory.getCache(LOAD_DATA_CACHE_NAME); if (cache == null) { log.debug("Cache not configured."); return getSedimentLoadUnknownUncached(river, description); } StaticSedimentLoadCacheKey key = new StaticSedimentLoadCacheKey(river, 0d, 0d, 0, 0); Element element = cache.get(key); if (element != null) { log.debug("SedimentLoad found in cache"); return (SedimentLoad)element.getValue(); } SedimentLoad values = getSedimentLoadUnknownUncached(river, description); if (values != null && key != null) { log.debug("Store static bed height values in cache."); element = new Element(key, values); cache.put(element); } return values; } /** * Get sediment loads with fraction 'unknown' from db. * @param river the river * @param type the sediment load type (year or epoch) * @return according sediment loads. */ public static SedimentLoad getSedimentLoadUnknownUncached( String river, String description ) { log.debug("SedimentLoadFactory.getSedimentLoadWithDataUncached"); Session session = SessionHolder.HOLDER.get(); SQLQuery sqlQuery = null; sqlQuery = session.createSQLQuery(SQL_SELECT_UNKNOWN_DATA) .addScalar("description", StandardBasicTypes.STRING) .addScalar("startYear", StandardBasicTypes.DATE) .addScalar("end", StandardBasicTypes.DATE) .addScalar("load", StandardBasicTypes.DOUBLE) .addScalar("km", StandardBasicTypes.DOUBLE) .addScalar("unit", StandardBasicTypes.STRING); sqlQuery.setString("name", river); sqlQuery.setString("descr", description); List<Object []> results = sqlQuery.list(); SedimentLoad load = new SedimentLoad(); if (results.isEmpty()) { return new SedimentLoad(); } Object[] row = results.get(0); load = new SedimentLoad( (String) row[0], (Date) row[1], (Date) row[2], false, (String)row[5]); for (int i = 0; i < results.size(); i++) { row = results.get(i); SedimentLoadFraction fraction = new SedimentLoadFraction(); fraction.setUnknown((Double)row[3]); load.addKm((Double)row[4], fraction); } return load; } public static SedimentLoad[] getSedimentLoadUnknown(String river) { Session session = SessionHolder.HOLDER.get(); SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_UNKNOWN) .addScalar("description", StandardBasicTypes.STRING) .addScalar("startYear", StandardBasicTypes.DATE) .addScalar("end", StandardBasicTypes.DATE); sqlQuery.setString("river", river); List<Object[]> results = sqlQuery.list(); SedimentLoad[] loads = new SedimentLoad[results.size()]; int counter = 0; for (Object[] row: results) { loads[counter] = new SedimentLoad( (String)row[0], (Date)row[1], (Date)row[2], false, ""); counter++; } return loads; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :