comparison flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/SedimentLoadFactory.java @ 4296:3051bc28ac43

Added data object and factory for sediment load calculation. The factory provides two methods to get sediment load data: The first is to get an array of loads for a specific range at a river, these loads contain the time and description. The second is to get a single sediment load with time, description and data values.
author Raimund Renkert <rrenkert@intevation.de>
date Mon, 29 Oct 2012 12:14:50 +0100
parents
children 6a65e7ef43c0
comparison
equal deleted inserted replaced
4295:2a64d42a75e6 4296:3051bc28ac43
1 package de.intevation.flys.artifacts.model.minfo;
2
3 import gnu.trove.TDoubleArrayList;
4
5 import java.util.Calendar;
6 import java.util.Date;
7 import java.util.List;
8
9 import net.sf.ehcache.Cache;
10 import net.sf.ehcache.Element;
11
12 import org.apache.log4j.Logger;
13 import org.hibernate.SQLQuery;
14 import org.hibernate.Session;
15 import org.hibernate.type.StandardBasicTypes;
16
17 import de.intevation.flys.artifacts.cache.CacheFactory;
18 import de.intevation.flys.artifacts.model.StaticSedimentLoadCacheKey;
19 import de.intevation.flys.backend.SessionHolder;
20
21
22 public class SedimentLoadFactory
23 {
24 /** Private logger to use here. */
25 private static Logger log = Logger.getLogger(SedimentLoadFactory.class);
26
27 public static final String LOADS_CACHE_NAME = "sedimentloads";
28 public static final String LOAD_DATA_CACHE_NAME = "sedimentload-data";
29
30 /** Query to get km and ws for wst_id and column_pos. */
31 public static final String SQL_SELECT_SINGLES =
32 "SELECT DISTINCT " +
33 " sy.description AS description, " +
34 " ti.start_time AS year " +
35 " FROM sediment_yield sy " +
36 " JOIN rivers r ON sy.river_id = r.id " +
37 " JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " +
38 " JOIN time_intervals ti ON sy.time_interval_id = ti.id " +
39 " WHERE r.name = :name " +
40 " AND ti.stop_time IS NULL " +
41 " AND syv.station BETWEEN :startKm AND :endKm";
42
43 /** Query to get name for wst_id and column_pos. */
44 public static final String SQL_SELECT_EPOCHS =
45 "SELECT DISTINCT " +
46 " sy.description AS description, " +
47 " ti.start_time AS start, " +
48 " ti.stop_time AS end " +
49 " FROM sediment_yield sy " +
50 " JOIN rivers r ON sy.river_id = r.id " +
51 " JOIN sediment_yield_values syv ON sy.id = syv.sediment_yield_id " +
52 " JOIN time_intervals ti ON sy.time_interval_id = ti.id " +
53 " WHERE r.name = :name " +
54 " AND ti.stop_time IS NOT NULL " +
55 " AND syv.station BETWEEN :startKm AND :endKm";
56
57 public static final String SQL_SELECT_SINGLES_DATA =
58 "SELECT" +
59 " sy.description AS description, " +
60 " ti.start_time AS year, " +
61 " syv.value AS load " +
62 " FROM sediment_yield sy " +
63 " JOIN rivers r ON sy.river_id = r.id " +
64 " JOIN time_intervals ti ON sy.time_interval_id = ti.id " +
65 " JOIN sediment_yield_vales syv ON sy.id = syv.sediment_yield_id " +
66 " JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id " +
67 " WHERE r.name = :name " +
68 " AND ti.start_time BETWEEN :begin AND :end " +
69 " AND ti_stop_time IS NULL " +
70 " AND gf.name = :grain " +
71 " AND syv.station BETWEEN :startKm AND :endKm";
72
73 public static final String SQL_SELECT_EPOCHS_DATA =
74 "SELECT" +
75 " sy.description AS description," +
76 " ti.start_time AS year," +
77 " syv.value AS load" +
78 " FROM sediment_yield sy" +
79 " JOIN rivers r ON sy.river_id = r.id " +
80 " JOIN time_intervals ti ON sy.time_interval_id = ti.id" +
81 " JOIN sediment_yield_vales syv ON sy.id = syv.sediment_yield_id" +
82 " JOIN grain_fraction gf ON sy.grain_fraction_id = gf.id" +
83 " WHERE r.name = :name" +
84 " AND ti.start_time BETWEEN :sbegin AND :send" +
85 " AND ti_stop_time IS NOT NULL" +
86 " AND ti_stop_time BETWEEN :ebegin AND :eend" +
87 " AND gf.name = :grain " +
88 " AND syv.station BETWEEN :startKm AND :endKm";
89
90 private SedimentLoadFactory() {
91 }
92
93 /**
94 *
95 */
96 public static SedimentLoad[] getLoads(
97 String river,
98 String type,
99 double startKm,
100 double endKm
101 ) {
102 log.debug("SedimentLoadFactory.getLoads");
103 Cache cache = CacheFactory.getCache(LOADS_CACHE_NAME);
104
105 if (cache == null) {
106 log.debug("Cache not configured.");
107 return getSedimentLoadsUncached(river, type, startKm, endKm);
108 }
109
110 StaticSedimentLoadCacheKey key =
111 new StaticSedimentLoadCacheKey(river, startKm, endKm, null);
112
113 Element element = cache.get(key);
114
115 if (element != null) {
116 log.debug("SedimentLoad found in cache");
117 return (SedimentLoad[])element.getValue();
118 }
119
120 SedimentLoad[] values =
121 getSedimentLoadsUncached(river, type, startKm, endKm);
122
123 if (values != null && key != null) {
124 log.debug("Store static sediment loads values in cache.");
125 element = new Element(key, values);
126 cache.put(element);
127 }
128 return values;
129 }
130
131 public static SedimentLoad getLoadwithData(
132 String river,
133 String type,
134 double startKm,
135 double endKm,
136 Date startDate,
137 Date endDate
138 ) {
139 log.debug("SedimentLoadFactory.getLoadWithData");
140 Cache cache = CacheFactory.getCache(LOAD_DATA_CACHE_NAME);
141
142 if (cache == null) {
143 log.debug("Cache not configured.");
144 return getSedimentLoadWithDataUncached(
145 river,
146 type,
147 startKm,
148 endKm,
149 startDate,
150 endDate);
151 }
152
153 StaticSedimentLoadCacheKey key =
154 new StaticSedimentLoadCacheKey(river, startKm, endKm, startDate);
155
156 Element element = cache.get(key);
157
158 if (element != null) {
159 log.debug("SedimentLoad found in cache");
160 return (SedimentLoad)element.getValue();
161 }
162
163 SedimentLoad values =
164 getSedimentLoadWithDataUncached(river, type, startKm, endKm, startDate, endDate);
165
166 if (values != null && key != null) {
167 log.debug("Store static bed height values in cache.");
168 element = new Element(key, values);
169 cache.put(element);
170 }
171 return values;
172 }
173
174 /**
175 * Get sediment loads from db.
176 * @param river the river
177 * @param type the sediment load type (year or epoch)
178 * @return according sediment loads.
179 */
180 public static SedimentLoad[] getSedimentLoadsUncached(
181 String river,
182 String type,
183 double startKm,
184 double endKm
185 ) {
186 log.debug("SedimentLoadFactory.getSedimentLoadsUncached");
187
188 Session session = SessionHolder.HOLDER.get();
189 SQLQuery sqlQuery = null;
190
191
192 if (type.equals("single")) {
193 sqlQuery = session.createSQLQuery(SQL_SELECT_SINGLES)
194 .addScalar("description", StandardBasicTypes.STRING)
195 .addScalar("year", StandardBasicTypes.DATE);
196 sqlQuery.setString("name", river);
197 sqlQuery.setDouble("startKm", startKm);
198 sqlQuery.setDouble("endKm", endKm);
199 List<Object []> results = sqlQuery.list();
200 SedimentLoad[] loads = new SedimentLoad[results.size()];
201 for (int i = 0; i < results.size(); i++) {
202 Object[] row = results.get(i);
203 loads[i] = new SedimentLoad(
204 (String) row[0],
205 (Date) row[1],
206 null,
207 false);
208 }
209 return loads;
210 }
211 else if (type.equals("epoch")) {
212 sqlQuery = session.createSQLQuery(SQL_SELECT_EPOCHS)
213 .addScalar("description", StandardBasicTypes.STRING)
214 .addScalar("start", StandardBasicTypes.DATE)
215 .addScalar("end", StandardBasicTypes.DATE);
216 sqlQuery.setString("name", river);
217 sqlQuery.setDouble("startKm", startKm);
218 sqlQuery.setDouble("endKm", endKm);
219 List<Object []> results = sqlQuery.list();
220
221 SedimentLoad[] loads = new SedimentLoad[results.size()];
222 for (int i = 0; i < results.size(); i++) {
223 Object[] row = results.get(i);
224 loads[i] = new SedimentLoad(
225 (String) row[0],
226 (Date) row[1],
227 (Date) row[2],
228 true);
229 }
230 return loads;
231 }
232 return new SedimentLoad[0];
233 }
234
235 /**
236 * Get sediment loads from db.
237 * @param river the river
238 * @param type the sediment load type (year or epoch)
239 * @return according sediment loads.
240 */
241 public static SedimentLoad getSedimentLoadWithDataUncached(
242 String river,
243 String type,
244 double startKm,
245 double endKm,
246 Date sdate,
247 Date edate
248 ) {
249 log.debug("SedimentLoadFactory.getBedHeightUncached");
250
251 Session session = SessionHolder.HOLDER.get();
252 SQLQuery sqlQuery = null;
253
254 Calendar cal = Calendar.getInstance();
255 cal.setTime(sdate);
256 int year = cal.get(Calendar.YEAR);
257 cal.set(year, 1, 1);
258 Calendar end = Calendar.getInstance();
259 end.set(year, 12, 31);
260
261 if (type.equals("single")) {
262 sqlQuery = session.createSQLQuery(SQL_SELECT_SINGLES_DATA)
263 .addScalar("description", StandardBasicTypes.STRING)
264 .addScalar("year", StandardBasicTypes.DATE)
265 .addScalar("load", StandardBasicTypes.DOUBLE);
266 sqlQuery.setString("name", river);
267 sqlQuery.setDouble("startKm", startKm);
268 sqlQuery.setDouble("endKm", endKm);
269 sqlQuery.setDate("begin", cal.getTime());
270 sqlQuery.setDate("end", end.getTime());
271 sqlQuery.setString("grain", "total");
272 List<Object []> results = sqlQuery.list();
273 SedimentLoad load = new SedimentLoad();
274 if (results.size() != 1) {
275 // should not happen. throw some exception.
276 return new SedimentLoad();
277 }
278 Object[] row = results.get(0);
279 load = new SedimentLoad(
280 (String) row[0],
281 (Date) row[1],
282 null,
283 false);
284 load.addCoarseValues(getValues("coarse", sqlQuery));
285 load.addFineMiddleValues(getValues("fine_middle", sqlQuery));
286 load.addSandValues(getValues("sand", sqlQuery));
287 load.addSuspSandBedValues(getValues("suspended_sediment", sqlQuery));
288 load.addSuspSandBedValues(getValues("susp_sand_bed", sqlQuery));
289 return load;
290 }
291 else if (type.equals("epoch")) {
292 Calendar send = Calendar.getInstance();
293 send.setTime(edate);
294 int eyear = send.get(Calendar.YEAR);
295 send.set(year, 1, 1);
296 Calendar eend = Calendar.getInstance();
297 eend.set(eyear, 12, 31);
298
299 sqlQuery = session.createSQLQuery(SQL_SELECT_EPOCHS)
300 .addScalar("description", StandardBasicTypes.STRING)
301 .addScalar("start_time", StandardBasicTypes.DATE)
302 .addScalar("stop_time", StandardBasicTypes.DATE)
303 .addScalar("load", StandardBasicTypes.DOUBLE);
304 sqlQuery.setString("name", river);
305 sqlQuery.setDouble("startKm", startKm);
306 sqlQuery.setDouble("endKm", endKm);
307 sqlQuery.setDate("sbegin", cal.getTime());
308 sqlQuery.setDate("sbegin", end.getTime());
309 sqlQuery.setDate("ebegin",send.getTime());
310 sqlQuery.setDate("eend", eend.getTime());
311 sqlQuery.setString("grain", "total");
312
313 List<Object []> results = sqlQuery.list();
314
315 SedimentLoad load = new SedimentLoad();
316 if (results.size() != 1) {
317 // should not happen. throw some exception.
318 return new SedimentLoad();
319 }
320 Object[] row = results.get(0);
321 load = new SedimentLoad(
322 (String) row[0],
323 (Date) row[1],
324 null,
325 false);
326 load.addCoarseValues(getValues("coarse", sqlQuery));
327 load.addFineMiddleValues(getValues("fine_middle", sqlQuery));
328 load.addSandValues(getValues("sand", sqlQuery));
329 load.addSuspSandBedValues(getValues("suspended_sediment", sqlQuery));
330 load.addSuspSandBedValues(getValues("susp_sand_bed", sqlQuery));
331 return load;
332 }
333 return new SedimentLoad();
334 }
335
336 /**
337 *
338 */
339 protected static TDoubleArrayList getValues (
340 String fraction,
341 SQLQuery query
342 ) {
343 query.setString("grain", fraction);
344 List<Object[]> results = query.list();
345 TDoubleArrayList values = new TDoubleArrayList();
346 for (int i = 0; i < results.size(); i++) {
347 Object[] row = results.get(i);
348 values.add(((Double)row[2]).doubleValue());
349 }
350 return values;
351 }
352 }

http://dive4elements.wald.intevation.org