Skip to content

Commit

Permalink
Improve RelateNG performance for A/L cases in prepared predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
dr-jts committed Nov 25, 2024
1 parent 930487a commit 10a9faf
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
4 changes: 4 additions & 0 deletions include/geos/operation/relateng/RelateGeometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,10 @@ class GEOS_DLL RelateGeometry {
case Dimension::A: return hasAreas;
}
return false;
}

bool hasAreaAndLine() const {
return hasAreas && hasLines;
}

/**
Expand Down
15 changes: 10 additions & 5 deletions src/operation/relateng/TopologyComputer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
13 changes: 12 additions & 1 deletion tests/unit/operation/relateng/RelateNGGCTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}


Expand All @@ -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);
}


Expand All @@ -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);}



Expand Down
22 changes: 22 additions & 0 deletions tests/xmltester/tests/general/TestRelateGC.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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
<test><op name="overlaps" arg1="A" arg2="B"> false </op></test>
<test><op name="touches" arg1="A" arg2="B"> false </op></test>
<test><op name="within" arg1="A" arg2="B"> true </op></test>

<test><op name="contains" arg1="B" arg2="A"> true </op></test>
<test><op name="coveredBy" arg1="B" arg2="A"> true </op></test>
<test><op name="covers" arg1="B" arg2="A"> true </op></test>
<test><op name="crosses" arg1="B" arg2="A"> false </op></test>
<test><op name="disjoint" arg1="B" arg2="A"> false </op></test>
<test><op name="equalsTopo" arg1="B" arg2="A"> true </op></test>
<test><op name="intersects" arg1="B" arg2="A"> true </op></test>
<test><op name="overlaps" arg1="B" arg2="A"> false </op></test>
<test><op name="touches" arg1="B" arg2="A"> false </op></test>
<test><op name="within" arg1="B" arg2="A"> true </op></test>
</case>

<case>
Expand All @@ -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
<test><op name="overlaps" arg1="A" arg2="B"> false </op></test>
<test><op name="touches" arg1="A" arg2="B"> false </op></test>
<test><op name="within" arg1="A" arg2="B"> true </op></test>

<test><op name="contains" arg1="B" arg2="A"> true </op></test>
<test><op name="coveredBy" arg1="B" arg2="A"> true </op></test>
<test><op name="covers" arg1="B" arg2="A"> true </op></test>
<test><op name="crosses" arg1="B" arg2="A"> false </op></test>
<test><op name="disjoint" arg1="B" arg2="A"> false </op></test>
<test><op name="equalsTopo" arg1="B" arg2="A"> true </op></test>
<test><op name="intersects" arg1="B" arg2="A"> true </op></test>
<test><op name="overlaps" arg1="B" arg2="A"> false </op></test>
<test><op name="touches" arg1="B" arg2="A"> false </op></test>
<test><op name="within" arg1="B" arg2="A"> true </op></test>
</case>

</run>

0 comments on commit 10a9faf

Please sign in to comment.