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@1194: sascha@1194: import java.io.Serializable; sascha@1194: sascha@1194: import java.util.List; sascha@2380: import java.util.ArrayList; sascha@2380: sascha@2380: import java.awt.geom.Point2D; sascha@1194: sascha@1194: import javax.persistence.Entity; sascha@1194: import javax.persistence.Id; sascha@1194: import javax.persistence.Table; sascha@1194: import javax.persistence.GeneratedValue; sascha@1194: import javax.persistence.Column; sascha@1194: import javax.persistence.SequenceGenerator; sascha@1194: import javax.persistence.GenerationType; sascha@1194: import javax.persistence.OneToOne; sascha@1194: import javax.persistence.OneToMany; sascha@1210: import javax.persistence.OrderBy; sascha@1194: import javax.persistence.JoinColumn; sascha@1194: sascha@2379: import java.math.MathContext; sascha@2379: import java.math.BigDecimal; sascha@2379: sascha@2379: import org.hibernate.Session; sascha@2380: import org.hibernate.SQLQuery; sascha@2379: import org.hibernate.Query; sascha@2379: sascha@2380: import org.hibernate.type.StandardBasicTypes; sascha@2380: teichmann@5829: import org.dive4elements.river.backend.SessionHolder; sascha@2379: sascha@1194: @Entity sascha@1194: @Table(name = "cross_sections") sascha@1194: public class CrossSection sascha@1194: implements Serializable sascha@1194: { sascha@2379: public static final MathContext PRECISION = new MathContext(6); sascha@2379: sascha@2380: public static final String SQL_FAST_CROSS_SECTION_LINES = sascha@2380: "SELECT km, x, y, csl.id AS csl_id " + sascha@2380: "FROM cross_section_lines csl JOIN cross_section_points csp " + sascha@2380: "ON csp.cross_section_line_id = csl.id " + sascha@2380: "WHERE csl.cross_section_id = :cs_id AND " + sascha@3334: "km between :from_km AND :to_km " + sascha@2380: "ORDER BY csl.id, csp.col_pos"; sascha@2380: sascha@1203: private Integer id; sascha@1203: private River river; sascha@1203: private TimeInterval timeInterval; sascha@1203: private String description; sascha@1203: private List lines; sascha@1194: sascha@1194: public CrossSection() { sascha@1194: } sascha@1194: sascha@1204: public CrossSection( sascha@1204: River river, sascha@1204: TimeInterval timeInterval, sascha@1204: String description sascha@1204: ) { sascha@1204: this.river = river; sascha@1204: this.timeInterval = timeInterval; sascha@1204: this.description = description; sascha@1204: } sascha@1204: sascha@1194: @Id sascha@1194: @SequenceGenerator( sascha@1194: name = "SEQUENCE_CROSS_SECTIONS_ID_SEQ", sascha@1194: sequenceName = "CROSS_SECTIONS_ID_SEQ", sascha@1194: allocationSize = 1) sascha@1194: @GeneratedValue( sascha@1194: strategy = GenerationType.SEQUENCE, sascha@1194: generator = "SEQUENCE_CROSS_SECTIONS_ID_SEQ") sascha@1194: @Column(name = "id") sascha@1194: public Integer getId() { sascha@1194: return id; sascha@1194: } sascha@1194: sascha@1194: public void setId(Integer id) { sascha@1194: this.id = id; sascha@1194: } sascha@1194: sascha@1194: @OneToOne sascha@1194: @JoinColumn(name = "river_id") sascha@1194: public River getRiver() { sascha@1194: return river; sascha@1194: } sascha@1194: sascha@1194: public void setRiver(River river) { sascha@1194: this.river = river; sascha@1194: } sascha@1194: sascha@1194: @OneToOne sascha@1194: @JoinColumn(name = "time_interval_id") sascha@1194: public TimeInterval getTimeInterval() { sascha@1194: return timeInterval; sascha@1194: } sascha@1194: sascha@1194: public void setTimeInterval(TimeInterval timeInterval) { sascha@1194: this.timeInterval = timeInterval; sascha@1194: } sascha@1194: sascha@1202: @Column(name = "description") sascha@1202: public String getDescription() { sascha@1202: return description; sascha@1202: } sascha@1202: sascha@1202: public void setDescription(String description) { sascha@1202: this.description = description; sascha@1202: } sascha@1202: sascha@1194: @OneToMany sascha@1210: @OrderBy("km") sascha@1194: @JoinColumn(name="cross_section_id") sascha@1203: public List getLines() { sascha@1203: return lines; sascha@1194: } sascha@1194: sascha@1203: public void setLines(List lines) { sascha@1203: this.lines = lines; sascha@1194: } sascha@2379: sascha@2379: public List getLines(double startKm, double endKm) { sascha@2379: Session session = SessionHolder.HOLDER.get(); sascha@2379: Query query = session.createQuery( sascha@2379: "from CrossSectionLine where crossSection=:crossSection " + sascha@2379: "and km between :startKm and :endKm order by km"); sascha@2379: query.setParameter("crossSection", this); sascha@2379: query.setParameter("startKm", new BigDecimal(startKm, PRECISION)); sascha@2379: query.setParameter("endKm", new BigDecimal(endKm, PRECISION)); sascha@2379: sascha@2379: return query.list(); sascha@2379: } sascha@2380: sascha@2380: public List getFastLines( sascha@2380: double startKm, sascha@2380: double endKm sascha@2380: ) { sascha@2380: Session session = SessionHolder.HOLDER.get(); sascha@2380: sascha@2380: SQLQuery sqlQuery = session.createSQLQuery(SQL_FAST_CROSS_SECTION_LINES) sascha@2380: .addScalar("km", StandardBasicTypes.DOUBLE) sascha@2380: .addScalar("x", StandardBasicTypes.DOUBLE) sascha@2380: .addScalar("y", StandardBasicTypes.DOUBLE) sascha@2380: .addScalar("csl_id", StandardBasicTypes.INTEGER); sascha@2380: sascha@2380: sqlQuery sascha@2380: .setInteger("cs_id", getId()) sascha@2380: .setDouble("from_km", startKm) sascha@2380: .setDouble("to_km", endKm); sascha@2380: sascha@2380: List results = sqlQuery.list(); sascha@2380: sascha@2380: ArrayList points = new ArrayList(500); sascha@2380: ArrayList lines = sascha@2380: new ArrayList(); sascha@2380: sascha@2380: Integer lastId = null; sascha@2380: Double lastKm = null; sascha@2380: sascha@2380: for (Object [] result: results) { sascha@2380: Double km = (Double)result[0]; sascha@2380: Double x = (Double)result[1]; sascha@2380: Double y = (Double)result[2]; sascha@2380: Integer id = (Integer)result[3]; sascha@2380: sascha@2380: if (lastId != null && !lastId.equals(id)) { sascha@2380: points.trimToSize(); sascha@2380: FastCrossSectionLine line = sascha@2380: new FastCrossSectionLine(lastKm, points); sascha@2380: lines.add(line); sascha@2380: points = new ArrayList(500); sascha@2380: } sascha@2380: sascha@2380: Point2D p = new Point2D.Double(x, y); sascha@2380: sascha@2380: if (CrossSectionLine.isValid(p)) { sascha@2380: points.add(p); sascha@2380: } sascha@2380: sascha@2380: lastKm = km; sascha@2380: lastId = id; sascha@2380: } sascha@2380: sascha@2380: if (lastId != null) { sascha@2380: points.trimToSize(); sascha@2380: FastCrossSectionLine line = sascha@2380: new FastCrossSectionLine(lastKm, points); sascha@2380: lines.add(line); sascha@2380: } sascha@2380: sascha@2380: lines.trimToSize(); sascha@2380: sascha@2380: return lines; sascha@2380: } sascha@1194: } sascha@1194: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :