comparison gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java @ 465:f7038820df2e

Added support to trace rasters to JTS multi polygons and multi line strings. Write them to shape files with GeoTools. gnv-artifacts/trunk@526 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 11 Jan 2010 00:29:45 +0000
parents 3cb2bea50456
children 1bf058f1a2d1
comparison
equal deleted inserted replaced
464:70df44021a9f 465:f7038820df2e
1 package de.intevation.gnv.raster; 1 package de.intevation.gnv.raster;
2 2
3 import java.util.List;
4 import java.util.HashSet;
5 import java.util.HashMap;
6 import java.util.ArrayList; 3 import java.util.ArrayList;
7 import java.util.Collection; 4 import java.util.Collection;
8 5
9 import org.apache.log4j.Logger; 6 import org.apache.log4j.Logger;
10 7
11 import gnu.trove.TIntHashSet;
12 import gnu.trove.TIntObjectHashMap; 8 import gnu.trove.TIntObjectHashMap;
13 import gnu.trove.TDoubleArrayList; 9 import gnu.trove.TDoubleArrayList;
14 import gnu.trove.TObjectProcedure;
15 10
16 import de.intevation.gnv.raster.Vectorizer.RingsHandler;
17 import de.intevation.gnv.raster.Vectorizer.Edge; 11 import de.intevation.gnv.raster.Vectorizer.Edge;
18 12
19 import de.intevation.gnv.math.IJKey; 13 import de.intevation.gnv.math.IJKey;
20 14
21 import de.intevation.gnv.jfreechart.PolygonSeries; 15 import de.intevation.gnv.jfreechart.PolygonSeries;
23 17
24 /** 18 /**
25 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) 19 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
26 */ 20 */
27 public class IsoPolygonSeriesProducer 21 public class IsoPolygonSeriesProducer
28 implements RingsHandler 22 extends IsoProducer
29 { 23 {
30 private static Logger log = Logger.getLogger( 24 private static Logger log = Logger.getLogger(
31 IsoPolygonSeriesProducer.class); 25 IsoPolygonSeriesProducer.class);
32 26
33 public static final Float LINE_WIDTH = Float.valueOf(0.1f); 27 public static final Float LINE_WIDTH = Float.valueOf(0.1f);
34 28
35 public interface AttributeGenerator {
36
37 Object generateAttribute(int neighbor1, int neighbor2);
38
39 } // interface AttributeGenerator
40
41 protected HashMap<Edge, Integer> open;
42 protected HashMap<IJKey, TIntObjectHashMap> commonOpen;
43 protected HashMap<IJKey, ArrayList<Edge>> complete;
44
45 protected int width;
46 protected int height;
47
48 protected double minX;
49 protected double minY;
50 protected double maxX;
51 protected double maxY;
52
53 public IsoPolygonSeriesProducer( 29 public IsoPolygonSeriesProducer(
54 double minX, double minY, 30 double minX, double minY,
55 double maxX, double maxY 31 double maxX, double maxY
56 ) { 32 ) {
57 this.minX = minX; 33 super(minX, minY, maxX, maxY);
58 this.minY = minY;
59 this.maxX = maxX;
60 this.maxY = maxY;
61
62 open = new HashMap<Edge, Integer>();
63 commonOpen = new HashMap<IJKey, TIntObjectHashMap>();
64 complete = new HashMap<IJKey, ArrayList<Edge>>();
65 } 34 }
66
67 public void handleRings(
68 List<Edge> rings,
69 int value,
70 int width,
71 int height
72 ) {
73 if (value == -1) {
74 return;
75 }
76 this.width = width;
77 this.height = height;
78
79 Integer v = Integer.valueOf(value);
80
81 for (Edge head: rings) {
82 Edge current = head;
83 do {
84 Integer neighbor = open.remove(current);
85
86 if (neighbor != null) {
87 IJKey pair = new IJKey(value, neighbor.intValue());
88 pair.sort();
89
90 TIntObjectHashMap co = commonOpen.get(pair);
91
92 if (co == null) {
93 commonOpen.put(pair, co = new TIntObjectHashMap());
94 }
95
96 Edge edge = new Edge(current);
97
98 Edge otherA = (Edge)co.remove(edge.a);
99 if (otherA != null) {
100 otherA.chain(edge, edge.a);
101 }
102
103 Edge otherB = (Edge)co.remove(edge.b);
104 if (otherB != null) {
105 otherB.chain(edge, edge.b);
106 }
107
108 if (edge.isComplete()) {
109 ArrayList list = complete.get(pair);
110 if (list == null) {
111 complete.put(pair, list = new ArrayList());
112 }
113 list.add(Vectorizer.simplify(edge, width));
114 }
115 else {
116 if (otherA == null) {
117 co.put(edge.a, edge);
118 }
119 if (otherB == null) {
120 co.put(edge.b, edge);
121 }
122 }
123 }
124 else {
125 Edge edge = new Edge(current.b, current.a);
126 open.put(edge, v);
127 }
128
129 current = current.next;
130 }
131 while (current != head);
132 } // for all rings
133
134 } // handleRings
135 35
136 public Collection<PolygonSeries> getSeries() { 36 public Collection<PolygonSeries> getSeries() {
137 return getSeries(null); 37 return getSeries(null);
138 } 38 }
139 39
150 double b2 = minY; 50 double b2 = minY;
151 double m2 = height != 1 51 double m2 = height != 1
152 ? (maxY - minY)/(height-1) 52 ? (maxY - minY)/(height-1)
153 : 0d; 53 : 0d;
154 54
155 // join keys of complete and open polygons
156 HashSet<IJKey> pairs = new HashSet<IJKey>();
157 for (IJKey key: complete.keySet()) {
158 pairs.add(key);
159 }
160 for (IJKey key: commonOpen.keySet()) {
161 pairs.add(key);
162 }
163
164 TDoubleArrayList vertices = new TDoubleArrayList(); 55 TDoubleArrayList vertices = new TDoubleArrayList();
165 56
166 for (IJKey key: pairs) { 57 for (IJKey key: joinPairs()) {
167 PolygonSeries ps = new PolygonSeries(); 58 PolygonSeries ps = new PolygonSeries();
168 59
169 // process complete 60 // process complete
170 ArrayList<Edge> completeList = complete.get(key); 61 ArrayList<Edge> completeList = complete.get(key);
171 if (completeList != null) { 62 if (completeList != null) {
186 77
187 // process open 78 // process open
188 TIntObjectHashMap map = commonOpen.get(key); 79 TIntObjectHashMap map = commonOpen.get(key);
189 80
190 if (map != null) { 81 if (map != null) {
191 final ArrayList<Edge> headList = new ArrayList<Edge>(); 82 for (Edge head: headList(map)) {
192 map.forEachValue(new TObjectProcedure() {
193 TIntHashSet headSet = new TIntHashSet();
194 public boolean execute(Object value) {
195 Edge head = ((Edge)value).head();
196 if (headSet.add(head.a)) {
197 headList.add(head);
198 }
199 return true;
200 }
201 });
202
203 for (Edge head: headList) {
204 83
205 head = Vectorizer.simplify(head, width); 84 head = Vectorizer.simplify(head, width);
206 Edge current = head, last = head; 85 Edge current = head, last = head;
207 do { 86 do {
208 vertices.add(m1*(current.a % width) + b1); 87 vertices.add(m1*(current.a % width) + b1);
232 } 111 }
233 } // for all pairs 112 } // for all pairs
234 113
235 return series; 114 return series;
236 } 115 }
237
238 public void clear() {
239 open.clear();
240 complete.clear();
241 commonOpen.clear();
242 }
243 } 116 }
244 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8: 117 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org