Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java @ 447:92b7ccbf6163
Improved generation of iso lines in vertical cross section.
gnv-artifacts/trunk@495 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Fri, 01 Jan 2010 21:52:41 +0000 |
parents | eb2ac62e853a |
children | 3cb2bea50456 |
comparison
equal
deleted
inserted
replaced
446:f5a041000357 | 447:92b7ccbf6163 |
---|---|
4 import java.util.HashSet; | 4 import java.util.HashSet; |
5 import java.util.HashMap; | 5 import java.util.HashMap; |
6 import java.util.ArrayList; | 6 import java.util.ArrayList; |
7 import java.util.Collection; | 7 import java.util.Collection; |
8 | 8 |
9 import org.apache.log4j.Logger; | |
10 | |
11 import gnu.trove.TIntHashSet; | |
9 import gnu.trove.TIntObjectHashMap; | 12 import gnu.trove.TIntObjectHashMap; |
10 import gnu.trove.TDoubleArrayList; | 13 import gnu.trove.TDoubleArrayList; |
11 import gnu.trove.TIntObjectIterator; | 14 import gnu.trove.TObjectProcedure; |
12 | 15 |
13 import de.intevation.gnv.raster.Vectorizer.RingsHandler; | 16 import de.intevation.gnv.raster.Vectorizer.RingsHandler; |
14 import de.intevation.gnv.raster.Vectorizer.Edge; | 17 import de.intevation.gnv.raster.Vectorizer.Edge; |
15 | 18 |
16 import de.intevation.gnv.math.IJKey; | 19 import de.intevation.gnv.math.IJKey; |
22 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) | 25 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) |
23 */ | 26 */ |
24 public class IsoPolygonSeriesProducer | 27 public class IsoPolygonSeriesProducer |
25 implements RingsHandler | 28 implements RingsHandler |
26 { | 29 { |
30 private static Logger log = Logger.getLogger( | |
31 IsoPolygonSeriesProducer.class); | |
32 | |
33 public static final Float LINE_WIDTH = Float.valueOf(0.1f); | |
34 | |
27 public interface LabelGenerator { | 35 public interface LabelGenerator { |
28 | 36 |
29 String generateLabel(int neighbor1, int neighbor2); | 37 String generateLabel(int neighbor1, int neighbor2); |
30 | 38 |
31 } // interface LabelGenerator | 39 } // interface LabelGenerator |
130 } | 138 } |
131 | 139 |
132 public Collection<PolygonSeries> getSeries(LabelGenerator labelGenerator) { | 140 public Collection<PolygonSeries> getSeries(LabelGenerator labelGenerator) { |
133 | 141 |
134 ArrayList<PolygonSeries> series = new ArrayList<PolygonSeries>(); | 142 ArrayList<PolygonSeries> series = new ArrayList<PolygonSeries>(); |
143 | |
135 double b1 = minX; | 144 double b1 = minX; |
136 double m1 = width != 1 | 145 double m1 = width != 1 |
137 ? (maxX - minX)/(width-1) | 146 ? (maxX - minX)/(width-1) |
138 : 0d; | 147 : 0d; |
139 | 148 |
153 | 162 |
154 TDoubleArrayList vertices = new TDoubleArrayList(); | 163 TDoubleArrayList vertices = new TDoubleArrayList(); |
155 | 164 |
156 for (IJKey key: pairs) { | 165 for (IJKey key: pairs) { |
157 PolygonSeries ps = new PolygonSeries(); | 166 PolygonSeries ps = new PolygonSeries(); |
158 series.add(ps); | |
159 | |
160 if (labelGenerator != null) { | |
161 ps.setAttribute( | |
162 "label", | |
163 labelGenerator.generateLabel(key.i, key.j)); | |
164 } | |
165 | 167 |
166 // process complete | 168 // process complete |
167 ArrayList<Edge> completeList = complete.get(key); | 169 ArrayList<Edge> completeList = complete.get(key); |
168 if (completeList != null) { | 170 if (completeList != null) { |
169 for (Edge head: completeList) { | 171 for (Edge head: completeList) { |
171 do { | 173 do { |
172 vertices.add(m1*(current.a % width) + b1); | 174 vertices.add(m1*(current.a % width) + b1); |
173 vertices.add(m2*(current.a / width) + b2); | 175 vertices.add(m2*(current.a / width) + b2); |
174 } | 176 } |
175 while ((current = current.next) != head); | 177 while ((current = current.next) != head); |
176 // TODO: Do we need to copy b of the tail? | 178 // add head again to close shape |
179 vertices.add(m1*(head.a % width) + b1); | |
180 vertices.add(m2*(head.a / width) + b2); | |
177 ps.addRing(new CompactXYItems(vertices.toNativeArray())); | 181 ps.addRing(new CompactXYItems(vertices.toNativeArray())); |
178 vertices.clear(); | 182 vertices.clear(); |
179 } | 183 } |
180 } | 184 } |
181 | 185 |
182 // process open | 186 // process open |
183 TIntObjectHashMap map = commonOpen.get(key); | 187 TIntObjectHashMap map = commonOpen.get(key); |
188 | |
184 if (map != null) { | 189 if (map != null) { |
185 for (TIntObjectIterator it = map.iterator(); it.hasNext();) { | 190 final ArrayList<Edge> headList = new ArrayList<Edge>(); |
186 it.advance(); | 191 map.forEachValue(new TObjectProcedure() { |
187 int k = it.key(); | 192 TIntHashSet headSet = new TIntHashSet(); |
188 Edge head = (Edge)it.value(); | 193 public boolean execute(Object value) { |
189 // ignore tails | 194 Edge head = ((Edge)value).head(); |
190 if ((head.next == null && head.prev != null) | 195 if (headSet.add(head.a)) { |
191 || (head.next == null && head.prev == null && head.b == k)) { | 196 headList.add(head); |
192 continue; | 197 } |
193 } | 198 return true; |
199 } | |
200 }); | |
201 | |
202 for (Edge head: headList) { | |
203 | |
194 head = Vectorizer.simplify(head, width); | 204 head = Vectorizer.simplify(head, width); |
195 Edge current = head, last = head; | 205 Edge current = head, last = head; |
196 do { | 206 do { |
197 vertices.add(m1*(current.a % width) + b1); | 207 vertices.add(m1*(current.a % width) + b1); |
198 vertices.add(m2*(current.a / width) + b2); | 208 vertices.add(m2*(current.a / width) + b2); |
204 vertices.add(m2*(last.b / width) + b2); | 214 vertices.add(m2*(last.b / width) + b2); |
205 ps.addRing(new CompactXYItems(vertices.toNativeArray())); | 215 ps.addRing(new CompactXYItems(vertices.toNativeArray())); |
206 vertices.clear(); | 216 vertices.clear(); |
207 } // for all in common open | 217 } // for all in common open |
208 } // if map defined for key | 218 } // if map defined for key |
219 | |
220 int itemCount = ps.getItemCount(); | |
221 | |
222 if (itemCount > 0) { | |
223 series.add(ps); | |
224 if (labelGenerator != null) { | |
225 ps.setAttribute( | |
226 "label", | |
227 labelGenerator.generateLabel(key.i, key.j)); | |
228 } | |
229 ps.setAttribute("line.width", LINE_WIDTH); | |
230 } | |
209 } // for all pairs | 231 } // for all pairs |
210 | 232 |
211 return series; | 233 return series; |
212 } | 234 } |
213 } | 235 } |