Mercurial > dive4elements > river
diff artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadFactory.java @ 5838:5aa05a7a34b7
Rename modules to more fitting names.
author | Sascha L. Teichmann <teichmann@intevation.de> |
---|---|
date | Thu, 25 Apr 2013 15:23:37 +0200 |
parents | flys-artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadFactory.java@bd047b71ab37 |
children | 4897a58c8746 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/minfo/SedimentLoadFactory.java Thu Apr 25 15:23:37 2013 +0200 @@ -0,0 +1,383 @@ +package org.dive4elements.river.artifacts.model.minfo; + +import gnu.trove.TDoubleArrayList; + +import java.util.Calendar; +import java.util.Date; +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 org.dive4elements.river.artifacts.cache.CacheFactory; +import org.dive4elements.river.artifacts.model.StaticSedimentLoadCacheKey; +import org.dive4elements.river.backend.SessionHolder; + +/** 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 start, " + + " ti.stop_time AS end " + + " 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 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 " + + " 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 " + + " 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"; + + 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 " + + " 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 " + + " 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"; + + 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("start", 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; + + 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); + 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); + getValues("coarse", sqlQuery, load); + getValues("fine_middle", sqlQuery, load); + getValues("sand", sqlQuery, load); + getValues("suspended_sediment", sqlQuery, load); + getValues("susp_sand_bed", sqlQuery, load); + getValues("susp_sand", sqlQuery, load); + + 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); + 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); + 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); + getValues("fine_middle", sqlQuery, load); + getValues("sand", sqlQuery, load); + getValues("suspended_sediment", sqlQuery, load); + getValues("susp_sand_bed", sqlQuery, load); + getValues("susp_sand", sqlQuery, load); + 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 + ) { + 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]; + double v = -1; + if (row[2] != null) { + v = ((Double)row[2]).doubleValue(); + } + if (fraction.equals("coarse")) { + load.setCoarse(km, v); + } + else if (fraction.equals("sand")) { + load.setSand(km, v); + } + else if (fraction.equals("fine_middle")) { + load.setFineMiddle(km, v); + } + else if (fraction.equals("suspended_sediment")) { + load.setSuspSediment(km, v); + } + else if (fraction.equals("susp_sand")) { + load.setSuspSand(km, v); + } + else if (fraction.equals("susp_sand_bed")) { + load.setSuspSandBed(km, v); + } + } + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :