Mercurial > dive4elements > river
view flys-backend/src/main/java/de/intevation/flys/model/River.java @ 4967:2954eed04288
Calculation4: Doc and TODO/issue.
author | Felix Wolfsteller <felix.wolfsteller@intevation.de> |
---|---|
date | Wed, 06 Feb 2013 09:56:46 +0100 |
parents | 8062b571884d |
children |
line wrap: on
line source
package de.intevation.flys.model; import de.intevation.flys.backend.SessionHolder; import java.io.Serializable; import java.math.BigDecimal; import java.math.MathContext; import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.TreeMap; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.OneToOne; import javax.persistence.OrderBy; import javax.persistence.SequenceGenerator; import javax.persistence.Table; import org.hibernate.Query; import org.hibernate.Session; @Entity @Table(name = "rivers") public class River implements Serializable { public static final MathContext PRECISION = new MathContext(6); public static final double EPSILON = 1e-5; public static final Comparator<Double> KM_CMP = new Comparator<Double>() { @Override public int compare(Double a, Double b) { double diff = a - b; if (diff < -EPSILON) return -1; if (diff > EPSILON) return +1; return 0; } }; private Integer id; private Long officialNumber; private String name; private boolean kmUp; private List<Gauge> gauges; private List<MeasurementStation> measurementstations; private Unit wstUnit; @Id @SequenceGenerator( name = "SEQUENCE_RIVERS_ID_SEQ", sequenceName = "RIVERS_ID_SEQ", allocationSize = 1) @GeneratedValue( strategy = GenerationType.SEQUENCE, generator = "SEQUENCE_RIVERS_ID_SEQ") @Column(name = "id") public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Column(name = "official_number") public Long getOfficialNumber() { return officialNumber; } public void setOfficialNumber(Long officialNumber) { this.officialNumber = officialNumber; } @Column(name = "name") public String getName() { return name; } public void setName(String name) { this.name = name; } @Column(name = "km_up") public boolean getKmUp() { return kmUp; } public void setKmUp(boolean kmUp) { this.kmUp = kmUp; } public River() { } public River(String name, Unit wstUnit) { this.name = name; this.wstUnit = wstUnit; } @OneToMany @JoinColumn(name="river_id") public List<Gauge> getGauges() { return gauges; } public void setGauges(List<Gauge> gauges) { this.gauges = gauges; } @OneToMany @OrderBy("station") @JoinColumn(name="river_id") public List<MeasurementStation> getMeasurementStations() { return measurementstations; } public void setMeasurementStations(List<MeasurementStation> mstations) { this.measurementstations = mstations; } @OneToOne @JoinColumn(name = "wst_unit_id" ) public Unit getWstUnit() { return wstUnit; } public void setWstUnit(Unit wstUnit) { this.wstUnit = wstUnit; } @Override public String toString() { return name != null ? name : ""; } /** * This method returns the gauges that intersect with <i>a</i> and * <i>b</i>, * * @param a A start point. * @param b An end point. * * @return the intersecting gauges. */ public List<Gauge> determineGauges(double a, double b) { Session session = SessionHolder.HOLDER.get(); if (a > b) { double t = a; a = b; b = t; } Query query = session.createQuery( "from Gauge where river=:river " + "and not (range.a > :b or range.b < :a) order by a"); query.setParameter("river", this); query.setParameter("a", new BigDecimal(a, PRECISION)); query.setParameter("b", new BigDecimal(b, PRECISION)); return query.list(); } public Gauge maxOverlap(double a, double b) { List<Gauge> gauges = determineGauges(a, b); if (gauges == null) { return null; } if (a > b) { double t = a; a = b; b = t; } double max = -Double.MAX_VALUE; Gauge result = null; for (Gauge gauge: gauges) { Range r = gauge.getRange(); double c = r.getA().doubleValue(); double d = r.getB().doubleValue(); double start = c >= a ? c : a; double stop = d <= b ? d : b; double length = stop - start; if (length > max) { max = length; result = gauge; } } return result; } public Gauge determineGaugeByName(String name) { Session session = SessionHolder.HOLDER.get(); Query query = session.createQuery( "from Gauge where river=:river and name=:name"); query.setParameter("river", this); query.setParameter("name", name); List<Gauge> gauges = query.list(); return gauges.isEmpty() ? null : gauges.get(0); } public Gauge determineGaugeByPosition(double p) { Session session = SessionHolder.HOLDER.get(); Query query = session.createQuery( "from Gauge g where river=:river " + "and :p between g.range.a and g.range.b"); query.setParameter("river", this); query.setParameter("p", new BigDecimal(p, PRECISION)); List<Gauge> gauges = query.list(); return gauges.isEmpty() ? null : gauges.get(0); } public Gauge determineGaugeByStation(double a, double b) { if (a > b) { double t = a; a = b; b = t; } Session session = SessionHolder.HOLDER.get(); Query query = session.createQuery( "from Gauge where river.id=:river " + "and station between :a and :b"); query.setParameter("river", getId()); query.setParameter("a", new BigDecimal(a)); query.setParameter("b", new BigDecimal(b)); List<Gauge> gauges = query.list(); return gauges.isEmpty() ? null : gauges.get(0); } public double[] determineMinMaxQ() { Session session = SessionHolder.HOLDER.get(); Query query = session.createQuery( "select min(wqr.q) as min, max(wqr.q) as max " + "from Wst as w " + "join w.columns as wc " + "join wc.columnQRanges as wcqr " + "join wcqr.wstQRange as wqr " + "where w.kind = 0 and river_id = :river"); query.setParameter("river", getId()); double minmax[] = new double[] { Double.MAX_VALUE, Double.MIN_VALUE }; List<Object> results = query.list(); if (!results.isEmpty()) { Object[] arr = (Object[]) results.get(0); BigDecimal minq = (BigDecimal)arr[0]; BigDecimal maxq = (BigDecimal)arr[1]; minmax[0] = minq.doubleValue(); minmax[1] = maxq.doubleValue(); } return minmax; } /** * This method returns the first gauge that is intersected by <i>a</i> and * <i>b</i>, * * @param a A start point. * @param b An end point. * * @return the first intersecting gauge. */ public Gauge determineGauge(double a, double b) { List<Gauge> gauges = determineGauges(a, b); int idx = a < b ? 0 : gauges.size() - 1; return gauges.isEmpty() ? null : gauges.get(idx); } /** * Returns the min and max distance of this river. The first position in the * resulting array contains the min distance, the second position the max * distance. * * @return the min and max distance of this river. */ public double[] determineMinMaxDistance() { List<Gauge> gauges = getGauges(); if (gauges == null || gauges.isEmpty()) { return null; } double minmax[] = new double[] { Double.MAX_VALUE, Double.MIN_VALUE }; for (Gauge g: gauges) { Range r = g.getRange(); if (r == null) { continue; } double a = r.getA().doubleValue(); minmax[0] = minmax[0] < a ? minmax[0] : a; BigDecimal bigB = r.getB(); if (bigB != null) { double b = bigB.doubleValue(); minmax[1] = minmax[1] > b ? minmax[1] : b; } } return minmax; } public Map<Double, Double> queryGaugeDatumsKMs() { List<Gauge> gauges = getGauges(); Map result = new TreeMap<Double, Double>(KM_CMP); for (Gauge gauge: gauges) { BigDecimal km = gauge.getStation(); BigDecimal datum = gauge.getDatum(); if (km != null && datum != null) { result.put(km.doubleValue(), datum.doubleValue()); } } return result; } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :