felix@2131: package de.intevation.flys.artifacts.model; felix@2131: felix@2131: import java.util.ArrayList; felix@2131: import java.util.List; felix@2131: felix@2148: import java.io.Serializable; felix@2148: felix@2131: import net.sf.ehcache.Cache; felix@2131: import net.sf.ehcache.Element; felix@2131: felix@2131: import org.apache.log4j.Logger; felix@2131: felix@2131: import org.hibernate.Query; felix@2131: import org.hibernate.Session; ingo@2419: import org.hibernate.SQLQuery; ingo@2419: import org.hibernate.type.StandardBasicTypes; felix@2131: felix@2155: import de.intevation.flys.model.HYK; felix@2131: import de.intevation.flys.model.HYKFormation; felix@2131: import de.intevation.flys.model.HYKFlowZone; felix@2131: felix@2131: import de.intevation.flys.artifacts.cache.CacheFactory; felix@2131: felix@2131: import de.intevation.flys.backend.SessionHolder; felix@2131: felix@2131: felix@2131: /** felix@2131: * Factory to access HYKs (hydrographic values). felix@2131: */ felix@2131: public class HYKFactory felix@2131: { felix@2131: private static Logger logger = Logger.getLogger(HYKFactory.class); felix@2131: felix@2131: public static String HYK_CACHE_NAME = "hykache"; felix@2131: felix@2131: felix@2131: /** Do not instantiate a HYKFactory. */ felix@2131: private HYKFactory() { felix@2131: } felix@2131: felix@2131: felix@2131: /** felix@2131: * Get List of Zones for given river and km. felix@2131: */ felix@2139: public static Object getHYKs(int hykid, double km) { felix@2131: logger.debug("HYKFactory.getHYKs"); felix@2131: felix@2131: Cache cache = CacheFactory.getCache(HYK_CACHE_NAME); felix@2131: felix@2131: String cacheKey; felix@2131: felix@2131: if (cache != null) { felix@2139: cacheKey = "" + hykid + "_" + km; felix@2131: Element element = cache.get(cacheKey); felix@2131: if (element != null) { felix@2131: logger.debug("Got hyk from cache"); felix@2131: return (List)element.getValue(); felix@2131: } felix@2131: } felix@2131: else { felix@2131: cacheKey = null; felix@2131: } felix@2131: felix@2139: List zones = getZonesUncached(hykid, km); felix@2131: felix@2131: if (zones != null && cacheKey != null) { felix@2131: logger.debug("Store hykzones in cache."); felix@2131: Element element = new Element(cacheKey, zones); felix@2131: cache.put(element); felix@2131: } felix@2131: felix@2131: return zones; felix@2131: } felix@2131: felix@2131: felix@2155: /** Return name for hyk with given id. */ felix@2139: public static String getHykName(int hykid) { felix@2139: logger.debug("HYKFactory.getHykName " + hykid); felix@2139: felix@2139: Session session = SessionHolder.HOLDER.get(); felix@2139: felix@2139: Query query = session.createQuery( felix@2139: "select description from HYK where id = :hykid "); felix@2139: query.setParameter("hykid", hykid); felix@2139: felix@2139: return (String) query.uniqueResult(); felix@2139: } felix@2139: felix@2139: felix@2131: /** felix@2155: * Ask DB for hyk zones. felix@2155: * @param hykid ID of the 'main' HYK to query. felix@2155: * @param km for which to get the hyk-zones. felix@2155: * @return according zones. felix@2131: */ felix@2139: public static List getZonesUncached(int hykid, double km) { felix@2131: if (logger.isDebugEnabled()) { felix@2139: logger.debug("HYKFactory.getZoneUncached " + hykid + " km " + km); felix@2131: } felix@2131: felix@2131: Session session = SessionHolder.HOLDER.get(); felix@2137: felix@2155: // Find out flow-direction of river. felix@2155: // OPTIMIZE: 1) query kmUp directly 2) merge queries. felix@2155: Query rQuery = session.createQuery("from HYK where id = :hykid"); felix@2155: rQuery.setParameter("hykid", hykid); felix@2155: rQuery.setMaxResults(1); felix@2155: HYK hyk = (HYK) rQuery.uniqueResult(); felix@2155: ingo@2419: double flowDir = hyk.getRiver().getKmUp() ? 1 : -1; felix@2148: ingo@2419: List forms = getHYKFormations(hykid, km, flowDir); ingo@2419: List zones = new ArrayList(); felix@2155: felix@2139: // Take the first one. felix@2139: if (forms.size() >= 1) { felix@2139: HYKFormation form = forms.get(0); felix@2131: // Create respective zones. felix@2131: for (HYKFlowZone flowZone: form.getZones()) { felix@2131: Zone z = new Zone(flowZone.getA().doubleValue(), felix@2131: flowZone.getB().doubleValue(), felix@2131: flowZone.getType().getName()); felix@2131: zones.add(z); felix@2131: } felix@2131: } felix@2131: felix@2131: return zones; felix@2131: } felix@2131: ingo@2419: ingo@2419: protected static List getHYKFormations( ingo@2419: int hykid, ingo@2419: double km, ingo@2419: double flowDir ingo@2419: ) { ingo@2419: Session session = SessionHolder.HOLDER.get(); ingo@2419: ingo@2419: String SQL = "SELECT " + ingo@2419: " f.id AS FID, " + ingo@2419: " f.distance_vl AS DIST, " + ingo@2419: " e.hyk_id AS HID, " + ingo@2419: " e.km AS KM " + ingo@2419: " FROM hyk_formations f INNER JOIN hyk_entries e " + ingo@2419: " ON e.id = f.hyk_entry_id " + ingo@2419: " WHERE e.hyk_id = :hykid " + ingo@2419: " AND :km between " + ingo@2419: " LEAST(e.km, e.km + :flowDir*(f.distance_vl/1000.0+0.001)) " + ingo@2419: " AND " + ingo@2419: " GREATEST(e.km, e.km + :flowDir*(f.distance_vl/1000.0+0.001))"; ingo@2419: ingo@2419: SQLQuery sqlQuery = session.createSQLQuery(SQL) ingo@2419: .addScalar("FID", StandardBasicTypes.INTEGER) ingo@2419: .addScalar("DIST", StandardBasicTypes.DOUBLE) ingo@2419: .addScalar("HID", StandardBasicTypes.INTEGER) ingo@2419: .addScalar("KM", StandardBasicTypes.DOUBLE); ingo@2419: ingo@2419: sqlQuery.setInteger("hykid", hykid); ingo@2419: sqlQuery.setDouble("flowDir", flowDir); ingo@2419: sqlQuery.setDouble("km", km); ingo@2419: ingo@2419: logger.debug("HYK SQL: " + sqlQuery.getQueryString()); ingo@2419: ingo@2419: List results = sqlQuery.list(); ingo@2419: ingo@2419: logger.debug("Found " + results.size() + " HYKFormation IDs in DB."); ingo@2419: ingo@2419: if (results == null || results.isEmpty()) { ingo@2419: logger.debug("No HYK found for ID " + hykid + " at km " + km); ingo@2419: return new ArrayList(); ingo@2419: } ingo@2419: ingo@2419: Object[] resultSet = results.get(0); ingo@2419: Integer hykFormationId = (Integer) resultSet[0]; ingo@2419: ingo@2419: Query query = session.createQuery("from HYKFormation where id = :id"); ingo@2419: query.setParameter("id", hykFormationId); ingo@2419: query.setMaxResults(1); ingo@2419: ingo@2419: return query.list(); ingo@2419: } ingo@2419: ingo@2419: felix@2131: /** Labelled section. */ felix@2148: public static class Zone implements Serializable { felix@2131: /** Lower end of segment. */ felix@2131: protected double from; felix@2131: /** Upper end of segment. */ felix@2131: protected double to; felix@2131: /** The label. */ felix@2131: protected String name; felix@2131: felix@2131: /** Constructor for labelled section. */ felix@2131: public Zone (double from, double to, String name) { felix@2131: this.from = from; felix@2131: this.to = to; felix@2131: this.name = name; felix@2131: } felix@2131: felix@2137: /** Get upper value. */ felix@2137: public double getTo() { felix@2137: return to; felix@2137: } felix@2137: felix@2137: /** Get lower value. */ felix@2131: public double getFrom() { felix@2131: return from; felix@2131: } felix@2131: felix@2137: /** Get name (type). */ felix@2131: public String getName() { felix@2131: return name; felix@2131: } felix@2131: } // public static class Zone felix@2131: } felix@2131: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :