view backend/src/main/java/org/dive4elements/river/model/MeasurementStation.java @ 8602:0860e4f642c4

(issue1753) Use epsilon comparator to compare range km's
author Andre Heinecke <andre.heinecke@intevation.de>
date Fri, 20 Mar 2015 16:32:44 +0100
parents 724d8dfb628a
children 8fbc0649da13
line wrap: on
line source
/* Copyright (C) 2011, 2012, 2013 by Bundesanstalt für Gewässerkunde
 * Software engineering by Intevation GmbH
 *
 * This file is Free Software under the GNU AGPL (>=v3)
 * and comes with ABSOLUTELY NO WARRANTY! Check out the
 * documentation coming with Dive4Elements River for details.
 */

package org.dive4elements.river.model;

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

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.OneToOne;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

import org.hibernate.Session;
import org.hibernate.Query;

import org.dive4elements.river.backend.SessionHolder;

import static org.dive4elements.river.backend.utils.EpsilonComparator.CMP;

@Entity
@Table(name = "measurement_station")
public class MeasurementStation {

    private Integer id;

    private String name;
    private String measurementType;
    private String riverside;
    private String operator;
    private String comment;

    private Range range;

    private Gauge gauge;
    private String gaugeName;

    private TimeInterval observationTimerange;

    public static final class MeasurementStationComparator
        implements Comparator<MeasurementStation> {

        public MeasurementStationComparator() {
        }

        @Override
        public int compare(MeasurementStation m1, MeasurementStation m2)
            throws IllegalArgumentException {

            if (m1.getRange().getRiver() != m2.getRange().getRiver()) {
                throw new IllegalArgumentException(
                    "Stations not at same river");
            }

            boolean kmUp = m1.getRange().getRiver().getKmUp();
            double s1 = kmUp && m1.getRange().getB() != null
                ? m1.getRange().getB().doubleValue()
                : m1.getRange().getA().doubleValue();
            double s2 = kmUp && m2.getRange().getB() != null
                ? m2.getRange().getB().doubleValue()
                : m2.getRange().getA().doubleValue();

            int cmpStations = CMP.compare(s1, s2);
            if (cmpStations == 0) {
                if (m1.getMeasurementType().equals(m2.getMeasurementType())) {
                    throw new IllegalArgumentException(
                        "Two stations of same type at same km");
                }

                return m1.getMeasurementType().equals("Geschiebe") ? -1 : +1;
            }
            return cmpStations;
        }
    }

    public MeasurementStation() {
    }

    public MeasurementStation(String name, String measurementType,
        String riverside, Range range, Gauge gauge,
        String gaugeName, TimeInterval observationTimerange, String operator,
        String comment
    ) {
        this.name = name;
        this.measurementType = measurementType;
        this.riverside = riverside;
        this.range = range;
        this.gauge = gauge;
        this.gaugeName = gaugeName;
        this.observationTimerange = observationTimerange;
        this.operator = operator;
        this.comment = comment;
    }

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

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

    @Column(name = "name")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(name = "measurement_type")
    public String getMeasurementType() {
        return measurementType;
    }

    public void setMeasurementType(String measurementType) {
        this.measurementType = measurementType;
    }

    @Column(name = "riverside")
    public String getRiverside() {
        return riverside;
    }

    public void setRiverside(String riverside) {
        this.riverside = riverside;
    }

    @OneToOne
    @JoinColumn(name = "reference_gauge_id")
    public Gauge getGauge() {
        return gauge;
    }

    public void setGauge(Gauge gauge) {
        this.gauge = gauge;
    }

    @Column(name = "reference_gauge_name")
    public String getGaugeName() {
        return gaugeName;
    }

    public void setGaugeName(String gaugeName) {
        this.gaugeName = gaugeName;
    }

    @OneToOne
    @JoinColumn(name = "range_id")
    public Range getRange() {
        return range;
    }

    public void setRange(Range range) {
        this.range = range;
    }

    @OneToOne
    @JoinColumn(name = "time_interval_id")
    public TimeInterval getObservationTimerange() {
        return observationTimerange;
    }

    public void setObservationTimerange(TimeInterval observationTimerange) {
        this.observationTimerange = observationTimerange;
    }

    @Column(name = "operator")
    public String getOperator() {
        return operator;
    }

    public void setOperator(String operator) {
        this.operator = operator;
    }

    @Column(name = "commentary")
    public String getComment() {
        return comment;
    }

    public void setComment(String comment) {
        this.comment = comment;
    }

    public static List<MeasurementStation> getStationsAtRiver(River river) {
        Session session = SessionHolder.HOLDER.get();

        Query query = session.createQuery(
            "from MeasurementStation " +
            "where range.river = :river");
        query.setParameter("river", river);

        List<MeasurementStation> result = query.list();
        Collections.sort(result, new MeasurementStationComparator());
        return result;
    }

    public static List<MeasurementStation> getStationsAtKM(
        River river,
        Double river_km
    ) {
        Session session = SessionHolder.HOLDER.get();

        Query query = session.createQuery(
            "from MeasurementStation where range.river = :river");
        query.setParameter("river", river);

        List<MeasurementStation> result = new ArrayList<MeasurementStation>();
        for (Iterator iter = query.iterate(); iter.hasNext();) {
            MeasurementStation st = (MeasurementStation)iter.next();
            Double a = st.getRange().getA().doubleValue();
            Double b = st.getRange().getB() == null
                ? null
                : st.getRange().getB().doubleValue();

            // In case river is km_up, station is at larger value of range
            if (river.getKmUp() && b != null && CMP.compare(b, river_km) == 0
                || !river.getKmUp() && CMP.compare(a, river_km) == 0
                || b == null && CMP.compare(a, river_km) == 0 // no end km given
            ) {
                result.add(st);
            }
        }
        return result;
    }
}

http://dive4elements.wald.intevation.org