LUCENE-8549: Polygon tessellator throws an error if some parts of the shape could not be processed

This commit is contained in:
iverase 2018-11-02 07:50:41 +01:00
parent 6ae9aa2a32
commit f7720aad82
3 changed files with 17 additions and 4 deletions

View File

@ -238,6 +238,9 @@ Improvements:
Bug Fixes:
* LUCENE-8549: Polygon tessellator throws an error if some parts of the shape
could not be processed. (Ignacio Vera)
* LUCENE-8540: Better handling of min/max values for Geo3d encoding. (Ignacio Vera)
* LUCENE-8534: Fix incorrect computation for triangles intersecting polygon edges in

View File

@ -321,7 +321,10 @@ final public class Tessellator {
continue earcut;
case SPLIT:
// as a last resort, try splitting the remaining polygon into two
splitEarcut(currEar, tessellation, mortonOptimized);
if (splitEarcut(currEar, tessellation, mortonOptimized) == false) {
//we could not process all points. Tessellation failed
tessellation.clear();
}
break;
}
break;
@ -439,8 +442,8 @@ final public class Tessellator {
return node;
}
/** Attempt to split a polygon and independently triangulate each side **/
private static final void splitEarcut(final Node start, final List<Triangle> tessellation, final boolean mortonIndexed) {
/** Attempt to split a polygon and independently triangulate each side. Return true if the polygon was splitted **/
private static final boolean splitEarcut(final Node start, final List<Triangle> tessellation, final boolean mortonIndexed) {
// Search for a valid diagonal that divides the polygon into two.
Node searchNode = start;
Node nextNode;
@ -462,12 +465,13 @@ final public class Tessellator {
earcutLinkedList(searchNode, tessellation, State.INIT, mortonIndexed);
earcutLinkedList(splitNode, tessellation, State.INIT, mortonIndexed);
// Finish the iterative search
return;
return true;
}
diagonal = diagonal.next;
}
searchNode = searchNode.next;
} while (searchNode != start);
return false;
}
/** Links two polygon vertices using a bridge. **/

View File

@ -84,4 +84,10 @@ public class TestTessellator extends LuceneTestCase {
List<Tessellator.Triangle> result = Tessellator.tessellate(polygons[0]);
assertEquals(113, result.size());
}
public void testInvalidPolygon() throws Exception {
String wkt = "POLYGON((0 0, 1 1, 0 1, 1 0, 0 0))";
Polygon polygon = (Polygon)SimpleWKTShapeParser.parse(wkt);
expectThrows( IllegalArgumentException.class, () -> {Tessellator.tessellate(polygon); });
}
}