/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2006-2008, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.geometry.iso.util.algorithm2D; import java.awt.geom.Area; import java.awt.geom.GeneralPath; import java.awt.geom.Line2D; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import org.geotools.geometry.iso.util.elem2D.Edge2D; /** * @author roehrig * * TODO To change the template for this generated type comment go to Window - * Preferences - Java - Code Style - Code Templates * * * * @source $URL$ */ public class AlgoArea { /** * returns a list of boundaries, whereas each boundary is a list of * connected Line2D segments (ArrayList<ArrayList<Line2D>>) * * @param area * @return */ public static ArrayList<ArrayList<Line2D>> getBoundariesLines(Area area) { ArrayList<ArrayList<Line2D>> result = new ArrayList<ArrayList<Line2D>>(); PathIterator pi = area.getPathIterator(null); double coords[] = new double[6]; while (!pi.isDone()) { int type = pi.currentSegment(coords); if (type == PathIterator.SEG_MOVETO) { ArrayList<Line2D> lines = new ArrayList<Line2D>(); result.add(lines); Point2D p0 = new Point2D.Double(coords[0], coords[1]); Point2D pStart = p0; pi.next(); while (!pi.isDone()) { type = pi.currentSegment(coords); if (type == PathIterator.SEG_CLOSE) { /** * according to our definition of ring, the first node * must be equal the last */ // Jr hier gibt es probleme: mit teresapolygon ist // p0==pStart, für HunderMalHundertQuadrat ist p0 der // punkt davor. Zwischenlösung, bis das erklärt wird: if (!AlgoPoint2D.equalsTol(p0, pStart)) { lines.add(new Line2D.Double(p0, pStart)); } pi.next(); break; } else if (type == PathIterator.SEG_LINETO) { Point2D p1 = new Point2D.Double(coords[0], coords[1]); lines.add(new Line2D.Double(p0, p1)); p0 = p1; } else if (type == PathIterator.SEG_QUADTO) { Point2D p1 = new Point2D.Double(coords[0], coords[1]); lines.add(new Line2D.Double(p0, p1)); Point2D p2 = new Point2D.Double(coords[2], coords[3]); lines.add(new Line2D.Double(p1, p2)); p0 = p2; } else if (type == PathIterator.SEG_CUBICTO) { Point2D p1 = new Point2D.Double(coords[0], coords[1]); lines.add(new Line2D.Double(p0, p1)); Point2D p2 = new Point2D.Double(coords[2], coords[3]); lines.add(new Line2D.Double(p1, p2)); Point2D p3 = new Point2D.Double(coords[4], coords[5]); lines.add(new Line2D.Double(p2, p3)); p0 = p3; } else { throw new IllegalArgumentException("Bad PathIterator"); } pi.next(); } } else { pi.next(); } } return result; } public ArrayList<ArrayList<Point2D>> getBoundariesPoints(Area area) { ArrayList<ArrayList<Point2D>> result = new ArrayList<ArrayList<Point2D>>(); PathIterator pi = area.getPathIterator(null); double startCoords[] = new double[6]; while (!pi.isDone()) { int type = pi.currentSegment(startCoords); if (type == PathIterator.SEG_MOVETO) { ArrayList<Point2D> points = new ArrayList<Point2D>(); result.add(points); points.add(new Point2D.Double(startCoords[0], startCoords[1])); pi.next(); while (!pi.isDone()) { double coords[] = new double[6]; type = pi.currentSegment(coords); if (type == PathIterator.SEG_CLOSE) { /** * according to our definition of ring, the first node * must be equal the last */ points.add(new Point2D.Double(startCoords[0], startCoords[1])); break; } else if (type == PathIterator.SEG_LINETO) { points.add(new Point2D.Double(coords[0], coords[1])); } else if (type == PathIterator.SEG_QUADTO) { points.add(new Point2D.Double(coords[0], coords[1])); points.add(new Point2D.Double(coords[2], coords[3])); } else if (type == PathIterator.SEG_LINETO) { points.add(new Point2D.Double(coords[0], coords[1])); points.add(new Point2D.Double(coords[2], coords[3])); points.add(new Point2D.Double(coords[4], coords[5])); } else { throw new IllegalArgumentException("Bad PathIterator"); } pi.next(); } } else { pi.next(); } } return result; } public static boolean linesOrientation(Collection<Line2D> segments){ //Algorithm for a lineString-Orientation (clockwise or counterclockwise) //is the value of result > 0 the Orientation of the lineString is clockwise //is the value of result < 0 the Orientation of the lineString is counterclockwise ArrayList<Point2D> points = new ArrayList<Point2D>(segments.size()+1); for (Iterator<Line2D> it = segments.iterator(); it.hasNext();) { Line2D edge = it.next(); points.add(((Line2D)it.next()).getP1()); } return AlgoPoint2D.pointsOrientation(points).booleanValue(); } public static GeneralPath createGeneralPathFromEdges(Collection<Edge2D> edges) { ArrayList<Point2D> nodes = new ArrayList<Point2D>(edges.size()); for (Iterator it = edges.iterator(); it.hasNext();) { Edge2D edge = (Edge2D)it.next(); nodes.add(edge.getNode1()); } return createGeneralPathFromNodes(nodes); } /** * @param points * @return */ public static GeneralPath createGeneralPathFromNodes(Collection<Point2D> points) { if (points==null) return null; if ( points.isEmpty()) return null; Point2D pointsArray[] = new Point2D[points.size()]; pointsArray = (Point2D[])points.toArray(pointsArray); int n = pointsArray.length; double x[] = new double[n]; double y[] = new double[n]; GeneralPath path = new GeneralPath(GeneralPath.WIND_NON_ZERO,n); Point2D p = pointsArray[0]; path.moveTo((float)p.getX(),(float)p.getY()); for (int i=1; i < n-1; i++) { p = pointsArray[i]; path.lineTo((float)p.getX(),(float)p.getY()); } if (pointsArray[0].equals(pointsArray[n-1])) { path.closePath(); } else { p = pointsArray[n-1]; path.lineTo((float)p.getX(),(float)p.getY()); } return path; } }