GeometryFunctions { @DescribeProcess(title = "Split Polygon", description = "Splits a polygon by a linestring") @DescribeResult(description = "The collection of split polygons") static public Geometry splitPolygon( @DescribeParameter(name = "polygon", description = "Polygon to split") Geometry polygon, @DescribeParameter(name = "line", description = "Linestring to split by") LineString line) { Geometry nodedLinework = polygon.getBoundary().union(line); Geometry polys = polygonize(nodedLinework); List<Polygon> output = new ArrayList<Polygon>(); for (int i = 0; i < polys.getNumGeometries(); i++) { Polygon candpoly = (Polygon) polys.getGeometryN(i); if (polygon.contains(candpoly.getInteriorPoint())) { output.add(candpoly); } } return polygon.getFactory().createGeometryCollection( GeometryFactory.toGeometryArray(output)); }  @DescribeProcess(title = "Contains Test", description = "Tests if no points of the second geometry lie in the exterior of the first geometry and at least one point of the interior of second geometry lies in the interior of first geometry.") @DescribeResult(description = "True if the first input contains the second input") static boolean contains(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry, tested to be contained in first geometry") Geometry b); @DescribeProcess(title = "Empty Test", description = "Tests if a geometry contains no vertices.") @DescribeResult(description = "True if the input is empty") static boolean isEmpty(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Length", description = "Returns the total length of all line segments in a geometry. Measurement is given in the source units, so geographic coordinates are not recommended.") @DescribeResult(description = "Total perimeter of the geometry") static double length(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Intersects Test", description = "Tests if two geometries intersect.") @DescribeResult(description = "True if the inputs intersect") static boolean intersects(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Valid Test", description = "Tests if a geometry is topologically valid.") @DescribeResult(description = "True if the input is valid") static boolean isValid(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Geometry Type", description = "Returns the name of a geometry's type. Values are one of POINT, LINESTRING, POLYGON, MULTIPOINT, MULTILINESTRING, MULTIPOLYGON, GEOMETRYCOLLECTION.") @DescribeResult(description = "The name of the geometry type") static String geometryType(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Number of Points", description = "Returns the number of vertices in a given geometry.") @DescribeResult(description = "Total number of vertices") static int numPoints(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Simple Test", description = "Tests if a geometry is topologically simple. Points, polygons, closed line strings, and linear rings are always simple. Other geometries are considered simple if no two points are identical.") @DescribeResult(description = "True if the input is simple") static boolean isSimple(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Distance", description = "Returns the minimum distance between two geometries. Measurement is given in the input units, so geographic coordinates are not recommended.") @DescribeResult(description = "Distance between the two input geometries") static double distance(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Within Distance Test", description = "Tests if the minimum distance between two geometries is less than a tolerance value.") @DescribeResult(description = "True if the inputs are within the specified distance") static boolean isWithinDistance(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b,
            @DescribeParameter(name = "distance", description = "Distance tolerance, in units of the input geometry") double distance); @DescribeProcess(title = "Area", description = "Returns the area of a geometry, in the units of the geometry. Assumes a Cartesian plane, so this process is only recommended for non-geographic CRSes.") @DescribeResult(description = "Area of the input geometry") static double area(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Centroid", description = "Returns the geometric centroid of a geometry. Output is a single point. The centroid point may be located outside the geometry.") @DescribeResult(description = "Centroid of the input geometry") static Geometry centroid(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Interior Point", description = "Returns a point that lies inside a geometry if possible, or that lies on its boundary.") @DescribeResult(description = "Interior point") static Geometry interiorPoint(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Dimension", description = "Returns the largest dimension of a geometry or geometry collection: 0 for point, 1 for line, 2 for polygon.") @DescribeResult(description = "Dimension of the input geometry") static int dimension(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Boundary", description = "Returns a geometry boundary. For polygons, returns a linear ring or multi-linestring equal to the boundary of the polygon(s). For linestrings, returns a multipoint equal to the endpoints of the linestring. For points, returns an empty geometry collection.") @DescribeResult(description = "Boundary of the input geometry") static Geometry boundary(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Envelope", description = "Returns the smallest bounding box polygon that contains a geometry. For a point geometry, returns the same point.") @DescribeResult(description = "Envelope of the input geometry") static Geometry envelope(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Disjoint Test", description = "Tests if two geometries do not have any points in common.") @DescribeResult(description = "True if the inputs are disjoint") static boolean disjoint(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Touches Test", description = "Tests if two geometries have at least one boundary point in common, but share no interior points.") @DescribeResult(description = "True if the inputs touch") static boolean touches(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Crosses Test", description = "Tests if two geometries have some, but not all, interior points in common.") @DescribeResult(description = "True if the inputs cross") static boolean crosses(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Within Test", description = "Tests if the first geometry is contained in the second geometry.") @DescribeResult(description = "True if the first input is within the second input") static boolean within(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Overlaps Test", description = "Tests if two geometries share some but not all interior points. Points or lines will always return False.") @DescribeResult(description = "True if the inputs overlap") static boolean overlaps(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Relate Test", description = "Tests if the spatial relationship between two geometries matches the given DE-9IM intersection matrix pattern. The pattern is given in the form [II][IB][IE][BI][BB][BE][EI][EB][EE] where I=interior, B=boundary, and E=exterior. Pattern symbols can be 2, 1, 0, F or *.") @DescribeResult(description = "True if the inputs have the given relationship") static boolean relatePattern(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "First input geometry") Geometry b,
            @DescribeParameter(name = "Relate pattern", description = "Intersection matrix pattern") String pattern); @DescribeProcess(title = "Relate Matrix String", description = "Returns the DE-9IM intersection matrix string for the spatial relationship between the input geometries. The matrix string is in the form [II][IB][IE][BI][BB][BE][EI][EB][EE] where I=interior, B=boundary, and E=exterior. Matrix symbols are 2, 1, 0 or F.") @DescribeResult(description = "Intersection matrix string") static String relate(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Buffer", description = "Returns a polygonal geometry representing the input geometry enlarged by a given distance around its exterior.") @DescribeResult(description = "Buffered geometry") static Geometry buffer(
            @DescribeParameter(name = "geom", description = "Input geometry") Geometry geom,
            @DescribeParameter(name = "distance", description = "Distance to buffer the input geometry, in the units of the geometry") double distance,
            @DescribeParameter(name = "quadrantSegments", description = "Number determining the style and smoothness of buffer corners. Positive numbers create round corners with that number of segments per quarter-circle, 0 creates flat corners.", min = 0) Integer quadrantSegments,
            @DescribeParameter(name = "capStyle", description = "Style for the buffer end caps. Values are: Round - rounded ends (default), Flat - flat ends; Square - square ends.", min = 0) BufferCapStyle capStyle); @DescribeProcess(title = "Convex Hull", description = "Returns the smallest convex polygon that contains the entire input geometry.") @DescribeResult(description = "Convex hull of input geometry") static Geometry convexHull(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom); @DescribeProcess(title = "Intersection", description = "Returns a geometry representing the points that two geometries have in common. The result may be a heterogeneous geometry collection. If no intersection, returns an empty geometry.") @DescribeResult(description = "Intersection of geometries") static Geometry intersection(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Union", description = "Returns a geometry representing all points contained in any of the geometries in a geometry collection.") @DescribeResult(description = "Union of input geometries") static Geometry union(
            @DescribeParameter(name = "geom", description = "Input geometries (minimum 2)", min = 2) Geometry... geoms); @DescribeProcess(title = "Difference", description = "Returns a geometry representing the points that are contained in a geometry but not contained in a second geometry. The result may be a heterogeneous geometry collection.") @DescribeResult(description = "Geometry representing the difference of the input geometries") static Geometry difference(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Symmetric Difference", description = "Returns a geometry representing the points contained in either one of two geometries but not in both. The result may be a heterogeneous geometry collection.") @DescribeResult(description = "Symmetric difference of the two geometries") static Geometry symDifference(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Exactly Equal Test with Tolerance", description = "Tests if two geometries are identical on a vertex-by-vertex basis, up to a vertex distance tolerance.") @DescribeResult(description = "True if the geometries are vertex-identical within tolerance") static boolean equalsExactTolerance(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b, @DescribeParameter(name = "tolerance", description = "Tolerance distance for vertex equality test") double tolerance); @DescribeProcess(title = "Exactly Equal Test", description = "Tests if two geometries are identical on a vertex-by-vertex basis.") @DescribeResult(description = "True if the geometries are vertex-identical") static boolean equalsExact(@DescribeParameter(name = "a", description = "First input geometry") Geometry a,
            @DescribeParameter(name = "b", description = "Second input geometry") Geometry b); @DescribeProcess(title = "Geometry Count", description = "Returns the total number of elements in a geometry collection. If not a geometry collection, returns 1. If empty, returns 0.") @DescribeResult(description = "Total number of geometries") static int numGeometries(@DescribeParameter(name = "geom", description = "Input geometry") Geometry collection); @DescribeProcess(title = "Nth Geometry", description = "Returns the geometry element at a given index in a geometry collection. Indexing starts at 0.") @DescribeResult(description = "Geometry element from the geometry collection") static Geometry getGeometryN(@DescribeParameter(name = "geom", description = "Input geometry") GeometryCollection collection, @DescribeParameter(name = "index", description = "Index of geometry element (0 is first)") int index); @DescribeProcess(title = "Get X Ordinate", description = "Returns the X value (first ordinate) for point geometries. For other geometry types returns the X value of the centroid.") @DescribeResult(description = "X value of point") static double getX(@DescribeParameter(name = "geom", description = "Input point") Point point); @DescribeProcess(title = "Get Y Ordinate", description = "Returns the Y value (second ordinate) for point geometries. For other geometry types returns the Y value of the centroid.") @DescribeResult(description = "Y value of point") static double getY(@DescribeParameter(name = "geom", description = "Input point") Point point); @DescribeProcess(title = "Closed Test", description = "Tests if the initial vertex equals the final vertex in a linear geometry. Points and polygons always return True.") @DescribeResult(description = "True if the input is closed") static boolean isClosed(@DescribeParameter(name = "geom", description = "Input geometry") LineString line); @DescribeProcess(title = "Nth Point", description = "Returns a point geometry equal to the Nth vertex in a geometry as determined by a given index. First vertex has index 0.") @DescribeResult(description = "Vertex as point geometry") static Point pointN(@DescribeParameter(name = "geom", description = "Input geometry") LineString line, @DescribeParameter(name = "index", description = "Index of vertex (0 is first)") int index); @DescribeProcess(title = "Start Point", description = "Returns a point geometry equal to the first vertex of a LineString.") @DescribeResult(description = "First vertex as point geometry") static Point startPoint(@DescribeParameter(name = "geom", description = "Input line") LineString line); @DescribeProcess(title = "End Point", description = "Returns a point geometry equal to the final vertex of a LineString.") @DescribeResult(description = "Final vertex as point geometry") static Point endPoint(@DescribeParameter(name = "geom", description = "Input line") LineString line); @DescribeProcess(title = "Ring Test", description = "Tests if a geometry is both closed and simple.") @DescribeResult(description = "True if the input is a ring") static boolean isRing(@DescribeParameter(name = "geom", description = "Input geometry") LineString line); @DescribeProcess(title = "Exterior Ring", description = "Returns the exterior ring of a polygonal geometry.") @DescribeResult(description = "Exterior ring of geometry") static Geometry exteriorRing(@DescribeParameter(name = "geom", description = "Input geometry") Polygon polygon); @DescribeProcess(title = "Interior Ring Count", description = "Returns the total number of interior rings in a polygonal geometry. Points and lines return 0.") @DescribeResult(description = "Total number of interior rings") static int numInteriorRing(@DescribeParameter(name = "geom", description = "Input geometry") Polygon polygon); @DescribeProcess(title = "Nth Interior Ring", description = "Returns a linear ring from a polygon containing interior rings (holes) determined by a given index. First interior ring has index 0. If no interior rings, returns null.") @DescribeResult(description = "Interior ring as a linear ring") static Geometry interiorRingN(@DescribeParameter(name = "geom", description = "Input polygon with interior ring") Polygon polygon, @DescribeParameter(name = "index", description = "Index of interior ring (0 is first)") int index); @DescribeProcess(title = "Simplify", description = "Returns a geometry that has been simplified (reduced in vertices) according to the Douglas-Peucker algorithm.") @DescribeResult(description = "Simplified geometry") static Geometry simplify(@DescribeParameter(name = "geom", description="Input geometry") Geometry geom,
            @DescribeParameter(name = "distance", description="Simplification distance tolerance, in units of the input geometry") double distance); @DescribeProcess(title = "Densify", description = "Returns a spatially equivalent geometry with vertices added to ensure line segments are no longer than a given distance.") @DescribeResult(description = "Densified geometry") static Geometry densify(@DescribeParameter(name = "geom", description = "Input geometry") Geometry geom,
            @DescribeParameter(name = "distance", description = "The maximum segment length in the result, in the units of the geometry") double distance); @DescribeProcess(title = "Polygonize", description = "Creates a set of polygons from linestrings delineating them. The linestrings must be corrctly noded (i.e. touch only at endpoints).") @DescribeResult(description = "The collection of created polygons") static Geometry polygonize(
            @DescribeParameter(name = "geom", description = "Linework to polygonize") Geometry geom); @DescribeProcess(title = "Split Polygon", description = "Splits a polygon by a linestring") @DescribeResult(description = "The collection of split polygons") static Geometry splitPolygon(
            @DescribeParameter(name = "polygon", description = "Polygon to split") Geometry polygon,
            @DescribeParameter(name = "line", description = "Linestring to split by") LineString line); @DescribeProcess(title = "Reproject Geometry", description = "Reprojects a given geometry into a supplied coordinate reference system.") @DescribeResult(name = "result", description = "Reprojected geometry") static Geometry reproject(
        @DescribeParameter(name = "geometry", description = "Input geometry") Geometry geometry,
        @DescribeParameter(name = "sourceCRS", min = 0, description = "Coordinate reference system of input geometry") CoordinateReferenceSystem sourceCRS,
        @DescribeParameter(name = "targetCRS", min = 0, description = "Target coordinate reference system to use for reprojection") CoordinateReferenceSystem targetCRS);  }
@Test public void testSplitPolygon() throws Exception { Geometry poly = wktRdr.read("POLYGON ((100 100, 200 200, 200 100, 100 100))"); LineString line = (LineString) wktRdr.read("LINESTRING (150 200, 150 50)"); Geometry output = GeometryFunctions.splitPolygon(poly, line); Geometry expectedOutput = wktRdr.read("GEOMETRYCOLLECTION (POLYGON ((150 100, 100 100, 150 150, 150 100)), POLYGON ((150 150, 200 200, 200 100, 150 100, 150 150)))"); assertTrue(output.norm().equalsExact(expectedOutput.norm())); }