Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/utils/ShapeFileWriter.java @ 1129:ccfa07b88476
merged geo-backend
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:14:01 +0200 |
parents | f953c9a559d8 |
children |
line wrap: on
line source
/* * 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 :