diff flys-artifacts/src/main/java/de/intevation/flys/artifacts/CrossSectionArtifact.java @ 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 85e442933e6d
children 741d2067cfe1
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 :

http://dive4elements.wald.intevation.org