sascha@650: package de.intevation.flys.artifacts.model; sascha@650: sascha@3441: import de.intevation.flys.model.DischargeTable; sascha@3441: import de.intevation.flys.model.Gauge; sascha@3441: import de.intevation.flys.model.River; sascha@3441: sascha@3419: import de.intevation.flys.utils.DoubleUtil; sascha@3419: sascha@3419: import gnu.trove.TDoubleArrayList; sascha@650: sascha@650: import java.io.Serializable; sascha@650: sascha@3419: import java.util.ArrayList; sascha@3441: import java.util.Collections; sascha@3439: import java.util.Comparator; sascha@3419: import java.util.List; sascha@650: sascha@3419: import org.apache.log4j.Logger; sascha@655: sascha@650: public class Segment sascha@650: implements Serializable sascha@650: { sascha@3441: private static Logger log = Logger.getLogger(Segment.class); sascha@650: sascha@3439: public static final Comparator REF_CMP = sascha@3439: new Comparator() { sascha@3439: @Override sascha@3439: public int compare(Segment a, Segment b) { sascha@3439: double d = a.referencePoint - b.referencePoint; sascha@3439: if (d < 0d) return -1; sascha@3439: return d > 0d ? +1 : 0; sascha@3439: } sascha@3439: }; sascha@3439: sascha@650: protected double from; sascha@650: protected double to; sascha@650: protected double [] values; sascha@655: protected double [] backup; sascha@655: protected double referencePoint; sascha@650: sascha@650: public Segment() { sascha@650: } sascha@650: sascha@655: public Segment(double referencePoint) { sascha@655: this.referencePoint = referencePoint; sascha@655: } sascha@655: sascha@650: public Segment(double from, double to, double [] values) { sascha@650: this.from = from; sascha@650: this.to = to; sascha@650: this.values = values; sascha@650: } sascha@650: sascha@650: public boolean isUp() { sascha@650: return from < to; sascha@650: } sascha@650: sascha@3449: public boolean inside(double km) { sascha@3552: return from < to sascha@3449: ? km >= from && km <= to sascha@3449: : km >= to && km <= from; sascha@3449: } sascha@3449: sascha@3419: @Override sascha@650: public String toString() { sascha@650: StringBuilder sb = new StringBuilder("Segment: ["); sascha@650: sb.append("from: ").append(from).append("; to: ") sascha@670: .append(to) sascha@670: .append("; ref: ").append(referencePoint) sascha@670: .append("; values: ("); sascha@650: for (int i = 0; i < values.length; ++i) { sascha@650: if (i > 0) sb.append(", "); sascha@650: sb.append(values[i]); sascha@650: } sascha@650: sb.append(")]"); sascha@650: return sb.toString(); sascha@650: } sascha@650: sascha@655: public void setFrom(double from) { sascha@655: this.from = from; sascha@655: } sascha@655: sascha@655: public void backup() { sascha@3419: backup = values != null sascha@3419: ? (double [])values.clone() sascha@3419: : null; sascha@655: } sascha@655: sascha@3449: public double [] getBackup() { sascha@3449: return backup; sascha@3449: } sascha@3449: sascha@655: public double getFrom() { sascha@655: return from; sascha@655: } sascha@655: sascha@655: public void setTo(double to) { sascha@655: this.to = to; sascha@655: } sascha@655: sascha@655: public double getTo() { sascha@655: return to; sascha@655: } sascha@655: sascha@655: public void setValues(double [] values) { sascha@655: this.values = values; sascha@655: } sascha@655: sascha@655: public double [] getValues() { sascha@655: return values; sascha@655: } sascha@655: sascha@3449: public int numValues() { sascha@3449: return values.length; sascha@3449: } sascha@3449: sascha@655: public void setReferencePoint(double referencePoint) { sascha@655: this.referencePoint = referencePoint; sascha@655: } sascha@655: sascha@655: public double getReferencePoint() { sascha@655: return referencePoint; sascha@655: } sascha@655: sascha@650: public static List parseSegments(String input) { sascha@650: sascha@650: ArrayList segments = new ArrayList(); sascha@650: sascha@650: TDoubleArrayList vs = new TDoubleArrayList(); sascha@650: sascha@650: for (String segmentStr: input.split(":")) { sascha@650: String [] parts = segmentStr.split(";"); sascha@650: if (parts.length < 3) { sascha@3441: log.warn("invalid segment: '" + segmentStr + "'"); sascha@650: continue; sascha@650: } sascha@650: try { sascha@650: double from = Double.parseDouble(parts[0].trim()); sascha@650: double to = Double.parseDouble(parts[1].trim()); sascha@650: sascha@650: vs.clear(); sascha@650: sascha@650: for (String valueStr: parts[2].split(",")) { sascha@655: vs.add(DoubleUtil.round( sascha@655: Double.parseDouble(valueStr.trim()))); sascha@650: } sascha@650: sascha@650: double [] values = vs.toNativeArray(); sascha@650: segments.add(new Segment(from, to, values)); sascha@650: } sascha@650: catch (NumberFormatException nfe) { sascha@3441: log.warn("invalid segment: '" + segmentStr + "'"); sascha@650: } sascha@650: } sascha@650: sascha@650: return segments; sascha@650: } sascha@3441: sascha@3441: public static boolean setReferencePointConvertQ( sascha@3441: List segments, sascha@3441: River river, sascha@3441: boolean isQ, sascha@3441: Calculation report sascha@3441: ) { sascha@3441: int numResults = -1; sascha@3441: sascha@3441: boolean success = true; sascha@3441: sascha@3441: // assign reference points sascha@3441: for (Segment segment: segments) { sascha@3441: Gauge gauge = river.maxOverlap(segment.getFrom(), segment.getTo()); sascha@3441: sascha@3441: if (gauge == null) { sascha@3441: log.warn("no gauge found. Defaults to mid point."); sascha@3441: segment.setReferencePoint( sascha@3441: 0.5*(segment.getFrom()+segment.getTo())); sascha@3441: } sascha@3441: else { sascha@3441: double ref = gauge.getStation().doubleValue(); sascha@3441: log.debug( sascha@3441: "reference gauge: " + gauge.getName() + sascha@3441: " (km " + ref + ")"); sascha@3441: segment.setReferencePoint(ref); sascha@3441: } sascha@3441: sascha@3441: double [] values = segment.values; sascha@3441: sascha@3441: if (numResults == -1) { sascha@3441: numResults = values.length; sascha@3441: } sascha@3441: else if (numResults != values.length) { sascha@3441: log.warn("wrong length of values"); sascha@3441: return false; sascha@3441: } sascha@3441: sascha@3441: // convert to Q if needed sascha@3441: if (!isQ && gauge != null) { sascha@3441: sascha@3441: DischargeTable dt = gauge.fetchMasterDischargeTable(); sascha@3441: sascha@3441: double [][] table = sascha@3441: DischargeTables.loadDischargeTableValues(dt, 1); sascha@3441: sascha@3441: // need the original values for naming sascha@3441: segment.backup(); sascha@3441: sascha@3441: for (int i = 0; i < values.length; ++i) { sascha@3441: double w = values[i] / 100.0; sascha@3441: double [] qs = DischargeTables.getQsForW(table, w); sascha@3441: if (qs.length == 0) { sascha@3441: log.warn("No Qs found for W = " + values[i]); sascha@3441: report.addProblem("cannot.find.w.for.q", values[i]); sascha@3441: values[i] = Double.NaN; sascha@3441: success = false; sascha@3441: } sascha@3441: else { sascha@3441: values[i] = qs[0]; sascha@3441: if (qs.length > 1) { sascha@3441: log.warn( sascha@3441: "More than one Q found for W = " + values[i]); sascha@3441: } sascha@3441: } sascha@3441: } sascha@3441: } sascha@3441: } // for all segments sascha@3441: sascha@3441: Collections.sort(segments, Segment.REF_CMP); sascha@3441: sascha@3441: return success; sascha@3441: } sascha@650: } sascha@650: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :