teichmann@5844: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5844: * Software engineering by Intevation GmbH teichmann@5844: * teichmann@5844: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5844: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5844: * documentation coming with Dive4Elements River for details. teichmann@5844: */ teichmann@5844: teichmann@5829: package org.dive4elements.river.model; sascha@167: sascha@167: import java.io.Serializable; ingo@468: import java.math.BigDecimal; ingo@468: import java.util.List; sascha@167: sascha@171: import javax.persistence.Entity; sascha@171: import javax.persistence.Id; sascha@171: import javax.persistence.Table; sascha@171: import javax.persistence.GeneratedValue; sascha@171: import javax.persistence.Column; sascha@171: import javax.persistence.SequenceGenerator; sascha@171: import javax.persistence.GenerationType; sascha@174: import javax.persistence.JoinColumn; sascha@174: import javax.persistence.OneToOne; sascha@475: import javax.persistence.OneToMany; sascha@171: ingo@468: import org.apache.log4j.Logger; ingo@468: ingo@468: import org.hibernate.Session; ingo@2374: import org.hibernate.SQLQuery; ingo@468: import org.hibernate.Query; ingo@2374: import org.hibernate.type.StandardBasicTypes; ingo@468: teichmann@5829: import org.dive4elements.river.backend.SessionHolder; ingo@468: ingo@468: sascha@171: @Entity sascha@171: @Table(name = "wsts") sascha@167: public class Wst sascha@167: implements Serializable sascha@167: { ingo@468: private static Logger logger = Logger.getLogger(Wst.class); ingo@468: sascha@171: private Integer id; sascha@171: private River river; sascha@171: private String description; sascha@467: private Integer kind; sascha@167: sascha@475: private List columns; sascha@475: ingo@2374: ingo@2374: public static final String SQL_SELECT_MINMAX = ingo@2374: "select min(q) as minQ, max(q) as maxQ from wst_q_values " + felix@2794: "where wst_id = :wst and not (a > :km or b < :km)"; ingo@2374: sascha@167: public Wst() { sascha@167: } sascha@167: sascha@201: public Wst(River river, String description) { ingo@2347: this(river, description, 0); sascha@467: } sascha@467: ingo@2347: public Wst(River river, String description, Integer kind) { sascha@201: this.river = river; sascha@201: this.description = description; sascha@467: this.kind = kind; sascha@201: } sascha@201: sascha@171: @Id sascha@171: @SequenceGenerator( sascha@171: name = "SEQUENCE_WSTS_ID_SEQ", sascha@171: sequenceName = "WSTS_ID_SEQ", sascha@171: allocationSize = 1) sascha@171: @GeneratedValue( sascha@171: strategy = GenerationType.SEQUENCE, sascha@171: generator = "SEQUENCE_WSTS_ID_SEQ") sascha@171: @Column(name = "id") sascha@171: public Integer getId() { sascha@171: return id; sascha@171: } sascha@171: sascha@168: public void setId(Integer id) { sascha@167: this.id = id; sascha@167: } sascha@167: sascha@174: @OneToOne sascha@174: @JoinColumn(name = "river_id" ) sascha@174: public River getRiver() { sascha@174: return river; sascha@174: } sascha@174: sascha@167: public void setRiver(River river) { sascha@167: this.river = river; sascha@167: } sascha@167: sascha@172: @Column(name = "description") sascha@172: public String getDescription() { sascha@172: return description; sascha@172: } sascha@172: sascha@167: public void setDescription(String description) { sascha@167: this.description = description; sascha@167: } sascha@467: sascha@467: @Column(name = "kind") sascha@467: public Integer getKind() { sascha@467: return kind; sascha@467: } sascha@467: sascha@467: public void setKind(Integer kind) { sascha@467: this.kind = kind; sascha@467: } ingo@468: sascha@475: @OneToMany sascha@475: @JoinColumn(name="wst_id") sascha@475: public List getColumns() { sascha@475: return columns; sascha@475: } sascha@475: sascha@475: public void setColumns(List columns) { sascha@475: this.columns = columns; sascha@475: } ingo@468: ingo@2346: ingo@468: /** ingo@468: * Determines the min and max Q values of this WST. The min value is placed ingo@468: * in the first field of the resulting array - the max value is placed in ingo@468: * the second field. ingo@468: * ingo@468: * @return the min and max Q values of this WST. ingo@468: */ ingo@468: public double[] determineMinMaxQ() { ingo@468: double[] ab = river.determineMinMaxDistance(); ingo@468: return determineMinMaxQ(new Range(ab[0], ab[1], river)); ingo@468: } ingo@468: ingo@468: ingo@468: /** ingo@468: * Determines the min and max Q values of this WST in the given range. The ingo@468: * min value is placed in the first field of the resulting array - the max ingo@468: * value is placed in the second field. ingo@468: * ingo@468: * @param range The range used for querying the Q values. ingo@468: * ingo@468: * @return the min and max Q values of this WST. ingo@468: */ ingo@468: public double[] determineMinMaxQ(Range range) { ingo@2372: if (range != null) { ingo@2372: return determineMinMaxQ( ingo@2372: range.getA().doubleValue(), ingo@2372: range.getB().doubleValue()); ingo@2372: } ingo@2372: ingo@2372: return null; ingo@2372: } ingo@2372: ingo@2372: ingo@2372: /** ingo@2372: * Determines the min and max Q values of this WST in the given range. The ingo@2372: * min value is placed in the first field of the resulting array - the max ingo@2372: * value is placed in the second field. ingo@2372: * ingo@2372: * @param fromKm the lower km value. ingo@2372: * @param toKm the upper km value. ingo@2372: * ingo@2372: * @return the min and max Q values of this WST. ingo@2372: */ ingo@2372: public double[] determineMinMaxQ(double fromKm, double toKm) { ingo@468: Session session = SessionHolder.HOLDER.get(); ingo@468: ingo@468: Query query = session.createQuery( ingo@468: "select min(q), max(q) from WstQRange where " + ingo@468: " id in " + ingo@468: " (select wstQRange.id from WstColumnQRange where " + ingo@468: " wstColumn.id in (select id from WstColumn where wst.id = :wst)) " + ingo@468: " and range.id in " + ingo@468: " (select id from Range where not (a > :end or b < :start))"); ingo@468: sascha@469: query.setParameter("wst", getId()); ingo@2372: query.setParameter("start", new BigDecimal(fromKm)); ingo@2372: query.setParameter("end", new BigDecimal(toKm)); ingo@468: sascha@469: List results = query.list(); ingo@468: sascha@469: if (results.isEmpty()) { sascha@469: return null; sascha@469: } sascha@469: felix@5850: if (results.get(0)[0] == null || results.get(0)[1] == null) { felix@5850: logger.warn("Could not process result from min/maxQ query."); felix@5850: return null; felix@5850: } felix@5850: sascha@469: Object [] result = results.get(0); sascha@469: sascha@469: return new double [] { sascha@469: ((BigDecimal)result[0]).doubleValue(), sascha@469: ((BigDecimal)result[1]).doubleValue() }; ingo@468: } ingo@2374: ingo@2374: ingo@2374: public double[] determineMinMaxQFree(double km) { ingo@2374: Session session = SessionHolder.HOLDER.get(); ingo@2374: ingo@2374: SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_MINMAX) ingo@2374: .addScalar("minQ", StandardBasicTypes.DOUBLE) ingo@2374: .addScalar("maxQ", StandardBasicTypes.DOUBLE); ingo@2374: ingo@2374: sqlQuery.setInteger("wst", getId()); ingo@2374: sqlQuery.setDouble("km", km); ingo@2374: ingo@2374: List minmaxQ = sqlQuery.list(); ingo@2374: felix@2794: ingo@2374: if (minmaxQ.isEmpty()) { ingo@2374: return null; ingo@2374: } ingo@2374: ingo@2374: Object[] mm = minmaxQ.get(0); ingo@2374: felix@2794: if (mm[0] == null || mm[1] == null) { ingo@2795: logger.warn ("No min/max Q for km " + km + " found."); felix@2794: return null; felix@2794: } felix@2794: ingo@2374: return new double[] { (Double) mm[0], (Double) mm[1] }; ingo@2374: } sascha@167: } sascha@167: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :