changeset 1106:e9f66d63bdd0

Write user defined barriers into a shapefile that is placed in the Artifact's directory. flys-artifacts/trunk@2609 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Tue, 30 Aug 2011 11:09:54 +0000 (2011-08-30)
parents adb52a2005e7
children 005c2964f9af
files flys-artifacts/ChangeLog flys-artifacts/pom.xml flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java flys-artifacts/src/main/java/de/intevation/flys/utils/GeometryUtils.java
diffstat 5 files changed, 250 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/flys-artifacts/ChangeLog	Tue Aug 30 08:09:52 2011 +0000
+++ b/flys-artifacts/ChangeLog	Tue Aug 30 11:09:54 2011 +0000
@@ -1,3 +1,19 @@
+2011-08-30  Ingo Weinzierl <ingo@intevation.de>
+
+	* pom.xml: Added GeoTools 2.7.2 dependencies for Shapefile, GeoJSON and
+	  EPSG support.
+
+	* src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java: Store
+	  'LIN' parameter in a list now. A WSPLGEN parameter might contain many
+	  LINs.
+
+	* src/main/java/de/intevation/flys/utils/GeometryUtils.java: New functions
+	  to create FeatureTypes and to write shapefiles.
+
+	* src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java:
+	  Write user specified barriers into a shapefile placed in the artifact
+	  directory.
+
 2011-08-30  Ingo Weinzierl <ingo@intevation.de>
 
 	* src/main/java/de/intevation/flys/utils/FLYSUtils.java: Added a function
--- a/flys-artifacts/pom.xml	Tue Aug 30 08:09:52 2011 +0000
+++ b/flys-artifacts/pom.xml	Tue Aug 30 11:09:54 2011 +0000
@@ -105,6 +105,21 @@
       <artifactId>commons-dbcp</artifactId>
       <version>1.2.2</version>
     </dependency>
+    <dependency>
+      <groupId>org.geotools</groupId>
+      <artifactId>gt-shapefile</artifactId>
+      <version>2.7.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.geotools</groupId>
+      <artifactId>gt-epsg-wkt</artifactId>
+      <version>2.7.2</version>
+    </dependency>
+    <dependency>
+      <groupId>org.geotools</groupId>
+      <artifactId>gt-geojson</artifactId>
+      <version>2.7.2</version>
+    </dependency>
   </dependencies>
   <repositories>
     <repository>
@@ -112,5 +127,10 @@
         <name>JBoss repo2</name>
         <url>http://repository.jboss.org/nexus/content/groups/public/</url>
     </repository>
+    <repository>
+      <id>gt2.repo</id>
+      <name>GeoTools2 Repository including JTS</name>
+      <url>http://download.osgeo.org/webdav/geotools</url>
+    </repository>
   </repositories>
 </project>
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java	Tue Aug 30 08:09:52 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/model/WSPLGENJob.java	Tue Aug 30 11:09:54 2011 +0000
@@ -5,6 +5,8 @@
 import java.io.FileOutputStream;
 import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
 
 
 public class WSPLGENJob {
@@ -17,12 +19,13 @@
     protected String pro;
     protected String wsp;
     protected String wspTag;
-    protected String lin;
     protected String axis;
     protected String area;
     protected String gel;
     protected String outFile;
 
+    protected List<String> lin;
+
     protected int out;
 
     protected double start;
@@ -35,13 +38,14 @@
 
 
     public WSPLGENJob() {
-        out    = -1;
-        start  = Double.NaN;
-        end    = Double.NaN;
-        from   = Double.NaN;
-        to     = Double.NaN;
-        diff   = Double.NaN;
-        dist   = Double.NaN;
+        out   = -1;
+        start = Double.NaN;
+        end   = Double.NaN;
+        from  = Double.NaN;
+        to    = Double.NaN;
+        diff  = Double.NaN;
+        dist  = Double.NaN;
+        lin   = new ArrayList<String>(2);
     }
 
 
@@ -65,12 +69,12 @@
     }
 
 
