Skip to content

Commit

Permalink
Skip over testing empty distances for mixed collections. Closes #979
Browse files Browse the repository at this point in the history
  • Loading branch information
pramsey committed Nov 2, 2023
1 parent 755b136 commit 5a3d493
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 6 deletions.
16 changes: 11 additions & 5 deletions src/operation/distance/DistanceOp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ DistanceOp::computeMinDistanceLines(
{
for(const LineString* line0 : lines0) {
for(const LineString* line1 : lines1) {

if (line0->isEmpty() || line1->isEmpty())
continue;

computeMinDistance(line0, line1, locGeom);
if(minDistance <= terminateDistance) {
return;
Expand All @@ -378,13 +382,11 @@ DistanceOp::computeMinDistancePoints(
array<unique_ptr<GeometryLocation>, 2> & locGeom)
{
for(const Point* pt0 : points0) {
if (pt0->isEmpty()) {
continue;
}
for(const Point* pt1 : points1) {
if (pt1->isEmpty()) {

if (pt1->isEmpty() || pt0->isEmpty())
continue;
}

double dist = pt0->getCoordinate()->distance(*(pt1->getCoordinate()));

#if GEOS_DEBUG
Expand Down Expand Up @@ -418,6 +420,10 @@ DistanceOp::computeMinDistanceLinesPoints(
{
for(const LineString* line : lines) {
for(const Point* pt : points) {

if (line->isEmpty() || pt->isEmpty())
continue;

computeMinDistance(line, pt, locGeom);
if(minDistance <= terminateDistance) {
return;
Expand Down
68 changes: 68 additions & 0 deletions tests/unit/operation/distance/DistanceOpTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,11 @@ void object::test<21>()
ensure_equals(g1->distance(g2.get()), 1.9996999774966246);
}

//
// Variations on a theme: testing EMPTY and collections with EMPTY
//

// Ignoring empty component
template<>
template<>
void object::test<22>()
Expand All @@ -576,6 +581,69 @@ void object::test<22>()
ensure_equals(g2->distance(g1.get()), 1);
}

// Empty is same as empty so zero...?
template<>
template<>
void object::test<23>()
{
auto g1 = wktreader.read("POINT EMPTY");
auto g2 = wktreader.read("LINESTRING EMPTY");

ensure(g1 != nullptr && g2 != nullptr);
ensure_equals(g1->distance(g2.get()), 0);
ensure_equals(g2->distance(g1.get()), 0);
}

template<>
template<>
void object::test<24>()
{
auto g1 = wktreader.read("GEOMETRYCOLLECTION(POINT EMPTY, LINESTRING EMPTY)");
auto g2 = wktreader.read("LINESTRING EMPTY");

ensure(g1 != nullptr && g2 != nullptr);
ensure_equals(g1->distance(g2.get()), 0);
ensure_equals(g2->distance(g1.get()), 0);
}

// But ignore empty if there's a real distance?
template<>
template<>
void object::test<25>()
{
auto g1 = wktreader.read("GEOMETRYCOLLECTION(LINESTRING EMPTY, POINT(2 1))");
auto g2 = wktreader.read("POINT(1 1)");

ensure(g1 != nullptr && g2 != nullptr);
ensure_equals(g1->distance(g2.get()), 1);
ensure_equals(g2->distance(g1.get()), 1);
}

template<>
template<>
void object::test<26>()
{
auto g1 = wktreader.read("GEOMETRYCOLLECTION(POINT(-2 0), POINT EMPTY)");
auto g2 = wktreader.read("GEOMETRYCOLLECTION(POINT(1 0),LINESTRING(0 0,1 0))");

ensure(g1 != nullptr && g2 != nullptr);
ensure_equals(g1->distance(g2.get()), 2);
ensure_equals(g2->distance(g1.get()), 2);
}

template<>
template<>
void object::test<27>()
{
auto g1 = wktreader.read("GEOMETRYCOLLECTION(POINT EMPTY)");
auto g2 = wktreader.read("GEOMETRYCOLLECTION(POINT(1 0))");

ensure(g1 != nullptr && g2 != nullptr);
ensure_equals(g1->distance(g2.get()), 0);
ensure_equals(g2->distance(g1.get()), 0);
}


// TODO: finish the tests by adding:
// LINESTRING - *all*
// MULTILINESTRING - *all*
Expand Down
67 changes: 66 additions & 1 deletion tests/xmltester/tests/general/TestDistance.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,62 +6,127 @@
<a> POINT(10 10) </a>
<b> POINT EMPTY </b>
<test><op name="distance" arg1="A" arg2="B"> 0.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 0.0 </op></test>
</case>

<case>
<desc>PP - point to point</desc>
<a> POINT(10 10) </a>
<b> POINT (10 0) </b>
<test><op name="distance" arg1="A" arg2="B"> 10.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 10.0 </op></test>
</case>

<case>
<desc>PP - point to multipoint</desc>
<a> POINT(10 10) </a>
<b> MULTIPOINT ((10 0), (30 30)) </b>
<test><op name="distance" arg1="A" arg2="B"> 10.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 10.0 </op></test>
</case>

<case>
<desc>PP - point to multipoint with empty element</desc>
<a> POINT(10 10) </a>
<b> MULTIPOINT ((10 0), EMPTY) </b>
<test><op name="distance" arg1="A" arg2="B"> 10.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 10.0 </op></test>
</case>

<case>
<desc>LL - line to empty line</desc>
<a> LINESTRING (0 0, 0 10) </a>
<b> LINESTRING EMPTY </b>
<test><op name="distance" arg1="A" arg2="B"> 0.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 0.0 </op></test>
</case>

<case>
<desc>LL - line to line</desc>
<a> LINESTRING (0 0, 0 10) </a>
<b> LINESTRING (10 0, 10 10) </b>
<test><op name="distance" arg1="A" arg2="B"> 10.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 10.0 </op></test>
</case>

<case>
<desc>LL - line to multiline</desc>
<a> LINESTRING (0 0, 0 10) </a>
<b> MULTILINESTRING ((10 0, 10 10), (50 50, 60 60)) </b>
<test><op name="distance" arg1="A" arg2="B"> 10.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 10.0 </op></test>
</case>

<case>
<desc>LL - line to multiline with empty element</desc>
<a> LINESTRING (0 0, 0 10) </a>
<b> MULTILINESTRING ((10 0, 10 10), EMPTY) </b>
<test><op name="distance" arg1="A" arg2="B"> 10.0 </op></test>
<test><op name="distance" arg1="B" arg2="A"> 10.0 </op></test>
</case>

<case>
<desc>PA - point to empty polygon</desc>
<a> POINT (240 160) </a>
<b> POLYGON EMPTY </b>
<test><op name="distance" arg1="A" arg2="B" > 0.0 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 0.0 </op></test>
</case>

<case>
<desc>PA - point inside polygon</desc>
<a> POINT (240 160) </a>
<b> POLYGON ((100 260, 340 180, 100 60, 180 160, 100 260)) </b>
<test><op name="distance" arg1="A" arg2="B" > 0.0 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 0.0 </op></test>
</case>

<case>
<desc>LL - crossing linestrings</desc>
<a> LINESTRING (40 300, 280 220, 60 160, 140 60) </a>
<b> LINESTRING (140 360, 260 280, 240 120, 120 160) </b>
<test><op name="distance" arg1="A" arg2="B" > 0.0 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 0.0 </op></test>
</case>

<case>
<desc>AA - overlapping polygons</desc>
<a> POLYGON ((60 260, 260 180, 100 60, 60 160, 60 260)) </a>
<b> POLYGON ((220 280, 120 160, 300 60, 360 220, 220 280)) </b>
<test><op name="distance" arg1="A" arg2="B" > 0.0 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 0.0 </op></test>
</case>

<case>
<desc>AA - disjoint polygons</desc>
<a> POLYGON ((100 320, 60 120, 240 180, 200 260, 100 320)) </a>
<b> POLYGON ((420 320, 280 260, 400 100, 420 320)) </b>
<test><op name="distance" arg1="A" arg2="B" > 71.55417527999327 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 71.55417527999327 </op></test>
</case>

<case>
<desc>mAmA - overlapping multipolygons</desc>
<a> MULTIPOLYGON (((40 240, 160 320, 40 380, 40 240)), ((100 240, 240 60, 40 40, 100 240))) </a>
<b> MULTIPOLYGON (((220 280, 120 160, 300 60, 360 220, 220 280)), ((240 380, 280 300, 420 340, 240 380))) </b>
<test><op name="distance" arg1="A" arg2="B" > 0.0 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 0.0 </op></test>
</case>

<case>
<desc>mAmA - multipolygon with empty component</desc>
<desc>mAmA - multipolygon with empty element</desc>
<a> MULTIPOLYGON (EMPTY, ((98 200, 200 200, 200 99, 98 99, 98 200))) </a>
<b> POLYGON ((300 200, 400 200, 400 100, 300 100, 300 200)) </b>
<test><op name="distance" arg1="A" arg2="B" > 100.0 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 100.0 </op></test>
</case>

<case>
<desc>GCGC - geometry collections with mixed dimensions</desc>
<a> GEOMETRYCOLLECTION (LINESTRING (10 10, 50 10), POINT (90 10)) </a>
<b> GEOMETRYCOLLECTION (POLYGON ((90 20, 60 20, 60 50, 90 50, 90 20)), LINESTRING (10 50, 30 70)) </b>
<test><op name="distance" arg1="A" arg2="B" > 10.0 </op></test>
<test><op name="distance" arg1="B" arg2="A" > 10.0 </op></test>
</case>

</run>

0 comments on commit 5a3d493

Please sign in to comment.