[geos-commits] [SCM] GEOS branch svn-3.6 updated. 287b45da2cbaaa70fc27c333b496e02bd161b1d4

git at osgeo.org git at osgeo.org
Mon Jan 28 14:05:19 PST 2019


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GEOS".

The branch, svn-3.6 has been updated
       via  287b45da2cbaaa70fc27c333b496e02bd161b1d4 (commit)
      from  d137633afbfc407efc7c8ca24ac65b0051693f99 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 287b45da2cbaaa70fc27c333b496e02bd161b1d4
Author: Paul Ramsey <pramsey at cleverelephant.ca>
Date:   Mon Jan 28 14:05:01 2019 -0800

    Invalid union result from valid polygon inputs
    Closes #838

diff --git a/NEWS b/NEWS
index 16d5a1f..cba7eb7 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@ Changes in 3.6.4
     GEOSisValidDetail (#941, Dan Baston)
   - Envelope constructor use strtod (#875)
   - Polygon build failure in Overlay difference (#789 Paul Ramsey)
+  - Invalid union result from valid polygon inputs (#838)
 
 
 Changes in 3.6.3
diff --git a/src/noding/SingleInteriorIntersectionFinder.cpp b/src/noding/SingleInteriorIntersectionFinder.cpp
index 9f05cb1..050f8b7 100644
--- a/src/noding/SingleInteriorIntersectionFinder.cpp
+++ b/src/noding/SingleInteriorIntersectionFinder.cpp
@@ -7,12 +7,12 @@
  *
  * This is free software; you can redistribute and/or modify it under
  * the terms of the GNU Lesser General Licence as published
- * by the Free Software Foundation. 
+ * by the Free Software Foundation.
  * See the COPYING file for more information.
  *
  **********************************************************************
  *
- * Last port: noding/SingleInteriorIntersectionFinder.java rev. ??? (JTS-1.8)
+ * Last port: noding/SingleInteriorIntersectionFinder.java rev. 2019-01-28
  *
  **********************************************************************/
 
@@ -23,6 +23,38 @@
 
 using namespace geos::geom;
 
+
+namespace { // anonymous
+
+	/* private in JTS */
+	bool isEndInteriorIntersection(
+	        const Coordinate& p0, bool isEnd0,
+	        const Coordinate& p1, bool isEnd1)
+	{
+		if (isEnd0 && isEnd1) return false;
+		if (p0.equals2D(p1)) {
+			return true;
+		}
+		return false;
+	}
+
+	/* public in JTS */
+	bool isEndInteriorIntersection(
+	        const Coordinate& p00, const Coordinate& p01,
+	        const Coordinate& p10, const Coordinate& p11,
+	        bool isEnd00, bool isEnd01,
+	        bool isEnd10, bool isEnd11)
+	{
+		if (isEndInteriorIntersection(p00, isEnd00, p10, isEnd10)) return true;
+		if (isEndInteriorIntersection(p00, isEnd00, p11, isEnd11)) return true;
+		if (isEndInteriorIntersection(p01, isEnd01, p10, isEnd10)) return true;
+		if (isEndInteriorIntersection(p01, isEnd01, p11, isEnd11)) return true;
+		return false;
+	}
+
+} // anonymous namespace
+
+
 namespace geos {
 namespace noding { // geos.noding
 
@@ -37,7 +69,7 @@ SingleInteriorIntersectionFinder::processIntersections(
 	// short-circuit if intersection already found
 	if (hasIntersection())
 		return;
-	
+
 	// don't bother intersecting a segment with itself
 	if (e0 == e1 && segIndex0 == segIndex1) return;
 
@@ -45,23 +77,29 @@ SingleInteriorIntersectionFinder::processIntersections(
 	const Coordinate& p01 = e0->getCoordinate(segIndex0 + 1);
 	const Coordinate& p10 = e1->getCoordinate(segIndex1);
 	const Coordinate& p11 = e1->getCoordinate(segIndex1 + 1);
-  
+
+	bool isEnd00 = segIndex0 == 0;
+	bool isEnd01 = segIndex0 + 2 == static_cast<int>(e0->size());
+	bool isEnd10 = segIndex1 == 0;
+	bool isEnd11 = segIndex1 + 2 == static_cast<int>(e1->size());
+
 	li.computeIntersection(p00, p01, p10, p11);
 //if (li.hasIntersection() && li.isProper()) Debug.println(li);
+	bool isProperInteriorInt = li.hasIntersection() &&
+	                           li.isInteriorIntersection();
+	bool isEndInteriorInt = (e0 != e1) && isEndInteriorIntersection(
+	         p00, p01, p10, p11, isEnd00, isEnd01, isEnd10, isEnd11);
 
-	if (li.hasIntersection())
-	{
-		if (li.isInteriorIntersection())
-		{
-			intSegments.resize(4);
-			intSegments[0] = p00;
-			intSegments[1] = p01;
-			intSegments[2] = p10;
-			intSegments[3] = p11;
-	
-			interiorIntersection = li.getIntersection(0);
-		}
+	if (isProperInteriorInt || isEndInteriorInt) {
+		// found an intersection!
+		intSegments.resize(4);
+		intSegments[0] = p00;
+		intSegments[1] = p01;
+		intSegments[2] = p10;
+		intSegments[3] = p11;
+		interiorIntersection = li.getIntersection(0);
 	}
+
 }
 
 
diff --git a/tests/xmltester/CMakeLists.txt b/tests/xmltester/CMakeLists.txt
index 3ee3eea..6a0e095 100644
--- a/tests/xmltester/CMakeLists.txt
+++ b/tests/xmltester/CMakeLists.txt
@@ -60,6 +60,7 @@ if(GEOS_ENABLE_TESTS)
     ${XMLTESTS_DIR}/ticket/bug188.xml
     ${XMLTESTS_DIR}/ticket/bug244.xml
     ${XMLTESTS_DIR}/ticket/bug275.xml
+    ${XMLTESTS_DIR}/ticket/bug838.xml
     ${XMLTESTS_DIR}/general/TestBoundary.xml
     ${XMLTESTS_DIR}/general/TestBuffer.xml
     ${XMLTESTS_DIR}/general/TestBufferMitredJoin.xml
diff --git a/tests/xmltester/Makefile.am b/tests/xmltester/Makefile.am
index 37928b0..00c1dc4 100644
--- a/tests/xmltester/Makefile.am
+++ b/tests/xmltester/Makefile.am
@@ -44,6 +44,7 @@ SAFE_XMLTESTS=$(srcdir)/tests/testLeaksBig.xml \
 	$(srcdir)/tests/ticket/bug615.xml \
 	$(srcdir)/tests/ticket/bug716.xml \
 	$(srcdir)/tests/ticket/bug837.xml \
+	$(srcdir)/tests/ticket/bug838.xml \
 	$(srcdir)/tests/general/TestBoundary.xml \
 	$(srcdir)/tests/general/TestBuffer.xml \
 	$(srcdir)/tests/general/TestBufferMitredJoin.xml \
diff --git a/tests/xmltester/tests/ticket/bug838.xml b/tests/xmltester/tests/ticket/bug838.xml
new file mode 100644
index 0000000..1d21cd0
--- /dev/null
+++ b/tests/xmltester/tests/ticket/bug838.xml
@@ -0,0 +1,20 @@
+<run>
+<precisionModel type="FLOATING" />
+<case>
+<desc>
+Union of two valid polygons resulting in an invalid geometry
+See https://trac.osgeo.org/geos/ticket/838
+</desc>
+<a>
+00000000060000000200000000030000000100000005412CD75B00000000413D8F0966666667412CD75933333333413D8F6D80000000412CD82166666667413D8F6E4CCCCCCD412CD82500000000413D8EA61999999A412CD75B00000000413D8F096666666700000000030000000100000005412CD82500000001413D8EA61999999A412CD82333333334413D8F0A33333333412CD8EB66666666413D8F0B19999999412CD8ED33333333413D8EA700000001412CD82500000001413D8EA61999999A
+</a>
+<b>
+00000000030000000100000007412CD9D4D50CE8F7413D8EA7FBC39C12412CD8ED33333333413D8EA700000000412CD8EB66666667413D8F0B1999999A412CD82333333333413D8F0A33333333412CD82166666667413D8F6E4CCCCCCD412CD9B1CCCCCCCD413D8F701999999A412CD9D4D50CE8F7413D8EA7FBC39C12
+</b>
+<test>
+  <op name="union" arg1="A" arg2="B">
+0103000000010000000A000000000000005BD72C4167666666098F3D413333333359D72C41000000806D8F3D416766666621D82C41CDCCCC4C6E8F3D41CDCCCCCCB1D92C419A999919708F3D41F7E80CD5D4D92C41129CC3FBA78E3D4133333333EDD82C4100000000A78E3D410100000025D82C419A999919A68E3D413333333323D82C41333333330A8F3D410000000025D82C419A999919A68E3D41000000005BD72C4167666666098F3D41
+  </op>
+</test>
+</case>
+</run>

-----------------------------------------------------------------------

Summary of changes:
 NEWS                                            |  1 +
 src/noding/SingleInteriorIntersectionFinder.cpp | 70 +++++++++++++++++++------
 tests/xmltester/CMakeLists.txt                  |  1 +
 tests/xmltester/Makefile.am                     |  1 +
 tests/xmltester/tests/ticket/bug838.xml         | 20 +++++++
 5 files changed, 77 insertions(+), 16 deletions(-)
 create mode 100644 tests/xmltester/tests/ticket/bug838.xml


hooks/post-receive
-- 
GEOS


More information about the geos-commits mailing list