comparison gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.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 feae2f9d6c6f
children f953c9a559d8
comparison
equal deleted inserted replaced
722:bb3ffe7d719e 875:5e9efdda6894
1 package de.intevation.gnv.raster;
2
3 import com.vividsolutions.jts.geom.Coordinate;
4 import com.vividsolutions.jts.geom.Geometry;
5 import com.vividsolutions.jts.geom.GeometryFactory;
6 import com.vividsolutions.jts.geom.LineString;
7 import com.vividsolutions.jts.geom.MultiLineString;
8 import com.vividsolutions.jts.geom.Polygon;
9 import com.vividsolutions.jts.geom.TopologyException;
10
11 import de.intevation.gnv.math.IJKey;
12
13 import de.intevation.gnv.raster.Vectorizer.Edge;
14
15 import de.intevation.gnv.utils.Pair;
16
17 import gnu.trove.TIntObjectHashMap;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.apache.log4j.Logger;
23
24 /**
25 * Vectorizer backend to generated iso lines in form of
26 * JTS multi linestrings.
27 *
28 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a>
29 */
30 public class JTSMultiLineStringProducer
31 extends IsoProducer
32 {
33 private static Logger log = Logger.getLogger(
34 JTSMultiLineStringProducer.class);
35
36 /**
37 * The JTS geometry factory of this producer.
38 */
39 protected GeometryFactory geometryFactory;
40
41 /**
42 * The polygon used to clip the produced multe line strings.
43 */
44 protected Polygon clip;
45
46 /**
47 * Constructor to create a JTSMultiLineStringProducer with
48 * a given clipping polygon and a world bounding box.
49 * @param clip The clipping polygon.
50 * @param minX Min x coord of the world.
51 * @param minY Min y coord of the world.
52 * @param maxX Max x coord of the world.
53 * @param maxY Max y coord of the world.
54 */
55 public JTSMultiLineStringProducer(
56 Polygon clip,
57 double minX, double minY,
58 double maxX, double maxY
59 ) {
60 this(
61 clip,
62 // XXX: Geotools crashes if only using a 2d packed data format!
63 JTSMultiPolygonProducer.createDefaultGeometryFactory(3),
64 minX, minY,
65 maxX, maxY);
66 }
67
68 /**
69 * Constructor to create a JTSMultiLineStringProducer with
70 * a given clipping polygon, a geometry factory
71 * and a world bounding box.
72 * @param clip The clipping polygon.
73 * @param geometryFactory The geometry factory.
74 * @param minX Min x coord of the world.
75 * @param minY Min y coord of the world.
76 * @param maxX Max x coord of the world.
77 * @param maxY Max y coord of the world.
78 */
79 public JTSMultiLineStringProducer(
80 Polygon clip,
81 GeometryFactory geometryFactory,
82 double minX, double minY,
83 double maxX, double maxY
84 ) {
85 super(minX, minY, maxX, maxY);
86 this.clip = clip;
87 this.geometryFactory = geometryFactory;
88 }
89
90 /**
91 * Clips a given line string against the clippin polygon. The
92 * result is stored in the given list of line strings.
93 * @param lineString The line string to be clipped.
94 * @param lineStrings The result line string list.
95 */
96 protected void clipLineString(
97 LineString lineString,
98 ArrayList<LineString> lineStrings
99 ) {
100 if (clip == null) {
101 lineStrings.add(lineString);
102 return;
103 }
104
105 if (!lineString.intersects(clip)) {
106 return;
107 }
108
109 try {
110 Geometry result = lineString.intersection(clip);
111
112 if (result instanceof LineString) {
113 lineStrings.add((LineString)result);
114 }
115 else if (result instanceof MultiLineString) {
116 MultiLineString mls = (MultiLineString)result;
117 for (int i = 0, N = mls.getNumGeometries(); i < N; ++i) {
118 Geometry g = mls.getGeometryN(i);
119 if (g instanceof LineString) {
120 lineStrings.add((LineString)g);
121 }
122 else {
123 log.warn("cannot handle geometry " + g.getClass());
124 }
125 }
126 }
127 else {
128 log.warn("cannot handle " + result.getClass());
129 }
130 }
131 catch (TopologyException te) {
132 log.error(te.getLocalizedMessage(), te);
133 lineStrings.add(lineString);
134 }
135 }
136
137 /**
138 * Returns a list of pairs attribute -&gt; multi line string.
139 * All line strings produced are grouped by there attribute
140 * which is generated with the given attribute generator.
141 * @param attributeGenerator The attribute generator.
142 * @return The list of attribute/multi line strings.
143 */
144 public List<Pair<Object, MultiLineString>> getMultiLineStrings(
145 AttributeGenerator attributeGenerator
146 ) {
147 ArrayList<Pair<Object, MultiLineString>> multiLineStrings =
148 new ArrayList<Pair<Object, MultiLineString>>();
149
150 double b1 = minX;
151 double m1 = width != 1
152 ? (maxX - minX)/(width-1)
153 : 0d;
154
155 double b2 = minY;
156 double m2 = height != 1
157 ? (maxY - minY)/(height-1)
158 : 0d;
159
160 ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
161
162 for (IJKey key: joinPairs()) {
163 ArrayList<LineString> lineStrings = new ArrayList<LineString>();
164
165 // process complete
166 ArrayList<Edge> completeList = complete.get(key);
167 if (completeList != null) {
168 for (Edge head: completeList) {
169 Edge current = head;
170 do {
171 coordinates.add(new Coordinate(
172 m1*(current.a % width) + b1,
173 m2*(current.a / width) + b2));
174 }
175 while ((current = current.next) != head);
176 // add head again to close shape
177 coordinates.add(new Coordinate(
178 m1*(head.a % width) + b1,
179 m2*(head.a / width) + b2));
180
181 clipLineString(
182 geometryFactory.createLineString(
183 coordinates.toArray(
184 new Coordinate[coordinates.size()])),
185 lineStrings);
186
187 coordinates.clear();
188 }
189 }
190
191 // process open
192 TIntObjectHashMap map = commonOpen.get(key);
193
194 if (map != null) {
195 for (Edge head: headList(map)) {
196
197 head = Vectorizer.simplify(head, width);
198 Edge current = head, last = head;
199 do {
200 coordinates.add(new Coordinate(
201 m1*(current.a % width) + b1,
202 m2*(current.a / width) + b2));
203 last = current;
204 }
205 while ((current = current.next) != null);
206 // add b from tail
207 coordinates.add(new Coordinate(
208 m1*(last.b % width) + b1,
209 m2*(last.b / width) + b2));
210
211 clipLineString(
212 geometryFactory.createLineString(
213 coordinates.toArray(
214 new Coordinate[coordinates.size()])),
215 lineStrings);
216
217 coordinates.clear();
218 } // for all in common open
219 } // if map defined for key
220
221 if (!lineStrings.isEmpty()) {
222 MultiLineString multiLineString =
223 geometryFactory.createMultiLineString(
224 lineStrings.toArray(
225 new LineString[lineStrings.size()]));
226 lineStrings.clear();
227 Object attribute = attributeGenerator != null
228 ? attributeGenerator.generateAttribute(key.i, key.j)
229 : key;
230 multiLineStrings.add(new Pair<Object, MultiLineString>(
231 attribute,
232 multiLineString));
233 }
234 } // for all pairs
235
236 return multiLineStrings;
237 }
238 }
239 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org