From 10a9fafc50ae263c5d9fc8bb92655e1999758df8 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Sun, 24 Nov 2024 17:32:22 -0800 Subject: [PATCH] Improve RelateNG performance for A/L cases in prepared predicates --- .../geos/operation/relateng/RelateGeometry.h | 4 ++++ src/operation/relateng/TopologyComputer.cpp | 15 ++++++++----- .../operation/relateng/RelateNGGCTest.cpp | 13 ++++++++++- .../xmltester/tests/general/TestRelateGC.xml | 22 +++++++++++++++++++ 4 files changed, 48 insertions(+), 6 deletions(-) diff --git a/include/geos/operation/relateng/RelateGeometry.h b/include/geos/operation/relateng/RelateGeometry.h index 09753b682e..d1282d52f2 100644 --- a/include/geos/operation/relateng/RelateGeometry.h +++ b/include/geos/operation/relateng/RelateGeometry.h @@ -179,6 +179,10 @@ class GEOS_DLL RelateGeometry { case Dimension::A: return hasAreas; } return false; + } + + bool hasAreaAndLine() const { + return hasAreas && hasLines; } /** diff --git a/src/operation/relateng/TopologyComputer.cpp b/src/operation/relateng/TopologyComputer.cpp index 0b6782e42a..e911bc6f8d 100644 --- a/src/operation/relateng/TopologyComputer.cpp +++ b/src/operation/relateng/TopologyComputer.cpp @@ -132,11 +132,16 @@ TopologyComputer::getDimension(bool isA) const bool TopologyComputer::isSelfNodingRequired() const { - if (predicate.requireSelfNoding()) { - if (geomA.isSelfNodingRequired() || - geomB.isSelfNodingRequired()) - return true; - } + if (! predicate.requireSelfNoding()) + return false; + + if (geomA.isSelfNodingRequired()) + return true; + + //-- if B is a mixed GC with A and L require full noding + if (geomB.hasAreaAndLine()) + return true; + return false; } diff --git a/tests/unit/operation/relateng/RelateNGGCTest.cpp b/tests/unit/operation/relateng/RelateNGGCTest.cpp index c8405328a5..7e78401c20 100644 --- a/tests/unit/operation/relateng/RelateNGGCTest.cpp +++ b/tests/unit/operation/relateng/RelateNGGCTest.cpp @@ -320,6 +320,10 @@ void object::test<23> () std::string a = "POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))"; std::string b = "GEOMETRYCOLLECTION (POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0)), MULTIPOINT ((0 2), (0 5)))"; checkEquals(a, b, true); + checkContainsWithin(a, b, true); + checkCoversCoveredBy(a, b, true); + checkContainsWithin(b, a, true); + checkCoversCoveredBy(b, a, true); } @@ -331,6 +335,10 @@ void object::test<24> () std::string a = "POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))"; std::string b = "GEOMETRYCOLLECTION (POLYGON ((0 0, 10 0, 10 10, 0 10, 0 0)), LINESTRING (0 2, 0 5))"; checkEquals(a, b, true); + checkContainsWithin(a, b, true); + checkCoversCoveredBy(a, b, true); + checkContainsWithin(b, a, true); + checkCoversCoveredBy(b, a, true); } @@ -341,7 +349,10 @@ void object::test<25> () std::string a = "POLYGON ((0 0, 0 10, 10 10, 10 0, 0 0))"; std::string b = "GEOMETRYCOLLECTION (POLYGON((0 0, 10 0, 10 10, 0 10, 0 0)),LINESTRING(0 2, 0 5, 5 5))"; checkEquals(a, b, true); -} + checkContainsWithin(a, b, true); + checkCoversCoveredBy(a, b, true); + checkContainsWithin(b, a, true); + checkCoversCoveredBy(b, a, true);} diff --git a/tests/xmltester/tests/general/TestRelateGC.xml b/tests/xmltester/tests/general/TestRelateGC.xml index f67b789a0a..a83444a013 100644 --- a/tests/xmltester/tests/general/TestRelateGC.xml +++ b/tests/xmltester/tests/general/TestRelateGC.xml @@ -574,6 +574,17 @@ GEOMETRYCOLLECTION (POLYGON ((1 9, 5 9, 6 6, 1 5, 1 9), (2 6, 4 8, 6 6, 2 6)), P false false true + + true + true + true + false + false + true + true + false + false + true @@ -596,6 +607,17 @@ GEOMETRYCOLLECTION (POLYGON ((1 9, 5 9, 6 6, 1 5, 1 9), (2 6, 4 8, 6 6, 2 6)), P false false true + + true + true + true + false + false + true + true + false + false + true