teichmann@5844: /* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde teichmann@5844: * Software engineering by Intevation GmbH teichmann@5844: * teichmann@5992: * This file is Free Software under the GNU AGPL (>=v3) teichmann@5844: * and comes with ABSOLUTELY NO WARRANTY! Check out the teichmann@5992: * 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.Column; mschaefer@8973: import javax.persistence.Entity; mschaefer@8973: import javax.persistence.GeneratedValue; sascha@171: import javax.persistence.GenerationType; mschaefer@8973: import javax.persistence.Id; sascha@174: import javax.persistence.JoinColumn; mschaefer@8973: import javax.persistence.OneToMany; sascha@174: import javax.persistence.OneToOne; mschaefer@8973: import javax.persistence.SequenceGenerator; mschaefer@8973: import javax.persistence.Table; sascha@171: ingo@468: import org.apache.log4j.Logger; mschaefer@8973: import org.dive4elements.river.backend.SessionHolder; mschaefer@8973: import org.hibernate.Query; ingo@2374: import org.hibernate.SQLQuery; mschaefer@8973: import org.hibernate.Session; ingo@2374: import org.hibernate.type.StandardBasicTypes; ingo@468: ingo@468: felix@6555: /** DB-mapped WST. */ sascha@171: @Entity sascha@171: @Table(name = "wsts") sascha@167: public class Wst sascha@167: implements Serializable sascha@167: { teichmann@8200: private static Logger log = 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; mschaefer@8973: private String sinfo_selection; sascha@167: sascha@475: private List columns; sascha@475: ingo@2374: ingo@2374: public static final String SQL_SELECT_MINMAX = mschaefer@8973: "select min(q) as minQ, max(q) as maxQ from wst_q_values " + mschaefer@8973: "where wst_id = :wst and not (a > :km or b < :km)"; ingo@2374: sascha@167: public Wst() { sascha@167: } sascha@167: mschaefer@8973: public Wst(final River river, final String description) { ingo@2347: this(river, description, 0); sascha@467: } sascha@467: mschaefer@8973: public Wst(final River river, final String description, final 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( mschaefer@8973: name = "SEQUENCE_WSTS_ID_SEQ", mschaefer@8973: sequenceName = "WSTS_ID_SEQ", mschaefer@8973: allocationSize = 1) sascha@171: @GeneratedValue( mschaefer@8973: strategy = GenerationType.SEQUENCE, mschaefer@8973: generator = "SEQUENCE_WSTS_ID_SEQ") sascha@171: @Column(name = "id") sascha@171: public Integer getId() { mschaefer@8973: return this.id; sascha@171: } sascha@171: mschaefer@8973: public void setId(final 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() { mschaefer@8973: return this.river; sascha@174: } sascha@174: mschaefer@8973: public void setRiver(final River river) { sascha@167: this.river = river; sascha@167: } sascha@167: sascha@172: @Column(name = "description") sascha@172: public String getDescription() { mschaefer@8973: return this.description; sascha@172: } sascha@172: mschaefer@8973: public void setDescription(final String description) { sascha@167: this.description = description; sascha@167: } sascha@467: sascha@467: @Column(name = "kind") sascha@467: public Integer getKind() { mschaefer@8973: return this.kind; sascha@467: } sascha@467: mschaefer@8973: public void setKind(final Integer kind) { sascha@467: this.kind = kind; sascha@467: } ingo@468: mschaefer@8973: @Column(name = "sinfo_selection") mschaefer@8973: public String getSInfoSelection() { mschaefer@8973: return this.sinfo_selection; mschaefer@8973: } mschaefer@8973: mschaefer@8973: public void setSInfoSelection(final String sinfoSelection) { mschaefer@8973: this.sinfo_selection = sinfoSelection; mschaefer@8973: } mschaefer@8973: sascha@475: @OneToMany sascha@475: @JoinColumn(name="wst_id") sascha@475: public List getColumns() { mschaefer@8973: return this.columns; sascha@475: } sascha@475: mschaefer@8973: public void setColumns(final 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() { mschaefer@8973: final double[] ab = this.river.determineMinMaxDistance(); mschaefer@8973: return determineMinMaxQ(new Range(ab[0], ab[1], this.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: */ mschaefer@8973: public double[] determineMinMaxQ(final Range range) { ingo@2372: if (range != null) { ingo@2372: return determineMinMaxQ( mschaefer@8973: range.getA().doubleValue(), mschaefer@8973: 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: */ mschaefer@8973: public double[] determineMinMaxQ(final double fromKm, final double toKm) { mschaefer@8973: final Session session = SessionHolder.HOLDER.get(); ingo@468: mschaefer@8973: final Query query = session.createQuery( mschaefer@8973: "select min(q), max(q) from WstQRange where " mschaefer@8973: + "id in " mschaefer@8973: + " (select wstQRange.id from WstColumnQRange where " mschaefer@8973: + " wstColumn.id in (select id from WstColumn where wst.id = :wst)) " mschaefer@8973: + "and range.id in " mschaefer@8973: + " (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: mschaefer@8973: final 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) { teichmann@8200: log.warn("Could not process result from min/maxQ query."); felix@5850: return null; felix@5850: } felix@5850: mschaefer@8973: final Object [] result = results.get(0); sascha@469: sascha@469: return new double [] { mschaefer@8973: ((BigDecimal)result[0]).doubleValue(), mschaefer@8973: ((BigDecimal)result[1]).doubleValue() }; ingo@468: } ingo@2374: ingo@2374: mschaefer@8973: public double[] determineMinMaxQFree(final double km) { mschaefer@8973: final Session session = SessionHolder.HOLDER.get(); ingo@2374: mschaefer@8973: final SQLQuery sqlQuery = session.createSQLQuery(SQL_SELECT_MINMAX) mschaefer@8973: .addScalar("minQ", StandardBasicTypes.DOUBLE) mschaefer@8973: .addScalar("maxQ", StandardBasicTypes.DOUBLE); ingo@2374: ingo@2374: sqlQuery.setInteger("wst", getId()); ingo@2374: sqlQuery.setDouble("km", km); ingo@2374: mschaefer@8973: final List minmaxQ = sqlQuery.list(); ingo@2374: felix@2794: ingo@2374: if (minmaxQ.isEmpty()) { ingo@2374: return null; ingo@2374: } ingo@2374: mschaefer@8973: final Object[] mm = minmaxQ.get(0); ingo@2374: felix@2794: if (mm[0] == null || mm[1] == null) { tom@8842: log.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 :