diff --git a/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/OverlayArea.java b/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/OverlayArea.java index 8e475ebd52..57033f3f2e 100644 --- a/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/OverlayArea.java +++ b/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/OverlayArea.java @@ -268,17 +268,27 @@ private static double areaForIntersection(Coordinate a0, Coordinate a1, Coordina * For accuracy the full edge is used to provide the direction vector. */ Coordinate intPt = li.getIntersection(0); - - boolean isAenteringB = Orientation.COUNTERCLOCKWISE == Orientation.index(a0, a1, b1); - - if ( isAenteringB ) { + + if ( Orientation.CLOCKWISE == Orientation.index(a0, a1, b0) ) { + if (intPt.equals2D(a1)) { + // Intersection at vertex and A0 -> A1 is outside of the intersection area + // Area will be computed by the segment A1 -> A2 + return 0.0; + } return EdgeVector.area2Term(intPt, a0, a1, true) + EdgeVector.area2Term(intPt, b1, b0, false); } - else { + else if ( Orientation.CLOCKWISE == Orientation.index(a0, a1, b1) ) { + if (intPt.equals2D(a0)) { + // Intersection at vertex and A0 -> A1 is outside of the intersection area + // Area will be computed by the segment A(-1) -> A0 + return 0.0; + } return EdgeVector.area2Term(intPt, a1, a0, false) + EdgeVector.area2Term(intPt, b0, b1, true); } + + return 0.0; } private double areaForInteriorVertices(LinearRing ring) { diff --git a/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayArea.java b/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayArea.java index 6d386c8af5..7007c510d9 100644 --- a/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayArea.java +++ b/modules/lab/src/main/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayArea.java @@ -116,14 +116,22 @@ private double areaForIntersections(CoordinateSequence ringA, boolean isCCWA, Co * Use full edge to compute direction, for accuracy. */ Coordinate intPt = li.getIntersection(0); - - boolean isAenteringB = Orientation.COUNTERCLOCKWISE == Orientation.index(a0, a1, b1); - - if ( isAenteringB ) { + + if ( Orientation.CLOCKWISE == Orientation.index(a0, a1, b0) ) { + if (intPt.equals2D(a1)) { + // Intersection at vertex and A0 -> A1 is outside of the intersection area + // Area will be computed by the segment A1 -> A2 + continue; + } area += EdgeVector.area2Term(intPt, a0, a1, true); area += EdgeVector.area2Term(intPt, b1, b0, false); } - else { + else if ( Orientation.CLOCKWISE == Orientation.index(a0, a1, b1) ) { + if (intPt.equals2D(a0)) { + // Intersection at vertex and A0 -> A1 is outside of the intersection area + // Area will be computed by the segment A(-1) -> A0 + continue; + } area += EdgeVector.area2Term(intPt, a1, a0, false); area += EdgeVector.area2Term(intPt, b0, b1, true); } diff --git a/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/OverlayAreaTest.java b/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/OverlayAreaTest.java index 369ee013aa..250d8654a0 100644 --- a/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/OverlayAreaTest.java +++ b/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/OverlayAreaTest.java @@ -31,13 +31,24 @@ public void testDisjoint() { "POLYGON ((10 90, 40 90, 40 60, 10 60, 10 90))", "POLYGON ((90 10, 50 10, 50 50, 90 50, 90 10))"); } - - //TODO: fix this bug - public void xtestTouching() { + + public void testTouchingTwoCollinear() { checkIntersectionArea( "POLYGON ((10 90, 50 90, 50 50, 10 50, 10 90))", "POLYGON ((90 10, 50 10, 50 50, 90 50, 90 10))"); } + + public void testTouchingOneCollinear() { + checkIntersectionArea( + "POLYGON ((10 90, 50 90, 50 50, 10 50, 10 90))", + "POLYGON ((90 10, 49 10, 50 50, 90 50, 90 10))"); + } + + public void testTouchingNoneCollinear() { + checkIntersectionArea( + "POLYGON ((10 90, 50 90, 50 50, 10 52, 10 90))", + "POLYGON ((90 10, 49 10, 50 50, 90 50, 90 10))"); + } public void testRectangleAContainsB() { checkIntersectionArea( diff --git a/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayAreaTest.java b/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayAreaTest.java index c2ab1813d7..1db355703f 100644 --- a/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayAreaTest.java +++ b/modules/lab/src/test/java/org/locationtech/jts/operation/overlayarea/SimpleOverlayAreaTest.java @@ -32,13 +32,24 @@ public void testDisjoint() { "POLYGON ((90 10, 50 10, 50 50, 90 50, 90 10))"); } - //TODO: fix this bug - public void xtestTouching() { + public void testTouchingTwoCollinear() { checkIntersectionArea( "POLYGON ((10 90, 50 90, 50 50, 10 50, 10 90))", "POLYGON ((90 10, 50 10, 50 50, 90 50, 90 10))"); } + public void testTouchingOneCollinear() { + checkIntersectionArea( + "POLYGON ((10 90, 50 90, 50 50, 10 50, 10 90))", + "POLYGON ((90 10, 49 10, 50 50, 90 50, 90 10))"); + } + + public void testTouchingNoneCollinear() { + checkIntersectionArea( + "POLYGON ((10 90, 50 90, 50 50, 10 52, 10 90))", + "POLYGON ((90 10, 49 10, 50 50, 90 50, 90 10))"); + } + public void testRectangleAContainsB() { checkIntersectionArea( "POLYGON ((100 300, 300 300, 300 100, 100 100, 100 300))",