sascha@167: package de.intevation.flys.model; sascha@167: sascha@167: import java.io.Serializable; sascha@167: ingo@465: import java.math.BigDecimal; sascha@768: import java.math.MathContext; ingo@465: sascha@168: import javax.persistence.Entity; sascha@168: import javax.persistence.Id; sascha@168: import javax.persistence.Table; sascha@168: import javax.persistence.GeneratedValue; sascha@168: import javax.persistence.Column; sascha@168: import javax.persistence.SequenceGenerator; sascha@174: import javax.persistence.OneToMany; sascha@174: import javax.persistence.JoinColumn; sascha@168: import javax.persistence.GenerationType; sascha@168: sascha@174: import java.util.List; sascha@174: ingo@472: import org.hibernate.Session; ingo@472: import org.hibernate.Query; ingo@472: ingo@472: import de.intevation.flys.backend.SessionHolder; ingo@472: ingo@472: sascha@168: @Entity sascha@168: @Table(name = "rivers") sascha@167: public class River sascha@167: implements Serializable sascha@167: { sascha@768: public static final MathContext PRECISION = new MathContext(6); sascha@768: sascha@168: private Integer id; sascha@167: sascha@168: private String name; sascha@167: sascha@505: private boolean kmUp; sascha@505: sascha@174: private List gauges; sascha@174: sascha@168: @Id sascha@168: @SequenceGenerator( sascha@171: name = "SEQUENCE_RIVERS_ID_SEQ", sascha@169: sequenceName = "RIVERS_ID_SEQ", sascha@169: allocationSize = 1) sascha@168: @GeneratedValue( sascha@168: strategy = GenerationType.SEQUENCE, sascha@171: generator = "SEQUENCE_RIVERS_ID_SEQ") sascha@168: @Column(name = "id") sascha@168: public Integer getId() { sascha@168: return id; sascha@168: } sascha@168: sascha@168: public void setId(Integer id) { sascha@167: this.id = id; sascha@167: } sascha@167: sascha@168: @Column(name = "name") sascha@168: public String getName() { sascha@168: return name; sascha@167: } sascha@167: sascha@167: public void setName(String name) { sascha@167: this.name = name; sascha@167: } sascha@167: sascha@505: @Column(name = "km_up") sascha@505: public boolean getKmUp() { sascha@505: return kmUp; sascha@505: } sascha@505: sascha@505: public void setKmUp(boolean kmUp) { sascha@505: this.kmUp = kmUp; sascha@505: } sascha@505: sascha@167: public River() { sascha@167: } sascha@169: sascha@169: public River(String name) { sascha@169: this.name = name; sascha@169: } sascha@174: sascha@174: @OneToMany sascha@174: @JoinColumn(name="river_id") sascha@174: public List getGauges() { sascha@174: return gauges; sascha@174: } sascha@174: sascha@174: public void setGauges(List gauges) { sascha@174: this.gauges = gauges; sascha@174: } sascha@188: sascha@188: public String toString() { sascha@188: return name != null ? name : ""; sascha@188: } ingo@465: ingo@472: ingo@472: /** ingo@488: * This method returns the gauges that intersect with a and ingo@488: * b, ingo@488: * ingo@488: * @param a A start point. ingo@488: * @param b An end point. ingo@488: * ingo@488: * @return the intersecting gauges. ingo@488: */ ingo@488: public List determineGauges(double a, double b) { ingo@488: Session session = SessionHolder.HOLDER.get(); ingo@488: sascha@756: if (a > b) { double t = a; a = b; b = t; } sascha@756: ingo@488: Query query = session.createQuery( ingo@488: "from Gauge where river=:river " + ingo@488: "and not (range.a > :b or range.b < :a) order by a"); ingo@488: query.setParameter("river", this); sascha@769: query.setParameter("a", new BigDecimal(a, PRECISION)); sascha@769: query.setParameter("b", new BigDecimal(b, PRECISION)); ingo@488: ingo@488: return query.list(); ingo@488: } ingo@488: sascha@769: public Gauge maxOverlap(double a, double b) { sascha@769: List gauges = determineGauges(a, b); sascha@769: if (gauges == null) { sascha@769: return null; sascha@769: } sascha@769: sascha@769: if (a > b) { double t = a; a = b; b = t; } sascha@769: sascha@769: double max = -Double.MAX_VALUE; sascha@769: sascha@769: Gauge result = null; sascha@769: sascha@769: for (Gauge gauge: gauges) { sascha@769: Range r = gauge.getRange(); sascha@769: double c = r.getA().doubleValue(); sascha@769: double d = r.getB().doubleValue(); sascha@769: sascha@769: double start = c >= a ? c : a; sascha@769: double stop = d <= b ? d : b; sascha@769: sascha@769: double length = stop - start; sascha@769: sascha@769: if (length > max) { sascha@769: max = length; sascha@769: result = gauge; sascha@769: } sascha@769: } sascha@769: sascha@769: return result; sascha@769: } sascha@769: sascha@767: public Gauge determineGaugeByName(String name) { sascha@767: Session session = SessionHolder.HOLDER.get(); sascha@767: Query query = session.createQuery( sascha@767: "from Gauge where river=:river and name=:name"); sascha@767: query.setParameter("river", this); sascha@767: query.setParameter("name", name); sascha@767: List gauges = query.list(); sascha@767: return gauges.isEmpty() ? null : gauges.get(0); sascha@767: } sascha@767: sascha@764: public Gauge determineGaugeByPosition(double p) { sascha@764: Session session = SessionHolder.HOLDER.get(); sascha@764: Query query = session.createQuery( sascha@768: "from Gauge g where river=:river " + sascha@768: "and :p between g.range.a and g.range.b"); sascha@764: query.setParameter("river", this); sascha@768: query.setParameter("p", new BigDecimal(p, PRECISION)); sascha@764: List gauges = query.list(); sascha@764: return gauges.isEmpty() ? null : gauges.get(0); sascha@764: } sascha@764: sascha@757: public Gauge determineGaugeByStation(double a, double b) { sascha@757: sascha@757: if (a > b) { double t = a; a = b; b = t; } sascha@757: sascha@757: Session session = SessionHolder.HOLDER.get(); sascha@757: sascha@757: Query query = session.createQuery( sascha@757: "from Gauge where river.id=:river " + sascha@757: "and station between :a and :b"); sascha@757: query.setParameter("river", getId()); sascha@757: query.setParameter("a", new BigDecimal(a)); sascha@757: query.setParameter("b", new BigDecimal(b)); sascha@757: sascha@757: List gauges = query.list(); sascha@757: return gauges.isEmpty() ? null : gauges.get(0); sascha@757: } sascha@757: ingo@488: ingo@488: /** ingo@472: * This method returns the first gauge that is intersected by a and ingo@472: * b, ingo@472: * ingo@472: * @param a A start point. ingo@472: * @param b An end point. ingo@472: * ingo@472: * @return the first intersecting gauge. ingo@472: */ ingo@472: public Gauge determineGauge(double a, double b) { ingo@488: List gauges = determineGauges(a, b); ingo@472: sascha@756: return gauges.isEmpty() ? null : gauges.get(0); ingo@472: } ingo@472: ingo@465: /** ingo@465: * Returns the min and max distance of this river. The first position in the ingo@465: * resulting array contains the min distance, the second position the max ingo@465: * distance. ingo@465: * ingo@465: * @return the min and max distance of this river. ingo@465: */ ingo@465: public double[] determineMinMaxDistance() { ingo@465: if (gauges == null) { ingo@465: return null; ingo@465: } ingo@465: ingo@465: double minmax[] = new double[] { Double.MAX_VALUE, Double.MIN_VALUE }; ingo@465: ingo@465: for (Gauge g: gauges) { ingo@465: Range r = g.getRange(); ingo@465: ingo@465: double a = r.getA().doubleValue(); ingo@465: minmax[0] = minmax[0] < a ? minmax[0] : a; ingo@465: ingo@465: BigDecimal bigB = r.getB(); ingo@465: if (bigB != null) { ingo@465: double b = bigB.doubleValue(); ingo@465: minmax[1] = minmax[1] > b ? minmax[1] : b; ingo@465: } ingo@465: } ingo@465: ingo@465: return minmax; ingo@465: } sascha@167: } sascha@167: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :