changeset 4628:03ab907b6f5d

Merged.
author Raimund Renkert <rrenkert@intevation.de>
date Mon, 03 Dec 2012 17:27:08 +0100
parents d5821c6f0ab0 (diff) 35dceb726fc4 (current diff)
children e29f368c09ba
files flys-client/src/main/java/de/intevation/flys/client/client/ui/MainMenu.java
diffstat 13 files changed, 375 insertions(+), 51 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/doc/conf/conf.xml	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/doc/conf/conf.xml	Mon Dec 03 17:27:08 2012 +0100
@@ -393,4 +393,12 @@
             <configuration>${artifacts.config.dir}/themes.xml</configuration>
         </themes>
     </flys>
+
+    <options>
+        <zoom-scales>
+            <zoom-scale river="Elbe" range="50" radius="1" />
+            <zoom-scale river="Elbe" range="100" radius="5" />
+            <zoom-scale river="Elbe" range="500" radius="10" />
+        </zoom-scales>
+    </options>
 </artifact-database>
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/context/FLYSContextFactory.java	Mon Dec 03 17:27:08 2012 +0100
@@ -1,6 +1,7 @@
 package de.intevation.flys.artifacts.context;
 
 import java.io.File;
+import java.text.ParseException;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -27,6 +28,7 @@
 import de.intevation.artifactdatabase.transition.TransitionEngine;
 
 import de.intevation.flys.artifacts.model.Module;
+import de.intevation.flys.artifacts.model.ZoomScale;
 import de.intevation.flys.artifacts.states.StateFactory;
 import de.intevation.flys.artifacts.transitions.TransitionFactory;
 import de.intevation.flys.themes.Theme;
@@ -84,6 +86,8 @@
 
     public static final String XPATH_MODULES = "/artifact-database/modules/module";
 