-    public void setLin(String lin) {
-        this.lin = lin;
+    public void addLin(String lin) {
+        this.lin.add(lin);
     }
 
 
-    public String getLin() {
+    public List<String> getLin() {
         return lin;
     }
 
@@ -281,10 +285,12 @@
     protected void writeLin(PrintWriter writer)
     throws IllegalArgumentException
     {
-        String lin = getLin();
+        List<String> lins = getLin();
 
-        if (lin != null && lin.length() > 0) {
-            writer.println("-LIN=\"" + lin + "\"");
+        if (lins != null && !lins.isEmpty()) {
+            for (String lin: lins) {
+                writer.println("-LIN=\"" + lin + "\"");
+            }
         }
     }
 
--- a/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java	Tue Aug 30 08:09:52 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/artifacts/states/FloodMapState.java	Tue Aug 30 11:09:54 2011 +0000
@@ -2,12 +2,23 @@
 
 import java.io.File;
 import java.io.IOException;
+import java.net.MalformedURLException;
 import java.util.List;
 
 import javax.xml.xpath.XPathConstants;
 
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.Polygon;
+
 import org.apache.log4j.Logger;
 
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.FeatureCollections;
+import org.geotools.feature.SchemaException;
+
 import de.intevation.artifacts.Artifact;
 import de.intevation.artifacts.CallContext;
 
@@ -21,6 +32,7 @@
 import de.intevation.flys.artifacts.model.WSPLGENFacet;
 import de.intevation.flys.artifacts.model.WSPLGENJob;
 import de.intevation.flys.utils.FLYSUtils;
+import de.intevation.flys.utils.GeometryUtils;
 
 
 public class FloodMapState
@@ -35,6 +47,8 @@
         "/artifact-database/floodmap/shapefile-path/@value";
 
     public static final String WSPLGEN_PARAMETER_FILE = "wsplgen.par";
+    public static final String WSPLGEN_BARRIERS_LINES = "barrier_lines.shp";
+    public static final String WSPLGEN_BARRIERS_POLY  = "barrier_polygons.shp";
 
     public static final int WSPLGEN_DEFAULT_OUTPUT = 0;
 
@@ -148,13 +162,13 @@
         setDelta(artifact, job);
         setGel(artifact, job);
         setDist(artifact, job);
+        setLine(artifact, artifactDir, job);
 
         // TODO
         // setDgm(artifact, job);    // SHP
         // setPro(artifact, job);    // SHP
         // setWsp(artifact, job);    // WSP
         // setWspTag(artifact, job);
-        // setLine(artifact, job);   // SHP
         // setAxis(artifact, job);   // SHP
         // setArea(artifact, job);   // SHP
         // setOutFile(artifact, job);
@@ -239,5 +253,68 @@
             // nothing to do here
         }
     }
+
+
+    protected void setLine(FLYSArtifact artifact, File dir, WSPLGENJob job) {
+        String geoJSON = artifact.getDataAsString("uesk.barriers");
+        String srid    = FLYSUtils.getRiverSrid(artifact);
+        String srs     = "EPSG:" + srid;
+
+        SimpleFeatureType   ft = GeometryUtils.buildBarriersFeatureType(srs);
+        List<SimpleFeature> features = GeometryUtils.parseGeoJSON(geoJSON, ft);
+
+        FeatureCollection[] fcs = splitLinesAndPolygons(features);
+
+        File shapeLines = new File(dir, WSPLGEN_BARRIERS_LINES);
+        File shapePolys = new File(dir, WSPLGEN_BARRIERS_POLY);
+
+        try {
+            GeometryUtils.writeShapefile(
+                shapeLines,
+                GeometryUtils.buildFeatureType("lines", srid, "LineString"),
+                fcs[0]);
+            job.addLin(shapeLines.getAbsolutePath());
+
+            GeometryUtils.writeShapefile(
+                shapePolys,
+                GeometryUtils.buildFeatureType("polygons", srid, "Polygon"),
+                fcs[1]);
+            job.addLin(shapePolys.getAbsolutePath());
+        }
+        catch (MalformedURLException mue) {
+            logger.error("Error while writing shapefile: " + mue.getMessage());
+        }
+        catch (IOException ioe) {
+            logger.error("Error while writing shapefile: " + ioe.getMessage());
+        }
+        catch (SchemaException se) {
+            logger.error("Error while writing shapefile: " + se.getMessage());
+        }
+    }
+
+
+    protected FeatureCollection[] splitLinesAndPolygons(List<SimpleFeature> f) {
+        FeatureCollection lines    = FeatureCollections.newCollection();
+        FeatureCollection polygons = FeatureCollections.newCollection();
+
+        for (SimpleFeature feature: f) {
+            Object geom = feature.getDefaultGeometry();
+
+            if (geom instanceof LineString) {
+                lines.add(feature);
+            }
+            else if (geom instanceof Polygon) {
+                polygons.add(feature);
+            }
+            else {
+                logger.warn("Feature not supported: " + geom.getClass());
+            }
+        }
+
+        logger.debug("Found " + lines.size() + " barrier lines.");
+        logger.debug("Found " + polygons.size() + " barrier polygons.");
+
+        return new FeatureCollection[] { lines, polygons };
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf-8 :
--- a/flys-artifacts/src/main/java/de/intevation/flys/utils/GeometryUtils.java	Tue Aug 30 08:09:52 2011 +0000
+++ b/flys-artifacts/src/main/java/de/intevation/flys/utils/GeometryUtils.java	Tue Aug 30 11:09:54 2011 +0000
@@ -1,8 +1,33 @@
 package de.intevation.flys.utils;
 
+import java.io.IOException;
+import java.io.File;
+import java.io.Serializable;
+import java.net.MalformedURLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import com.vividsolutions.jts.geom.Coordinate;
 import com.vividsolutions.jts.geom.Geometry;
 
+import org.opengis.feature.simple.SimpleFeature;
+import org.opengis.feature.simple.SimpleFeatureType;
+
+import org.geotools.data.DataStoreFactorySpi;
+import org.geotools.data.DataUtilities;
+import org.geotools.data.FeatureStore;
+import org.geotools.data.DefaultTransaction;
+import org.geotools.data.Transaction;
+import org.geotools.data.shapefile.ShapefileDataStore;
+import org.geotools.data.shapefile.ShapefileDataStoreFactory;
+import org.geotools.feature.FeatureIterator;
+import org.geotools.feature.FeatureCollection;
+import org.geotools.feature.SchemaException;
+import org.geotools.feature.simple.SimpleFeatureTypeBuilder;
+import org.geotools.geojson.feature.FeatureJSON;
+import org.geotools.referencing.crs.DefaultGeographicCRS;
 
 
 public class GeometryUtils {
@@ -28,5 +53,96 @@
 
         return "" + c[0].x + " " + c[1].y + " " + c[1].x + " " + c[0].y;
     }
+
+
+    /**
+     * Returns a SimpleFeatureType used while parsing the GeoJSON string that
+     * represents the barriers entered by the user.
+     *
+     * @param srs The SRS that is used by the GeoJSON string.
+     *
+     * @return a SimpleFeatureType.
+     */
+    public static SimpleFeatureType buildBarriersFeatureType(String srs) {
+        SimpleFeatureTypeBuilder builder = new SimpleFeatureTypeBuilder();
+
+        builder.setName("flys");
+        builder.setNamespaceURI("http://www.intevation.de/");
+        builder.setSRS(srs);
+        builder.setDefaultGeometry("geometry");
+
+        builder.add("geometry", org.opengis.geometry.Geometry.class);
+
+        return builder.buildFeatureType();
+    }
+
+
+    public static SimpleFeatureType buildFeatureType(
+        String name, String srid, String geometryType)
+    throws SchemaException
+    {
+        String schema = "geom:" + geometryType + ":srid=" + srid;
+
+        return DataUtilities.createType(name, schema);
+    }
+
+
+    public static List<SimpleFeature> parseGeoJSON(
+        String geojson, SimpleFeatureType ft
+    ) {
+        List<SimpleFeature> collection = new ArrayList<SimpleFeature>();
+
+        try {
+            FeatureJSON fjson = new FeatureJSON();
+            fjson.setFeatureType(ft);
+
+            FeatureIterator<SimpleFeature> iterator =
+                fjson.streamFeatureCollection(geojson);
+
+            while (iterator.hasNext()) {
+                collection.add(iterator.next());
+            }
+        }
+        catch (IOException ioe) {
+            // TODO handle exception
+        }
+
+        return collection;
+    }
+
+
+    public static boolean writeShapefile(
+        File              shape,
+        SimpleFeatureType featureType,
+        FeatureCollection collection)
+    throws MalformedURLException, IOException
+    {
+        Map<String, Serializable> params = new HashMap<String, Serializable>();
+        params.put("url", shape.toURI().toURL());
+        params.put("create spatial index", Boolean.TRUE);
+
+        DataStoreFactorySpi dataStoreFactory = new ShapefileDataStoreFactory();
+
+        ShapefileDataStore newDataStore =
+            (ShapefileDataStore)dataStoreFactory.createNewDataStore(params);
+
+        newDataStore.createSchema(featureType);
+        newDataStore.forceSchemaCRS(DefaultGeographicCRS.WGS84);
+
+        Transaction 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();
+
+        return true;
+    }
 }
 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org