IntersectionFeatureCollection implements VectorProcess { static double getIntersectionArea(Geometry first, CoordinateReferenceSystem firstCRS, Geometry second, CoordinateReferenceSystem secondCRS, boolean divideFirst) { if (firstCRS == null || secondCRS == null) throw new IllegalArgumentException("CRS cannot be set to null"); if (!Polygon.class.isAssignableFrom(first.getClass()) && !MultiPolygon.class.isAssignableFrom(first.getClass())) throw new IllegalArgumentException("first geometry must be poligonal"); if (!Polygon.class.isAssignableFrom(second.getClass()) && !MultiPolygon.class.isAssignableFrom(second.getClass())) throw new IllegalArgumentException("second geometry must be poligonal"); try { Geometry firstTargetGeometry = reprojectAndDensify(first, firstCRS, null); Geometry secondTargetGeometry = reprojectAndDensify(second, firstCRS, null); double numeratorArea = (double) (firstTargetGeometry.intersection(secondTargetGeometry)) .getArea(); if (divideFirst) { double denom = firstTargetGeometry.getArea(); if (denom!=0) return numeratorArea / denom; return 0; } double denom = secondTargetGeometry.getArea(); if (denom!=0) return numeratorArea / denom; return 0; } catch (Exception e) { e.printStackTrace(); return -1; } }  @DescribeResult(description = "Output feature collection") SimpleFeatureCollection execute(
            @DescribeParameter(name = "first feature collection", description = "First feature collection") SimpleFeatureCollection firstFeatures,
            @DescribeParameter(name = "second feature collection", description = "Second feature collection") SimpleFeatureCollection secondFeatures,
            @DescribeParameter(name = "first attributes to retain", collectionType = String.class, min = 0, description = "First feature collection attribute to include") List<String> firstAttributes,
            @DescribeParameter(name = "second attributes to retain", collectionType = String.class, min = 0, description = "Second feature collection attribute to include") List<String> sndAttributes,
            @DescribeParameter(name = "intersectionMode", min = 0, description = "Specifies geometry computed for intersecting features.  INTERSECTION (default) computes the spatial intersection of the inputs. FIRST copies geometry A.  SECOND copies geometry B.", defaultValue="INTERSECTION") IntersectionMode intersectionMode,
            @DescribeParameter(name = "percentagesEnabled", min = 0, description = "Indicates whether to output feature area percentages (attributes percentageA and percentageB)") Boolean percentagesEnabled,
            @DescribeParameter(name = "areasEnabled", min = 0, description = "Indicates whether to output feature areas (attributes areaA and areaB)") Boolean areasEnabled);  }
@Test public void testGetIntersectionAreaRate() { logger.info("Running testGetIntersectionAreaRate ..."); CoordinateReferenceSystem sourceCRS = org.geotools.referencing.crs.DefaultGeographicCRS.WGS84; Polygon worldPolygon = createRectangularPolygonByCoords(-180,180,-90, 90, sourceCRS); Polygon coloradoPolygon = createRectangularPolygonByCoords(-102,-109,37, 41, sourceCRS); double calculatedRate = IntersectionFeatureCollection.getIntersectionArea(worldPolygon, sourceCRS,coloradoPolygon , sourceCRS, true); double expectedRate = COLORADOAREA / WORLDAREA; assertEquals(0, (expectedRate - calculatedRate) / expectedRate, 0.01); }