view flys-backend/src/main/java/de/intevation/flys/model/CrossSectionLine.java @ 2360:9df06b88c079

Added model class for relation 'river_axes_km'. flys-backend/trunk@3133 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 01 Nov 2011 15:30:38 +0000
parents 3efc3942b765
children c5d83366d0b1
line wrap: on
line source
package de.intevation.flys.model;

import java.io.Serializable;

import java.math.BigDecimal;

import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.Comparator;

import java.awt.geom.Point2D;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.GeneratedValue;
import javax.persistence.Column;
import javax.persistence.SequenceGenerator;
import javax.persistence.GenerationType;
import javax.persistence.OneToOne;
import javax.persistence.OneToMany;
import javax.persistence.JoinColumn;

import org.apache.log4j.Logger;

@Entity
@Table(name = "cross_section_lines")
public class CrossSectionLine
implements   Serializable
{
    private static Logger logger = Logger.getLogger(CrossSectionLine.class);

    public static final double EPSILON   = 1e-4;

    public static final double TOO_SMALL = 0.2;
    public static final double TOO_BIG   = 500;

    private Integer                 id;
    private BigDecimal              km;
    private CrossSection            crossSection;

    private List<CrossSectionPoint> points;

    public static final Comparator<CrossSectionPoint> COL_POS_CMP =
        new Comparator<CrossSectionPoint>() {
            @Override
            public int compare(CrossSectionPoint a, CrossSectionPoint b) {
                double xa = a.getX().doubleValue();
                double xb = b.getX().doubleValue();
                double d = xa - xb;
                if (d < -EPSILON) return -1;
                if (d > +EPSILON) return +1;
                int diff = a.getColPos() - b.getColPos();
                return diff < 0 ? -1 : diff > 0 ? +1 : 0;
            }
        };


    public static final boolean isValid(double x) {
        x = Math.abs(x);
        return x > TOO_SMALL && x < TOO_BIG;
    }    


    public CrossSectionLine() {
    }

    public CrossSectionLine(CrossSection crossSection, BigDecimal km) {
        this.crossSection = crossSection;
        this.km           = km;
    }

    @Id
    @SequenceGenerator(
        name           = "SEQUENCE_CROSS_SECTION_LINES_ID_SEQ",
        sequenceName   = "CROSS_SECTION_LINES_ID_SEQ",
        allocationSize = 1)
    @GeneratedValue(
        strategy  = GenerationType.SEQUENCE,
        generator = "SEQUENCE_CROSS_SECTION_LINES_ID_SEQ")
    @Column(name = "id")
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(name = "km")
    public BigDecimal getKm() {
        return km;
    }

    public void setKm(BigDecimal km) {
        this.km = km;
    }

    @OneToOne
    @JoinColumn(name = "cross_section_id")
    public CrossSection getCrossSection() {
        return crossSection;
    }

    public void setCrossSection(CrossSection CrossSection) {
        this.crossSection = crossSection;
    }

    @OneToMany
    @JoinColumn(name="cross_section_line_id")
    public List<CrossSectionPoint> getPoints() {
        return points;
    }

    public void setPoints(List<CrossSectionPoint> points) {
        this.points = points;
    }


    public List<Point2D> fetchCrossSectionLinesPoints() {
        List<Point2D> points = new ArrayList<Point2D>();

        List<CrossSectionPoint> linePoints = getPoints();

        if (linePoints.isEmpty()) {
            logger.info("No points in selected CrossSectionLine.");
            return points;
        }

        linePoints = new ArrayList(linePoints);
        Collections.sort(linePoints, COL_POS_CMP);

        for (CrossSectionPoint p: linePoints) {
            double x = p.getX().doubleValue();
            double y = p.getY().doubleValue();
            if (isValid(x) && isValid(y)) {
                points.add(new Point2D.Double(x, y));
            }
        }

        return points;
    }

    public double [][] fetchCrossSectionProfile() {
        return fetchCrossSectionProfile(fetchCrossSectionLinesPoints());
    }

    public static double [][] fetchCrossSectionProfile(List<Point2D> points) {

        int P = points.size();

        double [] xs = new double[P];
        double [] ys = new double[P];

        if (P > 0) {
            xs[0] = points.get(0).getX();
            ys[0] = points.get(0).getY();

            for (int i = 1; i < P; i++) {
                Point2D p = points.get(i);
                double x = p.getX();
                double y = p.getY();

                if (x <= xs[i-1]) {
                    x = xs[i-1] + EPSILON;
                }

                xs[i] = x;
                ys[i] = y; 
            }
        }

        return new double [][] { xs, ys };
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org