comparison gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java @ 875:5e9efdda6894

merged gnv-artifacts/1.0
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:13:56 +0200
parents 4abe172be970
children f953c9a559d8
comparison
equal deleted inserted replaced
722:bb3ffe7d719e 875:5e9efdda6894
1 package de.intevation.gnv.raster;
2
3 import de.intevation.gnv.math.IJKey;
4
5 import de.intevation.gnv.raster.Vectorizer.Edge;
6
7 import gnu.trove.TIntHashSet;
8 import gnu.trove.TIntObjectHashMap;
9 import gnu.trove.TObjectProcedure;
10
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.HashSet;
14 import java.util.List;
15
16 /**
17 * Vectorizer backend to generate iso lines as line strings
18 * and custom labels on the chart.
19 *
20 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
21 */
22 public class IsoProducer
23 extends AbstractProducer
24 {
25 /**
26 * Iso lines separate two neighbors. This interface decouples
27 * the generation of a suitable label for these to neighbors.
28 */
29 public interface AttributeGenerator {
30
31 /**
32 * Generate attribute show as label for two given neighbors.
33 * @param neighbor1 The first neighbor.
34 * @param neighbor2 The second neighbor.
35 * @return The label attribute.
36 */
37 Object generateAttribute(int neighbor1, int neighbor2);
38
39 } // interface AttributeGenerator
40
41 /**
42 * Internal map of open edge to neighbor attributes.
43 */
44 protected HashMap<Edge, Integer> open;
45 /**
46 * Internal map to associate neighbors with open edges.
47 */
48 protected HashMap<IJKey, TIntObjectHashMap> commonOpen;
49 /**
50 * Internal map to associate neighbors with complete rings.
51 */
52 protected HashMap<IJKey, ArrayList<Edge>> complete;
53
54 /**
55 * Width of the index space.
56 */
57 protected int width;
58 /**
59 * Height of the index space.
60 */
61 protected int height;
62
63 /**
64 * Constructor with a given world bounding box.
65 * @param minX Min x coord of the world.
66 * @param minY Min y coord of the world.
67 * @param maxX Max x coord of the world.
68 * @param maxY Max y coord of the world.
69 */
70 public IsoProducer(
71 double minX, double minY,
72 double maxX, double maxY
73 ) {
74 super(minX, minY, maxX, maxY);
75
76 open = new HashMap<Edge, Integer>();
77 commonOpen = new HashMap<IJKey, TIntObjectHashMap>();
78 complete = new HashMap<IJKey, ArrayList<Edge>>();
79 }
80
81 public void handleRings(
82 List<Edge> rings,
83 int value,
84 int width,
85 int height
86 ) {
87 if (value == -1) {
88 return;
89 }
90 this.width = width;
91 this.height = height;
92
93 Integer v = Integer.valueOf(value);
94
95 for (Edge head: rings) {
96 Edge current = head;
97 do {
98 Integer neighbor = open.remove(current);
99
100 if (neighbor != null) {
101 IJKey pair = new IJKey(value, neighbor.intValue());
102 pair.sort();
103
104 TIntObjectHashMap co = commonOpen.get(pair);
105
106 if (co == null) {
107 commonOpen.put(pair, co = new TIntObjectHashMap());
108 }
109
110 Edge edge = new Edge(current);
111
112 Edge otherA = (Edge)co.remove(edge.a);
113 if (otherA != null) {
114 otherA.chain(edge, edge.a);
115 }
116
117 Edge otherB = (Edge)co.remove(edge.b);
118 if (otherB != null) {
119 otherB.chain(edge, edge.b);
120 }
121
122 if (edge.isComplete()) {
123 ArrayList list = complete.get(pair);
124 if (list == null) {
125 complete.put(pair, list = new ArrayList());
126 }
127 list.add(Vectorizer.simplify(edge, width));
128 }
129 else {
130 if (otherA == null) {
131 co.put(edge.a, edge);
132 }
133 if (otherB == null) {
134 co.put(edge.b, edge);
135 }
136 }
137 }
138 else {
139 Edge edge = new Edge(current.b, current.a);
140 open.put(edge, v);
141 }
142
143 current = current.next;
144 }
145 while (current != head);
146 } // for all rings
147
148 } // handleRings
149
150 /**
151 * Join the pairs of neighbors i,j to have a distinct set.
152 * @return The distinct pairs of neighbors.
153 */
154 protected HashSet<IJKey> joinPairs() {
155 HashSet<IJKey> pairs = new HashSet<IJKey>();
156 pairs.addAll(complete .keySet());
157 pairs.addAll(commonOpen.keySet());
158 return pairs;
159 }
160
161 /**
162 * Filter out the head list from the open edge lists.
163 * @param map Map of end and head lists.
164 * @return list of only head lists.
165 */
166 protected static ArrayList<Edge> headList(TIntObjectHashMap map) {
167 final ArrayList<Edge> headList = new ArrayList<Edge>();
168 map.forEachValue(new TObjectProcedure() {
169 TIntHashSet headSet = new TIntHashSet();
170 public boolean execute(Object value) {
171 Edge head = ((Edge)value).head();
172 if (headSet.add(head.a)) {
173 headList.add(head);
174 }
175 return true;
176 }
177 });
178 return headList;
179 }
180
181 /**
182 * Reset internal data structures to save some memory.
183 */
184 public void clear() {
185 open.clear();
186 complete.clear();
187 commonOpen.clear();
188 }
189 }
190 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org