# HG changeset patch # User Sascha L. Teichmann # Date 1261841528 0 # Node ID 6642ab6c583c289ab8389b3db32d5c51724317d8 # Parent 67091b17462d2c776c317d649f03969a33e1d9bb Added vectorizer rings callback which generates polygon datasets suitable for polygon plots. gnv-artifacts/trunk@484 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r 67091b17462d -r 6642ab6c583c gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Fri Dec 25 12:00:14 2009 +0000 +++ b/gnv-artifacts/ChangeLog Sat Dec 26 15:32:08 2009 +0000 @@ -1,3 +1,25 @@ +2009-12-26 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java: + New. Vectorizer rings callback which produces PolygonDatasets suitable + to be fed into PolygonPlot. + + * src/main/java/de/intevation/gnv/raster/Vectorizer.java: + Forward height to rings callback. + Made simplification of chains an option (default: true). + This should be turn off if generating iso lines. + Made edges hashable (handy to find neighbored edges in + iso line scanning). + + * src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java: + Added default constructor. Generate unique comparable long id + in thos constructor. + Added method to add a single ring. + + * src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java: + Added constructor to construct with a collection of polygon + series. + 2009-12-25 Sascha L. Teichmann * src/main/java/de/intevation/gnv/raster/Palette.java: Added diff -r 67091b17462d -r 6642ab6c583c gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java Fri Dec 25 12:00:14 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonDataset.java Sat Dec 26 15:32:08 2009 +0000 @@ -1,6 +1,7 @@ package de.intevation.gnv.jfreechart; import java.util.List; +import java.util.Collection; import java.util.ArrayList; import org.jfree.data.Range; @@ -17,12 +18,15 @@ public PolygonDataset() { - this(null); + data = new ArrayList(); } + public PolygonDataset(Collection series) { + data = new ArrayList(series); + } public PolygonDataset(PolygonSeries series) { - data = new ArrayList(); + this(); if (series != null) { data.add(series); diff -r 67091b17462d -r 6642ab6c583c gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java Fri Dec 25 12:00:14 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/jfreechart/PolygonSeries.java Sat Dec 26 15:32:08 2009 +0000 @@ -16,6 +16,15 @@ protected CompactXYItems [] rings; protected Map attributes; + private static long uniqueKey; + + protected synchronized static Long createUniqueKey() { + return new Long(uniqueKey++); + } + + public PolygonSeries() { + this(createUniqueKey(), null); + } public PolygonSeries(Comparable key, CompactXYItems [] rings) { this(key, null, rings, new HashMap()); @@ -49,6 +58,18 @@ return rings; } + public void addRing(CompactXYItems newRing) { + if (rings == null) { + rings = new CompactXYItems [] { newRing }; + } + else { + CompactXYItems [] nRings = new CompactXYItems[rings.length + 1]; + System.arraycopy(rings, 0, nRings, 0, rings.length); + nRings[rings.length] = newRing; + rings = nRings; + } + } + public void addRings(CompactXYItems [] newRings) { if (newRings == null || newRings.length == 0) { return; diff -r 67091b17462d -r 6642ab6c583c gnv-artifacts/src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java Sat Dec 26 15:32:08 2009 +0000 @@ -0,0 +1,97 @@ +package de.intevation.gnv.raster; + +import java.util.List; +import java.util.HashMap; + +import gnu.trove.TDoubleArrayList; + +import de.intevation.gnv.raster.Vectorizer.RingsHandler; +import de.intevation.gnv.raster.Vectorizer.Edge; + +import de.intevation.gnv.jfreechart.PolygonSeries; +import de.intevation.gnv.jfreechart.PolygonDataset; +import de.intevation.gnv.jfreechart.CompactXYItems; + +public class PolygonDatasetProducer +implements RingsHandler +{ + protected double minX; + protected double minY; + + protected double maxX; + protected double maxY; + + protected HashMap polygonSeries; + + protected PolygonDatasetProducer() { + } + + public PolygonDatasetProducer( + double minX, double minY, + double maxX, double maxY + + ) { + this.minX = minX; + this.minY = minY; + this.maxX = maxX; + this.maxY = maxY; + + polygonSeries = new HashMap(); + } + + public void handleRings( + List rings, + int value, + int width, + int height + ) { + if (value == -1) { + return; + } + + Integer v = Integer.valueOf(value); + + PolygonSeries ps = (PolygonSeries)polygonSeries.get(v); + + if (ps == null) { + polygonSeries.put(v, ps = new PolygonSeries()); + ps.setAttribute("fill", v); + } + + TDoubleArrayList vertices = new TDoubleArrayList(); + + /* minX = 0*m1 + b1 <=> b1 = minX + * maxX = (width-1)*m1 + b1 + * m1 = (maxX - minX)/(width-1) + */ + + double b1 = minX; + double m1 = width != 1 + ? (maxX - minX)/(width-1) + : 0d; + + double b2 = minY; + double m2 = height != 1 + ? (maxY - minY)/(height-1) + : 0d; + + for (Edge head: rings) { + Edge current = head; + do { + double x = m1*(current.a % width) + b1; + double y = m2*(current.a / width) + b2; + vertices.add(x); + vertices.add(y); + current = current.next; + } + while (current != head); + ps.addRing(new CompactXYItems(vertices.toNativeArray())); + vertices.clear(); + } + } + + public PolygonDataset getPolygonDataset() { + return new PolygonDataset(polygonSeries.values()); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: diff -r 67091b17462d -r 6642ab6c583c gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java Fri Dec 25 12:00:14 2009 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java Sat Dec 26 15:32:08 2009 +0000 @@ -14,7 +14,11 @@ { public interface RingsHandler { - void handleRings(List rings, int value, int width); + void handleRings( + List rings, + int value, + int width, + int height); } // interface RingsHandler @@ -69,6 +73,15 @@ do { ++length; } while ((current = current.next) != this); return length; } + + public int hashCode() { + return (a << 16) | b; + } + + public boolean equals(Object other) { + Edge e = (Edge)other; + return a == e.a && b == e.b; + } } // class Edge protected static Edge simplify(Edge edge, int width) { @@ -113,11 +126,17 @@ protected int [] raster; protected int width; protected TIntObjectHashMap openEdges; - protected ArrayList rings; + protected List rings; + protected boolean simplify; public Vectorizer() { - openEdges = new TIntObjectHashMap(); - rings = new ArrayList(); + this(true); + } + + public Vectorizer(boolean simplify) { + openEdges = new TIntObjectHashMap(); + rings = new ArrayList(); + this.simplify = simplify; } public Vectorizer(int [] raster, int width) { @@ -163,7 +182,7 @@ } if (edge.isComplete()) { - rings.add(simplify(edge, width + 1)); + rings.add(simplify ? simplify(edge, width + 1) : edge); } else { if (otherA == null) { @@ -183,6 +202,7 @@ int regions = 0; + int height = raster.length / width; for (int i = 0; i < raster.length; ++i) { if (visited.get(i)) { @@ -278,7 +298,11 @@ current = stack.pop(); } - handler.handleRings(rings, currentValue, width + 1); + handler.handleRings( + rings, + currentValue, + width + 1, + height + 1); resetRegion(); }