Mercurial > dive4elements > gnv-client
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 -> 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 : |