+    private static final String XPATH_ZOOM_SCALES = "/artifact-database/options/zoom-scales/zoom-scale";
+
     /**
      * Creates a new FLYSArtifactContext object and initialize all
      * components required by the application.
@@ -101,11 +105,56 @@
         configureThemesMappings(config, context);
         configureRiverWMS(config, context);
         configureModules(config, context);
+        configureZoomScales(config, context);
 
         return context;
     }
 
 
+    private void configureZoomScales(Document config, FLYSContext context) {
+        NodeList list = (NodeList)XMLUtils.xpath(
+            config,
+            XPATH_ZOOM_SCALES,
+            XPathConstants.NODESET);
+        ZoomScale scale = new ZoomScale();
+        for (int i = 0; i < list.getLength(); i++) {
+            Element element = (Element)list.item(i);
+            String river = "default";
+            double range = 0d;
+            double radius = 10d;
+            if (element.hasAttribute("river")) {
+                river = element.getAttribute("river");
+            }
+            if (!element.hasAttribute("range")) {
+                continue;
+            }
+            else {
+                String r = element.getAttribute("range");
+                try {
+                    range = Double.parseDouble(r);
+                }
+                catch (NumberFormatException nfe) {
+                    continue;
+                }
+            }
+            if (!element.hasAttribute("radius")) {
+                continue;
+            }
+            else {
+                String r = element.getAttribute("radius");
+                try {
+                    radius = Double.parseDouble(r);
+                }
+                catch (NumberFormatException nfe) {
+                    continue;
+                }
+            }
+            scale.addRange(river, range, radius);
+       }
+       context.put("zoomscale", scale);
+    }
+
+
     /**
      * This method initializes the transition configuration.
      *
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityCalculation.java	Mon Dec 03 17:27:08 2012 +0100
@@ -58,6 +58,7 @@
         if (mainIds != null) {
             for (int id: mainIds) {
                 DischargeZone zone = DischargeZone.getDischargeZoneById(id);
+                zone.putType("main");
 
                 if (zone != null) {
                     zones.add(zone);
@@ -68,9 +69,16 @@
         if (totalIds != null) {
             for (int id: totalIds) {
                 DischargeZone zone = DischargeZone.getDischargeZoneById(id);
-
                 if (zone != null) {
-                    zones.add(zone);
+                    int ndx = zones.indexOf(zone);
+                    if (zones.contains(zone) &&
+                        zones.get(ndx).fetchType().equals("main")) {
+                        zone.putType("main_total");
+                    }
+                    else {
+                        zone.putType("total");
+                        zones.add(zone);
+                    }
                 }
             }
         }
@@ -133,6 +141,7 @@
         String        lo   = zone.getLowerDischarge();
         String        hi   = zone.getUpperDischarge();
 
+        data.setType(zone.fetchType());
         if (lo.equals(hi)) {
             data.setZone(lo);
         }
@@ -152,7 +161,6 @@
         logger.debug("Prepare data for km range: " + kmLo + " - " + kmHi);
 
         FlowVelocityData[] data = new FlowVelocityData[models.size()];
-
         for (int i = 0, n = models.size(); i < n; i++) {
             FlowVelocityData d = new FlowVelocityData();
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityData.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityData.java	Mon Dec 03 17:27:08 2012 +0100
@@ -13,7 +13,7 @@
     private TDoubleArrayList tauMain;
     private TDoubleArrayList q;
     private String zone;
-
+    private String type;
 
     protected FlowVelocityData() {
         this.km      = new TDoubleArrayList();
@@ -72,6 +72,14 @@
         return zone;
     }
 
+    public void setType(String type) {
+        this.type = type;
+    }
+
+    public String getType() {
+        return this.type;
+    }
+
     public int size() {
         return km.size();
     }
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityFacet.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FlowVelocityFacet.java	Mon Dec 03 17:27:08 2012 +0100
@@ -7,6 +7,8 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
+import de.intevation.flys.artifacts.access.RiverAccess;
+import de.intevation.flys.artifacts.context.FLYSContext;
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
 
 import org.apache.log4j.Logger;
@@ -39,13 +41,36 @@
     public Object getData(Artifact artifact, CallContext context) {
         logger.debug("Get data for flow velocity at index: " + index);
 
+        Double start = (Double)context.getContextValue("startkm");
+        Double end = (Double)context.getContextValue("endkm");
         FLYSArtifact flys = (FLYSArtifact) artifact;
 
         CalculationResult res = (CalculationResult)
             flys.compute(context, hash, stateId, type, false);
 
         FlowVelocityData[] data = (FlowVelocityData[]) res.getData();
+        if(start != null && end != null) {
+            FLYSContext fc = (FLYSContext)context.globalContext();
+            ZoomScale scales = (ZoomScale)fc.get("zoomscale");
+            RiverAccess access = new RiverAccess((FLYSArtifact)artifact);
+            String river = access.getRiver();
 
+            double radius = scales.getRadius(river, start, end);
+            FlowVelocityData oldData = data[index];
+            FlowVelocityData newData = new FlowVelocityData();
+            double[][] q = oldData.getQPoints();
+            double[][] totalV = MovingAverage.weighted(oldData.getTotalChannelPoints(), radius);
+            double[][] mainV = MovingAverage.weighted(oldData.getMainChannelPoints(), radius);
+            double[][] tau = MovingAverage.weighted(oldData.getTauPoints(), radius);
+            for(int j = 0; j < q[0].length; j++) {
+                newData.addKM(q[0][j]);
+                newData.addQ(q[1][j]);
+                newData.addTauMain(tau[1][j]);
+                newData.addVMain(mainV[1][j]);
+                newData.addVTotal(totalV[1][j]);
+            }
+            return newData;
+        }
         return data[index];
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MovingAverage.java	Mon Dec 03 17:27:08 2012 +0100
@@ -0,0 +1,59 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+
+public class MovingAverage
+{
+
+    public static double[][] simple(double[][] values, double radius) {
+        TreeMap<Double, Double> map = toMap(values);
+        double[][] result = new double[values.length][values[0].length];
+        int ndx = 0;
+        for (double x: map.keySet()) {
+            SortedMap<Double, Double> range =
+                map.subMap(x-radius, true, x+radius, true);
+            double avg = 0d;
+            for (Double v: range.values()) {
+                avg += v;
+            }
+            avg /= range.size();
+            result[0][ndx] = x;
+            result[1][ndx] = avg;
+            ndx++;
+        }
+        return result;
+    }
+
+    public static double[][] weighted(double[][] values, double radius) {
+        TreeMap<Double, Double> map = toMap(values);
+        double[][] result = new double[values.length][values[0].length];
+        int ndx = 0;
+        for (double x: map.keySet()) {
+            double avg = 0d;
+            double weights = 0d;
+            for (Map.Entry<Double, Double> e:
+                map.subMap(x-radius, false, x+radius, false).entrySet()
+            ) {
+                double weight = 1d - Math.abs(x - e.getKey())/radius;
+                avg += weight*e.getValue();
+                weights += weight;
+            }
+            avg /= weights;
+            result[0][ndx] = x;
+            result[1][ndx] = avg;
+            ndx++;
+        }
+        return result;
+    }
+
+    private static TreeMap<Double, Double> toMap(double[][] values) {
+        TreeMap<Double, Double> map = new TreeMap<Double, Double>();
+        for(int i = 0; i < values[0].length; i++) {
+            map.put(values[0][i], values[1][i]);
+        }
+        return map;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/ZoomScale.java	Mon Dec 03 17:27:08 2012 +0100
@@ -0,0 +1,75 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.flys.artifacts.math.Linear;
+
+
+public class ZoomScale
+{
+    private static Logger logger = Logger.getLogger(ZoomScale.class);
+
+    private HashMap<String, TreeMap<Double, Double>> rivers;
+
+    public ZoomScale() {
+        this.rivers = new HashMap<String, TreeMap<Double, Double>>();
+    }
+
+    public ZoomScale(String river) {
+        this();
+        rivers.put(river, new TreeMap<Double, Double>());
+    }
+
+    public double getRadius(String river, double lower, double upper) {
+        double range = Math.abs(upper) - Math.abs(lower);
+        TreeMap<Double, Double> ranges = rivers.get(river);
+        if (ranges == null) {
+            return 0.001;
+        }
+        Map.Entry<Double, Double> next = ranges.higherEntry(range);
+        Map.Entry<Double, Double> prev = ranges.lowerEntry(range);
+        double x0 = 0d;
+        double x1 = 0d;
+        double y0 = 0d;
+        double y1 = 0d;
+        if (prev == null && next != null) {
+            x1 = next.getKey();
+            y1 = next.getValue();
+        }
+        else if (prev != null && next == null) {
+            return prev.getValue();
+        }
+        else {
+            x0 = prev.getKey();
+            x1 = next.getKey();
+            y0 = prev.getValue();
+            y1 = next.getValue();
+        }
+        return Linear.linear(range, x0, x1, y0, y1);
+    }
+
+    public void addRiver(String river) {
+        if (!this.rivers.containsKey(river)) {
+            this.rivers.put(river, new TreeMap<Double, Double>());
+        }
+    }
+
+    public Set<String> getRivers() {
+        return this.rivers.keySet();
+    }
+
+    public void addRange(String river, double range, double radius) {
+        if (this.rivers.containsKey(river)) {
+            this.rivers.get(river).put(range, radius);
+        }
+        else {
+            this.rivers.put(river, new TreeMap<Double, Double>());
+            this.rivers.get(river).put(range, radius);
+        }
+    }
+}
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FlowVelocityState.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FlowVelocityState.java	Mon Dec 03 17:27:08 2012 +0100
@@ -68,34 +68,61 @@
         int    idx = 0;
 
         for (FlowVelocityData d: data) {
-            logger.error("TODO: Implement Facet creation for chart!");
-
-            newFacets.add(new FlowVelocityFacet(
-                idx,
-                FLOW_VELOCITY_MAINCHANNEL,
-                buildMainChannelName(artifact, context, d),
-                ComputeType.ADVANCE,
-                id,
-                hash
-            ));
+            if (d.getType().equals("main")) {
+                newFacets.add(new FlowVelocityFacet(
+                    idx,
+                    FLOW_VELOCITY_MAINCHANNEL,
+                    buildMainChannelName(artifact, context, d),
+                    ComputeType.ADVANCE,
+                    id,
+                    hash
+                ));
 
-            newFacets.add(new FlowVelocityFacet(
-                idx,
-                FLOW_VELOCITY_TOTALCHANNEL,
-                buildTotalChannelName(artifact, context, d),
-                ComputeType.ADVANCE,
-                id,
-                hash
-            ));
-
-            newFacets.add(new FlowVelocityFacet(
-                idx,
-                FLOW_VELOCITY_TAU,
-                buildTauName(artifact, context, d),
-                ComputeType.ADVANCE,
-                id,
-                hash
-            ));
+                newFacets.add(new FlowVelocityFacet(
+                    idx,
+                    FLOW_VELOCITY_TAU,
+                    buildTauName(artifact, context, d),
+                    ComputeType.ADVANCE,
+                    id,
+                    hash
+                ));
+            }
+            else if (d.getType().equals("total")) {
+                newFacets.add(new FlowVelocityFacet(
+                    idx,
+                    FLOW_VELOCITY_TOTALCHANNEL,
+                    buildTotalChannelName(artifact, context, d),
+                    ComputeType.ADVANCE,
+                    id,
+                    hash
+                ));
+            }
+            else if(d.getType().equals("main_total")) {
+                 newFacets.add(new FlowVelocityFacet(
+                    idx,
+                    FLOW_VELOCITY_MAINCHANNEL,
+                    buildMainChannelName(artifact, context, d),
+                    ComputeType.ADVANCE,
+                    id,
+                    hash
+                ));
+                newFacets.add(new FlowVelocityFacet(
+                    idx,
+                    FLOW_VELOCITY_TAU,
+                    buildTauName(artifact, context, d),
+                    ComputeType.ADVANCE,
+                    id,
+                    hash
+                ));
+                newFacets.add(new FlowVelocityFacet(
+                    idx,
+                    FLOW_VELOCITY_TOTALCHANNEL,
+                    buildTotalChannelName(artifact, context, d),
+                    ComputeType.ADVANCE,
+                    id,
+                    hash
+                ));
+            }
 
             newFacets.add(new FlowVelocityFacet(
                 idx,
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/FlowVelocityGenerator.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/FlowVelocityGenerator.java	Mon Dec 03 17:27:08 2012 +0100
@@ -1,5 +1,7 @@
 package de.intevation.flys.exports;
 
+import java.util.Arrays;
+
 import org.apache.log4j.Logger;
 
 import org.jfree.data.xy.XYSeries;
@@ -11,10 +13,13 @@
 
 import de.intevation.flys.artifacts.FLYSArtifact;
 
+import de.intevation.flys.artifacts.access.FlowVelocityAccess;
 import de.intevation.flys.artifacts.model.FacetTypes;
 import de.intevation.flys.artifacts.model.FlowVelocityData;
 import de.intevation.flys.model.FlowVelocityMeasurementValue;
 
+import de.intevation.flys.jfree.Bounds;
+import de.intevation.flys.jfree.DoubleBounds;
 import de.intevation.flys.jfree.FLYSAnnotation;
 import de.intevation.flys.jfree.StyledXYSeries;
 
@@ -201,6 +206,32 @@
             return;
         }
 
+        if (getXBounds(0) != null && getDomainAxisRange() != null) {
+            logger.debug(Arrays.toString(getDomainAxisRangeFromRequest()));
+            Bounds bounds =
+                calculateZoom(getXBounds(0), getDomainAxisRange());
+            context.putContextValue("startkm", bounds.getLower());
+            context.putContextValue("endkm", bounds.getUpper());
+        }
+        else if (getXBounds(0) != null && getDomainAxisRange() == null) {
+            context.putContextValue("startkm", getXBounds(0).getLower());
+            context.putContextValue("endkm", getXBounds(0).getUpper());
+        }
+        else if (getXBounds(0) == null && getDomainAxisRange() == null) {
+            FLYSArtifact artifact = (FLYSArtifact)artifactAndFacet.getArtifact();
+            FlowVelocityAccess access = new FlowVelocityAccess(artifact);
+            context.putContextValue("startkm", access.getLowerKM());
+            context.putContextValue("endkm", access.getUpperKM());
+        }
+        else if (getXBounds(0) == null && getDomainAxisRange() != null){
+            FLYSArtifact artifact = (FLYSArtifact)artifactAndFacet.getArtifact();
+            FlowVelocityAccess access = new FlowVelocityAccess(artifact);
+            Bounds b = new DoubleBounds(access.getLowerKM(), access.getUpperKM());
+            Bounds bounds =
+                calculateZoom(b, getDomainAxisRange());
+            context.putContextValue("startkm", bounds.getLower());
+            context.putContextValue("endkm", bounds.getUpper());
+        }
         if (name.equals(FLOW_VELOCITY_MAINCHANNEL)) {
             doMainChannelOut(
                 (FlowVelocityData) artifactAndFacet.getData(context),
--- a/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-artifacts/src/main/java/de/intevation/flys/exports/XYChartGenerator.java	Mon Dec 03 17:27:08 2012 +0100
@@ -781,22 +781,7 @@
         }
 
         if (x != null) {
-            double min  = bounds.getLower().doubleValue();
-            double max  = bounds.getUpper().doubleValue();
-
-            if (logger.isDebugEnabled()) {
-                logger.debug("Minimum is: " + min);
-                logger.debug("Maximum is: " + max);
-                logger.debug("Lower zoom is: " + x.getLowerBound());
-                logger.debug("Upper zoom is: " + x.getUpperBound());
-            }
-
-            double diff = max > min ? max - min : min - max;
-
-            DoubleBounds computed = new DoubleBounds(
-                min + x.getLowerBound() * diff,
-                min + x.getUpperBound() * diff);
-
+            Bounds computed = calculateZoom(bounds, x);
             computed.applyBounds(axis, AXIS_SPACE);
 
             logger.debug("Zoom axis to: " + computed);
@@ -808,6 +793,31 @@
         return false;
     }
 
+    /**
+     * Calculates the start and end km for zoomed charts.
+     * @param bounds    The given total bounds (unzoomed).
+     * @param range     The range specifying the zoom.
+     * 
+     * @return The start and end km for the zoomed chart.
+     */
+    protected Bounds calculateZoom(Bounds bounds, Range range) {
+        double min  = bounds.getLower().doubleValue();
+        double max  = bounds.getUpper().doubleValue();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Minimum is: " + min);
+            logger.debug("Maximum is: " + max);
+            logger.debug("Lower zoom is: " + range.getLowerBound());
+            logger.debug("Upper zoom is: " + range.getUpperBound());
+        }
+
+        double diff = max > min ? max - min : min - max;
+
+        DoubleBounds computed = new DoubleBounds(
+            min + range.getLowerBound() * diff,
+            min + range.getUpperBound() * diff);
+        return computed;
+    }
 
     /**
      * Extract the minimum and maximum values for x and y axes
--- a/flys-backend/src/main/java/de/intevation/flys/model/DischargeZone.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-backend/src/main/java/de/intevation/flys/model/DischargeZone.java	Mon Dec 03 17:27:08 2012 +0100
@@ -40,6 +40,7 @@
     private String lowerDischarge;
     private String upperDischarge;
 
+    private String type;
 
     public DischargeZone() {
     }
@@ -122,6 +123,13 @@
         this.upperDischarge = upperDischarge;
     }
 
+    public void putType(String type) {
+        this.type = type;
+    }
+
+    public String fetchType() {
+        return this.type;
+    }
 
     public static List<DischargeZone> getDischargeZones(River river) {
         Session session = SessionHolder.HOLDER.get();
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrix.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrix.java	Mon Dec 03 17:27:08 2012 +0100
@@ -263,16 +263,23 @@
         }
 
         ListGridRecord[] records = listGrid.getRecords();
-        for (ListGridRecord record: records) {
+        Map<String, List<String>> result = new HashMap<String, List<String>>();
+        for (ListGridRecord record : records) {
             for (int i = 0, n = columnNames.size(); i < n; i++) {
                 String columnName = columnNames.get(i);
-                List<String> chosenItems = selected.get(columnName);
                 if (Boolean.valueOf(record.getAttribute(columnName)) == true) {
-                    chosenItems.add(record.getAttribute(columnName + "-value"));
+                    if (result.containsKey(columnName)) {
+                        result.get(columnName).add(record.getAttribute(columnName + "-value"));
+                    }
+                    else {
+                        List<String> items = new ArrayList<String>();
+                        items.add(record.getAttribute(columnName + "-value"));
+                        result.put(columnName, items);
+                    }
                 }
             }
         }
-        return selected;
+        return result;
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java	Mon Dec 03 10:53:58 2012 +0100
+++ b/flys-client/src/main/java/de/intevation/flys/client/client/ui/ParameterMatrixPanel.java	Mon Dec 03 17:27:08 2012 +0100
@@ -176,11 +176,20 @@
         GWT.log ("validation. validation. validation. ");
         List<String> errors = new ArrayList<String>();
         // Early stop on one (only) error.
+        boolean ok = false;
         for (Map.Entry<String, List<String>> entry : matrix.getSelection().entrySet()) {
+            /* single entries are allowed!!
                 if (entry.getValue() == null || entry.getValue().size() == 0) {
                     errors.add(MESSAGES.error_values_needed());
                     return errors;
                 }
+                */
+            if (entry.getValue() != null && entry.getValue().size() > 0) {
+                ok = true;
+            }
+        }
+        if (!ok) {
+            errors.add(MESSAGES.error_values_needed());
         }
         return errors;
     }

http://dive4elements.wald.intevation.org