mirror of https://github.com/apache/lucene.git
LUCENE-8550: Fix filtering of coplanar points when creating linked list on polygon tesselator
This commit is contained in:
parent
f7720aad82
commit
ae9185f7d8
|
@ -238,6 +238,9 @@ Improvements:
|
||||||
|
|
||||||
Bug Fixes:
|
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
|
* LUCENE-8549: Polygon tessellator throws an error if some parts of the shape
|
||||||
could not be processed. (Ignacio Vera)
|
could not be processed. (Ignacio Vera)
|
||||||
|
|
||||||
|
|
|
@ -124,17 +124,13 @@ final public class Tessellator {
|
||||||
// Link points into the circular doubly-linked list in the specified winding order
|
// Link points into the circular doubly-linked list in the specified winding order
|
||||||
if (windingOrder == polygon.getWindingOrder()) {
|
if (windingOrder == polygon.getWindingOrder()) {
|
||||||
for (int i = 0; i < polygon.numPoints(); ++i) {
|
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 {
|
} else {
|
||||||
for (int i = polygon.numPoints() - 1; i >= 0; --i) {
|
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
|
// if first and last node are the same then remove the end node and set lastNode to the start
|
||||||
if (lastNode != null && isVertexEquals(lastNode, lastNode.next)) {
|
if (lastNode != null && isVertexEquals(lastNode, lastNode.next)) {
|
||||||
removeNode(lastNode);
|
removeNode(lastNode);
|
||||||
|
@ -142,7 +138,7 @@ final public class Tessellator {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the last node in the Doubly-Linked List
|
// 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. **/
|
/** 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);
|
} 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 */
|
/** Eliminate colinear/duplicate points from the doubly linked list */
|
||||||
private static final Node filterPoints(final Node start, Node end) {
|
private static final Node filterPoints(final Node start, Node end) {
|
||||||
if (start == null) {
|
if (start == null) {
|
||||||
|
|
|
@ -90,4 +90,10 @@ public class TestTessellator extends LuceneTestCase {
|
||||||
Polygon polygon = (Polygon)SimpleWKTShapeParser.parse(wkt);
|
Polygon polygon = (Polygon)SimpleWKTShapeParser.parse(wkt);
|
||||||
expectThrows( IllegalArgumentException.class, () -> {Tessellator.tessellate(polygon); });
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue