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 :

http://dive4elements.wald.intevation.org