changeset 4814:47c529e2be26

merged.
author Raimund Renkert <rrenkert@intevation.de>
date Sun, 20 Jan 2013 15:04:32 +0100
parents bf2fd9c58ac4 (current diff) 65bfb6faa538 (diff)
children 61c2f739cf78 9e25c7523485
files
diffstat 22 files changed, 607 insertions(+), 224 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/doc/conf/mapserver/river-mapfile.vm	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/doc/conf/mapserver/river-mapfile.vm	Sun Jan 20 15:04:32 2013 +0100
@@ -3,7 +3,7 @@
     STATUS ON
     SIZE 600 400
     MAXSIZE 4000
-    EXTENT 3233232.55407617 5303455.37850183 3421524.44644752 5585825.50888523
+    #EXTENT 3233232.55407617 5303455.37850183 3421524.44644752 5585825.50888523
     UNITS DD
     SHAPEPATH "$SHAPEFILEPATH"
     FONTSET "$CONFIGDIR/mapserver/fontset.txt"
@@ -13,13 +13,13 @@
         "init=epsg:31467"
     END
 
-    DEBUG 5
+    DEBUG 3
     CONFIG "MS_ERRORFILE" "log/rivers.log"
 
     WEB
       METADATA
         "wms_title"             "FLYS Rivers Web Map Service"
-        "wms_onlineresource"    "$MAPSERVERURL"
+        #"wms_onlineresource"    "http://localhost:7777/river-wms" # "$MAPSERVERURL"
         "wms_accessconstraints" "none"
         "wms_fees"              "none"
         "wms_addresstype"       "postal"
--- a/flys-artifacts/doc/conf/mapserver/riveraxis-layer.vm	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/doc/conf/mapserver/riveraxis-layer.vm	Sun Jan 20 15:04:32 2013 +0100
@@ -20,10 +20,6 @@
         LABELITEM $LAYER.getLabelItem()
     #end
 
-    PROJECTION
-        "init=epsg:31467"
-    END
-
     METADATA
         "wms_title" "$LAYER.getTitle()"
         "gml_include_items" "all"
@@ -36,7 +32,7 @@
         $LAYER.getStyle()
     #else
         CLASS
-            NAME ""
+            NAME "unnamedclass"
             STYLE
                 SIZE 5
                 OUTLINECOLOR "#000000"
@@ -52,6 +48,7 @@
                     OFFSET 2 2
                 END
             #end
+            
         END
-    #end
+   #end
 END
\ No newline at end of file
--- a/flys-artifacts/doc/conf/rivermap.xml	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/doc/conf/rivermap.xml	Sun Jan 20 15:04:32 2013 +0100
@@ -11,4 +11,20 @@
     <velocity>
         <logfile path="${artifacts.config.dir}/../rivermap_velocity.log"/>
     </velocity>
+    
+    <river name="Saar">
+        <srid value="31467"/>
+        <river-wms url="http://localhost:7777/cgi-bin/river-wms" layers="Saar"/>
+        <background-wms url="http://osm.intevation.de/mapcache/?" layers="flys-wms"/>
+    </river>
+    <river name="Mosel">
+        <srid value="31467"/>
+        <river-wms url="http://localhost:7777/cgi-bin/river-wms" layers="Mosel"/>
+        <background-wms url="http://osm.intevation.de/mapcache/?" layers="flys-wms"/>
+    </river>
+    <river name="Elbe">
+        <srid value="31467"/>
+        <river-wms url="http://localhost:7777/cgi-bin/river-wms" layers="Elbe"/>
+        <background-wms url="http://osm.intevation.de/mapcache/?" layers="flys-wms"/>
+    </river>
 </rivermap>
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/WINFOArtifact.java	Sun Jan 20 15:04:32 2013 +0100
@@ -10,6 +10,8 @@
 
 import de.intevation.artifacts.common.utils.StringUtils;
 
+import de.intevation.flys.artifacts.access.Calculation4Access;
+
 import de.intevation.flys.artifacts.geom.Lines;
 
 import de.intevation.flys.artifacts.model.Calculation1;
@@ -22,15 +24,16 @@
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.DischargeTables;
 import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.Segment;
 import de.intevation.flys.artifacts.model.WQCKms;
 import de.intevation.flys.artifacts.model.WQKms;
 import de.intevation.flys.artifacts.model.WW;
 import de.intevation.flys.artifacts.model.WstValueTable;
 import de.intevation.flys.artifacts.model.WstValueTableFactory;
+
 import de.intevation.flys.artifacts.model.extreme.ExtremeResult;
 
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
 import de.intevation.flys.artifacts.states.LocationDistanceSelect;
 
 import de.intevation.flys.model.DischargeTable;
@@ -47,7 +50,6 @@
 
 import java.util.Arrays;
 import java.util.Calendar;
-import java.util.Collections;
 import java.util.GregorianCalendar;
 import java.util.List;
 import java.util.Map;
@@ -169,6 +171,12 @@
         return this.getWaterlevelData(null);
     }
 
+    // THIS IS FREAKY BULLSHIT! Felix, why do you call the calculation directly????
+    protected CalculationResult getDischargeLongitudinalSectionData() {
+        // XXX: THIS AN _EXPENSIVE_ CALCULATION! CACHE IT!
+        return new Calculation4(new Calculation4Access(this)).calculate();
+    }
+
     /**
      * Returns the data that is computed by a waterlevel computation.
      *
@@ -405,48 +413,6 @@
 
 
     /**
-     * Returns the data computed by the discharge longitudinal section
-     * computation.
-     *
-     * @return an array of WQKms object - one object for each given Q value.
-     */
-    public CalculationResult getDischargeLongitudinalSectionData() {
-
-        logger.debug("WINFOArtifact.getDischargeLongitudinalSectionData");
-
-        River river = FLYSUtils.getRiver(this);
-        if (river == null) {
-            logger.debug("No river selected.");
-            return error(new WQKms[0], "no.river.selected");
-        }
-
-        WstValueTable table = WstValueTableFactory.getTable(river);
-        if (table == null) {
-            logger.debug("No wst found for selected river.");
-            return error(new WQKms[0], "no.wst.for.river");
-        }
-
-        List<Segment> segments = getSegments();
-
-        if (segments == null) {
-            logger.debug("Cannot create segments.");
-            return error(new WQKms[0], "cannot.create.segments");
-        }
-
-        double [] range = getFromToStep();
-
-        if (range == null) {
-            logger.debug("Cannot figure out range.");
-            return error(new WQKms[0], "no.range.found");
-        }
-
-        Calculation4 calc4 = new Calculation4(segments, river, isQ());
-
-        return calc4.calculate(table, range[0], range[1], range[2]);
-    }
-
-
-    /**
      * Returns the data that is computed by a reference curve computation.
      *
      * @return the data computed by a reference curve computation.
@@ -574,21 +540,6 @@
     }
 
 
-    public List<Segment> getSegments() {
-        StateData wqValues = getData("wq_values");
-        if (wqValues == null) {
-            logger.warn("no wq_values given");
-            return Collections.<Segment>emptyList();
-        }
-        String input = (String) wqValues.getValue();
-        if (input == null || (input = input.trim()).length() == 0) {
-            logger.warn("wq_values are empty");
-            return Collections.<Segment>emptyList();
-        }
-        return Segment.parseSegments(input);
-    }
-
-
     /**
      * Get corrected waterline against surface/profile.
      */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/access/Calculation4Access.java	Sun Jan 20 15:04:32 2013 +0100
