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