package jeql.awt.geom; import java.awt.Shape; import java.awt.geom.GeneralPath; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.ArrayList; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.MultiLineString; import com.vividsolutions.jts.geom.MultiPolygon; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; /** * Converts JTS Geometry objects into Java 2D Shape objects */ public class Java2DConverter { private static double POINT_MARKER_SIZE = 3.0; private PointConverter pointConverter; public Java2DConverter(PointConverter pointConverter) { this.pointConverter = pointConverter; } public Java2DConverter() { this(new DefaultPointConverter()); } private Shape toShape(Polygon p) { ArrayList holeVertexCollection = new ArrayList(); for (int j = 0; j < p.getNumInteriorRing(); j++) { holeVertexCollection.add( toViewCoordinates(p.getInteriorRingN(j).getCoordinates())); } return new PolygonShape( toViewCoordinates(p.getExteriorRing().getCoordinates()), holeVertexCollection); } private Coordinate[] toViewCoordinates(Coordinate[] modelCoordinates) { Coordinate[] viewCoordinates = new Coordinate[modelCoordinates.length]; for (int i = 0; i < modelCoordinates.length; i++) { Point2D point2D = toViewPoint(modelCoordinates[i]); viewCoordinates[i] = new Coordinate(point2D.getX(), point2D.getY()); } return viewCoordinates; } private Shape toShape(GeometryCollection gc) { GeometryCollectionShape shape = new GeometryCollectionShape(); for (int i = 0; i < gc.getNumGeometries(); i++) { Geometry g = (Geometry) gc.getGeometryN(i); shape.add(toShape(g)); } return shape; } private GeneralPath toShape(MultiLineString mls) { GeneralPath path = new GeneralPath(); for (int i = 0; i < mls.getNumGeometries(); i++) { LineString lineString = (LineString) mls.getGeometryN(i); path.append(toShape(lineString), false); } //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be //converted to GeneralPaths. [Jon Aquino] return path; } private GeneralPath toShape(LineString lineString) { GeneralPath shape = new GeneralPath(); Point2D viewPoint = toViewPoint(lineString.getCoordinateN(0)); shape.moveTo((float) viewPoint.getX(), (float) viewPoint.getY()); for (int i = 1; i < lineString.getNumPoints(); i++) { viewPoint = toViewPoint(lineString.getCoordinateN(i)); shape.lineTo((float) viewPoint.getX(), (float) viewPoint.getY()); } //BasicFeatureRenderer expects LineStrings and MultiLineStrings to be //converted to GeneralPaths. [Jon Aquino] return shape; } private Shape toShape(Point point){ Rectangle2D.Double pointMarker = new Rectangle2D.Double( 0.0, 0.0, POINT_MARKER_SIZE, POINT_MARKER_SIZE); Point2D viewPoint = toViewPoint(point.getCoordinate()); pointMarker.x = (double) (viewPoint.getX() - (POINT_MARKER_SIZE / 2)); pointMarker.y = (double) (viewPoint.getY() - (POINT_MARKER_SIZE / 2)); return pointMarker; } private Point2D toViewPoint(Coordinate modelCoordinate) { // Do the rounding now; don't rely on Java 2D rounding, because it // seems to do it differently for drawing and filling, resulting in the draw // being a pixel off from the fill sometimes. [Jon Aquino] Point2D viewPoint = pointConverter.toView(modelCoordinate); viewPoint.setLocation(Math.round(viewPoint.getX()), Math.round(viewPoint .getY())); return viewPoint; } /** * If you pass in a general GeometryCollection, note that a Shape cannot * preserve information about which elements are 1D and which are 2D. * For example, if you pass in a GeometryCollection containing a ring and a * disk, you cannot render them as such: if you use Graphics.fill, you'll get * two disks, and if you use Graphics.draw, you'll get two rings. Solution: * create Shapes for each element. */ public Shape toShape(Geometry geometry) { if (geometry.isEmpty()) { return new GeneralPath(); } if (geometry instanceof Polygon) { return toShape((Polygon) geometry); } if (geometry instanceof MultiPolygon) { return toShape((MultiPolygon) geometry); } if (geometry instanceof LineString) { return toShape((LineString) geometry); } if (geometry instanceof MultiLineString) { return toShape((MultiLineString) geometry); } if (geometry instanceof Point) { return toShape((Point) geometry); } if (geometry instanceof GeometryCollection) { return toShape((GeometryCollection) geometry); } throw new IllegalArgumentException( "Unrecognized Geometry class: " + geometry.getClass()); } }