diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java index 124b46bf2ae..8eaea1a4937 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConcavePolygon.java @@ -207,21 +207,6 @@ class GeoConcavePolygon extends GeoBasePolygon { invertedEdges[i] = new SidedPlane(edges[i]); notableEdgePoints[i] = new GeoPoint[]{start, end}; } - /* Disable since GeoPolygonFactory does this too. - // In order to naively confirm that the polygon is concave, I would need to - // check every edge, and verify that every point (other than the edge endpoints) - // is within the edge's sided plane. This is an order n^2 operation. That's still - // not wrong, though, because everything else about polygons has a similar cost. - for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) { - final SidedPlane edge = edges[edgeIndex]; - for (int pointIndex = 0; pointIndex < points.size(); pointIndex++) { - if (pointIndex != edgeIndex && pointIndex != legalIndex(edgeIndex + 1)) { - if (edge.isWithin(points.get(pointIndex))) - throw new IllegalArgumentException("Polygon is not concave: Point " + points.get(pointIndex) + " Edge " + edge); - } - } - } - */ // For each edge, create a bounds object. eitherBounds = new HashMap<>(edges.length); @@ -241,6 +226,26 @@ class GeoConcavePolygon extends GeoBasePolygon { // Pick an edge point arbitrarily edgePoints = new GeoPoint[]{points.get(0)}; + + if (isWithinHoles(points.get(0))) { + throw new IllegalArgumentException("Polygon edge intersects a polygon hole; not allowed"); + } + + } + + /** Check if a point is within the provided holes. + *@param point point to check. + *@return true if the point is within any of the holes. + */ + protected boolean isWithinHoles(final GeoPoint point) { + if (holes != null) { + for (final GeoPolygon hole : holes) { + if (hole.isWithin(point)) { + return true; + } + } + } + return false; } /** Compute a legal point index from a possibly illegal one, that may have wrapped. diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java index 64aa7c45f96..17a2120db3f 100755 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoConvexPolygon.java @@ -203,21 +203,6 @@ class GeoConvexPolygon extends GeoBasePolygon { edges[i] = sp; notableEdgePoints[i] = new GeoPoint[]{start, end}; } - /* Disabled since GeoPolygonFactory does the checking too. - // In order to naively confirm that the polygon is convex, I would need to - // check every edge, and verify that every point (other than the edge endpoints) - // is within the edge's sided plane. This is an order n^2 operation. That's still - // not wrong, though, because everything else about polygons has a similar cost. - for (int edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) { - final SidedPlane edge = edges[edgeIndex]; - for (int pointIndex = 0; pointIndex < points.size(); pointIndex++) { - if (pointIndex != edgeIndex && pointIndex != legalIndex(edgeIndex + 1)) { - if (!edge.isWithin(points.get(pointIndex))) - throw new IllegalArgumentException("Polygon is not convex: Point " + points.get(pointIndex) + " Edge " + edge); - } - } - } - */ // For each edge, create a bounds object. eitherBounds = new HashMap<>(edges.length); @@ -236,8 +221,28 @@ class GeoConvexPolygon extends GeoBasePolygon { // Pick an edge point arbitrarily edgePoints = new GeoPoint[]{points.get(0)}; + + if (isWithinHoles(points.get(0))) { + throw new IllegalArgumentException("Polygon edge intersects a polygon hole; not allowed"); + } + } + /** Check if a point is within the provided holes. + *@param point point to check. + *@return true if the point is within any of the holes. + */ + protected boolean isWithinHoles(final GeoPoint point) { + if (holes != null) { + for (final GeoPolygon hole : holes) { + if (hole.isWithin(point)) { + return true; + } + } + } + return false; + } + /** Compute a legal point index from a possibly illegal one, that may have wrapped. *@param index is the index. *@return the normalized index.