Mercurial > dive4elements > gnv-client
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: |