comparison gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java @ 657:af3f56758f59

merged gnv-artifacts/0.5
author Thomas Arendsen Hein <thomas@intevation.de>
date Fri, 28 Sep 2012 12:13:53 +0200
parents 70adafe2b9d5
children b1f5f2a8840f
comparison
equal deleted inserted replaced
590:5f5f273c8566 657:af3f56758f59
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 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
25 */
26 public class JTSMultiLineStringProducer
27 extends IsoProducer
28 {
29 private static Logger log = Logger.getLogger(
30 JTSMultiLineStringProducer.class);
31
32 protected GeometryFactory geometryFactory;
33
34 protected Polygon clip;
35
36 public JTSMultiLineStringProducer(
37 Polygon clip,
38 double minX, double minY,
39 double maxX, double maxY
40 ) {
41 this(
42 clip,
43 // XXX: Geotools crashes if only using a 2d packed data format!
44 JTSMultiPolygonProducer.createDefaultGeometryFactory(3),
45 minX, minY,
46 maxX, maxY);
47 }
48
49 public JTSMultiLineStringProducer(
50 Polygon clip,
51 GeometryFactory geometryFactory,
52 double minX, double minY,
53 double maxX, double maxY
54 ) {
55 super(minX, minY, maxX, maxY);
56 this.clip = clip;
57 this.geometryFactory = geometryFactory;
58 }
59
60 protected void clipLineString(
61 LineString lineString,
62 ArrayList<LineString> lineStrings
63 ) {
64 if (clip == null) {
65 lineStrings.add(lineString);
66 return;
67 }
68
69 if (!lineString.intersects(clip)) {
70 return;
71 }
72
73 try {
74 Geometry result = lineString.intersection(clip);
75
76 if (result instanceof LineString) {
77 lineStrings.add((LineString)result);
78 }
79 else if (result instanceof MultiLineString) {
80 MultiLineString mls = (MultiLineString)result;
81 for (int i = 0, N = mls.getNumGeometries(); i < N; ++i) {
82 Geometry g = mls.getGeometryN(i);
83 if (g instanceof LineString) {
84 lineStrings.add((LineString)g);
85 }
86 else {
87 log.warn("cannot handle geometry " + g.getClass());
88 }
89 }
90 }
91 else {
92 log.warn("cannot handle " + result.getClass());
93 }
94 }
95 catch (TopologyException te) {
96 log.error(te.getLocalizedMessage(), te);
97 lineStrings.add(lineString);
98 }
99 }
100
101 public List<Pair<Object, MultiLineString>> getMultiLineStrings(
102 AttributeGenerator attributeGenerator
103 ) {
104 ArrayList<Pair<Object, MultiLineString>> multiLineStrings =
105 new ArrayList<Pair<Object, MultiLineString>>();
106
107 double b1 = minX;
108 double m1 = width != 1
109 ? (maxX - minX)/(width-1)
110 : 0d;
111
112 double b2 = minY;
113 double m2 = height != 1
114 ? (maxY - minY)/(height-1)
115 : 0d;
116
117 ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>();
118
119 for (IJKey key: joinPairs()) {
120 ArrayList<LineString> lineStrings = new ArrayList<LineString>();
121
122 // process complete
123 ArrayList<Edge> completeList = complete.get(key);
124 if (completeList != null) {
125 for (Edge head: completeList) {
126 Edge current = head;
127 do {
128 coordinates.add(new Coordinate(
129 m1*(current.a % width) + b1,
130 m2*(current.a / width) + b2));
131 }
132 while ((current = current.next) != head);
133 // add head again to close shape
134 coordinates.add(new Coordinate(
135 m1*(head.a % width) + b1,
136 m2*(head.a / width) + b2));
137
138 clipLineString(
139 geometryFactory.createLineString(
140 coordinates.toArray(
141 new Coordinate[coordinates.size()])),
142 lineStrings);
143
144 coordinates.clear();
145 }
146 }
147
148 // process open
149 TIntObjectHashMap map = commonOpen.get(key);
150
151 if (map != null) {
152 for (Edge head: headList(map)) {
153
154 head = Vectorizer.simplify(head, width);
155 Edge current = head, last = head;
156 do {
157 coordinates.add(new Coordinate(
158 m1*(current.a % width) + b1,
159 m2*(current.a / width) + b2));
160 last = current;
161 }
162 while ((current = current.next) != null);
163 // add b from tail
164 coordinates.add(new Coordinate(
165 m1*(last.b % width) + b1,
166 m2*(last.b / width) + b2));
167
168 clipLineString(
169 geometryFactory.createLineString(
170 coordinates.toArray(
171 new Coordinate[coordinates.size()])),
172 lineStrings);
173
174 coordinates.clear();
175 } // for all in common open
176 } // if map defined for key
177
178 if (!lineStrings.isEmpty()) {
179 MultiLineString multiLineString =
180 geometryFactory.createMultiLineString(
181 lineStrings.toArray(
182 new LineString[lineStrings.size()]));
183 lineStrings.clear();
184 Object attribute = attributeGenerator != null
185 ? attributeGenerator.generateAttribute(key.i, key.j)
186 : key;
187 multiLineStrings.add(new Pair<Object, MultiLineString>(
188 attribute,
189 multiLineString));
190 }
191 } // for all pairs
192
193 return multiLineStrings;
194 }
195 }
196 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org