@@ -0,0 +1,90 @@
+package de.intevation.flys.artifacts.access;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.model.Segment;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.utils.DoubleUtil;
+import de.intevation.flys.utils.FLYSUtils;
+
+public class Calculation4Access
+extends      RiverAccess
+{
+    private static Logger log = Logger.getLogger(Calculation4Access.class);
+
+    protected List<Segment> segments;
+
+    protected double [] fromToStep;
+
+    protected Boolean isQ;
+
+    protected Boolean isRange;
+
+    public Calculation4Access() {
+    }
+
+    public Calculation4Access(FLYSArtifact artifact) {
+        super(artifact);
+    }
+
+    public List<Segment> getSegments() {
+        if (segments == null) {
+            String input = getString("wq_values");
+            if (input == null || (input = input.trim()).length() == 0) {
+                log.warn("no wq_values given");
+                segments = Collections.<Segment>emptyList();
+            }
+        }
+        return segments;
+    }
+
+    public boolean isQ() {
+        if (isQ == null) {
+            Boolean value = getBoolean("wq_isq");
+            isQ = value != null && value;
+        }
+        return isQ;
+    }
+
+    public boolean isRange() {
+        if (isRange == null) {
+            String mode = getString("ld_mode");
+            isRange = mode == null || mode.equals("distance");
+        }
+        return isRange;
+    }
+
+    public double [] getFromToStep() {
+        if (fromToStep == null) {
+            // XXX: Is this really needed in this calculation?
+            if (!isRange()) {
+                return null;
+            }
+
+            // XXX: FLYSArtifact sucks!
+            double [] fromTo = FLYSUtils.getKmRange(artifact);
+
+            if (fromTo == null) {
+                return null;
+            }
+
+            Double dStep = getDouble("ld_step");
+            if (dStep == null) {
+                return null;
+            }
+
+            fromToStep =  new double [] {
+                fromTo[0],
+                fromTo[1],
+                DoubleUtil.round(dStep / 1000d)
+            };
+        }
+        return fromToStep;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/templating/CompiledStatement.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/datacage/templating/CompiledStatement.java	Sun Jan 20 15:04:32 2013 +0100
@@ -188,6 +188,7 @@
 
         int index = 0;
 
+        // Find variables like ${varname}.
         while (m.find()) {
             String key = m.group(1).toUpperCase();
             List<Integer> indices = positions.get(key);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/StdDevOutlier.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/math/StdDevOutlier.java	Sun Jan 20 15:04:32 2013 +0100
@@ -2,21 +2,12 @@
 
 import java.util.List;
 
-import org.apache.commons.math.MathException;
-
-import org.apache.commons.math.distribution.TDistributionImpl;
-
-import org.apache.commons.math.stat.descriptive.moment.Mean;
 import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
 
 import org.apache.log4j.Logger;
 
-import de.intevation.flys.artifacts.model.sq.SQ;
-
 public class StdDevOutlier
 {
-    public static final double EPSILON = 1e-5;
-
     public static final double DEFAULT_FACTOR = 3;
 
     private static Logger log = Logger.getLogger(StdDevOutlier.class);
@@ -28,7 +19,11 @@
         return findOutlier(values, DEFAULT_FACTOR, null);
     }
 
-    public static Integer findOutlier(List<Double> values, double factor, double[] stdDevResult) {
+    public static Integer findOutlier(
+        List<Double> values,
+        double       factor, 
+        double []    stdDevResult
+    ) {
         boolean debug = log.isDebugEnabled();
 
         if (debug) {
@@ -41,7 +36,7 @@
             log.debug("Values to check: " + N);
         }
 
-        if (values.size() < 3) {
+        if (N < 3) {
             return null;
         }
 
@@ -49,15 +44,13 @@
 
         double maxValue = -Double.MAX_VALUE;
         int    maxIndex = -1;
-        int    ndx = 0;
-        for (int i = values.size()-1; i >= 0; --i) {
+        for (int i = N-1; i >= 0; --i) {
             double value = Math.abs(values.get(i));
             stdDev.increment(value);
             if (value > maxValue) {
                 maxValue = value;
-                maxIndex = ndx;
+                maxIndex = i;
             }
-            ++ndx;
         }
 
         double sd = stdDev.getResult();
@@ -69,9 +62,11 @@
             log.debug("accepted: " + accepted);
             log.debug("max value: " + maxValue);
         }
+
         if (stdDevResult != null) {
             stdDevResult[0] = sd;
         }
+
         return maxValue > accepted ? maxIndex : null;
     }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation4.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/Calculation4.java	Sun Jan 20 15:04:32 2013 +0100
@@ -5,12 +5,16 @@
 import de.intevation.flys.artifacts.math.Identity;
 import de.intevation.flys.artifacts.math.Linear;
 
+import de.intevation.flys.artifacts.model.RiverFactory;
 import de.intevation.flys.artifacts.model.WstValueTable.QPosition;
 
 import de.intevation.flys.model.River;
 
 import de.intevation.flys.utils.DoubleUtil;
 
+import de.intevation.flys.artifacts.access.Calculation4Access;
+
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
 
@@ -25,23 +29,69 @@
 
     protected List<Segment> segments;
 
-    protected boolean       isQ;
+    protected boolean isQ;
+    protected double  from;
+    protected double  to;
+    protected double  step;
+    protected String  river;
 
     public Calculation4() {
     }
 
-    public Calculation4(List<Segment> segments, River river, boolean isQ) {
+    public Calculation4(Calculation4Access access) {
+        String        river    = access.getRiver();
+        List<Segment> segments = access.getSegments();
+        double []     range    = access.getFromToStep();
+        boolean       isQ      = access.isQ();
 
-        this.segments = segments;
-        this.isQ      = isQ;
+        if (river == null) {
+            addProblem("no.river.selected");
+        }
 
-        Segment.setReferencePointConvertQ(segments, river, isQ, this);
+        if (range == null) {
+            addProblem("no.range.found");
+        }
+
+        if (segments == null || segments.isEmpty()) {
+            addProblem("cannot.create.segments");
+        }
+
+        if (!hasProblems()) {
+            this.river    = river;
+            this.segments = segments;
+            this.from     = range[0];
+            this.to       = range[1];
+            this.step     = range[2];
+            this.isQ      = isQ;
+        }
     }
 
-    public CalculationResult calculate(
-        WstValueTable table,
-        double from, double to, double step
-    ) {
+    public CalculationResult calculate() {
+        if (hasProblems()) {
+            return new CalculationResult(new WQKms[0], this);
+        }
+
+        WstValueTable table = null;
+        River r = RiverFactory.getRiver(river);
+        if (r == null) {
+            addProblem("no.river.found");
+        }
+        else {
+            table = WstValueTableFactory.getTable(r);
+            if (table == null) {
+                addProblem("no.wst.for.river");
+            }
+            else {
+                Segment.setReferencePointConvertQ(segments, r, isQ, this);
+            }
+        }
+
+        return hasProblems()
+            ? new CalculationResult(new WQKms[0], this)
+            : innerCalculate(table);
+    }
+
+    protected CalculationResult innerCalculate(WstValueTable table) {
         boolean debug = logger.isDebugEnabled();
 
         if (debug) {
@@ -53,12 +103,6 @@
             }
         }
 
-        if (segments.isEmpty()) {
-            logger.debug("no segments found");
-            addProblem("no.segments.found");
-            return new CalculationResult(new WQKms[0], this);
-        }
-
         int numResults = segments.get(0).values.length;
 
         if (numResults < 1) {
@@ -228,9 +272,63 @@
             results[i].setName(createName(i));
         }
 
+        // Generate the "Umhuellende".
+        results = generateInfolding(table, results, from, to, step);
+
         return new CalculationResult(results, this);
     }
 
+    protected WQKms [] generateInfolding(
+        WstValueTable wst,
+        WQKms []      results,
+        double        from,
+        double        to,
+        double        step
+    ) {
+        WstValueTable.Column [] columns = wst.getColumns();
+
+        InfoldingColumns ic = new InfoldingColumns(columns);
+        ic.markInfoldingColumns(results);
+
+        List<WQKms> infoldings = new ArrayList<WQKms>();
+
+        boolean [] infoldingColumns = ic.getInfoldingColumns();
+        for (int i = 0; i < infoldingColumns.length; ++i) {
+            if (!infoldingColumns[i]) {
+                continue;
+            }
+            double q = columns[i].getQRangeTree().findQ(from);
+            if (Double.isNaN(q)) {
+                addProblem(from, "cannot.find.q");
+                continue;
+            }
+            double [] kms = DoubleUtil.explode(from, to, step);
+            double [] oqs = new double[kms.length];
+            double [] ows = new double[kms.length];
+            boolean success =
+                wst.interpolate(q, from, kms, ows, oqs, this) != null;
+
+            if (success) {
+                // TODO: generate a better name. I18N.
+                String name = "Umh\u00fcllende " + columns[i].getName();
+                WQKms wqkms = new WQKms(kms, oqs, ows, name);
+                infoldings.add(wqkms);
+            }
+        }
+
+        int N = infoldings.size();
+        if (N > 0) {
+            WQKms [] newResults = new WQKms[results.length + N];
+            System.arraycopy(results, 0, newResults, 0, results.length);
+            for (int i = 0; i < N; ++i) {
+                newResults[i+results.length] = infoldings.get(i);
+            }
+            results = newResults;
+        }
+
+        return results;
+    }
+
     protected String createName(int index) {
         // TODO: i18n
         StringBuilder sb = new StringBuilder(isQ ? "Q" : "W");
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/InfoldingColumns.java	Sun Jan 20 15:04:32 2013 +0100
@@ -0,0 +1,78 @@
+package de.intevation.flys.artifacts.model;
+
+/** A pretty naive pointwise algorithm to find out the columns
+ *  of a WSTValueTable which imfold ("umhuellen") a set of WQKMs
+ *  in terms of Q.
+ *  A better implemention would exploit the fact that the
+ *  Qs normally are constant for a while along km. This would
+ *  reduce the runtime complexity to only a few Q spans instead
+ *  of the pointwise evaluation.
+ */
+public class InfoldingColumns
+{
+    private QRangeTree.QuickQFinder [] qFinders;
+
+    private boolean [] infoldingColumns;
+
+    public InfoldingColumns() {
+    }
+
+    public InfoldingColumns(WstValueTable.Column [] columns) {
+
+        qFinders = new QRangeTree.QuickQFinder[columns.length];
+        for (int i = 0; i < qFinders.length; ++i) {
+            qFinders[i] = columns[i].getQRangeTree().new QuickQFinder();
+        }
+
+        infoldingColumns = new boolean[columns.length];
+    }
+
+    public boolean [] getInfoldingColumns() {
+        return infoldingColumns;
+    }
+
+    public void markInfoldingColumns(WQKms [] wqkms) {
+        for (WQKms wqk: wqkms) {
+            markInfoldingColumns(wqk);
+        }
+    }
+
+    public void markInfoldingColumns(WQKms wqkms) {
+        int N = wqkms.size();
+        int C = qFinders.length-1;
+        for (int i = 0; i < N; ++i) {
+            double km       = wqkms.getKm(i);
+            double q        = wqkms.getQ(i);
+            double above    =  Double.MAX_VALUE;
+            double below    = -Double.MAX_VALUE;
+            int    aboveIdx = -1;
+            int    belowIdx = -1;
+
+            for (int j = C; j >= 0; --j) {
+                double qc = qFinders[j].findQ(km);
+                if (Double.isNaN(qc)) {
+                    continue;
+                }
+                if (qc <= q) {
+                    if (qc > below) {
+                        below    = qc;
+                        belowIdx = j;
+                    }
+                }
+                else if (qc < above) { // qc > q
+                    above    = qc;
+                    aboveIdx = j;
+                }
+            }
+
+            if (aboveIdx != -1) {
+                infoldingColumns[aboveIdx] = true;
+            }
+
+            if (belowIdx != -1) {
+                infoldingColumns[belowIdx] = true;
+            }
+        }
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/QRangeTree.java	Sun Jan 20 15:04:32 2013 +0100
@@ -101,8 +101,52 @@
                 return current.q;
             }
         }
+
+        public Node findNode(double pos) {
+            Node current = this;
+            while (current != null) {
+                if (pos < current.a) {
+                    current = current.left;
+                }
+                else if (pos > current.b) {
+                    current = current.right;
+                }
+                return current;
+            }
+            return null;
+        }
+
+        public boolean contains(double c) {
+            return c >= a && c <= b;
+        }
     } // class Node
 
+    /** Class to cache the last found tree leaf in a search for Q.
+     *  Its likely that a neighbored pos search
+     *  results in using the same leaf node. So
+     *  caching this leaf will minimize expensive
+     *  tree traversals.
+     *  Modeled as inner class because the QRangeTree
+     *  itself is a shared data structure.
+     *  Using this class omits interpolation between
+     *  leaves.
+     */
+    public final class QuickQFinder {
+
+        private Node last;
+
+        public QuickQFinder() {
+        }
+
+        public double findQ(double pos) {
+            if (last != null && last.contains(pos)) {
+                return last.q;
+            }
+            last = QRangeTree.this.findNode(pos);
+            return last != null ? last.q : Double.NaN;
+        }
+    } // class QuickQFinder
+
     protected Node root;
 
     public QRangeTree() {
@@ -212,6 +256,10 @@
         return root != null ? root.findQ(pos) : Double.NaN;
     }
 
+    public Node findNode(double pos) {
+        return root != null ? root.findNode(pos) : null;
+    }
+
     protected Node head() {
         Node head = root;
         while (head.left != null) {
@@ -220,6 +268,20 @@
         return head;
     }
 
+    public boolean intersectsQRange(double qMin, double qMax) {
+        if (qMin > qMax) {
+            double t = qMin;
+            qMin = qMax;
+            qMax = t;
+        }
+        for (Node curr = head(); curr != null; curr = curr.next) {
+            if (curr.q >= qMin || curr.q <= qMax) {
+                return true;
+            }
+        }
+        return false;
+    }
+
     public List<Range> findSegments(double a, double b) {
         if (a > b) { double t = a; a = b; b = t; }
         return findSegments(new Range(a, b));
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WstValueTable.java	Sun Jan 20 15:04:32 2013 +0100
@@ -59,7 +59,7 @@
             this.name = name;
         }
 
-    public QRangeTree getQRangeTree() {
+        public QRangeTree getQRangeTree() {
             return qRangeTree;
         }
 
@@ -540,6 +540,10 @@
         this.rows    = rows;
     }
 
+    public Column [] getColumns() {
+        return columns;
+    }
+
     /** Sort rows (by km). */
     public void sortRows() {
         Collections.sort(rows);
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/BedQualityCalculation.java	Sun Jan 20 15:04:32 2013 +0100
@@ -329,3 +329,4 @@
         return weight;
     }
 }
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/minfo/QualityMeasurementFactory.java	Sun Jan 20 15:04:32 2013 +0100
@@ -200,4 +200,5 @@
             //session.close();
         }
     }
-}
\ No newline at end of file
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/sq/Outlier.java	Sun Jan 20 15:04:32 2013 +0100
@@ -1,20 +1,17 @@
 package de.intevation.flys.artifacts.model.sq;
 
+import de.intevation.artifacts.common.utils.Config;
+
+import de.intevation.flys.artifacts.math.GrubbsOutlier;
+import de.intevation.flys.artifacts.math.StdDevOutlier;
+
 import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.commons.math.MathException;
 
-import org.apache.commons.math.stat.descriptive.moment.StandardDeviation;
-
 import org.apache.log4j.Logger;
 
-import de.intevation.artifacts.GlobalContext;
-import de.intevation.artifacts.common.utils.Config;
-import de.intevation.flys.artifacts.context.FLYSContext;
-import de.intevation.flys.artifacts.math.GrubbsOutlier;
-import de.intevation.flys.artifacts.math.StdDevOutlier;
-
 public class Outlier
 {
     private static Logger log = Logger.getLogger(Outlier.class);
@@ -24,7 +21,7 @@
 
     private static final String GRUBBS = "grubbs";
 
-    private static final String STD_DEV = "std-dev";
+    //private static final String STD_DEV = "std-dev";
 
     public interface Callback {
 
@@ -48,42 +45,54 @@
     {
         boolean debug = log.isDebugEnabled();
 
-        if (debug) {
-            log.debug("stdDevFactor: " + stdDevFactor);
-        }
         String method = Config.getStringXPath(OUTLIER_METHOD);
-        log.debug("method: " + method);
+
         if (method == null) {
             method = "std-dev";
         }
+
+        if (debug) {
+            log.debug("stdDevFactor: " + stdDevFactor);
+            log.debug("method: " + method);
+        }
+
         List<SQ> data = new ArrayList<SQ>(sqs);
 
+        double [] stdDev = new double[1];
+
+        boolean useGrubbs = method.equals(GRUBBS);
+
+        if (useGrubbs) {
+            stdDevFactor = Math.max(0d, Math.min(stdDevFactor/100d, 1d));
+        }
+
+        List<Double> values = new ArrayList<Double>(data.size());
+
         while (data.size() > 2) {
 
             callback.initialize(data);
 
-            List<Double> values = new ArrayList<Double>();
             for (SQ sq: data) {
                 values.add(callback.eval(sq));
             }
 
-            Integer ndx = null;
-            double[] stdDev = new double[1];
-            if (method.equals(GRUBBS)) {
-                ndx = GrubbsOutlier.findOutlier(values, stdDevFactor/100, stdDev);
-            }
-            else {
-                ndx = StdDevOutlier.findOutlier(values, stdDevFactor, stdDev);
-            }
+            Integer ndx = useGrubbs
+                ? GrubbsOutlier.findOutlier(values, stdDevFactor, stdDev)
+                : StdDevOutlier.findOutlier(values, stdDevFactor, stdDev);
+
             if (ndx == null) {
                 callback.iterationFinished(stdDev[0], null, data);
                 break;
             }
 
-            SQ outlier = data.remove((int)ndx);
-            log.debug("stdDev: " + stdDev[0]);
-            log.debug("removed " + ndx + "; S: " + outlier.getS() + " Q: " + outlier.getQ());
+            SQ outlier = data.remove(ndx.intValue());
+            if (debug) {
+                log.debug("stdDev: " + stdDev[0]);
+                log.debug("removed " + ndx + 
+                    "; S: " + outlier.getS() + " Q: " + outlier.getQ());
+            }
             callback.iterationFinished(stdDev[0], outlier, data);
+            values.clear();
         }
     }
 }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MapInfoService.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/services/MapInfoService.java	Sun Jan 20 15:04:32 2013 +0100
@@ -1,29 +1,25 @@
 package de.intevation.flys.artifacts.services;
 
-import org.apache.log4j.Logger;
-
-import java.util.Map;
-import java.util.HashMap;
-
-import org.w3c.dom.Document;
-import org.w3c.dom.Node;
-import org.w3c.dom.Element;
-
-import javax.xml.xpath.XPathConstants;
-
 import com.vividsolutions.jts.geom.Envelope;
 
+import de.intevation.artifactdatabase.XMLService;
 import de.intevation.artifacts.CallMeta;
 import de.intevation.artifacts.GlobalContext;
-
 import de.intevation.artifacts.common.ArtifactNamespaceContext;
 import de.intevation.artifacts.common.utils.Config;
 import de.intevation.artifacts.common.utils.XMLUtils;
 import de.intevation.artifacts.common.utils.XMLUtils.ElementCreator;
+import de.intevation.flys.utils.GeometryUtils;
 
-import de.intevation.artifactdatabase.XMLService;
+import java.util.HashMap;
+import java.util.Map;
 
-import de.intevation.flys.utils.GeometryUtils;
+import javax.xml.xpath.XPathConstants;
+
+import org.apache.log4j.Logger;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
 
 /**
  * This service provides information about the supported rivers by this
@@ -36,14 +32,16 @@
     /** XPath that points to the river.*/
     public static final String XPATH_RIVER = "/mapinfo/river/text()";
 
-    public static final String XPATH_RIVER_PROJECTION =
-        "/artifact-database/floodmap/river[@name=$river]/srid/@value";
+    public static final String XPATH_MAPTYPE = "/mapinfo/maptype/text()";
 
-    public static final String XPATH_RIVER_BACKGROUND =
-        "/artifact-database/floodmap/river[@name=$river]/background-wms";
+    private static final String XPATH_RIVER_PROJECTION =
+        "/artifact-database/*[local-name()=$maptype]/river[@name=$river]/srid/@value";
 
-    public static final String XPATH_RIVER_WMS =
-        "/artifact-database/floodmap/river[@name=$river]/river-wms/@url";
+    private static final String XPATH_RIVER_BACKGROUND =
+        "/artifact-database/*[local-name()=$maptype]/river[@name=$river]/background-wms";
+
+    private static final String XPATH_RIVER_WMS =
+        "/artifact-database/*[local-name()=$maptype]/river[@name=$river]/river-wms";
 
 
     /** The logger used in this service.*/
@@ -94,6 +92,12 @@
             return result;
         }
 
+        String mapType = extractMaptype(data);
+        if (mapType == null
+        || !(mapType.equals("floodmap") || mapType.equals("rivermap"))) {
+            mapType = "floodmap";
+        }
+
         Element root = cr.create("river");
         cr.addAttr(root, "name", river);
         mapinfo.appendChild(root);
@@ -101,7 +105,9 @@
         Envelope env = GeometryUtils.getRiverBoundary(river);
         if (env != null) {
             String bounds = GeometryUtils.jtsBoundsToOLBounds(env);
-            logger.debug("River '" + river + "' bounds: " + bounds);
+            if (logger.isDebugEnabled()) {
+                logger.debug("River '" + river + "' bounds: " + bounds);
+            }
 
             Element bbox = cr.create("bbox");
             cr.addAttr(bbox, "value", bounds);
@@ -109,6 +115,7 @@
         }
 
         Map<String, String> vars = new HashMap<String, String>();
+        vars.put("maptype", mapType);
         vars.put("river", river);
 
         String sridStr = getStringXPath(XPATH_RIVER_PROJECTION, vars);
@@ -119,28 +126,55 @@
             root.appendChild(srid);
         }
 
-        Element back = (Element)getNodeXPath(XPATH_RIVER_BACKGROUND, vars);
-        if (back != null) {
-            Element background = cr.create("background-wms");
-            cr.addAttr(background, "url", back.getAttribute("url"));
-            cr.addAttr(background, "layers", back.getAttribute("layers"));
-            root.appendChild(background);
+        if (logger.isDebugEnabled()) {
+            logger.debug("processXML: " + XMLUtils.toString(root));
         }
 
-        String wmsStr = getStringXPath(XPATH_RIVER_WMS, vars);
-        if (wmsStr != null && wmsStr.length() > 0) {
-            Element wms = cr.create("river-wms");
-            cr.addAttr(wms, "url", wmsStr);
-            root.appendChild(wms);
-        }
+        root.appendChild(
+            createWMSElement("background-wms",
+                XPATH_RIVER_BACKGROUND, vars, cr));
+
+        root.appendChild(
+            createWMSElement("river-wms",
+                XPATH_RIVER_WMS, vars, cr));
 
         return result;
     }
 
 
-    protected String extractRiver(Document data) {
+    protected Element createWMSElement(
+        String elementName,
+        String xpath,
+        Map<String, String> vars,
+        ElementCreator cr)
+    {
+        logger.debug("createWMSElement()");
+
+        Element el = cr.create(elementName);
+        Element wms = (Element)getNodeXPath(xpath, vars);
+
+        if (wms != null) {
+            cr.addAttr(el, "url", wms.getAttribute("url"));
+            cr.addAttr(el, "layers", wms.getAttribute("layers"));
+
+            logger.debug("createWMSElement: " + XMLUtils.toString(el));
+        }
+        else {
+            logger.debug("createWMSElement: wms == null");
+        }
+
+        return el;
+    }
+
+
+    private static String extractRiver(Document data) {
         return XMLUtils.xpathString(
             data, XPATH_RIVER, ArtifactNamespaceContext.INSTANCE);
     }
+
+    private static String extractMaptype(Document data) {
+        return XMLUtils.xpathString(
+            data, XPATH_MAPTYPE, ArtifactNamespaceContext.INSTANCE);
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DischargeLongitudinalSection.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/DischargeLongitudinalSection.java	Sun Jan 20 15:04:32 2013 +0100
@@ -1,37 +1,36 @@
 package de.intevation.flys.artifacts.states;
 
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.ChartArtifact;
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.access.Calculation4Access;
+
+import de.intevation.flys.artifacts.model.Calculation4;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.CrossSectionWaterLineFacet;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.EmptyFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.ReportFacet;
+import de.intevation.flys.artifacts.model.WQCKms;
+import de.intevation.flys.artifacts.model.WQKms;
+import de.intevation.flys.artifacts.model.WaterlevelFacet;
+
 import java.util.List;
 
 import org.apache.log4j.Logger;
 
-import de.intevation.artifacts.CallContext;
-
-import de.intevation.artifactdatabase.state.Facet;
-
-import de.intevation.flys.artifacts.FLYSArtifact;
-import de.intevation.flys.artifacts.WINFOArtifact;
-import de.intevation.flys.artifacts.ChartArtifact;
-
-import de.intevation.flys.artifacts.model.CrossSectionWaterLineFacet;
-import de.intevation.flys.artifacts.model.FacetTypes;
-import de.intevation.flys.artifacts.model.ReportFacet;
-import de.intevation.flys.artifacts.model.WaterlevelFacet;
-import de.intevation.flys.artifacts.model.EmptyFacet;
-
-import de.intevation.flys.artifacts.model.WQKms;
-import de.intevation.flys.artifacts.model.WQCKms;
-import de.intevation.flys.artifacts.model.CalculationResult;
-
-import de.intevation.flys.artifacts.model.DataFacet;
-
 public class DischargeLongitudinalSection
 extends      DefaultState
 implements   FacetTypes
 {
-    private static Logger logger =
+    private static Logger log =
         Logger.getLogger(DischargeLongitudinalSection.class);
 
-
     @Override
     public Object computeAdvance(
         FLYSArtifact artifact,
@@ -46,11 +45,11 @@
             return null;
         }
 
-        WINFOArtifact winfo = (WINFOArtifact)artifact;
+        Calculation4Access access = new Calculation4Access(artifact);
 
         CalculationResult res = old instanceof CalculationResult
             ? (CalculationResult)old
-            : winfo.getDischargeLongitudinalSectionData();
+            : new Calculation4(access).calculate();
 
         if (facets == null) {
             return res;
@@ -62,7 +61,7 @@
             String nameW = null;
             String nameQ = null;
 
-            if (winfo.isQ()) {
+            if (access.isQ()) {
                 nameQ = wqkms[i].getName();
                 nameW = "W(" + nameQ + ")";
             }
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/FLYSUtils.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/FLYSUtils.java	Sun Jan 20 15:04:32 2013 +0100
@@ -225,15 +225,13 @@
         if (mode == null || mode.length() == 0) {
             return KM_MODE.NONE;
         }
-        else if (mode.equals("distance"))  {
+        if (mode.equals("distance"))  {
             return KM_MODE.RANGE;
         }
-        else if (mode.equals("locations")) {
+        if (mode.equals("locations")) {
             return KM_MODE.LOCATIONS;
         }
-        else {
-            return KM_MODE.NONE;
-        }
+        return KM_MODE.NONE;
     }
 
     /**
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/RiverMapfileGenerator.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/RiverMapfileGenerator.java	Sun Jan 20 15:04:32 2013 +0100
@@ -1,8 +1,12 @@
 package de.intevation.flys.utils;
 
+import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.LineString;
+
 import de.intevation.flys.artifacts.model.LayerInfo;
 import de.intevation.flys.artifacts.model.RiverFactory;
 import de.intevation.flys.model.River;
+import de.intevation.flys.model.RiverAxis;
 
 import java.io.File;
 import java.io.FileNotFoundException;
@@ -48,11 +52,26 @@
         List<String> riverFiles = new ArrayList<String>();
 
         for (River river : rivers) {
+            // We expect that every river has only one RiverAxis.
+            // This is not correct but currently the case here, see
+            // RiverAxis.java.
+            List<RiverAxis> riverAxis = RiverAxis.getRiverAxis(river.getName());
+            if (riverAxis == null) {
+                logger.warn("River " + river.getName() + " has no river axis!");
+                continue;
+            }
+            LineString geom = riverAxis.get(0).getGeom();
+            Envelope extent = geom.getEnvelopeInternal();
+
             createRiverAxisLayer(
                     river.getName(),
                     river.getId(),
-                    "41677",
-                    "-10000 -10000 10000 10000");
+                    Integer.toString(geom.getSRID()),
+                    extent.getMinX() + " " +
+                    extent.getMinY() + " " +
+                    extent.getMaxX() + " " +
+                    extent.getMaxY());
+
             riverFiles.add("river-" + river.getName() + ".map");
         }
         writeMapfile(riverFiles);
@@ -64,7 +83,7 @@
         layerInfo.setSrid(srid);
         layerInfo.setExtent(extend);
         layerInfo.setType("line");
-        layerInfo.setData("geom FROM river_axis");      // FIXME: Use templates for that
+        layerInfo.setData("geom FROM river_axes");      // FIXME: Use templates for that
         layerInfo.setFilter("river_id = " + riverID);
         layerInfo.setTitle(riverName + " RiverAxis");
 
--- a/flys-backend/src/main/java/de/intevation/flys/importer/ImportRiver.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/ImportRiver.java	Sun Jan 20 15:04:32 2013 +0100
@@ -190,7 +190,7 @@
 
            addCrossSections(parser);
         }
-    }
+    } // ImportRiverCrossSectionParserCallback 
 
 
     public ImportRiver() {
--- a/flys-backend/src/main/java/de/intevation/flys/importer/parsers/W80Parser.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-backend/src/main/java/de/intevation/flys/importer/parsers/W80Parser.java	Sun Jan 20 15:04:32 2013 +0100
@@ -62,10 +62,27 @@
     private Anchor anchor;
 
 
+    /**
+     * Reference point for distance calculations, introduced to
+     * deal with bends in the lines.
+     * Array has two entrys: first is GK-Right, second GK-High.
+     */
+    private double[] lastPointGK;
+
+
     /** Measurement date of anchor as listed in w80 file. */
     private Date anchorDate;
 
 
+    private double distanceToLastPoint(double gkr, double gkh) {
+        double dx = gkr - lastPointGK[0];
+        double dy = gkh - lastPointGK[1];
+        double d  = dx*dx + dy*dy;
+
+        return Math.sqrt(d);
+    }
+
+
     /** Trivial constructor. */
     public W80Parser() {
         data = new TreeMap<Double, List<XY>>(EpsilonComparator.CMP);
@@ -103,7 +120,6 @@
 
     public void parseW80s(File root, final Callback callback) {
 
-        // TODO use the removeExtension/guess description and date.
         FileTools.walkTree(root, new FileTools.FileVisitor() {
             @Override
             public boolean visit(File file) {
@@ -135,6 +151,7 @@
         currentLine = new ArrayList<XY>();
         anchor = null;
         anchorDate = null;
+        lastPointGK = new double[] {0d,0d};
     }
 
 
@@ -142,7 +159,7 @@
      * Get the Index of the last cross-section lines point.
      * @return last points index, -1 if not available.
      */
-    private int lastPointIdx() {
+    private int getLastPointIdx() {
         if (currentLine == null || currentLine.isEmpty()) {
             return -1;
         }
@@ -151,6 +168,15 @@
     }
 
 
+    private double getLastPointX() {
+        if (currentLine == null || currentLine.isEmpty()) {
+            return 0d;
+        }
+        XY lastPoint = this.currentLine.get(currentLine.size()-1);
+        return lastPoint.getX();
+    }
+
+
     /**
      * Add a Point (YZ,Index) to the current cross section line.
      * @param y The y coordinate of new point.
@@ -160,22 +186,22 @@
      *         parsable y or z values.
      */
     private boolean addPoint(double gkr, double gkh, double height, String idx) {
-        // Calculate distance between this and anchor-point.
-        double d = anchor.distance(gkr, gkh);
-
-        // TODO: Scale to have "x==0" e.g. at axis of river.
-        // TODO: Handle "not straight lines."
+        // Calculate distance between this and lst point (add distances).
+        double d = distanceToLastPoint(gkr, gkh);
+        double totalX = getLastPointX() + d;
 
         // We ignore idx, and increment instead.
         int index;
-        int lastPointIdx = lastPointIdx();
+        int lastPointIdx = getLastPointIdx();
         if (lastPointIdx <= 0) {
             index = 1;
         } else {
             index = lastPointIdx + 1;
         }
 
-        currentLine.add(new XY(d, height/1000d, index));
+        this.lastPointGK[0] = gkr;
+        this.lastPointGK[1] = gkh;
+        currentLine.add(new XY(totalX, height/1000d, index));
         return true;
     }
 
@@ -191,10 +217,10 @@
         // negative.
         String pointId = line.substring(0,20);
         String station = line.substring(9,15);
-        String shore   = line.substring(15,17);
+        String shore   = line.substring(15,16);
         // TODO: There is 'station' and a 'shore'-code behind.
         // 1 = left, 2 = right. none = middle
-        String pointIndex = line.substring(17,21);
+        String pointIndex = line.substring(16,21);
         // For GK, first seven digits are of interest.
         String gkRight = line.substring(20,30);
         String gkHigh  = line.substring(30,40);
@@ -222,9 +248,11 @@
         // New (or first) line.
         if (anchor == null || !anchor.sameStation(stationKm)) {
             anchor = new Anchor(gkRightKm, gkHighKm, heightM, stationKm);
+            lastPointGK[0] = gkRightKm;
+            lastPointGK[1] = gkHighKm;
             currentLine = new ArrayList<XY>();
             data.put(stationKm, currentLine);
-            currentLine.add(new XY(0d, heightM,0));
+            currentLine.add(new XY(0d, heightM, 0));
             try {
                 anchorDate = DateGuesser.guessDate(date);
             }
@@ -252,8 +280,8 @@
 
         logger.warn("Start parsing files.");
         for (String arg: args) {
+            logger.warn("Parsing a file.");
             parser.parseW80s(new File(arg), null);
-            logger.warn("Parsing a file.");
         }
         logger.error("Finished parsing files.");
     }
--- a/flys-backend/src/main/java/de/intevation/flys/model/River.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-backend/src/main/java/de/intevation/flys/model/River.java	Sun Jan 20 15:04:32 2013 +0100
@@ -1,31 +1,29 @@
 package de.intevation.flys.model;
 
+import de.intevation.flys.backend.SessionHolder;
+
 import java.io.Serializable;
-
 import java.math.BigDecimal;
 import java.math.MathContext;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
 
+import javax.persistence.Column;
 import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
 import javax.persistence.Id;
-import javax.persistence.Table;
-import javax.persistence.GeneratedValue;
-import javax.persistence.Column;
-import javax.persistence.SequenceGenerator;
+import javax.persistence.JoinColumn;
 import javax.persistence.OneToMany;
 import javax.persistence.OneToOne;
 import javax.persistence.OrderBy;
-import javax.persistence.JoinColumn;
-import javax.persistence.GenerationType;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
 
-import java.util.List;
-import java.util.Comparator;
-import java.util.Map;
-import java.util.TreeMap;
-
+import org.hibernate.Query;
 import org.hibernate.Session;
-import org.hibernate.Query;
-
-import de.intevation.flys.backend.SessionHolder;
 
 
 @Entity
@@ -37,7 +35,7 @@
 
     public static final double EPSILON = 1e-5;
 
-    public static final Comparator KM_CMP = new Comparator<Double>() {
+    public static final Comparator<Double> KM_CMP = new Comparator<Double>() {
         @Override
         public int compare(Double a, Double b) {
             double diff = a - b;
@@ -147,6 +145,7 @@
 
 
 
+    @Override
     public String toString() {
         return name != null ? name : "";
     }
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/DigitizePanel.java	Sun Jan 20 15:02:19 2013 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/DigitizePanel.java	Sun Jan 20 15:04:32 2013 +0100
@@ -2,7 +2,6 @@
 
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.user.client.rpc.AsyncCallback;
-
 import com.smartgwt.client.types.Encoding;
 import com.smartgwt.client.types.VerticalAlignment;
 import com.smartgwt.client.util.SC;
@@ -22,6 +21,8 @@
 import com.smartgwt.client.widgets.tab.events.TabSelectedHandler;
 
 import de.intevation.flys.client.client.Config;
+import de.intevation.flys.client.client.FLYS;
+import de.intevation.flys.client.client.FLYSConstants;
 import de.intevation.flys.client.client.services.MapInfoService;
 import de.intevation.flys.client.client.services.MapInfoServiceAsync;
 import de.intevation.flys.client.client.ui.map.FloodMap;
@@ -58,6 +59,8 @@
 
     public static final String UESK_BARRIERS = "uesk.barriers";
 
+    /** The message class that provides i18n strings. */
+    protected FLYSConstants MSG = GWT.create(FLYSConstants.class);
 
     public DigitizePanel() {
     }
@@ -104,7 +107,7 @@
                 String msg = caught.getMessage();
 
                 GWT.log("Error while fetching MapInfo: " + msg);
-                SC.warn(MSG.getString(msg));
+                SC.warn(FLYS.getExceptionString(MSG, caught));
             }
 
             @Override

http://dive4elements.wald.intevation.org