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