changeset 2713:b60751cfdd6c

Start MINFO middle bed height calculation in the relevant state and creates facets for chart and csv. flys-artifacts/trunk@4437 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Fri, 18 May 2012 09:18:39 +0000
parents ed612b85fb6d
children 2952f6dee5cf
files flys-artifacts/ChangeLog flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightData.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightFacet.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/MiddleBedHeight.java
diffstat 7 files changed, 500 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Fri May 18 07:03:38 2012 +0000
+++ b/flys-artifacts/ChangeLog	Fri May 18 09:18:39 2012 +0000
@@ -1,3 +1,26 @@
+2012-05-18  Ingo Weinzierl <ingo@intevation.de>
+
+	* src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightData.java:
+	  New model class for storing data for middle bed height exports (chart,
+	  data exports).
+
+	* src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java:
+	  New Calculation that generates new MiddleBedHeightData.
+
+	* src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightFacet.java:
+	  New Facet which is used for middle bed height charts.
+
+	* src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java: Added
+	  new facet type for middle bed height curves.
+
+	* src/main/java/de/intevation/flys/artifacts/states/MiddleBedHeight.java:
+	  Calculate middle bed height data using MiddleBedHeightCalculation and
+	  create new facets for charts and csv export.
+
+	* src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java: Added new
+	  methods that return the IDs of selected single bed heights and epoch bed
+	  heights.
+
 2012-05-18  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/artifacts/states/SoundingsSelect.java:
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java	Fri May 18 07:03:38 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/MINFOArtifact.java	Fri May 18 09:18:39 2012 +0000
@@ -23,9 +23,12 @@
 import de.intevation.flys.artifacts.model.FacetTypes;
 
 import de.intevation.flys.artifacts.states.DefaultState;
+import de.intevation.flys.artifacts.states.SoundingsSelect;
 
 import de.intevation.flys.utils.FLYSUtils;
 
+import gnu.trove.TIntArrayList;
+
 import java.util.LinkedList;
 import java.util.List;
 
@@ -268,5 +271,63 @@
 
         return FLYSUtils.intArrayFromString(data);
     }
+
+
+    public int[] getBedHeightSingleIDs() {
+        String data = getDataAsString("soundings");
+
+        if (data == null) {
+            logger.warn("No 'soundings' parameter specified!");
+            return null;
+        }
+
+        String[] parts = data.split(";");
+
+        TIntArrayList ids = new TIntArrayList();
+
+        for (String part: parts) {
+            if (part.indexOf(SoundingsSelect.PREFIX_SINGLE) >= 0) {
+                String tmp = part.replace(SoundingsSelect.PREFIX_SINGLE, "");
+
+                try {
+                    ids.add(Integer.parseInt(tmp));
+                }
+                catch (NumberFormatException nfe) {
+                    logger.warn("Cannot parse int from string: '" + tmp + "'");
+                }
+            }
+        }
+
+        return ids.toNativeArray();
+    }
+
+
+    public int[] getBedHeightEpochIDs() {
+        String data = getDataAsString("soundings");
+
+        if (data == null) {
+            logger.warn("No 'soundings' parameter specified!");
+            return null;
+        }
+
+        String[] parts = data.split(";");
+
+        TIntArrayList ids = new TIntArrayList();
+
+        for (String part: parts) {
+            if (part.indexOf(SoundingsSelect.PREFIX_EPOCH) >= 0) {
+                String tmp = part.replace(SoundingsSelect.PREFIX_EPOCH, "");
+
+                try {
+                    ids.add(Integer.parseInt(tmp));
+                }
+                catch (NumberFormatException nfe) {
+                    logger.warn("Cannot parse int from string: '" + tmp + "'");
+                }
+            }
+        }
+
+        return ids.toNativeArray();
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Fri May 18 07:03:38 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/FacetTypes.java	Fri May 18 09:18:39 2012 +0000
@@ -147,5 +147,7 @@
     String FLOW_VELOCITY_TOTALCHANNEL = "flow_velocity.totalchannel";
     String FLOW_VELOCITY_TAU          = "flow_velocity.tau";
     String FLOW_VELOCITY_ANNOTATION   = "flow_velocity.annotation";
+
+    String MIDDLE_BED_HEIGHT = "bedheight_middle.height";
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightCalculation.java	Fri May 18 09:18:39 2012 +0000
@@ -0,0 +1,172 @@
+package de.intevation.flys.artifacts.model;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+
+import de.intevation.artifacts.common.utils.DateUtils;
+
+import de.intevation.flys.model.BedHeightEpoch;
+import de.intevation.flys.model.BedHeightEpochValue;
+import de.intevation.flys.model.BedHeightSingle;
+import de.intevation.flys.model.BedHeightSingleValue;
+import de.intevation.flys.model.TimeInterval;
+
+import de.intevation.flys.artifacts.MINFOArtifact;
+import de.intevation.flys.artifacts.model.MiddleBedHeightData;
+
+
+public class MiddleBedHeightCalculation extends Calculation {
+
+    private static final Logger logger =
+        Logger.getLogger(MiddleBedHeightCalculation.class);
+
+
+    public CalculationResult calculate(MINFOArtifact artifact) {
+        logger.info("MiddleBedHeightCalculation.calculate");
+
+        int[] singleIds = artifact.getBedHeightSingleIDs();
+        int[] epochIds  = artifact.getBedHeightEpochIDs();
+
+        if (logger.isDebugEnabled()) {
+            logger.debug("Artifact '" + artifact.identifier() + "' contains:");
+            if (singleIds != null) {
+                logger.debug("   " + singleIds.length + " single bedheight ids");
+            }
+
+            if (epochIds != null) {
+                logger.debug("   " + epochIds.length + " epoch bedheight ids");
+            }
+        }
+
+        List<BedHeightSingle> singles = getSingles(artifact, singleIds);
+        List<BedHeightEpoch>  epochs  = getEpochs(artifact, epochIds);
+
+        return buildCalculationResult(artifact, singles, epochs);
+    }
+
+
+    protected List<BedHeightSingle> getSingles(MINFOArtifact minfo, int[] ids) {
+        List<BedHeightSingle> singles = new ArrayList<BedHeightSingle>();
+
+        for (int id: ids) {
+            BedHeightSingle s = BedHeightSingle.getBedHeightSingleById(id);
+
+            if (s != null) {
+                singles.add(s);
+            }
+            else {
+                logger.warn("Cannot find Sngle by id: " + id);
+                // TODO ADD WARNING
+            }
+        }
+
+        return singles;
+    }
+
+
+    protected List<BedHeightEpoch> getEpochs(MINFOArtifact minfo, int[] ids) {
+        List<BedHeightEpoch> epochs = new ArrayList<BedHeightEpoch>();
+
+        for (int id: ids) {
+            BedHeightEpoch e = BedHeightEpoch.getBedHeightEpochById(id);
+
+            if (e != null) {
+                epochs.add(e);
+            }
+            else {
+                logger.warn("Cannot find Epoch by id: " + id);
+                // TODO ADD WARNING
+            }
+        }
+
+        return epochs;
+    }
+
+
+    protected CalculationResult buildCalculationResult(
+        MINFOArtifact         artifact,
+        List<BedHeightSingle> singles,
+        List<BedHeightEpoch>  epochs
+    ) {
+        logger.info("MiddleBedHeightCalculation.buildCalculationResult");
+
+        int size = singles.size() + epochs.size();
+
+        List<MiddleBedHeightData> data = new ArrayList<MiddleBedHeightData>();
+
+        for (BedHeightSingle single: singles) {
+            MiddleBedHeightData d = prepareSingleData(single);
+
+            if (d != null) {
+                data.add(d);
+            }
+        }
+
+        for (BedHeightEpoch epoch: epochs) {
+            MiddleBedHeightData d = prepareEpochData(epoch);
+
+            if (d != null) {
+                data.add(d);
+            }
+        }
+
+        logger.debug("Calculation results in " + data.size() + " data objects.");
+
+        return new CalculationResult((MiddleBedHeightData[])
+            data.toArray(new MiddleBedHeightData[data.size()]), this);
+    }
+
+
+    protected MiddleBedHeightData prepareSingleData(BedHeightSingle single) {
+        logger.debug("Prepare data for single: " + single.getDescription());
+
+        List<BedHeightSingleValue> values = single.getValues();
+
+        MiddleBedHeightData data = new MiddleBedHeightData(
+            single.getYear(),
+            single.getYear(),
+            single.getEvaluationBy(),
+            single.getDescription());
+
+        for (BedHeightSingleValue value: values) {
+            data.addKM(value.getStation().doubleValue());
+            data.addMiddleHeight(value.getHeight().doubleValue());
+            data.addUncertainty(value.getUncertainty().doubleValue());
+            data.addSoundingWidth(value.getSoundingWidth().doubleValue());
+            data.addDataGap(value.getDataGap().doubleValue());
+            data.addWidth(value.getWidth().doubleValue());
+        }
+
+        logger.debug("Single contains " + values.size() + " values");
+
+        return data;
+    }
+
+
+    protected MiddleBedHeightData prepareEpochData(BedHeightEpoch epoch) {
+        logger.debug("Prepare data for epoch: " + epoch.getDescription());
+
+        TimeInterval ti = epoch.getTimeInterval();
+
+        List<BedHeightEpochValue> values = epoch.getValues();
+
+        MiddleBedHeightData data = new MiddleBedHeightData(
+            DateUtils.getYearFromDate(ti.getStartTime()),
+            DateUtils.getYearFromDate(ti.getStopTime()),
+            epoch.getEvaluationBy(),
+            epoch.getDescription()
+        );
+
+        for (BedHeightEpochValue value: values) {
+            data.addKM(value.getStation().doubleValue());
+            data.addMiddleHeight(value.getHeight().doubleValue());
+        }
+
+        logger.debug("Epoch contains " + values.size() + " values");
+
+        return data;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightData.java	Fri May 18 09:18:39 2012 +0000
@@ -0,0 +1,118 @@
+package de.intevation.flys.artifacts.model;
+
+import java.io.Serializable;
+
+import gnu.trove.TDoubleArrayList;
+
+
+public class MiddleBedHeightData implements Serializable {
+
+    private int    startYear;
+    private int    endYear;
+    private String evaluatedBy;
+    private String description;
+
+    private TDoubleArrayList km;
+    private TDoubleArrayList middleHeight;
+    private TDoubleArrayList uncertainty;
+    private TDoubleArrayList soundingWidth;
+    private TDoubleArrayList dataGap;
+    private TDoubleArrayList width;
+
+
+    protected MiddleBedHeightData(int start, int end, String eval, String desc) {
+        this.startYear   = start;
+        this.endYear     = end;
+        this.evaluatedBy = eval;
+        this.description = desc;
+
+        this.km            = new TDoubleArrayList();
+        this.middleHeight  = new TDoubleArrayList();
+        this.uncertainty   = new TDoubleArrayList();
+        this.soundingWidth = new TDoubleArrayList();
+        this.dataGap       = new TDoubleArrayList();
+        this.width         = new TDoubleArrayList();
+    }
+
+
+    public int getStartYear() {
+        return startYear;
+    }
+
+    public int getEndYear() {
+        return endYear;
+    }
+
+    public String getEvaluatedBy() {
+        return evaluatedBy;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+
+    public void addKM(double km) {
+        this.km.add(km);
+    }
+
+    public double getKM(int idx) {
+        return km.get(idx);
+    }
+
+    public void addMiddleHeight(double middleHeight) {
+        this.middleHeight.add(middleHeight);
+    }
+
+    public double getMiddleHeight(int idx) {
+        return middleHeight.get(idx);
+    }
+
+    public void addUncertainty(double uncertainty) {
+        this.uncertainty.add(uncertainty);
+    }
+
+    public double getUncertainty(int idx) {
+        return uncertainty.get(idx);
+    }
+
+    public void addSoundingWidth(double soundingWidth) {
+        this.soundingWidth.add(soundingWidth);
+    }
+
+    public double getSoundingWidth(int idx) {
+        return soundingWidth.get(idx);
+    }
+
+    public void addDataGap(double gap) {
+        this.dataGap.add(gap);
+    }
+
+    public double getDataGap(int idx) {
+        return dataGap.get(idx);
+    }
+
+    public void addWidth(double width) {
+        this.width.add(width);
+    }
+
+    public double getWidth(int idx) {
+        return width.get(idx);
+    }
+
+    public int size() {
+        return km.size();
+    }
+
+
+    public double[][] getMiddleHeightsPoints() {
+        double[][] points = new double[2][size()];
+
+        for (int i = 0, n = size(); i < n; i++) {
+            points[0][i] = getKM(i);
+            points[1][i] = getMiddleHeight(i);
+        }
+
+        return points;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/MiddleBedHeightFacet.java	Fri May 18 09:18:39 2012 +0000
@@ -0,0 +1,64 @@
+package de.intevation.flys.artifacts.model;
+
+import de.intevation.artifactdatabase.state.Facet;
+
+import de.intevation.artifacts.Artifact;
+import de.intevation.artifacts.CallContext;
+
+import de.intevation.flys.artifacts.FLYSArtifact;
+
+import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
+
+import org.apache.log4j.Logger;
+
+/**
+ * Facet of a MiddleBedHeight curve.
+ */
+public class MiddleBedHeightFacet extends DataFacet {
+
+    private static Logger logger = Logger.getLogger(MiddleBedHeightFacet.class);
+
+
+    public MiddleBedHeightFacet() {
+        // required for clone operation deepCopy()
+    }
+
+
+    public MiddleBedHeightFacet(
+        int         idx,
+        String      name,
+        String      description,
+        ComputeType type,
+        String      stateId,
+        String      hash
+    ) {
+        super(idx, name, description, type, hash, stateId);
+    }
+
+
+    public Object getData(Artifact artifact, CallContext context) {
+        logger.debug("Get data for middle bed height at index: " + index);
+
+        FLYSArtifact flys = (FLYSArtifact) artifact;
+
+        CalculationResult res = (CalculationResult)
+            flys.compute(context, hash, stateId, type, false);
+
+        MiddleBedHeightData[] data = (MiddleBedHeightData[]) res.getData();
+
+        return data[index];
+    }
+
+
+    /** Copy deeply. */
+    @Override
+    public Facet deepCopy() {
+        MiddleBedHeightFacet copy = new MiddleBedHeightFacet();
+        copy.set(this);
+        copy.type    = type;
+        copy.hash    = hash;
+        copy.stateId = stateId;
+        return copy;
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/MiddleBedHeight.java	Fri May 18 07:03:38 2012 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/MiddleBedHeight.java	Fri May 18 09:18:39 2012 +0000
@@ -1,5 +1,6 @@
 package de.intevation.flys.artifacts.states;
 
+import java.util.ArrayList;
 import java.util.List;
 
 import org.apache.log4j.Logger;
@@ -9,9 +10,16 @@
 import de.intevation.artifactdatabase.state.Facet;
 
 import de.intevation.flys.artifacts.FLYSArtifact;
+import de.intevation.flys.artifacts.MINFOArtifact;
+import de.intevation.flys.artifacts.model.CalculationResult;
+import de.intevation.flys.artifacts.model.DataFacet;
+import de.intevation.flys.artifacts.model.FacetTypes;
+import de.intevation.flys.artifacts.model.MiddleBedHeightData;
+import de.intevation.flys.artifacts.model.MiddleBedHeightFacet;
+import de.intevation.flys.artifacts.model.MiddleBedHeightCalculation;
 
 
-public class MiddleBedHeight extends DefaultState {
+public class MiddleBedHeight extends DefaultState implements FacetTypes {
 
     private static final Logger logger = Logger.getLogger(MiddleBedHeight.class);
 
@@ -26,9 +34,58 @@
     ) {
         logger.debug("MiddleBedHeight.computeAdvance");
 
-        logger.warn("TODO: Implement MiddleBedHeight.computeAdvance");
+        List<Facet> newFacets = new ArrayList<Facet>();
 
-        return null;
+        CalculationResult res = old instanceof CalculationResult
+            ? (CalculationResult) old
+            : new MiddleBedHeightCalculation().calculate((MINFOArtifact) artifact);
+
+        if (facets == null || res == null) {
+            return res;
+        }
+
+        MiddleBedHeightData[] data = (MiddleBedHeightData[]) res.getData();
+
+        logger.debug("Calculated " + data.length + " MiddleBedHeightData objects");
+
+        String id  = getID();
+        int    idx = 0;
+
+        for (MiddleBedHeightData d: data) {
+            newFacets.add(new MiddleBedHeightFacet(
+                idx,
+                MIDDLE_BED_HEIGHT,
+                buildMiddleBedHeightName(artifact, context, d),
+                ComputeType.ADVANCE,
+                id,
+                hash
+            ));
+
+            idx++;
+        }
+
+        Facet csv = new DataFacet(
+            CSV, "CSV data", ComputeType.ADVANCE, hash, id);
+
+        // TODO ADD PDF FACET
+
+        newFacets.add(csv);
+
+        logger.debug("Created " + newFacets.size() + " new Facets.");
+
+        facets.addAll(newFacets);
+
+        return res;
+    }
+
+
+    protected String buildMiddleBedHeightName(
+        FLYSArtifact        artifact,
+        CallContext         cc,
+        MiddleBedHeightData data
+    ) {
+        logger.error("TODO: Implement buildMiddleBedHeightName");
+        return "TODO: Implement buildMiddleBedHeightName";
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org