changeset 1967:27bb2e24f7f8

Preparations for better CrossSection diagrams. flys-artifacts/trunk@3378 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Felix Wolfsteller <felix.wolfsteller@intevation.de>
date Fri, 09 Dec 2011 15:57:32 +0000
parents f572536af56c
children 18928f0f339b
files flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/CrossSectionFacet.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java
diffstat 3 files changed, 162 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java	Fri Dec 09 15:53:24 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java	Fri Dec 09 15:57:32 2011 +0000
@@ -13,6 +13,9 @@
 
 import de.intevation.flys.artifacts.model.CrossSectionFacet;
 
+import de.intevation.flys.model.CrossSection;
+import de.intevation.flys.model.CrossSectionLine;
+import de.intevation.flys.artifacts.model.CrossSectionFactory;
 import de.intevation.artifacts.common.ArtifactNamespaceContext;
 import de.intevation.artifacts.common.utils.XMLUtils;
 
@@ -37,6 +40,15 @@
     /** Name of state. */
     public static final String STATIC_STATE_NAME = "state.cross_section";
 
+    /** Name of data item keeping the position. */
+    public static final String DATA_KM = "cross_section.km";
+
+    /** Name of data item keeping the database id of this c.s.. */
+    public static final String DATA_DBID = "cross_section.dbid";
+
+    /** Name of data item keeping the database id of this c.s.. */
+    public static final String DATA_IS_MASTER = "cross_section.master?";
+
     /** Own logger. */
     private static final Logger logger =
         Logger.getLogger(CrossSectionArtifact.class);
@@ -66,12 +78,17 @@
             data, XPATH_IDS, ArtifactNamespaceContext.INSTANCE);
 
         if (ids != null && ids.length() > 0) {
-            addStringData("ids", ids);
+            addStringData(DATA_DBID, ids);
+            logger.debug("CrossSectionArtifacts db-id: " + ids);
         }
         else {
             throw new IllegalArgumentException("No attribute 'ids' found!");
         }
 
+        // Assume we start at km 0.
+        addStringData(DATA_KM, "0");
+        addStringData(DATA_IS_MASTER, "0");
+
         List<Facet> fs = new ArrayList<Facet>();
         fs.add(new CrossSectionFacet(0, "TODO GET NAME FROM DB"));
 
@@ -100,18 +117,11 @@
      */
     @Override
     public State getCurrentState(Object cc) {
-        State state = new StaticState(STATIC_STATE_NAME);
+        StaticState state = new StaticState(STATIC_STATE_NAME);
 
         List<Facet> fs = facets.get(getCurrentStateId());
 
-        DefaultOutput o = new DefaultOutput(
-            "cross_section",
-            "cross_section",
-            "image/png",
-            fs,
-            "chart");
-
-        state.getOutputs().add(o);
+        state.addDefaultChartOutput("cross_section", fs);
 
         return state;
     }
@@ -129,5 +139,96 @@
 
         return states;
     }
+
+    // TODO all data access needs proper caching.
+
+    /**
+     * Get a DataItem casted to int (0 if fails).
+     */
+    public int getDataAsIntNull(String dataName) {
+        String val = getDataAsString(dataName);
+        try {
+            return Integer.valueOf(val);
+        }
+        catch (NumberFormatException e) {
+            logger.warn("Could not get data " + dataName + " as int", e);
+            return 0;
+        }
+    }
+
+
+    /** Returns database-id of cross-section (from data). */
+    protected int getDBID() {
+        return getDataAsIntNull(DATA_DBID);
+    }
+
+
+    /**
+     * Return position (km) from data, 0 if not found.
+     */
+    protected double getKm() {
+        String val = getDataAsString(DATA_KM);
+        try {
+            return Double.valueOf(val);
+        }
+        catch (NumberFormatException e) {
+            logger.warn("Could not get data " + DATA_KM + " as double", e);
+            return 0;
+        }
+    }
+
+
+    /** Returns true if artifact is set to be a "master" (other facets will
+     * refer to this). */
+    public boolean isMaster() {
+        return !getDataAsString(DATA_IS_MASTER).equals("0");
+    }
+
+
+    /**
+     * Get points of Profile of cross section at given kilometer.
+     *
+     * @return an array holding coordinates of points of profile (
+     *         in the form {{x1, x2} {y1, y2}} ).
+     */
+    public double [][] getCrossSectionData() {
+        logger.info("getCrossSectionData() for cross_section.km "
+            + getDataAsString(DATA_KM));
+        CrossSectionLine line = searchCrossSectionLine();
+
+        return line != null
+               ? line.fetchCrossSectionProfile()
+               : null;
+    }
+
+
+    /**
+     * Get CrossSectionLine spatially closest to what is specified in the data
+     * "cross_section.km".
+     *
+     * @return CrossSectionLine closest to "cross_section.km".
+     */
+    public CrossSectionLine searchCrossSectionLine() {
+        double wishKM = getKm();
+
+        CrossSection crossSection = CrossSectionFactory.getCrossSection(getDBID());
+        logger.debug("dbid " + getDBID() + " : " + crossSection);
+        List<CrossSectionLine> crossSectionLines =
+            crossSection.getLines();
+            
+        // Get the cross section closest to requested km.
+        // Naive, linear approach.
+        CrossSectionLine oldLine = crossSectionLines.get(0);
+        double oldDiff = Math.abs(wishKM - oldLine.getKm().doubleValue());
+        for (CrossSectionLine line: crossSectionLines) {
+            double diff = Math.abs(wishKM - line.getKm().doubleValue());
+            if (diff > oldDiff) {
+                break;
+            }
+            oldDiff = diff;
+            oldLine = line;
+        }
+        return oldLine;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/CrossSectionFacet.java	Fri Dec 09 15:53:24 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/CrossSectionFacet.java	Fri Dec 09 15:57:32 2011 +0000
@@ -1,5 +1,8 @@
 package de.intevation.flys.artifacts.model;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.apache.log4j.Logger;
 
 import de.intevation.artifacts.Artifact;
@@ -8,22 +11,26 @@
 import de.intevation.artifactdatabase.state.DefaultFacet;
 import de.intevation.artifactdatabase.state.Facet;
 
-import de.intevation.flys.artifacts.WINFOArtifact;
+import de.intevation.flys.artifacts.CrossSectionArtifact;
 
 import de.intevation.flys.artifacts.states.DefaultState.ComputeType;
 
 
 /**
- * Trival Facet for Cross Sections.
+ * Trival Facet for Cross Sections (profiles).
  */
 public class CrossSectionFacet
 extends      DefaultFacet
 implements   FacetTypes {
 
+    public static String BLACKBOARD_CS_MASTER_DATA
+        = "crosssection.masterprofile.data";
+
     private static Logger logger = Logger.getLogger(CrossSectionFacet.class);
 
     protected ComputeType type;
 
+
     /** Trivial constructor, set (maybe localized) description. */
     public CrossSectionFacet(int idx, String description) {
         super(idx, CROSS_SECTION, description);
@@ -31,15 +38,53 @@
     }
 
 
+    /** Tell world we know about crosssection masters data and its index. */
+    public List getDataProviderKeys(Artifact art) {
+        CrossSectionArtifact artifact = (CrossSectionArtifact) art;
+        List keys = new ArrayList();
+        if (artifact.isMaster()) {
+            keys.add(BLACKBOARD_CS_MASTER_DATA);
+        }
+        return keys;
+    }
+
+
     /**
-     * Gets dummy data.
+     * Can provide the master cross section lines or its index.
+     * @param artifact crosssection-artifact
+     * @param key      will respond on BLACKBOARD_CS_MASTER_DATA
+     * @param param    ignored
+     * @param context  ignored
+     * @return data from artifact (cross section master track).
      */
-    public Object getData(Artifact artifact, CallContext context) {
+    public Object provideBlackboardData(Artifact artifact,
+        Object key,
+        Object param,
+        CallContext context
+    ) {
+        CrossSectionArtifact crossSection = (CrossSectionArtifact) artifact;
+
+        if (key.equals(BLACKBOARD_CS_MASTER_DATA)) {
+            return crossSection.searchCrossSectionLine();
+        }
+        else {
+            logger.warn("Cannot provide data for key: " + key);
+            return null;
+        }
+    }
+
+
+    /**
+     * Gets Cross Section (profile).
+     * @param art artifact to get data from.
+     * @param context ignored
+     */
+    public Object getData(Artifact art, CallContext context) {
         logger.debug("Get data for cross section");
 
-        WINFOArtifact winfo = (WINFOArtifact)artifact;
+        CrossSectionArtifact artifact = (CrossSectionArtifact)art;
 
-        return winfo.getCrossSectionData();
+        return artifact.getCrossSectionData();
     }
 
 
@@ -52,4 +97,3 @@
     }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :
-
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java	Fri Dec 09 15:53:24 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/WaterlevelState.java	Fri Dec 09 15:57:32 2011 +0000
@@ -11,7 +11,6 @@
 import de.intevation.flys.artifacts.FLYSArtifact;
 import de.intevation.flys.artifacts.WINFOArtifact;
 import de.intevation.flys.artifacts.model.DataFacet;
-import de.intevation.flys.artifacts.model.CrossSectionFacet;
 import de.intevation.flys.artifacts.model.CrossSectionWaterLineFacet;
 import de.intevation.flys.artifacts.model.CalculationResult;
 import de.intevation.flys.artifacts.model.FacetTypes;
@@ -85,11 +84,6 @@
 
             facets.add(wst);
             facets.add(csv);
-            // Also register the CrossSectionFacets.
-            int idx = 0;
-            for (String name: winfo.getCrossSectionNames()) {
-                facets.add(new CrossSectionFacet(idx++, name));
-            }
         }
 
         if (res.getReport().hasProblems()) {

http://dive4elements.wald.intevation.org