Mercurial > dive4elements > gnv-client
diff 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java Fri Sep 28 12:14:00 2012 +0200 @@ -0,0 +1,495 @@ +/* + * Copyright (c) 2010 by Intevation GmbH + * + * This program is free software under the LGPL (>=v2.1) + * Read the file LGPL.txt coming with the software for details + * or visit http://www.gnu.org/licenses/ if it does not exist. + */ + +package de.intevation.gnv.utils; + +import java.io.File; +import java.io.IOException; +import java.io.Serializable; +import java.net.MalformedURLException; +import java.text.NumberFormat; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.geotools.data.DataStoreFactorySpi; +import org.geotools.data.DataUtilities; +import org.geotools.data.DefaultTransaction; +import org.geotools.data.FeatureStore; +import org.geotools.data.Transaction; +import org.geotools.data.shapefile.ShapefileDataStore; +import org.geotools.data.shapefile.ShapefileDataStoreFactory; +import org.geotools.feature.FeatureCollection; +import org.geotools.feature.FeatureCollections; +import org.geotools.feature.SchemaException; +import org.geotools.feature.simple.SimpleFeatureBuilder; +import org.geotools.referencing.crs.DefaultGeographicCRS; +import org.opengis.feature.simple.SimpleFeature; +import org.opengis.feature.simple.SimpleFeatureType; + +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.MultiPolygon; +import com.vividsolutions.jts.io.ParseException; +import com.vividsolutions.jts.io.WKTReader; + +import de.intevation.gnv.geobackend.base.Result; +import de.intevation.gnv.geobackend.base.ResultDescriptor; + +/** + * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> + */ +public final class ShapeFileWriter +{ + private static Logger log = Logger.getLogger( + ShapeFileWriter.class); + + private static NumberFormat format = NumberFormat.getInstance(); + + /** + * Precision used to format double values. + */ + public static final int DOUBLE_PRECISION = 3; + + static { + format.setMaximumFractionDigits(DOUBLE_PRECISION); + } + + private ShapeFileWriter() { + } + + + /** + * Write multilinestrings to shapefile. + * + * @param shapeFile Shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiLineStrings The multilinestring. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiLineStringsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + List<Pair<Object, MultiLineString>> multiLineStrings + ) { + return writeMultiLineStringsToFile( + shapeFile, + parameterId, + layer, + date, + multiLineStrings, + "isolines"); + } + + + /** + * Write multilinestrings to shapefile. + * + * @param shapeFile Shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiLineStrings The multilinestring. + * @param name A name. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiLineStringsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + List<Pair<Object, MultiLineString>> multiLineStrings, + String name + ) { + Map<String, Serializable> params = new HashMap<String, Serializable>(); + + try { + params.put("url", shapeFile.toURI().toURL()); + } + catch (MalformedURLException mue) { + log.error(mue.getLocalizedMessage(), mue); + return false; + } + + params.put("create spatial index", Boolean.TRUE); + + + if (name == null) { + name = shapeFile.getName(); + } + + SimpleFeatureType TYPE; + + try { + TYPE = DataUtilities.createType( + name, + "geom:MultiLineString:srid=4326," + + "PARAMETER:Integer," + + "LAYER:Integer," + + "DATE:Date," + + "VALUE:Double," + + "DESC:String"); + } + catch (SchemaException se) { + log.error(se.getLocalizedMessage(), se); + return false; + } + + SimpleFeatureBuilder featureBuilder = + new SimpleFeatureBuilder(TYPE); + + FeatureCollection<SimpleFeatureType, SimpleFeature> collection = + FeatureCollections.newCollection(); + + for (Pair<Object, MultiLineString> pair: multiLineStrings) { + featureBuilder.add(pair.getB()); + featureBuilder.add(parameterId); + featureBuilder.add(layer); + featureBuilder.add(date); + featureBuilder.add(pair.getA()); + featureBuilder.add(value2description(asDouble(pair.getA()))); + SimpleFeature feature = featureBuilder.buildFeature(null); + collection.add(feature); + } + + DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); + + Transaction transaction = null; + + boolean success = false; + try { + ShapefileDataStore newDataStore = + (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); + + newDataStore.createSchema(TYPE); + newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); + + transaction = new DefaultTransaction("create"); + + String typeName = newDataStore.getTypeNames()[0]; + + FeatureStore<SimpleFeatureType, SimpleFeature> featureStore = + (FeatureStore<SimpleFeatureType, SimpleFeature>) + newDataStore.getFeatureSource(typeName); + + featureStore.setTransaction(transaction); + + featureStore.addFeatures(collection); + transaction.commit(); + success = true; + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + finally { + if (transaction != null) { + if (!success) { + try { transaction.rollback(); } + catch (IOException ioe) {} + } + try { transaction.close(); } + catch (IOException ioe) {} + } + } + + return success; + } + + + /** + * Write multipolygon to file. + * + * @param shapeFile The shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiPolygons Multipolygons. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiPolygonsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + Map<Integer, MultiPolygon> multiPolygons + ) { + return writeMultiPolygonsToFile( + shapeFile, + parameterId, + layer, + date, + multiPolygons, + "polygons"); + } + + + /** + * Write data to shapefile. + * + * @param shapeFile The shapefile. + * @param name The name. + * @param data The data. + * @param geometryType The geometry type. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeDataToFile(File shapeFile, + String name, + Collection<Result> data, + String geometryType){ + + WKTReader wktReader = new WKTReader(); + + Map<String, Serializable> params = new HashMap<String, Serializable>(); + + try { + params.put("url", shapeFile.toURI().toURL()); + } + catch (MalformedURLException mue) { + log.error(mue.getLocalizedMessage(), mue); + return false; + } + + params.put("create spatial index", Boolean.TRUE); + + + if (name == null) { + name = shapeFile.getName(); + } + + SimpleFeatureType type = null; + SimpleFeatureBuilder featureBuilder = null; + FeatureCollection<SimpleFeatureType, SimpleFeature> collection = + FeatureCollections.newCollection(); + int j = 0; + for (Result result: data) { + j++; + try { + Geometry g = wktReader.read(result.getString(0)); + ResultDescriptor rd = result.getResultDescriptor(); + int columns = rd.getColumnCount(); + if (type == null){ + try { + String schema = "geom:"+geometryType+":srid=4326"; + for (int i = 1; i < columns; i++){ + schema+=","+rd.getColumnName(i)+ + ":"+rd.getColumnClassName(i); + } + type = DataUtilities.createType(name, schema); + } + catch (SchemaException se) { + log.error(se.getLocalizedMessage(), se); + return false; + } + featureBuilder = new SimpleFeatureBuilder(type); + } + featureBuilder.add(g); + for (int i = 1; i < columns; i++){ + featureBuilder.add(result.getObject(i)); + } + SimpleFeature feature = featureBuilder.buildFeature(null); + collection.add(feature); + } catch (ParseException e) { + log.error("cannot create geometry "+j+" for "+result.getString(0)); + } catch (java.lang.IllegalArgumentException e){ + log.error("cannot create geometry for "+result.getString(0)); + } + } + + DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); + + Transaction transaction = null; + + boolean success = false; + try { + ShapefileDataStore newDataStore = + (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); + + newDataStore.createSchema(type); + newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); + + transaction = new DefaultTransaction("create"); + + String typeName = newDataStore.getTypeNames()[0]; + + FeatureStore<SimpleFeatureType, SimpleFeature> featureStore = + (FeatureStore<SimpleFeatureType, SimpleFeature>) + newDataStore.getFeatureSource(typeName); + + featureStore.setTransaction(transaction); + + featureStore.addFeatures(collection); + transaction.commit(); + success = true; + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + finally { + if (transaction != null) { + if (!success) { + try { transaction.rollback(); } + catch (IOException ioe) {} + } + try { transaction.close(); } + catch (IOException ioe) {} + } + } + + return true; + } + + + /** + * Write multipolygons to file. + * + * @param shapeFile The shapefile. + * @param parameterId The parameter id. + * @param layer The layer. + * @param date The date. + * @param multiPolygons Multipolygons. + * @param name A name. + * @return true, if shapefile writing was successful - otherwise false. + */ + public static boolean writeMultiPolygonsToFile( + File shapeFile, + Integer parameterId, + Integer layer, + Date date, + Map<Integer, MultiPolygon> multiPolygons, + String name + ) { + Map<String, Serializable> params = new HashMap<String, Serializable>(); + + try { + params.put("url", shapeFile.toURI().toURL()); + } + catch (MalformedURLException mue) { + log.error(mue.getLocalizedMessage(), mue); + return false; + } + + params.put("create spatial index", Boolean.TRUE); + + + if (name == null) { + name = shapeFile.getName(); + } + + SimpleFeatureType TYPE; + + try { + TYPE = DataUtilities.createType( + name, + "geom:MultiPolygon:srid=4326," + + "PARAMETER:Integer," + + "LAYER:Integer," + + "DATE:Date," + + "CLASS:Integer"); + } + catch (SchemaException se) { + log.error(se.getLocalizedMessage(), se); + return false; + } + + SimpleFeatureBuilder featureBuilder = + new SimpleFeatureBuilder(TYPE); + + FeatureCollection<SimpleFeatureType, SimpleFeature> collection = + FeatureCollections.newCollection(); + + for (Map.Entry<Integer, MultiPolygon> entry: + multiPolygons.entrySet() + ) { + featureBuilder.add(entry.getValue()); + featureBuilder.add(parameterId); + featureBuilder.add(layer); + featureBuilder.add(date); + featureBuilder.add(entry.getKey()); + SimpleFeature feature = featureBuilder.buildFeature(null); + collection.add(feature); + } + + DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory(); + + Transaction transaction = null; + + boolean success = false; + try { + ShapefileDataStore newDataStore = + (ShapefileDataStore)dataStoreFactory.createNewDataStore(params); + + newDataStore.createSchema(TYPE); + newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84); + + transaction = new DefaultTransaction("create"); + + String typeName = newDataStore.getTypeNames()[0]; + + FeatureStore<SimpleFeatureType, SimpleFeature> featureStore = + (FeatureStore<SimpleFeatureType, SimpleFeature>) + newDataStore.getFeatureSource(typeName); + + featureStore.setTransaction(transaction); + + featureStore.addFeatures(collection); + transaction.commit(); + success = true; + } + catch (IOException ioe) { + log.error(ioe.getLocalizedMessage(), ioe); + } + finally { + if (transaction != null) { + if (!success) { + try { transaction.rollback(); } + catch (IOException ioe) {} + } + try { transaction.close(); } + catch (IOException ioe) {} + } + } + + return success; + } + + /** + * Returns an object as Double. + * + * @param a An object. + * @return Object <i>a</i> as Double. If <i>a</i> is not a double and no + * number, 0d is returned. + */ + private static final Double asDouble(Object a) { + if (a instanceof Double) { + return (Double)a; + } + if (a instanceof Number) { + return Double.valueOf(((Number)a).doubleValue()); + } + return 0d; + } + + /** + * Turns a double value into a string representation taking account of the + * locale. + * + * @param value A double value. + * @return The double value formatted as string. + */ + private static final String value2description(Double value) { + return format.format(value); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :