comparison gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java @ 465:f7038820df2e

Added support to trace rasters to JTS multi polygons and multi line strings. Write them to shape files with GeoTools. gnv-artifacts/trunk@526 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 11 Jan 2010 00:29:45 +0000
parents
children 6e8364e766fa
comparison
equal deleted inserted replaced
464:70df44021a9f 465:f7038820df2e
1 package de.intevation.gnv.raster;
2
3 import java.util.Map;
4 import java.util.List;
5 import java.util.HashMap;
6 import java.util.TreeMap;
7 import java.util.ArrayList;
8
9 import com.vividsolutions.jts.geom.GeometryFactory;
10 import com.vividsolutions.jts.geom.MultiPolygon;
11 import com.vividsolutions.jts.geom.Polygon;
12 import com.vividsolutions.jts.geom.Coordinate;
13 import com.vividsolutions.jts.geom.LinearRing;
14 import com.vividsolutions.jts.geom.PrecisionModel;
15
16 import com.vividsolutions.jts.algorithm.CGAlgorithms;
17
18 import com.vividsolutions.jts.geom.impl.PackedCoordinateSequenceFactory;
19
20 import org.apache.log4j.Logger;
21
22 import de.intevation.gnv.raster.Vectorizer.Edge;
23
24 /**
25 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
26 */
27 public class JTSMultiPolygonProducer
28 extends AbstractProducer
29 {
30 private static Logger log = Logger.getLogger(
31 JTSMultiPolygonProducer.class);
32
33 public static final int SRID_WGS84 = 4326;
34
35 public interface ValueConverter {
36
37 Integer convert(Integer value);
38
39 } // interface ValueConverter
40
41 protected GeometryFactory geometryFactory;
42
43 protected HashMap<Integer, ArrayList<Polygon>> valueToPolygons;
44
45 public JTSMultiPolygonProducer() {
46 }
47
48 public JTSMultiPolygonProducer(
49 double minX, double minY,
50 double maxX, double maxY
51 ) {
52 this(
53 createDefaultGeometryFactory(),
54 minX, minY,
55 maxX, maxY);
56 }
57
58 public JTSMultiPolygonProducer(
59 GeometryFactory geometryFactory,
60 double minX, double minY,
61 double maxX, double maxY
62 ) {
63 super(minX, minY, maxX, maxY);
64 this.geometryFactory = geometryFactory;
65 valueToPolygons = new HashMap<Integer, ArrayList<Polygon>>();
66 }
67
68 public static GeometryFactory createDefaultGeometryFactory() {
69 return new GeometryFactory(
70 new PrecisionModel(
71 PrecisionModel.FLOATING),
72 SRID_WGS84,
73 new PackedCoordinateSequenceFactory(
74 PackedCoordinateSequenceFactory.DOUBLE,
75 2));
76 }
77
78 public void handleRings(
79 List<Edge> rings,
80 int value,
81 int width,
82 int height
83 ) {
84 if (value == -1) {
85 return;
86 }
87
88 Integer v = Integer.valueOf(value);
89
90 ArrayList<Polygon> polygons = valueToPolygons.get(v);
91
92 if (polygons == null) {
93 valueToPolygons.put(v, polygons = new ArrayList<Polygon>());
94 }
95
96 double b1 = minX;
97 double m1 = width != 1
98 ? (maxX - minX)/(width-1)
99 : 0d;
100
101 double b2 = minY;
102 double m2 = height != 1
103 ? (maxY - minY)/(height-1)
104 : 0d;
105
106 ArrayList<Coordinate> vertices = new ArrayList<Coordinate>();
107
108 LinearRing shell = null;
109 ArrayList<LinearRing> holes = new ArrayList<LinearRing>();
110
111 for (Edge head: rings) {
112 Edge current = head;
113 do {
114 vertices.add(new Coordinate(
115 m1*(current.a % width) + b1,
116 m2*(current.a / width) + b2));
117 }
118 while ((current = current.next) != head);
119 vertices.add(new Coordinate(
120 m1*(head.a % width) + b1,
121 m2*(head.a / width) + b2));
122
123 Coordinate [] coordinates =
124 vertices.toArray(new Coordinate[vertices.size()]);
125
126 vertices.clear();
127
128 LinearRing ring = geometryFactory.createLinearRing(
129 coordinates);
130
131 if (CGAlgorithms.isCCW(coordinates)) {
132 shell = ring;
133 }
134 else {
135 holes.add(ring);
136 }
137 }
138
139 if (shell == null) {
140 log.error("polygon has no shell");
141 return;
142 }
143
144 Polygon polygon = geometryFactory.createPolygon(
145 shell,
146 holes.toArray(new LinearRing[holes.size()]));
147
148 polygons.add(polygon);
149 }
150
151 public Map<Integer, MultiPolygon> getMultiPolygons() {
152 return getMultiPolygons(null);
153 }
154
155 public Map<Integer, MultiPolygon> getMultiPolygons(
156 ValueConverter valueConverter
157 ) {
158 TreeMap<Integer, MultiPolygon> multiPolygons =
159 new TreeMap<Integer, MultiPolygon>();
160
161 for (Map.Entry<Integer, ArrayList<Polygon>> entry:
162 valueToPolygons.entrySet()
163 ) {
164 ArrayList<Polygon> polygons = entry.getValue();
165
166 Integer value = valueConverter != null
167 ? valueConverter.convert(entry.getKey())
168 : entry.getKey();
169
170 multiPolygons.put(
171 value,
172 geometryFactory.createMultiPolygon(
173 polygons.toArray(new Polygon[polygons.size()])));
174 }
175
176 return multiPolygons;
177 }
178
179 public void clear() {
180 valueToPolygons.clear();
181 }
182 }
183 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org