comparison flys-artifacts/src/main/java/org/dive4elements/river/utils/GeometryUtils.java @ 5831:bd047b71ab37

Repaired internal references
author Sascha L. Teichmann <teichmann@intevation.de>
date Thu, 25 Apr 2013 12:06:39 +0200
parents flys-artifacts/src/main/java/de/intevation/flys/utils/GeometryUtils.java@fd07bcaff880
children
comparison
equal deleted inserted replaced
5830:160f53ee0870 5831:bd047b71ab37
1 package org.dive4elements.river.utils;
2
3 import com.vividsolutions.jts.geom.Coordinate;
4 import com.vividsolutions.jts.geom.Envelope;
5 import com.vividsolutions.jts.geom.Geometry;
6
7 import org.dive4elements.river.model.RiverAxis;
8
9 import java.io.File;
10 import java.io.IOException;
11 import java.io.Serializable;
12 import java.net.MalformedURLException;
13 import java.util.ArrayList;
14 import java.util.HashMap;
15 import java.util.List;
16 import java.util.Map;
17
18 import org.apache.log4j.Logger;
19 import org.geotools.data.DataStoreFactorySpi;
20 import org.geotools.data.DefaultTransaction;
21 import org.geotools.data.FeatureWriter;
22 import org.geotools.data.Transaction;
23 import org.geotools.data.shapefile.ShapefileDataStore;
24 import org.geotools.data.shapefile.ShapefileDataStoreFactory;
25 import org.geotools.data.simple.SimpleFeatureIterator;
26 import org.geotools.feature.FeatureCollection;
27 import org.geotools.feature.FeatureIterator;
28 import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
29 import org.geotools.geojson.feature.FeatureJSON;
30 import org.geotools.geometry.jts.JTS;
31 import org.geotools.geometry.jts.ReferencedEnvelope;
32 import org.geotools.referencing.CRS;
33 import org.hibernate.HibernateException;
34 import org.opengis.feature.simple.SimpleFeature;
35 import org.opengis.feature.simple.SimpleFeatureType;
36 import org.opengis.referencing.FactoryException;
37 import org.opengis.referencing.NoSuchAuthorityCodeException;
38 import org.opengis.referencing.crs.CoordinateReferenceSystem;
39 import org.opengis.referencing.operation.MathTransform;
40 import org.opengis.referencing.operation.TransformException;
41
42 public class GeometryUtils {
43
44 private static final Logger logger = Logger.getLogger(GeometryUtils.class);
45
46 public static final String PREFIX_EPSG = "EPSG:";
47
48 public static final String DEFAULT_EPSG = "EPSG:31467";
49
50 private GeometryUtils() {
51 }
52
53 public static Envelope getRiverBoundary(String rivername) {
54 try {
55 List<RiverAxis> axes = RiverAxis.getRiverAxis(rivername);
56 if (axes != null && axes.size() > 0) {
57 Envelope max = null;
58
59 for (RiverAxis axis: axes) {
60 // TODO Take the correct EPSG into account. Maybe, we need to
61 // reproject the geometry.
62 Envelope env = axis.getGeom().getEnvelopeInternal();
63
64 if (max == null) {
65 max = env;
66 }
67 else {
68 max.expandToInclude(env);
69 }
70 }
71
72 return max;
73 }
74 }
75 catch(HibernateException iae) {
76 logger.warn("No vaild river axis found for " + rivername);
77 return null;
78 }
79 logger.warn("No vaild river axis found for " + rivername);
80
81 return null;
82 }
83
84 public static String getRiverBounds(String rivername) {
85 Envelope env = getRiverBoundary(rivername);
86
87 if (env != null) {
88 return jtsBoundsToOLBounds(env);
89 }
90
91 return null;
92 }
93
94 /**
95 * Returns the boundary of Envelope <i>env</i> in OpenLayers representation.
96 *
97 * @param env The envelope of a geometry.
98 *
99 * @return the OpenLayers boundary of <i>env</i>.
100 */
101 public static String jtsBoundsToOLBounds(Envelope env) {
102 StringBuilder buf = new StringBuilder();
103 buf.append(env.getMinX()); buf.append(' ');
104 buf.append(env.getMinY()); buf.append(' ');
105 buf.append(env.getMaxX()); buf.append(' ');
106 buf.append(env.getMaxY());
107 return buf.toString();
108 }
109
110 public static String createOLBounds(Geometry a, Geometry b) {
111 Coordinate[] ca = a.getCoordinates();
112 Coordinate[] cb = b.getCoordinates();
113
114 double lowerX = Double.MAX_VALUE;
115 double lowerY = Double.MAX_VALUE;
116 double upperX = -Double.MAX_VALUE;
117 double upperY = -Double.MAX_VALUE;
118
119 for (Coordinate c: ca) {
120 lowerX = lowerX < c.x ? lowerX : c.x;
121 lowerY = lowerY < c.y ? lowerY : c.y;
122
123 upperX = upperX > c.x ? upperX : c.x;
124 upperY = upperY > c.y ? upperY : c.y;
125 }
126
127 for (Coordinate c: cb) {
128 lowerX = lowerX < c.x ? lowerX : c.x;
129 lowerY = lowerY < c.y ? lowerY : c.y;
130
131 upperX = upperX > c.x ? upperX : c.x;
132 upperY = upperY > c.y ? upperY : c.y;
133 }
134
135 return "" + lowerX + " " + lowerY + " " + upperX + " " + upperY;
136 }
137
138 public static SimpleFeatureType buildFeatureType(
139 String name, String srs, Class<?> geometryType)
140 {
141 return buildFeatureType(name, srs, geometryType, null);
142 }
143
144 /**
145 * Creates a new SimpleFeatureType using a SimpleFeatureTypeBuilder.
146 *
147 * @param name The name of the FeatureType.
148 * @param srs The SRS (e.g. "EPSG:31466").
149 * @param geometryType The geometry type's class (e.g. Polygon.class).
150 * @param attrs Optional. An object with attribute-name/attribute-class pairs
151 * where index 0 specifies the name as string and index 1 the
152 * ype as class.
153 *
154 * @return a new SimpleFeatureType.
155 */
156 public static SimpleFeatureType buildFeatureType(String name, String srs,
157 Class<?> geometryType, Object[][] attrs) {
158 try {
159 SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
160 CoordinateReferenceSystem crs = CRS.decode(srs);
161
162 builder.setName("flys");
163 builder.setNamespaceURI("http://www.intevation.de/");
164 builder.setCRS(crs);
165 builder.setSRS(srs);
166
167 builder.add("geometry", geometryType, crs);
168
169 if (attrs != null) {
170 for (Object[] attr: attrs) {
171 builder.add((String) attr[0], (Class<?>) attr[1]);
172 }
173 }
174
175 return builder.buildFeatureType();
176 }
177 catch (NoSuchAuthorityCodeException nsae) {
178 }
179 catch (FactoryException fe) {
180 }
181
182 return null;
183 }
184
185 public static List<SimpleFeature> parseGeoJSON(
186 String geojson, SimpleFeatureType ft
187 ) {
188 List<SimpleFeature> collection = new ArrayList<SimpleFeature>();
189
190 try {
191 FeatureJSON fjson = new FeatureJSON();
192 fjson.setFeatureType(ft);
193
194 FeatureIterator<SimpleFeature> iterator =
195 fjson.streamFeatureCollection(geojson);
196
197 while (iterator.hasNext()) {
198 collection.add(iterator.next());
199 }
200 }
201 catch (IOException ioe) {
202 // TODO handle exception
203 }
204
205 return collection;
206 }
207
208
209 /**
210 * This method returns the {@link CoordinateReferenceSystem} by the
211 * {@link String} <i>epsg</i>.
212 *
213 * @param epsg An EPSG code like <b>EPSG:31466</b>
214 *
215 * @return the {@link CoordinateReferenceSystem} specified by <i>epsg</i>.
216 */
217 public static CoordinateReferenceSystem getCoordinateReferenceSystem(
218 String epsg
219 ) {
220 if (epsg == null) {
221 logger.warn("cannot create CoordinateReferenceSystem with null");
222 return null;
223 }
224
225 if (!epsg.startsWith(PREFIX_EPSG)) {
226 epsg = PREFIX_EPSG + epsg;
227 }
228
229 try {
230 return CRS.decode(epsg);
231 }
232 catch (FactoryException fe) {
233 logger.error(
234 "unable to get CoordinateReferenceSystem for: " + epsg,
235 fe);
236 }
237
238 return null;
239 }
240
241
242 public static Envelope transform(Envelope orig, String targetSrs) {
243 return transform(orig, targetSrs, DEFAULT_EPSG);
244 }
245
246
247 public static Envelope transform(
248 Envelope orig,
249 String targetSrs,
250 String origSrs
251 ) {
252 if (targetSrs == null || orig == null || origSrs == null) {
253 logger.warn("unable to transform envelope: empty parameters");
254 return orig;
255 }
256
257 logger.debug("Transform envlope to '" + targetSrs + "'");
258 try {
259 CoordinateReferenceSystem sourceCRS =
260 getCoordinateReferenceSystem(origSrs);
261
262 CoordinateReferenceSystem targetCRS =
263 getCoordinateReferenceSystem(targetSrs);
264
265 if (sourceCRS != null && targetCRS != null) {
266 ReferencedEnvelope tmpEnv =
267 new ReferencedEnvelope(orig, CRS.decode(origSrs));
268
269 Envelope target = tmpEnv.transform(targetCRS, false);
270
271 if (logger.isDebugEnabled()) {
272 logger.debug(" orig envelope : " + orig);
273 logger.debug(" transformed envelope: " + target);
274 }
275
276 return target;
277 }
278 }
279 catch (NoSuchAuthorityCodeException nsae) {
280 logger.error("Cannot get CoordinateReferenceSystem!", nsae);
281 }
282 catch (FactoryException fe) {
283 logger.error("Cannot get CoordinateReferenceSystem!", fe);
284 }
285 catch (TransformException te) {
286 logger.error("Cannot transform envelope from source "
287 + origSrs + " to target srs " + targetSrs);
288 }
289
290 return null;
291 }
292
293
294 public static boolean writeShapefile(File shape,
295 SimpleFeatureType featureType, FeatureCollection<?, ?> collection) {
296 return writeShapefile(shape, featureType, collection,
297 featureType.getCoordinateReferenceSystem());
298 }
299
300
301 public static boolean writeShapefile(File shape,
302 SimpleFeatureType featureType, FeatureCollection<?, ?> collection,
303 CoordinateReferenceSystem crs) {
304 if (collection.isEmpty()) {
305 logger.warn("Shapefile is not written - no features given!");
306 return false;
307 }
308
309 Transaction transaction = null;
310
311 try {
312 MathTransform transform = CRS.findMathTransform(
313 CRS.decode(DEFAULT_EPSG), crs);
314
315 Map<String, Serializable> params =
316 new HashMap<String, Serializable>();
317
318 params.put("url", shape.toURI().toURL());
319 params.put("create spatial index", Boolean.TRUE);
320
321 DataStoreFactorySpi dataStoreFactory =
322 new ShapefileDataStoreFactory();
323
324 ShapefileDataStore newDataStore =
325 (ShapefileDataStore)dataStoreFactory.createNewDataStore(params);
326 newDataStore.createSchema(featureType);
327
328 transaction = new DefaultTransaction("create");
329
330 String typeName = newDataStore.getTypeNames()[0];
331
332 FeatureWriter<SimpleFeatureType, SimpleFeature> writer =
333 newDataStore.getFeatureWriter(typeName, transaction);
334
335 SimpleFeatureIterator iterator = (SimpleFeatureIterator) collection.features();
336
337 while (iterator.hasNext()){
338 SimpleFeature feature = iterator.next();
339 SimpleFeature copy = writer.next();
340
341 copy.setAttributes(feature.getAttributes());
342
343 Geometry orig = (Geometry) feature.getDefaultGeometry();
344 Geometry reprojected = JTS.transform(orig, transform);
345
346 copy.setDefaultGeometry(reprojected);
347 writer.write();
348 }
349
350 transaction.commit();
351
352 return true;
353 }
354 catch (MalformedURLException mue) {
355 logger.error("Unable to prepare shapefile: " + mue.getMessage());
356 }
357 catch (IOException ioe) {
358 logger.error("Unable to write shapefile: " + ioe.getMessage());
359 }
360 catch (NoSuchAuthorityCodeException nsae) {
361 logger.error("Cannot get CoordinateReferenceSystem for '"
362 + DEFAULT_EPSG + "'");
363 }
364 catch (FactoryException fe) {
365 logger.error("Cannot get CoordinateReferenceSystem for '"
366 + DEFAULT_EPSG + "'");
367 }
368 catch (TransformException te) {
369 logger.error("Was not able to transform geometry!", te);
370 }
371 finally {
372 if (transaction != null) {
373 try {
374 transaction.close();
375 }
376 catch (IOException ioe) { /* do nothing */ }
377 }
378 }
379
380 return false;
381 }
382 }
383 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org