changeset 6397:f579e4a80b84

Artifacts: Official lines finder: handle the cases from the state model.
author Sascha L. Teichmann <teichmann@intevation.de>
date Fri, 21 Jun 2013 17:36:50 +0200
parents f1018fd85183
children 13ecaf6c0f20
files artifacts/src/main/java/org/dive4elements/river/artifacts/model/OfficialLineFinder.java
diffstat 1 files changed, 116 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/artifacts/src/main/java/org/dive4elements/river/artifacts/model/OfficialLineFinder.java	Fri Jun 21 17:28:57 2013 +0200
+++ b/artifacts/src/main/java/org/dive4elements/river/artifacts/model/OfficialLineFinder.java	Fri Jun 21 17:36:50 2013 +0200
@@ -42,18 +42,21 @@
         private double value;
         private int    wstId;
         private int    columnPos;
+        private String name;
 
         public ValueRange(
             double start,
             double end, 
             double value,
             int    wstId,
-            int    columnPos
+            int    columnPos,
+            String name
         ) {
             super(start, end);
             this.value     = value;
             this.wstId     = wstId;
             this.columnPos = columnPos;
+            this.name      = name;
         }
 
         public boolean sameValue(double value) {
@@ -67,6 +70,23 @@
         public int getColumnPos() {
             return columnPos;
         }
+
+        public boolean intersectsValueRange(Range r) {
+            return r.inside(value);
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof ValueRange)) {
+                return false;
+            }
+            ValueRange r = (ValueRange)o;
+            return wstId == r.wstId && columnPos == r.columnPos;
+        }
     }
 
     public OfficialLineFinder() {
@@ -121,7 +141,7 @@
                         int    wstId = wst.getId();
                         int    pos   = wc.getPosition();
                         ValueRange range =
-                            new ValueRange(from, to, value, wstId, pos);
+                            new ValueRange(from, to, value, wstId, pos, name);
                         ranges.add(range);
                         break;
                     }
@@ -186,15 +206,98 @@
         return list;
     }
 
+    private static List<ValueRange> filterByQRange(Range range, List<ValueRange> ranges) {
+        List<ValueRange> list = new ArrayList<ValueRange>(ranges.size());
+        for (ValueRange r: ranges) {
+            if (r.intersectsValueRange(range) && !list.contains(r)) {
+                list.add(r);
+            }
+        }
+        return list;
+    }
+
     private static boolean isQ(D4EArtifact artifact) {
         Boolean b = artifact.getDataAsBoolean("wq_isq");
         return b != null && b;
     }
 
-    public static List<OfficialLine> findOfficialLines(D4EArtifact artifact) {
+    private static boolean isRange(D4EArtifact artifact) {
+        Boolean b = artifact.getDataAsBoolean("wq_isrange");
+        return b != null && b;
+    }
+
+    public static final Range Q_OUT_OF_RANGE = new Range(-10000, -9999);
+
+    private static Range singleQs(D4EArtifact artifact) {
+        String singleData = nn(artifact.getDataAsString("wq_single"));
+        double min =  Double.MAX_VALUE;
+        double max = -Double.MAX_VALUE;
+
+        for (String value: singleData.split(" ")) {
+            try {
+                double x = Double.parseDouble(value);
+                if (x < min) min = x;
+                if (x > max) max = x;
+            }
+            catch (NumberFormatException nfe) {
+            }
+        }
+
+        return min == Double.MAX_VALUE
+            ? Q_OUT_OF_RANGE
+            : new Range(min, max);
+
+    }
+
+    private static Range qRange(D4EArtifact artifact) {
+        try {
+            Double from = artifact.getDataAsDouble("wq_from");
+            Double to   = artifact.getDataAsDouble("wq_to");
+
+            if (from == null || to == null) {
+                return Q_OUT_OF_RANGE;
+            }
+            double f = from;
+            double t = to;
+            return new Range(Math.min(f, t), Math.max(f, t));
+        }
+        catch (NumberFormatException nfe) {
+            return Q_OUT_OF_RANGE;
+        }
+    }
+
+    private static Range tripleQRange(D4EArtifact artifact) {
+        String rangesData = nn(artifact.getDataAsString("wq_values"));
+
+        double min =  Double.MAX_VALUE;
+        double max = -Double.MAX_VALUE;
+
+        for (String range: rangesData.split(":")) {
+            String [] parts = range.split(";");
+            if (parts.length < 3) {
+                continue;
+            }
+            String [] values = parts[2].split(",");
+            for (String value: values) {
+                try {
+                    double x = Double.parseDouble(value);
+                    if (x < min) min = x;
+                    if (x > max) max = x;
+                }
+                catch (NumberFormatException nfe) {
+                }
+            }
+        }
+
+        return min == Double.MAX_VALUE
+            ? Q_OUT_OF_RANGE
+            : new Range(min, max);
+    }
+
+    public static List<ValueRange> findOfficialLines(D4EArtifact artifact) {
 
         if (!isQ(artifact)) { // Only handle Q calculations
-            return Collections.<OfficialLine>emptyList();
+            return Collections.<ValueRange>emptyList();
         }
 
         Map<String, List<ValueRange>> rivers2officialLines = getAll();
@@ -204,18 +307,23 @@
         List<ValueRange> ranges = rivers2officialLines.get(riverName);
 
         if (ranges == null) {
-            return Collections.<OfficialLine>emptyList();
+            return Collections.<ValueRange>emptyList();
         }
 
         ranges = filterByRange(extractRange(artifact), ranges);
 
         if (ranges.isEmpty()) {
-            return Collections.<OfficialLine>emptyList();
+            return Collections.<ValueRange>emptyList();
         }
 
+        Range qRange = isRange(artifact)
+            ? qRange(artifact)
+            : singleQs(artifact);
 
-        // TODO: Figure out all the cases here.
+        if (qRange == Q_OUT_OF_RANGE) {
+            qRange = tripleQRange(artifact);
+        }
 
-        return Collections.<OfficialLine>emptyList();
+        return filterByQRange(qRange, ranges);
     }
 }

http://dive4elements.wald.intevation.org