changeset 499:e065a72f6b62

Clip "Horizontalschnitte" against given clipping polygon. gnv-artifacts/trunk@579 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 19 Jan 2010 23:01:24 +0000
parents 4080b57dcb52
children ca5162aa644d
files gnv-artifacts/ChangeLog gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java
diffstat 4 files changed, 152 insertions(+), 44 deletions(-) [+]
line wrap: on
line diff
--- a/gnv-artifacts/ChangeLog	Tue Jan 19 21:23:28 2010 +0000
+++ b/gnv-artifacts/ChangeLog	Tue Jan 19 23:01:24 2010 +0000
@@ -1,3 +1,14 @@
+2010-01-20	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
+
+	* src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java,
+	  src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java:
+	  Clip against given polygon. BTW: Geotools has problems with
+	  writing clipped polygons in packed 2-tuple form, too. Therefore
+	  polygons are also stores in the packed 3-tuple form. :-/
+
+	* src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java:
+	  Forward clipping polygon to isoline and polygon generator.
+
 2010-01-19	Sascha L. Teichmann	<sascha.teichmann@intevation.de>
 
 	* trunk/pom.xml: Upgraded Geotools to 2.5.8
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java	Tue Jan 19 21:23:28 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java	Tue Jan 19 23:01:24 2010 +0000
@@ -1,23 +1,26 @@
 package de.intevation.gnv.raster;
 
-import java.util.List;
-import java.util.ArrayList;
-
-import org.apache.log4j.Logger;
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.LineString;
+import com.vividsolutions.jts.geom.MultiLineString;
+import com.vividsolutions.jts.geom.TopologyException;
 
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.MultiLineString;
-import com.vividsolutions.jts.geom.LineString;
-import com.vividsolutions.jts.geom.Coordinate;
-
-import gnu.trove.TIntObjectHashMap;
+import de.intevation.gnv.math.IJKey;
 
 import de.intevation.gnv.raster.Vectorizer.Edge;
 
 import de.intevation.gnv.utils.Pair;
 
-import de.intevation.gnv.math.IJKey;
+import gnu.trove.TIntObjectHashMap;
 
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
 /**
  * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
  */
@@ -29,11 +32,15 @@
 
     protected GeometryFactory geometryFactory;
 
+    protected Polygon clip;
+
     public JTSMultiLineStringProducer(
+        Polygon clip,
         double minX, double minY,
         double maxX, double maxY
     ) {
         this(
+            clip,
             // XXX: Geotools crashes if only using a 2d packed data format!
             JTSMultiPolygonProducer.createDefaultGeometryFactory(3),
             minX, minY,
@@ -41,14 +48,57 @@
     }
 
     public JTSMultiLineStringProducer(
+        Polygon clip,
         GeometryFactory geometryFactory,
         double minX, double minY,
         double maxX, double maxY
     ) {
         super(minX, minY, maxX, maxY);
+        this.clip = clip;
         this.geometryFactory = geometryFactory;
     }
 
+    protected void clipLineString(
+        LineString            lineString,
+        ArrayList<LineString> lineStrings
+    ) {
+        if (clip == null) {
+            lineStrings.add(lineString);
+            return;
+        }
+
+        if (!lineString.intersects(clip)) {
+            return;
+        }
+
+        try {
+            Geometry result = lineString.intersection(clip);
+
+            if (result instanceof LineString) {
+                lineStrings.add((LineString)result);
+            }
+            else if (result instanceof MultiLineString) {
+                MultiLineString mls = (MultiLineString)result;
+                for (int i = 0, N = mls.getNumGeometries(); i < N; ++i) {
+                    Geometry g = mls.getGeometryN(i);
+                    if (g instanceof LineString) {
+                        lineStrings.add((LineString)g);
+                    }
+                    else {
+                        log.warn("cannot handle geometry " + g.getClass());
+                    }
+                }
+            }
+            else {
+                log.warn("cannot handle " + result.getClass());
+            }
+        }
+        catch (TopologyException te) {
+            log.error(te.getLocalizedMessage(), te);
+            lineStrings.add(lineString);
+        }
+    }
+
     public List<Pair<Object, MultiLineString>> getMultiLineStrings(
         AttributeGenerator attributeGenerator
     ) {
@@ -85,10 +135,13 @@
                     coordinates.add(new Coordinate(
                         m1*(head.a % width) + b1,
                         m2*(head.a / width) + b2));
-                    lineStrings.add(
+
+                    clipLineString(
                         geometryFactory.createLineString(
                             coordinates.toArray(
-                                new Coordinate[coordinates.size()])));
+                                new Coordinate[coordinates.size()])),
+                        lineStrings);
+
                     coordinates.clear();
                 }
             }
@@ -112,10 +165,13 @@
                     coordinates.add(new Coordinate(
                         m1*(last.b % width) + b1,
                         m2*(last.b / width) + b2));
-                    lineStrings.add(
+
+                    clipLineString(
                         geometryFactory.createLineString(
                             coordinates.toArray(
-                                new Coordinate[coordinates.size()])));
+                                new Coordinate[coordinates.size()])),
+                        lineStrings);
+
                     coordinates.clear();
                 } // for all in common open
             } // if map defined for key
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java	Tue Jan 19 21:23:28 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java	Tue Jan 19 23:01:24 2010 +0000
@@ -1,26 +1,29 @@
 package de.intevation.gnv.raster;
 
-import java.util.Map;
-import java.util.List;
-import java.util.HashMap;
-import java.util.TreeMap;
-import java.util.ArrayList;
-
-import com.vividsolutions.jts.geom.GeometryFactory;
-import com.vividsolutions.jts.geom.MultiPolygon;
-import com.vividsolutions.jts.geom.Polygon;
-import com.vividsolutions.jts.geom.Coordinate;
-import com.vividsolutions.jts.geom.LinearRing;
-import com.vividsolutions.jts.geom.PrecisionModel;
-
 import com.vividsolutions.jts.algorithm.CGAlgorithms;
 
+import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.Geometry;
+import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.LinearRing;
+import com.vividsolutions.jts.geom.MultiPolygon;
+import com.vividsolutions.jts.geom.Polygon;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import com.vividsolutions.jts.geom.TopologyException;
+
 import com.vividsolutions.jts.geom.impl.PackedCoordinateSequenceFactory;
 
+import de.intevation.gnv.raster.Vectorizer.Edge;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
 import org.apache.log4j.Logger;
 
-import de.intevation.gnv.raster.Vectorizer.Edge;
-
 /**
  * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
  */
@@ -40,33 +43,39 @@
 
     protected GeometryFactory geometryFactory;
 
+    protected Polygon clip;
+
     protected HashMap<Integer, ArrayList<Polygon>> valueToPolygons;
 
     public JTSMultiPolygonProducer() {
     }
 
     public JTSMultiPolygonProducer(
+        Polygon clip,
         double minX, double minY,
         double maxX, double maxY
     ) {
         this(
+            clip,
             createDefaultGeometryFactory(),
             minX, minY,
             maxX, maxY);
     }
 
     public JTSMultiPolygonProducer(
+        Polygon clip,
         GeometryFactory geometryFactory,
         double minX, double minY,
         double maxX, double maxY
     ) {
         super(minX, minY, maxX, maxY);
+        this.clip = clip;
         this.geometryFactory = geometryFactory;
         valueToPolygons = new HashMap<Integer, ArrayList<Polygon>>();
     }
 
     public static GeometryFactory createDefaultGeometryFactory() {
-        return createDefaultGeometryFactory(2);
+        return createDefaultGeometryFactory(3);
     }
 
     public static GeometryFactory createDefaultGeometryFactory(int dim) {
@@ -89,14 +98,6 @@
             return;
         }
 
-        Integer v = Integer.valueOf(value);
-
-        ArrayList<Polygon> polygons = valueToPolygons.get(v);
-
-        if (polygons == null) {
-            valueToPolygons.put(v, polygons = new ArrayList<Polygon>());
-        }
-
         double b1 = minX;
         double m1 = width != 1
            ? (maxX - minX)/(width-1)
@@ -149,13 +150,39 @@
             shell,
             holes.toArray(new LinearRing[holes.size()]));
 
-        polygons.add(polygon);
+        if (clip == null || clip.intersects(polygon)) {
+            Integer v = Integer.valueOf(value);
+
+            ArrayList<Polygon> polygons = valueToPolygons.get(v);
+
+            if (polygons == null) {
+                valueToPolygons.put(v, polygons = new ArrayList<Polygon>());
+            }
+
+            polygons.add(polygon);
+        }
     }
 
     public Map<Integer, MultiPolygon> getMultiPolygons() {
         return getMultiPolygons(null);
     }
 
+    protected MultiPolygon flattenCollection(Geometry result) {
+
+        if (result instanceof MultiPolygon) {
+            return (MultiPolygon)result;
+        }
+
+        if (result instanceof Polygon) {
+            return geometryFactory.createMultiPolygon(
+                new Polygon[] { (Polygon)result });
+        }
+
+        log.warn("cannot handle " + result.getClass());
+
+        return null;
+    }
+
     public Map<Integer, MultiPolygon> getMultiPolygons(
         ValueConverter valueConverter
     ) {
@@ -171,10 +198,22 @@
                 ? valueConverter.convert(entry.getKey())
                 : entry.getKey();
 
-            multiPolygons.put(
-                value,
-                geometryFactory.createMultiPolygon(
-                    polygons.toArray(new Polygon[polygons.size()])));
+            MultiPolygon mp = geometryFactory.createMultiPolygon(
+                polygons.toArray(new Polygon[polygons.size()]));
+
+            if (clip != null) {
+                try {
+                    Geometry result = mp.intersection(clip);
+
+                    MultiPolygon mp2 = flattenCollection(result);
+
+                    if (mp2 != null) { mp = mp2; }
+                }
+                catch (TopologyException te) {
+                    log.error(te.getLocalizedMessage(), te);
+                }
+            }
+            multiPolygons.put(value, mp);
         }
 
         return multiPolygons;
--- a/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java	Tue Jan 19 21:23:28 2010 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/state/profile/horizontalcrosssection/HorizontalCrossSectionMeshOutputState.java	Tue Jan 19 23:01:24 2010 +0000
@@ -536,6 +536,7 @@
         // produce JTS compatible polygons
 
         JTSMultiPolygonProducer jtsmpp = new JTSMultiPolygonProducer(
+            polygon,
             boundingBox.getMinX(), boundingBox.getMinY(),
             boundingBox.getMaxX(), boundingBox.getMaxY());
             
@@ -573,6 +574,7 @@
         }
 
         JTSMultiLineStringProducer jtslsp = new JTSMultiLineStringProducer(
+            polygon,
             boundingBox.getMinX(), boundingBox.getMinY(),
             boundingBox.getMaxX(), boundingBox.getMaxY());
 

http://dive4elements.wald.intevation.org