Skip to content

Commit

Permalink
Port JTS locationtech/jts#756 to match
Browse files Browse the repository at this point in the history
IsValidReason more closely to historic reasons for self-intersecting
polygons.
  • Loading branch information
pramsey committed Jul 13, 2021
1 parent 917aeec commit 1bfc5b2
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 3 deletions.
5 changes: 3 additions & 2 deletions src/operation/valid/PolygonIntersectionAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ PolygonIntersectionAnalyzer::findInvalidIntersection(
return TopologyValidationError::oNoInvalidIntersection;
}

bool isSameSegString = (ss0 == ss1);

/**
* Check for an intersection in the interior of both segments.
* Collinear intersections by definition contain an interior intersection.
Expand All @@ -89,7 +91,6 @@ PolygonIntersectionAnalyzer::findInvalidIntersection(
* (since they are not collinear).
* This is valid.
*/
bool isSameSegString = ss0 == ss1;
bool isAdjacentSegments = isSameSegString && isAdjacentInRing(ss0, segIndex0, segIndex1);
// Assert: intersection is an endpoint of both segs
if (isAdjacentSegments) return TopologyValidationError::oNoInvalidIntersection;
Expand All @@ -99,7 +100,7 @@ PolygonIntersectionAnalyzer::findInvalidIntersection(
* So the intersection is invalid.
*/
if (isSameSegString && ! isInvertedRingValid) {
return TopologyValidationError::eSelfIntersection;
return TopologyValidationError::eRingSelfIntersection;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/unit/capi/GEOSisValidDetailTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ void object::test<4>
geom1_ = GEOSGeomFromWKT("POLYGON((0 1, -10 10, 10 10, 0 1, 4 6, -4 6, 0 1))");
int r = GEOSisValidDetail(geom1_, 0, &reason_, &loc_);
ensure_equals(r, 0); // invalid
ensure_equals(std::string(reason_), std::string("Self-intersection"));
ensure_equals(std::string(reason_), std::string("Ring Self-intersection"));
ensure_equals(toWKT(loc_), "POINT (0 1)");
}

Expand Down
62 changes: 62 additions & 0 deletions tests/unit/operation/valid/IsValidOpTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,16 @@ void object::test<8> ()
"POLYGON ((10 90, 90 10, 90 90, 10 10, 10 90))");
}

// testInvalidPolygonInverted
template<>
template<>
void object::test<22> ()
{
checkInvalid(
TopologyValidationError::eRingSelfIntersection,
"POLYGON ((70 250, 40 500, 100 400, 70 250, 80 350, 60 350, 70 250))");
}

// testSimplePolygonHole
template<>
template<>
Expand Down Expand Up @@ -309,6 +319,58 @@ void object::test<21> ()
"MULTIPOLYGON (((20 380, 420 380, 420 20, 20 20, 20 380), (220 340, 180 240, 60 200, 140 100, 340 60, 300 240, 220 340)), ((60 200, 340 60, 220 340, 60 200)))");
}

// testLineString
template<>
template<>
void object::test<23> ()
{
checkInvalid(
"LINESTRING(0 0, 0 0)");
}

// testLinearRingTriangle
template<>
template<>
void object::test<24> ()
{
checkValid(
"LINEARRING (100 100, 150 200, 200 100, 100 100)");
}

// testLinearRingSelfCrossing
template<>
template<>
void object::test<25> ()
{
checkInvalid(TopologyValidationError::eRingSelfIntersection,
"LINEARRING (150 100, 300 300, 100 300, 350 100, 150 100)");
}

// testLinearRingSelfCrossing2
template<>
template<>
void object::test<26> ()
{
checkInvalid(TopologyValidationError::eRingSelfIntersection,
"LINEARRING (0 0, 100 100, 100 0, 0 100, 0 0)");
}

//
template<>
template<>
void object::test<27> ()
{
checkInvalid(TopologyValidationError::eRingSelfIntersection,
"POLYGON ((70 250, 40 500, 100 400, 70 250, 80 350, 60 350, 70 250))");
}

template<>
template<>
void object::test<28> ()
{
checkInvalid(TopologyValidationError::eSelfIntersection,
"POLYGON ((70 250, 70 500, 80 400, 40 400, 70 250))");
}


} // namespace tut

0 comments on commit 1bfc5b2

Please sign in to comment.