From ae9185f7d82d04a0bde6743dd6f8d009d0271bb7 Mon Sep 17 00:00:00 2001 From: iverase Date: Fri, 2 Nov 2018 08:01:29 +0100 Subject: [PATCH] LUCENE-8550: Fix filtering of coplanar points when creating linked list on polygon tesselator --- lucene/CHANGES.txt | 3 +++ .../org/apache/lucene/geo/Tessellator.java | 23 +++---------------- .../apache/lucene/geo/TestTessellator.java | 6 +++++ 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/lucene/CHANGES.txt b/lucene/CHANGES.txt index 22b40891012..69a983445e5 100644 --- a/lucene/CHANGES.txt +++ b/lucene/CHANGES.txt @@ -238,6 +238,9 @@ Improvements: Bug Fixes: +* LUCENE-8550: Fix filtering of coplanar points when creating linked list on + polygon tesselator. (Ignacio Vera) + * LUCENE-8549: Polygon tessellator throws an error if some parts of the shape could not be processed. (Ignacio Vera) diff --git a/lucene/sandbox/src/java/org/apache/lucene/geo/Tessellator.java b/lucene/sandbox/src/java/org/apache/lucene/geo/Tessellator.java index 048125a632f..345a73b9381 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/geo/Tessellator.java +++ b/lucene/sandbox/src/java/org/apache/lucene/geo/Tessellator.java @@ -124,15 +124,11 @@ final public class Tessellator { // Link points into the circular doubly-linked list in the specified winding order if (windingOrder == polygon.getWindingOrder()) { for (int i = 0; i < polygon.numPoints(); ++i) { - if (lastNode == null || filter(polygon, i, lastNode) == false) { - lastNode = insertNode(polygon, startIndex++, i, lastNode); - } + lastNode = insertNode(polygon, startIndex++, i, lastNode); } } else { for (int i = polygon.numPoints() - 1; i >= 0; --i) { - if (lastNode == null || filter(polygon, i, lastNode) == false) { - lastNode = insertNode(polygon, startIndex++, i, lastNode); - } + lastNode = insertNode(polygon, startIndex++, i, lastNode); } } // if first and last node are the same then remove the end node and set lastNode to the start @@ -142,7 +138,7 @@ final public class Tessellator { } // Return the last node in the Doubly-Linked List - return lastNode; + return filterPoints(lastNode, null); } /** Links every hole into the outer loop, producing a single-ring polygon without holes. **/ @@ -641,19 +637,6 @@ final public class Tessellator { } while (numMerges > 1); } - /** utility method to filter a single duplicate or colinear triangle */ - private static boolean filter(final Polygon polygon, final int i, final Node node) { - final double x = polygon.getPolyLon(i); - final double y = polygon.getPolyLat(i); - final boolean equal = (x == node.getX() && y == node.getY()); - if (equal == true) { - return true; - } else if (node.previous == node || node.previous.previous == node) { - return false; - } - return area(node.previous.previous.getX(), node.previous.previous.getY(), node.previous.getX(), node.previous.getY(), x, y) == 0d; - } - /** Eliminate colinear/duplicate points from the doubly linked list */ private static final Node filterPoints(final Node start, Node end) { if (start == null) { diff --git a/lucene/sandbox/src/test/org/apache/lucene/geo/TestTessellator.java b/lucene/sandbox/src/test/org/apache/lucene/geo/TestTessellator.java index 5cc9da1678f..82ba5b41698 100644 --- a/lucene/sandbox/src/test/org/apache/lucene/geo/TestTessellator.java +++ b/lucene/sandbox/src/test/org/apache/lucene/geo/TestTessellator.java @@ -90,4 +90,10 @@ public class TestTessellator extends LuceneTestCase { Polygon polygon = (Polygon)SimpleWKTShapeParser.parse(wkt); expectThrows( IllegalArgumentException.class, () -> {Tessellator.tessellate(polygon); }); } + + public void testLUCENE8550() throws Exception { + String wkt = "POLYGON((24.04725 59.942,24.04825 59.94125,24.04875 59.94125,24.04875 59.94175,24.048 59.9425,24.0475 59.94275,24.0465 59.94225,24.046 59.94225,24.04575 59.9425,24.04525 59.94225,24.04725 59.942))"; + Polygon polygon = (Polygon)SimpleWKTShapeParser.parse(wkt); + assertTrue(Tessellator.tessellate(polygon).size() == 8); + } } \ No newline at end of file