comparison gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java @ 1119:7c4f81f74c47

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

http://dive4elements.wald.intevation.org