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@1203: sascha@1203: import java.io.Serializable; sascha@1203: sascha@2342: import java.util.ArrayList; sascha@1203: import java.util.List; sascha@2342: import java.util.Collections; sascha@2342: import java.util.Comparator; sascha@2342: sascha@2342: import java.awt.geom.Point2D; sascha@1203: sascha@1203: import javax.persistence.Entity; sascha@1203: import javax.persistence.Id; sascha@1203: import javax.persistence.Table; sascha@1203: import javax.persistence.GeneratedValue; sascha@1203: import javax.persistence.Column; sascha@1203: import javax.persistence.SequenceGenerator; sascha@1203: import javax.persistence.GenerationType; sascha@1203: import javax.persistence.OneToOne; sascha@1203: import javax.persistence.OneToMany; sascha@1203: import javax.persistence.JoinColumn; sascha@1203: sascha@2342: import org.apache.log4j.Logger; sascha@2342: sascha@1203: @Entity sascha@1203: @Table(name = "cross_section_lines") sascha@1203: public class CrossSectionLine sascha@1203: implements Serializable sascha@1203: { sascha@2342: private static Logger logger = Logger.getLogger(CrossSectionLine.class); sascha@2342: sascha@2342: public static final double EPSILON = 1e-4; sascha@2342: sascha@2342: public static final double TOO_SMALL = 0.2; felix@3684: public static final double TOO_BIG = 2500; sascha@2342: sascha@1203: private Integer id; felix@6281: private Double km; sascha@1203: private CrossSection crossSection; sascha@1203: sascha@1204: private List points; sascha@1204: sascha@2342: public static final Comparator COL_POS_CMP = sascha@2342: new Comparator() { sascha@2342: @Override sascha@2342: public int compare(CrossSectionPoint a, CrossSectionPoint b) { sascha@2342: double xa = a.getX().doubleValue(); sascha@2342: double xb = b.getX().doubleValue(); sascha@2342: double d = xa - xb; sascha@2342: if (d < -EPSILON) return -1; sascha@2342: if (d > +EPSILON) return +1; sascha@2342: int diff = a.getColPos() - b.getColPos(); sascha@2342: return diff < 0 ? -1 : diff > 0 ? +1 : 0; sascha@2342: } sascha@2342: }; sascha@2342: sascha@2342: sascha@2342: public static final boolean isValid(double x) { sascha@2342: x = Math.abs(x); sascha@2342: return x > TOO_SMALL && x < TOO_BIG; sascha@2380: } sascha@2380: sascha@2380: public static final boolean isValid(Point2D p) { sascha@2380: return isValid(p.getX()) && isValid(p.getY()); sascha@2380: } sascha@2342: sascha@2342: sascha@1203: public CrossSectionLine() { sascha@1203: } sascha@1203: sascha@2860: public CrossSectionLine(CrossSection crossSection, Double km) { sascha@1204: this.crossSection = crossSection; sascha@1204: this.km = km; sascha@1204: } sascha@1204: sascha@1203: @Id sascha@1203: @SequenceGenerator( sascha@1203: name = "SEQUENCE_CROSS_SECTION_LINES_ID_SEQ", sascha@1203: sequenceName = "CROSS_SECTION_LINES_ID_SEQ", sascha@1203: allocationSize = 1) sascha@1203: @GeneratedValue( sascha@1203: strategy = GenerationType.SEQUENCE, sascha@1203: generator = "SEQUENCE_CROSS_SECTION_LINES_ID_SEQ") sascha@1203: @Column(name = "id") sascha@1203: public Integer getId() { sascha@1203: return id; sascha@1203: } sascha@1203: sascha@1203: public void setId(Integer id) { sascha@1203: this.id = id; sascha@1203: } sascha@1203: sascha@1203: @Column(name = "km") sascha@2860: public Double getKm() { sascha@1203: return km; sascha@1203: } sascha@1203: sascha@2860: public void setKm(Double km) { sascha@1203: this.km = km; sascha@1203: } sascha@1203: sascha@1203: @OneToOne sascha@1203: @JoinColumn(name = "cross_section_id") sascha@1203: public CrossSection getCrossSection() { sascha@1203: return crossSection; sascha@1203: } sascha@1203: felix@6058: public void setCrossSection(CrossSection crossSection) { sascha@1203: this.crossSection = crossSection; sascha@1203: } sascha@1203: sascha@1203: @OneToMany sascha@1203: @JoinColumn(name="cross_section_line_id") sascha@1203: public List getPoints() { sascha@1203: return points; sascha@1203: } sascha@1203: sascha@1203: public void setPoints(List points) { sascha@1203: this.points = points; sascha@1203: } sascha@2342: sascha@2342: sascha@2342: public List fetchCrossSectionLinesPoints() { sascha@2342: sascha@3334: List linePoints = sascha@2378: new ArrayList(getPoints()); sascha@2342: sascha@2342: Collections.sort(linePoints, COL_POS_CMP); sascha@2342: sascha@2378: List points = new ArrayList(linePoints.size()); sascha@2342: for (CrossSectionPoint p: linePoints) { sascha@2342: double x = p.getX().doubleValue(); sascha@2342: double y = p.getY().doubleValue(); sascha@2342: if (isValid(x) && isValid(y)) { sascha@2342: points.add(new Point2D.Double(x, y)); sascha@2342: } sascha@2342: } sascha@2342: sascha@2342: return points; sascha@2342: } sascha@2342: sascha@2342: public double [][] fetchCrossSectionProfile() { sascha@2342: return fetchCrossSectionProfile(fetchCrossSectionLinesPoints()); sascha@2342: } sascha@2342: felix@6281: /** double[][] from List */ sascha@2342: public static double [][] fetchCrossSectionProfile(List points) { sascha@2342: sascha@2342: int P = points.size(); sascha@2342: sascha@2342: double [] xs = new double[P]; sascha@2342: double [] ys = new double[P]; sascha@2342: sascha@2342: if (P > 0) { sascha@2342: xs[0] = points.get(0).getX(); sascha@2342: ys[0] = points.get(0).getY(); sascha@2342: sascha@2342: for (int i = 1; i < P; i++) { sascha@2342: Point2D p = points.get(i); sascha@2342: double x = p.getX(); sascha@2342: double y = p.getY(); sascha@2342: sascha@2342: if (x <= xs[i-1]) { sascha@2342: x = xs[i-1] + EPSILON; sascha@2342: } sascha@2342: sascha@2342: xs[i] = x; sascha@3334: ys[i] = y; sascha@2342: } sascha@2342: } sascha@2342: sascha@2342: return new double [][] { xs, ys }; sascha@2342: } sascha@1203: } sascha@1203: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :