/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2008-2011, 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.process.jts; import org.geotools.process.factory.DescribeParameter; import org.geotools.process.factory.DescribeProcess; import org.geotools.process.factory.DescribeResult; import com.vividsolutions.jts.densify.Densifier; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryCollection; import com.vividsolutions.jts.geom.LineString; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.operation.buffer.BufferParameters; import com.vividsolutions.jts.simplify.DouglasPeuckerSimplifier; /** * A set of static functions powering the {@link GeometryProcessFactory}. * @author Andrea Aime */ public class GeometryFunctions { /** * Maps the enumeration into a set of * * @author Andrea Aime - OpenGeo * */ enum BufferCapStyle { Round(BufferParameters.CAP_ROUND), Flat(BufferParameters.CAP_FLAT), Square( BufferParameters.CAP_SQUARE); int value; private BufferCapStyle(int value) { this.value = value; } }; @DescribeProcess(title = "Geometry containment check", description = "Checks if a contains b") static public boolean contains(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.contains(b); } @DescribeProcess(title = "Geometry emptiness check", description = "Checks if the provided geometry is empty") static public boolean isEmpty(@DescribeParameter(name = "geom") Geometry geom) { return geom.isEmpty(); } @DescribeProcess(title = "Geometry length", description = "Returns the geometry perimeters, computed using cartesian geometry expressions in the same unit of measure as the geometry (will not return a valid perimeter for geometries expressed geographic coordinates") static public double length(@DescribeParameter(name = "geom") Geometry geom) { return geom.getLength(); } @DescribeProcess(title = "Geometry intersection test", description = "Returns true if the two geometries intersect, false otherwise") static public boolean intersects(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.intersects(b); } @DescribeProcess(title = "Geometry validity test", description = "Returns true if the geometry is topologically valid, false otherwise") static public boolean isValid(@DescribeParameter(name = "geom") Geometry geom) { return geom.isValid(); } @DescribeProcess(title = "Geometry type detector", description = "Returns the type of the geometry (POINT,LINE,POLYGON,MULTIPOINT,MULTILINE,MULTIPOLYGON,GEOMETRY COLLECTION)") static public String geometryType(@DescribeParameter(name = "geom") Geometry geom) { return geom.getGeometryType(); } @DescribeProcess(title = "Point counter", description = "Returns the number of points in the geometry") static public int numPoints(@DescribeParameter(name = "geom") Geometry geom) { return geom.getNumPoints(); } @DescribeProcess(title = "Geometry simplicity test", description = "Returns true if the geometry is simple") static public boolean isSimple(@DescribeParameter(name = "geom") Geometry geom) { return geom.isSimple(); } @DescribeProcess(title = "Geometry distance", description = "Returns the minimum distance between a and b") static public double distance(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.distance(b); } @DescribeProcess(title = "Proximity check", description = "Returns true if the distance between the two geomeries is less than the specified value") static public boolean isWithinDistance(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b, @DescribeParameter(name = "distance") double distance) { return a.isWithinDistance(b, distance); } @DescribeProcess(title = "Geometry area", description = "Computes the geometry area (in a cartesian plane, using the same unit of measure as the geometry coordinates, don't use with geometries expressed in geographic coordinates)") static public double area(@DescribeParameter(name = "geom") Geometry geom) { return geom.getArea(); } @DescribeProcess(title = "Centroid", description = "Extracts a geometry centroid") static public Geometry centroid(@DescribeParameter(name = "geom") Geometry geom) { return geom.getCentroid(); } @DescribeProcess(title = "Interior point", description = "Returns a point that lies inside the geometry, or at most is located on its boundary") static public Geometry interiorPoint(@DescribeParameter(name = "geom") Geometry geom) { return geom.getInteriorPoint(); } @DescribeProcess(title = "Geometry dimension", description = "Returns 0 for points, 1 for lines, 2 for polygons") static public int dimension(@DescribeParameter(name = "geom") Geometry geom) { return geom.getDimension(); } @DescribeProcess(title = "Boundary", description = "Returns a geometry boundary, or an empty geometry if there is no boundary") static public Geometry boundary(@DescribeParameter(name = "geom") Geometry geom) { return geom.getBoundary(); } @DescribeProcess(title = "Envelope", description = "Returns the geometry envelope either as a Polygon, or a Point if the input is a Point") static public Geometry envelope(@DescribeParameter(name = "geom") Geometry geom) { return geom.getEnvelope(); } @DescribeProcess(title = "Disjoint check", description = "Returns true if the two geometries have no points in common") static public boolean disjoint(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.disjoint(b); } @DescribeProcess(title = "Touch check", description = "Returns true if the two geometries touch each other") static public boolean touches(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.touches(b); } @DescribeProcess(title = "Crossing check", description = "Returns true if the two geometries cross each other") static public boolean crosses(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.crosses(b); } @DescribeProcess(title = "Within check", description = "Returns true if a is within b") static public boolean within(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.within(b); } @DescribeProcess(title = "Overlap check", description = "Returns true if a overlaps with b") static public boolean overlaps(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.overlaps(b); } @DescribeProcess(title = "Relate check", description = "Returns true if a and b DE-9IM intersection matrix matches the provided pattern") static public boolean relatePattern(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b, String pattern) { return a.relate(b, pattern); } @DescribeProcess(title = "Relate", description = "Returns the DE-9IM intersection matrix of the two geometries") static public String relate(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.relate(b).toString(); } @DescribeProcess(title = "Geometry buffer", description = "Buffers a geometry using a certain distance") @DescribeResult(description = "The buffered geometry") static public Geometry buffer( @DescribeParameter(name = "geom", description = "The geometry to be buffered") Geometry geom, @DescribeParameter(name = "distance", description = "The distance (same unit of measure as the geometry)") double distance, @DescribeParameter(name = "quadrantSegments", description = "Number of quadrant segments. Use > 0 for round joins, 0 for flat joins, < 0 for mitred joins", min = 0) Integer quadrantSegments, @DescribeParameter(name = "capStyle", description = "The buffer cap style, round, flat, square", min = 0) BufferCapStyle capStyle) { if (quadrantSegments == null) quadrantSegments = BufferParameters.DEFAULT_QUADRANT_SEGMENTS; if (capStyle == null) capStyle = BufferCapStyle.Round; return geom.buffer(distance, quadrantSegments, capStyle.value); } @DescribeProcess(title = "Convex hull", description = "Returns the convex hull of the specified geometry") static public Geometry convexHull(@DescribeParameter(name = "geom") Geometry geom) { return geom.convexHull(); } @DescribeProcess(title = "Intersection", description = "Returns the intersectoin between a and b (eventually an empty collection if there is no intersection)") static public Geometry intersection(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.intersection(b); } @DescribeProcess(title = "Union", description = "Performs the geometric union of two or more geometries") @DescribeResult(description = "The union of all input geometries") static public Geometry union( @DescribeParameter(name = "geom", description = "The geometries to be united", min = 2) Geometry... geoms) { Geometry result = null; for (Geometry g : geoms) { if (result == null) { result = g; } else { result = result.union(g); } } return result; } @DescribeProcess(title = "Difference", description = "Returns the difference between a and b (all the points that are in a but not in b)") static public Geometry difference(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.difference(b); } @DescribeProcess(title = "Symmetrical difference", description = "Returns a geometry made of points that are in a or b, but not in both") static public Geometry symDifference(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.symDifference(b); } @DescribeProcess(title = "EqualsExactTolerance", description = "Returns true if the two geometries are exactly the same, minus small differences in coordinate values") static public boolean equalsExactTolerance(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b, double tolerance) { return a.equalsExact(b, tolerance); } @DescribeProcess(title = "EqualsExact", description = "Returns true if the two geometries are exactly the same") static public boolean equalsExact(@DescribeParameter(name = "a") Geometry a, @DescribeParameter(name = "b") Geometry b) { return a.equalsExact(b); } @DescribeProcess(title = "Geometry count", description = "Returns the number of elements in the geometry collection, or one if it's not a collection") static public int numGeometries(Geometry collection) { return collection.getNumGeometries(); } @DescribeProcess(title = "N-th geometry", description = "Returns the n-th geomery in the collection") static public Geometry getGeometryN(GeometryCollection collection, int index) { return collection.getGeometryN(index); } @DescribeProcess(title = "GetX", description = "Returns the X ordinate of the point") static public double getX(Point point) { return point.getX(); } @DescribeProcess(title = "GetY", description = "Returns the Y ordinate of the point") static public double getY(Point point) { return point.getY(); } @DescribeProcess(title = "Closed", description = "Returns true if the line is closed") static public boolean isClosed(LineString line) { return line.isClosed(); } @DescribeProcess(title = "N-th point", description = "Returns the n-th point in the line") static public Point pointN(LineString line, int index) { return line.getPointN(index); } @DescribeProcess(title = "Start point", description = "Returns the start point of the line") static public Point startPoint(LineString line) { return line.getStartPoint(); } @DescribeProcess(title = "End point", description = "Returns the end point of the line") static public Point endPoint(LineString line) { return line.getEndPoint(); } @DescribeProcess(title = "Ring", description = "Returns true if the line is a ring") static public boolean isRing(LineString line) { return line.isRing(); } @DescribeProcess(title = "Exterior ring", description = "Returns the exterior ring of the polygon") static public Geometry exteriorRing(Polygon polygon) { return polygon.getExteriorRing(); } @DescribeProcess(title = "Interior ring count", description = "Returns the number of interior rings in the polygon") static public int numInteriorRing(Polygon polygon) { return polygon.getNumInteriorRing(); } @DescribeProcess(title = "N-th interorior ring", description = "Returns the n-th interior ring in the polygon") static public Geometry interiorRingN(Polygon polygon, int index) { return polygon.getInteriorRingN(index); } @DescribeProcess(title = "Simplify", description = "Simplifies the geometry using the specified distance using the Douglas-Peuker algorithm") static public Geometry simplify(@DescribeParameter(name = "geom") Geometry geom, @DescribeParameter(name = "distance") double distance) { return DouglasPeuckerSimplifier.simplify(geom, distance); } @DescribeProcess(title = "Densify", description = "Densifies the geometry using the specified distance") static public Geometry densify(@DescribeParameter(name = "geom") Geometry geom, @DescribeParameter(name = "distance") double distance) { return Densifier.densify(geom, distance); } }