changeset 448:3cb2bea50456

Generate iso line classes according gnv-issues/issue108 gnv-artifacts/trunk@496 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Sun, 03 Jan 2010 12:16:55 +0000
parents 92b7ccbf6163
children c7ca2fce041f
files gnv-artifacts/ChangeLog gnv-artifacts/src/main/java/de/intevation/gnv/math/XYColumn.java gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java
diffstat 6 files changed, 141 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/gnv-artifacts/ChangeLog	Fri Jan 01 21:52:41 2010 +0000
+++ b/gnv-artifacts/ChangeLog	Sun Jan 03 12:16:55 2010 +0000
@@ -1,15 +1,53 @@
+2010-01-03	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java:
+	  Generate iso line classes according gnv-issues/issue108:
+
+	  - If there are more than nine colors used in the chart
+	    only the borders of the regions are traced.
+	  - If there are less than ten colors each color region
+	    is devided into two sub regions.
+	  - If there are less than five colors each color region
+	    is devided into five sub regions.
+
+	  Generate attribute per iso line class with the parameter value
+	  of the iso line.
+
+	* src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java:
+	  Renamed inner interface from LabelGenerator to AttributeGenerator to
+	  reflect the fact that the concrete label generation is a matter
+	  of i18n too. The concrete label generation should be done when 
+	  the final chart is going to be created. TODO: Add
+	  a JFreeChart style label generator to PolygonRenderer
+
+	* src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java:
+	  New. Implements the AttributeGenerator interface. It takes
+	  the indices of the neighboring regions, uses these values
+	  to look into the iso palette and averages the parameter values
+	  at the touching borders. This should help in cases where 
+	  two regions are neighbored in the chart which are not neighbored
+	  in the palette which may happen by quantification artifacts.
+
+	* src/main/java/de/intevation/gnv/raster/Palette.java: Added
+	  getters to 'from' and 'to' fields.
+
+	* src/main/java/de/intevation/gnv/math/XYColumn.java: Fixed
+	  another silly bug with adding values at surface and ground.
+
+	* ChangeLog: Typo fixes
+
 2010-01-01	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java:
 	  Generate iso lines by dividing palette ranges in two
-	  parts each and traces them. This shows that the ideas described
+	  parts each and trace them. This shows that the ideas described
 	  by K. Jancke in gnv-issues/issue108 are possible not the
 	  right way to go. Applying this strategy there would be
 	  locally to many isolines if there is a steep gradient. 
 	  On the other side large areas are splitted in too less sections
 	  by too less iso lines. A better way may be a splitting with
-	  a look at the areas and shapes of regions. Large, round areas need
-	  more splits. Long, thin areas need less splits.
+	  a look at the areas and shapes of the regions. Large, round 
+	  regions need more splits. Long, thin regions need less.
 
 	* src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java:
 	  Stabilized iso line hashing a bit. Added line width to
@@ -17,7 +55,8 @@
 	  The according value is stored in "line.width".
 
 	* src/main/java/de/intevation/gnv/raster/Vectorizer.java: Fixed silly
-	  bug when simplifying lines. This prevented iso line
+	  bug when simplifying lines. This prevented iso lines 
+	  from rendering.
 
 	* src/main/java/de/intevation/gnv/raster/Palette.java: Fixed index issue
 	  when generating a divided palette.
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/XYColumn.java	Fri Jan 01 21:52:41 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/XYColumn.java	Sun Jan 03 12:16:55 2010 +0000
@@ -82,17 +82,16 @@
                 // if there is no value at 0 repeat first value
                 HeightValue first = values.get(0);
                 if (first.z < 0d) {
-                    values.add(0, new HeightValue(0d, first.z, first.k-1));
+                    values.add(0, new HeightValue(0d, first.v, first.k-1));
                     ++N;
                 }
 
                 // if there is no value at depth repeat last value
                 HeightValue last = values.get(N-1);
                 if (last.z > depth) {
-                    values.add(new HeightValue(depth, last.z, last.k+1));
+                    values.add(new HeightValue(depth, last.v, last.k+1));
                     ++N;
                 }
-                N = values.size();
                 if (N < 3) { // interpolate linear
                     first = values.get(0);
                     last  = values.get(N-1);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoAttributeGenerator.java	Sun Jan 03 12:16:55 2010 +0000
@@ -0,0 +1,31 @@
+package de.intevation.gnv.raster;
+
+public class IsoAttributeGenerator
+implements   IsoPolygonSeriesProducer.AttributeGenerator
+{
+    protected Palette palette;
+
+    public IsoAttributeGenerator() {
+    }
+
+    public IsoAttributeGenerator(Palette palette) {
+        this.palette = palette;
+    }
+
+    public Object generateAttribute(int neighbor1, int neighbor2) {
+        Palette.Entry e1 = palette.getEntryByIndex(neighbor1);
+        Palette.Entry e2 = palette.getEntryByIndex(neighbor2);
+
+        if (e1 == null || e2 == null) {
+            return null;
+        }
+
+        double e1t = e1.getFrom();
+        double e2f = e2.getTo();
+
+        return Double.valueOf(e2f >= e1t
+            ? 0.5d*(e1t+e2f)
+            : 0.5d*(e2.getTo()+e1.getFrom()));
+    }
+}
+// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java	Fri Jan 01 21:52:41 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java	Sun Jan 03 12:16:55 2010 +0000
@@ -27,16 +27,16 @@
 public class IsoPolygonSeriesProducer
 implements   RingsHandler
 {
-	private static Logger log = Logger.getLogger(
-		IsoPolygonSeriesProducer.class);
+    private static Logger log = Logger.getLogger(
+        IsoPolygonSeriesProducer.class);
 
 	public static final Float LINE_WIDTH = Float.valueOf(0.1f);
 
-    public interface LabelGenerator {
+    public interface AttributeGenerator {
 
-        String generateLabel(int neighbor1, int neighbor2);
+        Object generateAttribute(int neighbor1, int neighbor2);
 
-    } // interface LabelGenerator
+    } // interface AttributeGenerator
 
     protected HashMap<Edge, Integer>            open;
     protected HashMap<IJKey, TIntObjectHashMap> commonOpen;
@@ -137,8 +137,9 @@
         return getSeries(null);
     }
 
-    public Collection<PolygonSeries> getSeries(LabelGenerator labelGenerator) {
-
+    public Collection<PolygonSeries> getSeries(
+        AttributeGenerator attributeGenerator
+    ) {
         ArrayList<PolygonSeries> series = new ArrayList<PolygonSeries>();
 
         double b1 = minX;
@@ -187,17 +188,17 @@
             TIntObjectHashMap map = commonOpen.get(key);
 
             if (map != null) {
-				final ArrayList<Edge> headList = new ArrayList<Edge>();
-				map.forEachValue(new TObjectProcedure() {
-					TIntHashSet headSet = new TIntHashSet();
-					public boolean execute(Object value) {
-						Edge head = ((Edge)value).head();
-						if (headSet.add(head.a)) {
-							headList.add(head);
-						}
-						return true;
-					}
-				});
+                final ArrayList<Edge> headList = new ArrayList<Edge>();
+                map.forEachValue(new TObjectProcedure() {
+                    TIntHashSet headSet = new TIntHashSet();
+                    public boolean execute(Object value) {
+                        Edge head = ((Edge)value).head();
+                        if (headSet.add(head.a)) {
+                            headList.add(head);
+                        }
+                        return true;
+                    }
+                });
 
                 for (Edge head: headList) {
 
@@ -217,14 +218,15 @@
                 } // for all in common open
             } // if map defined for key
 
-			int itemCount = ps.getItemCount();
-
-			if (itemCount > 0) {
+			if (ps.getItemCount() > 0) {
 				series.add(ps);
-				if (labelGenerator != null) {
-					ps.setAttribute(
-						"label",
-						labelGenerator.generateLabel(key.i, key.j));
+				if (attributeGenerator != null) {
+                    Object attribute = attributeGenerator
+                        .generateAttribute(key.i, key.j);
+
+                    if (attribute != null) {
+                        ps.setAttribute("label", attribute);
+					}
 				}
 				ps.setAttribute("line.width", LINE_WIDTH);
 			}
@@ -232,5 +234,11 @@
 
         return series;
     }
+
+    public void clear() {
+        open.clear();
+        complete.clear();
+        commonOpen.clear();
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java	Fri Jan 01 21:52:41 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java	Sun Jan 03 12:16:55 2010 +0000
@@ -67,6 +67,14 @@
             return 0;
         }
 
+        public double getFrom() {
+            return from;
+        }
+
+        public double getTo() {
+            return to;
+        }
+
         public Entry locateEntry(double value) {
             Entry current = this;
             while (current != null) {
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java	Fri Jan 01 21:52:41 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/verticalcrosssection/VerticalCrossSectionOutputState.java	Sun Jan 03 12:16:55 2010 +0000
@@ -76,6 +76,7 @@
 import de.intevation.gnv.raster.Palette;
 import de.intevation.gnv.raster.Raster;
 import de.intevation.gnv.raster.PolygonDatasetProducer;
+import de.intevation.gnv.raster.IsoAttributeGenerator;
 import de.intevation.gnv.raster.IsoPolygonSeriesProducer;
 import de.intevation.gnv.raster.Vectorizer;
 
@@ -284,9 +285,9 @@
         }
 
         // scan for regions with base palette
-        Palette base = paletteManager.getBase();
+        Palette basePalette = paletteManager.getBase();
 
-        int [] intRaster = raster.toIndexed(base);
+        int [] intRaster = raster.toIndexed(basePalette);
 
         // produce JFreeChart compatible polygons
 
@@ -303,20 +304,33 @@
         int numRegions = new Vectorizer(intRaster, rasterSize.width)
             .process(pdsp);
 
-        intRaster = null; // help gc
+        PolygonDataset pds = pdsp.getPolygonDataset();
 
-        PolygonDataset pds = pdsp.getPolygonDataset();
+        int numColors = pds.getSeriesCount();
 
         if (debug) {
             log.debug("number of regions: " + numRegions);
-            log.debug("number of series:  " + pds.getSeriesCount());
+            log.debug("number of colors:  " + numColors);
         }
 
         // generate iso lines
 
-        Palette isoPalette = paletteManager.getLevel(2);
+        int numIso;
 
-        intRaster = raster.toIndexed(isoPalette);
+             if (numColors <  5) { numIso = 5; }
+        else if (numColors < 10) { numIso = 2; }
+        else                     { numIso = 0; }
+
+        Palette isoPalette;
+
+        if (numIso == 0) { // same palette
+            isoPalette = basePalette;
+            /* intRaster = intRaster; */
+        }
+        else {
+            isoPalette = paletteManager.getLevel(numIso);
+            intRaster  = raster.toIndexed(isoPalette);
+        }
 
         IsoPolygonSeriesProducer ipsp = new IsoPolygonSeriesProducer(
             0, 0,
@@ -325,8 +339,9 @@
         numRegions = new Vectorizer(false, intRaster, rasterSize.width)
             .process(ipsp);
 
-        // TODO: Use label generator
-        Collection<PolygonSeries> ps = ipsp.getSeries(/* label generator */); 
+        IsoAttributeGenerator iag = new IsoAttributeGenerator(isoPalette);
+        Collection<PolygonSeries> ps = ipsp.getSeries(iag); 
+        ipsp.clear();
 
         if (debug) {
             log.debug("num of iso regions: " + numRegions);

http://dive4elements.wald.intevation.org