Mercurial > dive4elements > gnv-client
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());