Mercurial > dive4elements > river
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 : |