Mercurial > dive4elements > gnv-client
diff gnv-artifacts/src/main/java/de/intevation/gnv/raster/JTSMultiPolygonProducer.java @ 465:f7038820df2e
Added support to trace rasters to JTS multi polygons and multi line strings.
Write them to shape files with GeoTools.
gnv-artifacts/trunk@526 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Mon, 11 Jan 2010 00:29:45 +0000 |
parents | |
children | 6e8364e766fa |
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/JTSMultiPolygonProducer.java Mon Jan 11 00:29:45 2010 +0000 @@ -0,0 +1,183 @@ +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.impl.PackedCoordinateSequenceFactory; + +import org.apache.log4j.Logger; + +import de.intevation.gnv.raster.Vectorizer.Edge; + +/** + * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) + */ +public class JTSMultiPolygonProducer +extends AbstractProducer +{ + private static Logger log = Logger.getLogger( + JTSMultiPolygonProducer.class); + + public static final int SRID_WGS84 = 4326; + + public interface ValueConverter { + + Integer convert(Integer value); + + } // interface ValueConverter + + protected GeometryFactory geometryFactory; + + protected HashMap<Integer, ArrayList<Polygon>> valueToPolygons; + + public JTSMultiPolygonProducer() { + } + + public JTSMultiPolygonProducer( + double minX, double minY, + double maxX, double maxY + ) { + this( + createDefaultGeometryFactory(), + minX, minY, + maxX, maxY); + } + + public JTSMultiPolygonProducer( + GeometryFactory geometryFactory, + double minX, double minY, + double maxX, double maxY + ) { + super(minX, minY, maxX, maxY); + this.geometryFactory = geometryFactory; + valueToPolygons = new HashMap<Integer, ArrayList<Polygon>>(); + } + + public static GeometryFactory createDefaultGeometryFactory() { + return new GeometryFactory( + new PrecisionModel( + PrecisionModel.FLOATING), + SRID_WGS84, + new PackedCoordinateSequenceFactory( + PackedCoordinateSequenceFactory.DOUBLE, + 2)); + } + + public void handleRings( + List<Edge> rings, + int value, + int width, + int height + ) { + if (value == -1) { + 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) + : 0d; + + double b2 = minY; + double m2 = height != 1 + ? (maxY - minY)/(height-1) + : 0d; + + ArrayList<Coordinate> vertices = new ArrayList<Coordinate>(); + + LinearRing shell = null; + ArrayList<LinearRing> holes = new ArrayList<LinearRing>(); + + for (Edge head: rings) { + Edge current = head; + do { + vertices.add(new Coordinate( + m1*(current.a % width) + b1, + m2*(current.a / width) + b2)); + } + while ((current = current.next) != head); + vertices.add(new Coordinate( + m1*(head.a % width) + b1, + m2*(head.a / width) + b2)); + + Coordinate [] coordinates = + vertices.toArray(new Coordinate[vertices.size()]); + + vertices.clear(); + + LinearRing ring = geometryFactory.createLinearRing( + coordinates); + + if (CGAlgorithms.isCCW(coordinates)) { + shell = ring; + } + else { + holes.add(ring); + } + } + + if (shell == null) { + log.error("polygon has no shell"); + return; + } + + Polygon polygon = geometryFactory.createPolygon( + shell, + holes.toArray(new LinearRing[holes.size()])); + + polygons.add(polygon); + } + + public Map<Integer, MultiPolygon> getMultiPolygons() { + return getMultiPolygons(null); + } + + public Map<Integer, MultiPolygon> getMultiPolygons( + ValueConverter valueConverter + ) { + TreeMap<Integer, MultiPolygon> multiPolygons = + new TreeMap<Integer, MultiPolygon>(); + + for (Map.Entry<Integer, ArrayList<Polygon>> entry: + valueToPolygons.entrySet() + ) { + ArrayList<Polygon> polygons = entry.getValue(); + + Integer value = valueConverter != null + ? valueConverter.convert(entry.getKey()) + : entry.getKey(); + + multiPolygons.put( + value, + geometryFactory.createMultiPolygon( + polygons.toArray(new Polygon[polygons.size()]))); + } + + return multiPolygons; + } + + public void clear() { + valueToPolygons.clear(); + } +} +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :