Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java @ 875:5e9efdda6894
merged gnv-artifacts/1.0
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:56 +0200 |
parents | 2cea76f1112e |
children | f953c9a559d8 |
comparison
equal
deleted
inserted
replaced
722:bb3ffe7d719e | 875:5e9efdda6894 |
---|---|
1 package de.intevation.gnv.utils; | |
2 | |
3 import java.io.File; | |
4 import java.io.IOException; | |
5 import java.io.Serializable; | |
6 import java.net.MalformedURLException; | |
7 import java.text.NumberFormat; | |
8 import java.util.Collection; | |
9 import java.util.Date; | |
10 import java.util.HashMap; | |
11 import java.util.List; | |
12 import java.util.Map; | |
13 | |
14 import org.apache.log4j.Logger; | |
15 import org.geotools.data.DataStoreFactorySpi; | |
16 import org.geotools.data.DataUtilities; | |
17 import org.geotools.data.DefaultTransaction; | |
18 import org.geotools.data.FeatureStore; | |
19 import org.geotools.data.Transaction; | |
20 import org.geotools.data.shapefile.ShapefileDataStore; | |
21 import org.geotools.data.shapefile.ShapefileDataStoreFactory; | |
22 import org.geotools.feature.FeatureCollection; | |
23 import org.geotools.feature.FeatureCollections; | |
24 import org.geotools.feature.SchemaException; | |
25 import org.geotools.feature.simple.SimpleFeatureBuilder; | |
26 import org.geotools.referencing.crs.DefaultGeographicCRS; | |
27 import org.opengis.feature.simple.SimpleFeature; | |
28 import org.opengis.feature.simple.SimpleFeatureType; | |
29 | |
30 import com.vividsolutions.jts.geom.Geometry; | |
31 import com.vividsolutions.jts.geom.MultiLineString; | |
32 import com.vividsolutions.jts.geom.MultiPolygon; | |
33 import com.vividsolutions.jts.io.ParseException; | |
34 import com.vividsolutions.jts.io.WKTReader; | |
35 | |
36 import de.intevation.gnv.geobackend.base.Result; | |
37 import de.intevation.gnv.geobackend.base.ResultDescriptor; | |
38 | |
39 /** | |
40 * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> | |
41 */ | |
42 public final class ShapeFileWriter | |
43 { | |
44 private static Logger log = Logger.getLogger( | |
45 ShapeFileWriter.class); | |
46 | |
47 private static NumberFormat format = NumberFormat.getInstance(); | |
48 | |
49 /** | |
50 * Precision used to format double values. | |
51 */ | |
52 public static final int DOUBLE_PRECISION = 3; | |
53 | |
54 static { | |
55 format.setMaximumFractionDigits(DOUBLE_PRECISION); | |
56 } | |
57 | |
58 private ShapeFileWriter() { | |
59 } | |
60 | |
61 | |
62 /** | |
63 * Write multilinestrings to shapefile. | |
64 * | |
65 * @param shapeFile Shapefile. | |
66 * @param parameterId The parameter id. | |
67 * @param layer The layer. | |
68 * @param date The date. | |
69 * @param multiLineStrings The multilinestring. | |
70 * @return true, if shapefile writing was successful - otherwise false. | |
71 */ | |
72 public static boolean writeMultiLineStringsToFile( | |
73 File shapeFile, | |
74 Integer parameterId, | |
75 Integer layer, | |
76 Date date, | |
77 List<Pair<Object, MultiLineString>> multiLineStrings | |
78 ) { | |
79 return writeMultiLineStringsToFile( | |
80 shapeFile, | |
81 parameterId, | |
82 layer, | |
83 date, | |
84 multiLineStrings, | |
85 "isolines"); | |
86 } | |
87 | |
88 | |
89 /** | |
90 * Write multilinestrings to shapefile. | |
91 * | |
92 * @param shapeFile Shapefile. | |
93 * @param parameterId The parameter id. | |
94 * @param layer The layer. | |
95 * @param date The date. | |
96 * @param multiLineStrings The multilinestring. | |
97 * @param name A name. | |
98 * @return true, if shapefile writing was successful - otherwise false. | |
99 */ | |
100 public static boolean writeMultiLineStringsToFile( | |
101 File shapeFile, | |
102 Integer parameterId, | |
103 Integer layer, | |
104 Date date, | |
105 List<Pair<Object, MultiLineString>> multiLineStrings, | |
106 String name | |
107 ) { | |
108 Map<String, Serializable> params = new HashMap<String, Serializable>(); | |
109 | |
110 try { | |
111 params.put("url", shapeFile.toURI().toURL()); | |
112 } | |
113 catch (MalformedURLException mue) { | |
114 log.error(mue.getLocalizedMessage(), mue); | |
115 return false; | |
116 } | |
117 | |
118 params.put("create spatial index", Boolean.TRUE); | |
119 | |
120 | |
121 if (name == null) { | |
122 name = shapeFile.getName(); | |
123 } | |
124 | |
125 SimpleFeatureType TYPE; | |
126 | |
127 try { | |
128 TYPE = DataUtilities.createType( | |
129 name, | |
130 "geom:MultiLineString:srid=4326," + | |
131 "PARAMETER:Integer," + | |
132 "LAYER:Integer," + | |
133 "DATE:Date," + | |
134 "VALUE:Double," + | |
135 "DESC:String"); | |
136 } | |
137 catch (SchemaException se) { | |
138 log.error(se.getLocalizedMessage(), se); | |
139 return false; | |
140 } | |
141 | |
142 SimpleFeatureBuilder featureBuilder = | |
143 new SimpleFeatureBuilder(TYPE); | |
144 | |
145 FeatureCollection<SimpleFeatureType, SimpleFeature> collection = | |
146 FeatureCollections.newCollection(); | |
147 | |
148 for (Pair<Object, MultiLineString> pair: multiLineStrings) { | |
149 featureBuilder.add(pair.getB()); | |
150 featureBuilder.add(parameterId); | |
151 featureBuilder.add(layer); | |
152 featureBuilder.add(date); | |
153 featureBuilder.add(pair.getA()); | |
154 featureBuilder.add(value2description(asDouble(pair.getA()))); | |
155 SimpleFeature feature = featureBuilder.buildFeature(null); | |
156 collection.add(feature); | |
157 } | |
158 | |
159 DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); | |
160 | |
161 Transaction transaction = null; | |
162 | |
163 boolean success = false; | |
164 try { | |
165 ShapefileDataStore newDataStore = | |
166 (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); | |
167 | |
168 newDataStore.createSchema(TYPE); | |
169 newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); | |
170 | |
171 transaction = new DefaultTransaction("create"); | |
172 | |
173 String typeName = newDataStore.getTypeNames()[0]; | |
174 | |
175 FeatureStore<SimpleFeatureType, SimpleFeature> featureStore = | |
176 (FeatureStore<SimpleFeatureType, SimpleFeature>) | |
177 newDataStore.getFeatureSource(typeName); | |
178 | |
179 featureStore.setTransaction(transaction); | |
180 | |
181 featureStore.addFeatures(collection); | |
182 transaction.commit(); | |
183 success = true; | |
184 } | |
185 catch (IOException ioe) { | |
186 log.error(ioe.getLocalizedMessage(), ioe); | |
187 } | |
188 finally { | |
189 if (transaction != null) { | |
190 if (!success) { | |
191 try { transaction.rollback(); } | |
192 catch (IOException ioe) {} | |
193 } | |
194 try { transaction.close(); } | |
195 catch (IOException ioe) {} | |
196 } | |
197 } | |
198 | |
199 return success; | |
200 } | |
201 | |
202 | |
203 /** | |
204 * Write multipolygon to file. | |
205 * | |
206 * @param shapeFile The shapefile. | |
207 * @param parameterId The parameter id. | |
208 * @param layer The layer. | |
209 * @param date The date. | |
210 * @param multiPolygons Multipolygons. | |
211 * @return true, if shapefile writing was successful - otherwise false. | |
212 */ | |
213 public static boolean writeMultiPolygonsToFile( | |
214 File shapeFile, | |
215 Integer parameterId, | |
216 Integer layer, | |
217 Date date, | |
218 Map<Integer, MultiPolygon> multiPolygons | |
219 ) { | |
220 return writeMultiPolygonsToFile( | |
221 shapeFile, | |
222 parameterId, | |
223 layer, | |
224 date, | |
225 multiPolygons, | |
226 "polygons"); | |
227 } | |
228 | |
229 | |
230 /** | |
231 * Write data to shapefile. | |
232 * | |
233 * @param shapeFile The shapefile. | |
234 * @param name The name. | |
235 * @param data The data. | |
236 * @param geometryType The geometry type. | |
237 * @return true, if shapefile writing was successful - otherwise false. | |
238 */ | |
239 public static boolean writeDataToFile(File shapeFile, | |
240 String name, | |
241 Collection<Result> data, | |
242 String geometryType){ | |
243 | |
244 WKTReader wktReader = new WKTReader(); | |
245 | |
246 Map<String, Serializable> params = new HashMap<String, Serializable>(); | |
247 | |
248 try { | |
249 params.put("url", shapeFile.toURI().toURL()); | |
250 } | |
251 catch (MalformedURLException mue) { | |
252 log.error(mue.getLocalizedMessage(), mue); | |
253 return false; | |
254 } | |
255 | |
256 params.put("create spatial index", Boolean.TRUE); | |
257 | |
258 | |
259 if (name == null) { | |
260 name = shapeFile.getName(); | |
261 } | |
262 | |
263 SimpleFeatureType type = null; | |
264 SimpleFeatureBuilder featureBuilder = null; | |
265 FeatureCollection<SimpleFeatureType, SimpleFeature> collection = | |
266 FeatureCollections.newCollection(); | |
267 int j = 0; | |
268 for (Result result: data) { | |
269 j++; | |
270 try { | |
271 Geometry g = wktReader.read(result.getString(0)); | |
272 ResultDescriptor rd = result.getResultDescriptor(); | |
273 int columns = rd.getColumnCount(); | |
274 if (type == null){ | |
275 try { | |
276 String schema = "geom:"+geometryType+":srid=4326"; | |
277 for (int i = 1; i < columns; i++){ | |
278 schema+=","+rd.getColumnName(i)+ | |
279 ":"+rd.getColumnClassName(i); | |
280 } | |
281 type = DataUtilities.createType(name, schema); | |
282 } | |
283 catch (SchemaException se) { | |
284 log.error(se.getLocalizedMessage(), se); | |
285 return false; | |
286 } | |
287 featureBuilder = new SimpleFeatureBuilder(type); | |
288 } | |
289 featureBuilder.add(g); | |
290 for (int i = 1; i < columns; i++){ | |
291 featureBuilder.add(result.getObject(i)); | |
292 } | |
293 SimpleFeature feature = featureBuilder.buildFeature(null); | |
294 collection.add(feature); | |
295 } catch (ParseException e) { | |
296 log.error("cannot create geometry "+j+" for "+result.getString(0)); | |
297 } catch (java.lang.IllegalArgumentException e){ | |
298 log.error("cannot create geometry for "+result.getString(0)); | |
299 } | |
300 } | |
301 | |
302 DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); | |
303 | |
304 Transaction transaction = null; | |
305 | |
306 boolean success = false; | |
307 try { | |
308 ShapefileDataStore newDataStore = | |
309 (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); | |
310 | |
311 newDataStore.createSchema(type); | |
312 newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); | |
313 | |
314 transaction = new DefaultTransaction("create"); | |
315 | |
316 String typeName = newDataStore.getTypeNames()[0]; | |
317 | |
318 FeatureStore<SimpleFeatureType, SimpleFeature> featureStore = | |
319 (FeatureStore<SimpleFeatureType, SimpleFeature>) | |
320 newDataStore.getFeatureSource(typeName); | |
321 | |
322 featureStore.setTransaction(transaction); | |
323 | |
324 featureStore.addFeatures(collection); | |
325 transaction.commit(); | |
326 success = true; | |
327 } | |
328 catch (IOException ioe) { | |
329 log.error(ioe.getLocalizedMessage(), ioe); | |
330 } | |
331 finally { | |
332 if (transaction != null) { | |
333 if (!success) { | |
334 try { transaction.rollback(); } | |
335 catch (IOException ioe) {} | |
336 } | |
337 try { transaction.close(); } | |
338 catch (IOException ioe) {} | |
339 } | |
340 } | |
341 | |
342 return true; | |
343 } | |
344 | |
345 | |
346 /** | |
347 * Write multipolygons to file. | |
348 * | |
349 * @param shapeFile The shapefile. | |
350 * @param parameterId The parameter id. | |
351 * @param layer The layer. | |
352 * @param date The date. | |
353 * @param multiPolygons Multipolygons. | |
354 * @param name A name. | |
355 * @return true, if shapefile writing was successful - otherwise false. | |
356 */ | |
357 public static boolean writeMultiPolygonsToFile( | |
358 File shapeFile, | |
359 Integer parameterId, | |
360 Integer layer, | |
361 Date date, | |
362 Map<Integer, MultiPolygon> multiPolygons, | |
363 String name | |
364 ) { | |
365 Map<String, Serializable> params = new HashMap<String, Serializable>(); | |
366 | |
367 try { | |
368 params.put("url", shapeFile.toURI().toURL()); | |
369 } | |
370 catch (MalformedURLException mue) { | |
371 log.error(mue.getLocalizedMessage(), mue); | |
372 return false; | |
373 } | |
374 | |
375 params.put("create spatial index", Boolean.TRUE); | |
376 | |
377 | |
378 if (name == null) { | |
379 name = shapeFile.getName(); | |
380 } | |
381 | |
382 SimpleFeatureType TYPE; | |
383 | |
384 try { | |
385 TYPE = DataUtilities.createType( | |
386 name, | |
387 "geom:MultiPolygon:srid=4326," + | |
388 "PARAMETER:Integer," + | |
389 "LAYER:Integer," + | |
390 "DATE:Date," + | |
391 "CLASS:Integer"); | |
392 } | |
393 catch (SchemaException se) { | |
394 log.error(se.getLocalizedMessage(), se); | |
395 return false; | |
396 } | |
397 | |
398 SimpleFeatureBuilder featureBuilder = | |
399 new SimpleFeatureBuilder(TYPE); | |
400 | |
401 FeatureCollection<SimpleFeatureType, SimpleFeature> collection = | |
402 FeatureCollections.newCollection(); | |
403 | |
404 for (Map.Entry<Integer, MultiPolygon> entry: | |
405 multiPolygons.entrySet() | |
406 ) { | |
407 featureBuilder.add(entry.getValue()); | |
408 featureBuilder.add(parameterId); | |
409 featureBuilder.add(layer); | |
410 featureBuilder.add(date); | |
411 featureBuilder.add(entry.getKey()); | |
412 SimpleFeature feature = featureBuilder.buildFeature(null); | |
413 collection.add(feature); | |
414 } | |
415 | |
416 DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); | |
417 | |
418 Transaction transaction = null; | |
419 | |
420 boolean success = false; | |
421 try { | |
422 ShapefileDataStore newDataStore = | |
423 (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); | |
424 | |
425 newDataStore.createSchema(TYPE); | |
426 newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); | |
427 | |
428 transaction = new DefaultTransaction("create"); | |
429 | |
430 String typeName = newDataStore.getTypeNames()[0]; | |
431 | |
432 FeatureStore<SimpleFeatureType, SimpleFeature> featureStore = | |
433 (FeatureStore<SimpleFeatureType, SimpleFeature>) | |
434 newDataStore.getFeatureSource(typeName); | |
435 | |
436 featureStore.setTransaction(transaction); | |
437 | |
438 featureStore.addFeatures(collection); | |
439 transaction.commit(); | |
440 success = true; | |
441 } | |
442 catch (IOException ioe) { | |
443 log.error(ioe.getLocalizedMessage(), ioe); | |
444 } | |
445 finally { | |
446 if (transaction != null) { | |
447 if (!success) { | |
448 try { transaction.rollback(); } | |
449 catch (IOException ioe) {} | |
450 } | |
451 try { transaction.close(); } | |
452 catch (IOException ioe) {} | |
453 } | |
454 } | |
455 | |
456 return success; | |
457 } | |
458 | |
459 /** | |
460 * Returns an object as Double. | |
461 * | |
462 * @param a An object. | |
463 * @return Object <i>a</i> as Double. If <i>a</i> is not a double and no | |
464 * number, 0d is returned. | |
465 */ | |
466 private static final Double asDouble(Object a) { | |
467 if (a instanceof Double) { | |
468 return (Double)a; | |
469 } | |
470 if (a instanceof Number) { | |
471 return Double.valueOf(((Number)a).doubleValue()); | |
472 } | |
473 return 0d; | |
474 } | |
475 | |
476 /** | |
477 * Turns a double value into a string representation taking account of the | |
478 * locale. | |
479 * | |
480 * @param value A double value. | |
481 * @return The double value formatted as string. | |
482 */ | |
483 private static final String value2description(Double value) { | |
484 return format.format(value); | |
485 } | |
486 } | |
487 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |