From 8f7a7df145b8fe47373c861927bbc6a0ad6be0d4 Mon Sep 17 00:00:00 2001 From: Mike Taves Date: Wed, 15 Jan 2025 13:17:31 +1300 Subject: [PATCH] Fix invalid values from CoverageUnionNG (#1226) --- src/operation/overlayng/CoverageUnion.cpp | 6 ++-- .../overlayng/CoverageUnionNGTest.cpp | 30 +++++++++++++++++++ 2 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/operation/overlayng/CoverageUnion.cpp b/src/operation/overlayng/CoverageUnion.cpp index c0c8a14581..3d860c92a7 100644 --- a/src/operation/overlayng/CoverageUnion.cpp +++ b/src/operation/overlayng/CoverageUnion.cpp @@ -33,7 +33,6 @@ namespace overlayng { // geos.operation.overlayng std::unique_ptr CoverageUnion::geomunion(const Geometry* coverage) { - double area_in = coverage->getArea(); std::unique_ptr result; // a precision model is not needed since no noding is done @@ -47,9 +46,10 @@ CoverageUnion::geomunion(const Geometry* coverage) result = OverlayNG::geomunion(coverage, nullptr, &bcn); } - double area_out = result->getArea(); + double area_in = coverage->getArea(); - if (std::abs((area_out - area_in)/area_in) > AREA_PCT_DIFF_TOL) { + if ( (area_in != 0.0) && + (std::abs((result->getArea() - area_in)/area_in) > AREA_PCT_DIFF_TOL)) { throw geos::util::TopologyException("CoverageUnion cannot process overlapping inputs."); } diff --git a/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp b/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp index aec919b207..86d8ac9486 100644 --- a/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp +++ b/tests/unit/operation/overlayng/CoverageUnionNGTest.cpp @@ -8,6 +8,7 @@ #include // std +#include #include using namespace geos::geom; @@ -31,7 +32,9 @@ struct test_coverageunionng_data { { std::unique_ptr geom = r.read(wkt); std::unique_ptr expected = r.read(wktExpected); + std::feclearexcept(FE_ALL_EXCEPT); std::unique_ptr result = CoverageUnion::geomunion(geom.get()); + ensure("FE_INVALID raised", !std::fetestexcept(FE_INVALID)); try { ensure_equals_geometry_xyzm(result.get(), expected.get()); @@ -220,4 +223,31 @@ void object::test<17>() "POLYGON M ((0 0 0, 1 0 1, 1 1 2, 0 1 3, 0 0 0))"); } +// Check empty polygon +template<> +template<> +void object::test<18>() +{ + checkUnion("POLYGON EMPTY", + "POLYGON EMPTY"); +} + +// Check empty GeometryCollection, with M dimension +template<> +template<> +void object::test<19>() +{ + checkUnion("GEOMETRYCOLLECTION M EMPTY", + "GEOMETRYCOLLECTION M EMPTY"); +} + +// Check GeometryCollection of empty polygon +template<> +template<> +void object::test<20>() +{ + checkUnion("GEOMETRYCOLLECTION( POLYGON EMPTY )", + "POLYGON EMPTY"); +} + } // namespace tut