Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java @ 657:af3f56758f59
merged gnv-artifacts/0.5
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Fri, 28 Sep 2012 12:13:53 +0200 |
parents | 70adafe2b9d5 |
children | b1f5f2a8840f |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiLineStringProducer.java Fri Sep 28 12:13:53 2012 +0200 @@ -0,0 +1,196 @@ +package de.intevation.gnv.raster; + +import com.vividsolutions.jts.geom.Coordinate; +import com.vividsolutions.jts.geom.Geometry; +import com.vividsolutions.jts.geom.GeometryFactory; +import com.vividsolutions.jts.geom.LineString; +import com.vividsolutions.jts.geom.MultiLineString; +import com.vividsolutions.jts.geom.Polygon; +import com.vividsolutions.jts.geom.TopologyException; + +import de.intevation.gnv.math.IJKey; + +import de.intevation.gnv.raster.Vectorizer.Edge; + +import de.intevation.gnv.utils.Pair; + +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) + */ +public class JTSMultiLineStringProducer +extends IsoProducer +{ + private static Logger log = Logger.getLogger( + JTSMultiLineStringProducer.class); + + 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, + maxX, maxY); + } + + 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 + ) { + ArrayList<Pair<Object, MultiLineString>> multiLineStrings = + new ArrayList<Pair<Object, MultiLineString>>(); + + double b1 = minX; + double m1 = width != 1 + ? (maxX - minX)/(width-1) + : 0d; + + double b2 = minY; + double m2 = height != 1 + ? (maxY - minY)/(height-1) + : 0d; + + ArrayList<Coordinate> coordinates = new ArrayList<Coordinate>(); + + for (IJKey key: joinPairs()) { + ArrayList<LineString> lineStrings = new ArrayList<LineString>(); + + // process complete + ArrayList<Edge> completeList = complete.get(key); + if (completeList != null) { + for (Edge head: completeList) { + Edge current = head; + do { + coordinates.add(new Coordinate( + m1*(current.a % width) + b1, + m2*(current.a / width) + b2)); + } + while ((current = current.next) != head); + // add head again to close shape + coordinates.add(new Coordinate( + m1*(head.a % width) + b1, + m2*(head.a / width) + b2)); + + clipLineString( + geometryFactory.createLineString( + coordinates.toArray( + new Coordinate[coordinates.size()])), + lineStrings); + + coordinates.clear(); + } + } + + // process open + TIntObjectHashMap map = commonOpen.get(key); + + if (map != null) { + for (Edge head: headList(map)) { + + head = Vectorizer.simplify(head, width); + Edge current = head, last = head; + do { + coordinates.add(new Coordinate( + m1*(current.a % width) + b1, + m2*(current.a / width) + b2)); + last = current; + } + while ((current = current.next) != null); + // add b from tail + coordinates.add(new Coordinate( + m1*(last.b % width) + b1, + m2*(last.b / width) + b2)); + + clipLineString( + geometryFactory.createLineString( + coordinates.toArray( + new Coordinate[coordinates.size()])), + lineStrings); + + coordinates.clear(); + } // for all in common open + } // if map defined for key + + if (!lineStrings.isEmpty()) { + MultiLineString multiLineString = + geometryFactory.createMultiLineString( + lineStrings.toArray( + new LineString[lineStrings.size()])); + lineStrings.clear(); + Object attribute = attributeGenerator != null + ? attributeGenerator.generateAttribute(key.i, key.j) + : key; + multiLineStrings.add(new Pair<Object, MultiLineString>( + attribute, + multiLineString)); + } + } // for all pairs + + return multiLineStrings; + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :