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