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.math.BigDecimal; sascha@167: sascha@167: import java.io.Serializable; sascha@167: sascha@203: import java.util.List; sascha@203: 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@203: import javax.persistence.OneToMany; sascha@171: ingo@468: import org.hibernate.Session; ingo@468: import org.hibernate.Query; ingo@468: teichmann@5969: import org.apache.log4j.Logger; teichmann@5969: teichmann@5829: import org.dive4elements.river.backend.SessionHolder; ingo@468: felix@5374: /** Database-mapped Gauge with all info about it. */ sascha@171: @Entity sascha@171: @Table(name = "gauges") sascha@167: public class Gauge ingo@4174: implements Serializable, Comparable sascha@167: { teichmann@5969: private static final Logger log = Logger.getLogger(Gauge.class); teichmann@5969: ingo@2385: public static final int MASTER_DISCHARGE_TABLE = 0; ingo@2385: sascha@171: private Integer id; sascha@167: private String name; sascha@167: private River river; sascha@167: private BigDecimal station; sascha@167: private BigDecimal aeo; sascha@167: private BigDecimal datum; sascha@2371: private Long officialNumber; sascha@167: private Range range; sascha@167: sascha@203: private List dischargeTables; sascha@203: felix@1233: /** MainValues at this Gauge. */ felix@1233: protected List mainValues; felix@1233: sascha@167: public Gauge() { sascha@167: } sascha@167: sascha@192: public Gauge( sascha@192: String name, sascha@192: River river, sascha@192: BigDecimal station, sascha@192: BigDecimal aeo, sascha@192: BigDecimal datum, sascha@2371: Long officialNumber, sascha@192: Range range sascha@192: ) { sascha@2371: this.name = name; sascha@2371: this.river = river; sascha@2371: this.station = station; sascha@2371: this.aeo = aeo; sascha@2371: this.datum = datum; sascha@2371: this.officialNumber = officialNumber; sascha@2371: this.range = range; sascha@192: } sascha@192: sascha@171: @Id sascha@171: @SequenceGenerator( sascha@171: name = "SEQUENCE_GAUGES_ID_SEQ", sascha@171: sequenceName = "GAUGES_ID_SEQ", sascha@171: allocationSize = 1) sascha@171: @GeneratedValue( sascha@171: strategy = GenerationType.SEQUENCE, sascha@171: generator = "SEQUENCE_GAUGES_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@193: @OneToOne sascha@193: @JoinColumn(name = "river_id" ) sascha@193: public River getRiver() { sascha@193: return river; sascha@193: } sascha@193: sascha@193: public void setRiver(River river) { sascha@193: this.river = river; sascha@193: } sascha@193: sascha@172: @Column(name = "name") sascha@172: public String getName() { sascha@172: return name; sascha@172: } sascha@172: sascha@167: public void setName(String name) { sascha@167: this.name = name; sascha@167: } sascha@167: sascha@172: @Column(name = "station") // FIXME: type mapping needed sascha@172: public BigDecimal getStation() { sascha@172: return station; sascha@167: } sascha@167: sascha@167: public void setStation(BigDecimal station) { sascha@167: this.station = station; sascha@167: } sascha@167: sascha@172: @Column(name = "aeo") // FIXME: type mapping needed sascha@172: public BigDecimal getAeo() { sascha@172: return aeo; sascha@167: } sascha@167: sascha@167: public void setAeo(BigDecimal aeo) { sascha@167: this.aeo = aeo; sascha@167: } sascha@167: sascha@172: @Column(name = "datum") // FIXME: type mapping needed sascha@172: public BigDecimal getDatum() { sascha@172: return datum; sascha@167: } sascha@167: sascha@167: public void setDatum(BigDecimal datum) { sascha@167: this.datum = datum; sascha@167: } sascha@167: sascha@2371: @Column(name = "official_number") sascha@2371: public Long getOfficialNumber() { sascha@2371: return officialNumber; sascha@2371: } sascha@2371: sascha@2371: public void setOfficialNumber(Long officialNumber) { sascha@2371: this.officialNumber = officialNumber; sascha@2371: } sascha@2371: sascha@174: @OneToOne sascha@174: @JoinColumn(name = "range_id" ) sascha@172: public Range getRange() { sascha@172: return range; sascha@167: } sascha@167: sascha@167: public void setRange(Range range) { sascha@167: this.range = range; sascha@167: } sascha@203: sascha@203: @OneToMany sascha@203: @JoinColumn(name = "gauge_id") sascha@203: public List getDischargeTables() { sascha@203: return dischargeTables; sascha@203: } sascha@203: sascha@203: public void setDischargeTables(List dischargeTables) { sascha@203: this.dischargeTables = dischargeTables; sascha@203: } ingo@468: ingo@468: ingo@468: /** ingo@468: * Returns min and max W values of this gauge. ingo@468: * felix@1233: * @return the min and max W value of this gauge [min,max]. ingo@468: */ teichmann@6327: public double[] determineMinMaxW() { ingo@468: Session session = SessionHolder.HOLDER.get(); ingo@468: ingo@468: List tables = getDischargeTables(); ingo@468: DischargeTable dischargeTable = null; ingo@468: ingo@468: for (DischargeTable tmp: tables) { ingo@468: if (tmp.getKind() == 0) { ingo@468: dischargeTable = tmp; ingo@468: break; ingo@468: } ingo@468: } ingo@468: ingo@468: if (dischargeTable == null) { ingo@468: return null; ingo@468: } ingo@468: ingo@468: Query query = session.createQuery( ingo@468: "select min(w) as min, max(w) as max from DischargeTableValue " + ingo@468: "where table_id =:table"); ingo@468: query.setParameter("table", dischargeTable.getId()); ingo@468: teichmann@5969: List results = query.list(); teichmann@5969: if (results.isEmpty()) { teichmann@5969: log.error("No values in discharge table found."); teichmann@5969: return null; teichmann@5969: } ingo@468: teichmann@5969: Object[] result = (Object[])results.get(0); teichmann@5969: teichmann@5969: BigDecimal a = (BigDecimal)result[0]; teichmann@5969: BigDecimal b = (BigDecimal)result[1]; teichmann@5969: teichmann@5969: return a != null && b != null teichmann@6327: ? new double [] { a.doubleValue(), b.doubleValue() } ingo@468: : null; ingo@468: } felix@1233: felix@1233: @OneToMany felix@1233: @JoinColumn(name = "gauge_id") felix@1233: public List getMainValues() { felix@1233: return mainValues; felix@1233: } felix@1233: felix@1233: public void setMainValues(List mainValues) { felix@1233: this.mainValues = mainValues; ingo@2381: } ingo@2381: ingo@2381: public static Gauge getGaugeByOfficialNumber(long number) { ingo@2381: Session session = SessionHolder.HOLDER.get(); ingo@2381: ingo@2381: Query query = session.createQuery( ingo@2381: "from Gauge where officialNumber=:number"); ingo@2381: ingo@2381: query.setParameter("number", number); ingo@2381: ingo@2381: List results = query.list(); ingo@2381: ingo@2381: return results.isEmpty() ? null : results.get(0); ingo@2381: } ingo@2385: aheinecke@6838: public static Gauge getGaugeByOfficialNumber(long number, String river_name) { aheinecke@6838: Session session = SessionHolder.HOLDER.get(); aheinecke@6838: aheinecke@6838: Query query = session.createQuery( aheinecke@6838: "from Gauge as gau " + aheinecke@6838: "where gau.officialNumber=:number and gau.river.name=:river_name"); aheinecke@6838: aheinecke@6838: query.setParameter("number", number); aheinecke@6838: query.setParameter("river_name", river_name); aheinecke@6838: aheinecke@6838: List results = query.list(); aheinecke@6838: aheinecke@6838: return results.isEmpty() ? null : results.get(0); aheinecke@6838: } aheinecke@6838: ingo@2385: ingo@2385: public DischargeTable fetchMasterDischargeTable() { ingo@2385: for (DischargeTable dt: dischargeTables) { ingo@2385: if (dt.getKind() == MASTER_DISCHARGE_TABLE) { ingo@2385: return dt; ingo@2385: } ingo@2385: } ingo@2385: ingo@2385: return null; ingo@2385: } bjoern@3686: bjoern@3686: /** bjoern@3686: * Returns an array of [days, qs] necessary to create duration curves. bjoern@3686: * bjoern@3686: * @return a 2dim array of [days, qs] where days is an int[] and qs is bjoern@3686: * an double[]. bjoern@3686: */ bjoern@3688: public Object[] fetchDurationCurveData() { bjoern@3686: Session session = SessionHolder.HOLDER.get(); bjoern@3686: bjoern@3686: Query query = session.createQuery( bjoern@3686: "select cast(nmv.name as integer) as days, mv.value as q " + bjoern@3686: "from MainValue as mv " + bjoern@3686: "join mv.mainValue as nmv " + bjoern@3686: "join nmv.type mvt " + bjoern@3686: "where mvt.name = 'D' and mv.gauge.id = :gauge_id " + bjoern@3686: "order by days"); bjoern@3686: bjoern@3686: query.setParameter("gauge_id", getId()); bjoern@3686: bjoern@3686: List results = query.list(); bjoern@3686: int[] days = new int[results.size()]; bjoern@3686: double[] qs = new double[results.size()]; bjoern@3686: bjoern@3686: int idx = 0; bjoern@3686: bjoern@3686: for (Object obj: results) { bjoern@3686: Object[] arr = (Object[]) obj; bjoern@3686: bjoern@3686: try { bjoern@3686: int day = ((Integer) arr[0]).intValue(); bjoern@3686: double q = ((BigDecimal) arr[1]).doubleValue(); bjoern@3686: bjoern@3686: days[idx] = day; bjoern@3686: qs[idx++] = q; bjoern@3686: } bjoern@3686: catch (NumberFormatException nfe) { bjoern@3686: } bjoern@3686: } bjoern@3686: bjoern@3686: return new Object[] { days, qs }; bjoern@3686: } bjoern@3686: bjoern@3789: /** bjoern@3789: * Calculates the maximum and minimum W and Q values bjoern@3789: * bjoern@3789: * @return the MaxMinWQ object representing the calculated values bjoern@3789: */ bjoern@3789: public MinMaxWQ fetchMaxMinWQ() { bjoern@3789: Session session = SessionHolder.HOLDER.get(); bjoern@3789: bjoern@3789: Query query = session.createQuery( bjoern@3789: "select max(mv.value) as max, min(mv.value) as min " + bjoern@3789: "from MainValue as mv " + bjoern@3789: "join mv.mainValue as nmv " + bjoern@3789: "join nmv.type mvt " + sascha@3790: "where mvt.name in ('W', 'Q') " + sascha@3790: "and mv.gauge.id = :gauge_id " + bjoern@3789: "group by mvt.name order by mvt.name" bjoern@3789: ); bjoern@3789: bjoern@3789: query.setParameter("gauge_id", getId()); bjoern@3789: bjoern@3789: List results = query.list(); sascha@3790: if (results.isEmpty()) { bjoern@3789: // No values found bjoern@3789: return new MinMaxWQ(); bjoern@3789: } bjoern@3789: sascha@3790: Object[] arr = (Object[]) results.get(0); sascha@3790: BigDecimal maxw = (BigDecimal)arr[0]; sascha@3790: BigDecimal minw = (BigDecimal)arr[1]; bjoern@3789: BigDecimal maxq = null; bjoern@3789: BigDecimal minq = null; bjoern@3789: bjoern@3789: bjoern@3789: if (results.size() > 1) { bjoern@3789: arr = (Object[]) results.get(1); bjoern@3789: maxq = (BigDecimal)arr[0]; bjoern@3789: minq = (BigDecimal)arr[1]; bjoern@3789: } bjoern@3789: bjoern@3789: return new MinMaxWQ(minw, maxw, minq, maxq); bjoern@3789: } ingo@4174: ingo@4174: @Override ingo@4174: public int compareTo(Gauge o) { ingo@4174: return getName().compareTo(o.getName()); ingo@4174: } sascha@167: } sascha@167: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :