diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java index 4b5ab92764a..0f2395c890b 100644 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/Geo3DPoint.java @@ -142,7 +142,7 @@ public final class Geo3DPoint extends Field { } final GeoShape shape; if (polygons.length == 1) { - final GeoShape component = fromPolygon(polygons[0], false); + final GeoShape component = fromPolygon(polygons[0]); if (component == null) { // Polygon is degenerate shape = new GeoCompositePolygon(); @@ -152,7 +152,7 @@ public final class Geo3DPoint extends Field { } else { final GeoCompositePolygon poly = new GeoCompositePolygon(); for (final Polygon p : polygons) { - final GeoPolygon component = fromPolygon(p, false); + final GeoPolygon component = fromPolygon(p); if (component != null) { poly.addShape(component); } @@ -192,17 +192,16 @@ public final class Geo3DPoint extends Field { * Convert a Polygon object into a GeoPolygon. * This method uses * @param polygon is the Polygon object. - * @param reverseMe is true if the order of the points should be reversed. * @return the GeoPolygon. */ - private static GeoPolygon fromPolygon(final Polygon polygon, final boolean reverseMe) { + private static GeoPolygon fromPolygon(final Polygon polygon) { // First, assemble the "holes". The geo3d convention is to use the same polygon sense on the inner ring as the // outer ring, so we process these recursively with reverseMe flipped. final Polygon[] theHoles = polygon.getHoles(); final List holeList = new ArrayList<>(theHoles.length); for (final Polygon hole : theHoles) { //System.out.println("Hole: "+hole); - final GeoPolygon component = fromPolygon(hole, !reverseMe); + final GeoPolygon component = fromPolygon(hole); if (component != null) { holeList.add(component); } @@ -216,12 +215,8 @@ public final class Geo3DPoint extends Field { final List points = new ArrayList<>(polyLats.length-1); // We skip the last point anyway because the API requires it to be repeated, and geo3d doesn't repeat it. for (int i = 0; i < polyLats.length - 1; i++) { - if (reverseMe) { - points.add(new GeoPoint(PlanetModel.WGS84, fromDegrees(polyLats[i]), fromDegrees(polyLons[i]))); - } else { - final int index = polyLats.length - 2 - i; - points.add(new GeoPoint(PlanetModel.WGS84, fromDegrees(polyLats[index]), fromDegrees(polyLons[index]))); - } + final int index = polyLats.length - 2 - i; + points.add(new GeoPoint(PlanetModel.WGS84, fromDegrees(polyLats[index]), fromDegrees(polyLons[index]))); } //System.err.println(" building polygon with "+points.size()+" points..."); final GeoPolygon rval = GeoPolygonFactory.makeGeoPolygon(PlanetModel.WGS84, points, holeList); 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 8eaea1a4937..c18d40f75d4 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 @@ -224,8 +224,25 @@ class GeoConcavePolygon extends GeoBasePolygon { eitherBounds.put(edge, new EitherBound(invertedEdges[legalIndex(bound1Index)], invertedEdges[legalIndex(bound2Index)])); } - // Pick an edge point arbitrarily - edgePoints = new GeoPoint[]{points.get(0)}; + // Pick an edge point arbitrarily from the outer polygon. Glom this together with all edge points from + // inner polygons. + int edgePointCount = 1; + if (holes != null) { + for (final GeoPolygon hole : holes) { + edgePointCount += hole.getEdgePoints().length; + } + } + edgePoints = new GeoPoint[edgePointCount]; + edgePointCount = 0; + edgePoints[edgePointCount++] = points.get(0); + if (holes != null) { + for (final GeoPolygon hole : holes) { + final GeoPoint[] holeEdgePoints = hole.getEdgePoints(); + for (final GeoPoint p : holeEdgePoints) { + edgePoints[edgePointCount++] = p; + } + } + } if (isWithinHoles(points.get(0))) { throw new IllegalArgumentException("Polygon edge intersects a polygon hole; not allowed"); @@ -240,7 +257,7 @@ class GeoConcavePolygon extends GeoBasePolygon { protected boolean isWithinHoles(final GeoPoint point) { if (holes != null) { for (final GeoPolygon hole : holes) { - if (hole.isWithin(point)) { + if (!hole.isWithin(point)) { return true; } } @@ -268,7 +285,7 @@ class GeoConcavePolygon extends GeoBasePolygon { } if (holes != null) { for (final GeoPolygon polygon : holes) { - if (polygon.isWithin(x, y, z)) { + if (!polygon.isWithin(x, y, z)) { return false; } } @@ -405,6 +422,14 @@ class GeoConcavePolygon extends GeoBasePolygon { minimumDistance = newDist; } } + if (holes != null) { + for (final GeoPolygon hole : holes) { + double holeDistance = hole.computeOutsideDistance(distanceStyle, x, y, z); + if (holeDistance != 0.0 && holeDistance < minimumDistance) { + minimumDistance = holeDistance; + } + } + } return minimumDistance; } 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 17a2120db3f..6f71d18bb5b 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 @@ -219,8 +219,25 @@ class GeoConvexPolygon extends GeoBasePolygon { eitherBounds.put(edge, new EitherBound(edges[legalIndex(bound1Index)], edges[legalIndex(bound2Index)])); } - // Pick an edge point arbitrarily - edgePoints = new GeoPoint[]{points.get(0)}; + // Pick an edge point arbitrarily from the outer polygon. Glom this together with all edge points from + // inner polygons. + int edgePointCount = 1; + if (holes != null) { + for (final GeoPolygon hole : holes) { + edgePointCount += hole.getEdgePoints().length; + } + } + edgePoints = new GeoPoint[edgePointCount]; + edgePointCount = 0; + edgePoints[edgePointCount++] = points.get(0); + if (holes != null) { + for (final GeoPolygon hole : holes) { + final GeoPoint[] holeEdgePoints = hole.getEdgePoints(); + for (final GeoPoint p : holeEdgePoints) { + edgePoints[edgePointCount++] = p; + } + } + } if (isWithinHoles(points.get(0))) { throw new IllegalArgumentException("Polygon edge intersects a polygon hole; not allowed"); @@ -235,7 +252,7 @@ class GeoConvexPolygon extends GeoBasePolygon { protected boolean isWithinHoles(final GeoPoint point) { if (holes != null) { for (final GeoPolygon hole : holes) { - if (hole.isWithin(point)) { + if (!hole.isWithin(point)) { return true; } } @@ -263,7 +280,7 @@ class GeoConvexPolygon extends GeoBasePolygon { } if (holes != null) { for (final GeoPolygon polygon : holes) { - if (polygon.isWithin(x, y, z)) { + if (!polygon.isWithin(x, y, z)) { return false; } } @@ -393,6 +410,14 @@ class GeoConvexPolygon extends GeoBasePolygon { minimumDistance = newDist; } } + if (holes != null) { + for (final GeoPolygon hole : holes) { + double holeDistance = hole.computeOutsideDistance(distanceStyle, x, y, z); + if (holeDistance != 0.0 && holeDistance < minimumDistance) { + minimumDistance = holeDistance; + } + } + } return minimumDistance; } diff --git a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java index 99fc7c90e4d..609c8643c62 100755 --- a/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java +++ b/lucene/spatial3d/src/java/org/apache/lucene/spatial3d/geom/GeoPolygonFactory.java @@ -56,7 +56,8 @@ public class GeoPolygonFactory { * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. If points go * clockwise from a given pole, then that pole should be within the polygon. If points go * counter-clockwise, then that pole should be outside the polygon. - * @param holes is a list of polygons representing "holes" in the outside polygon. Null == none. + * @param holes is a list of polygons representing "holes" in the outside polygon. Holes describe the area outside + * each hole as being "in set". Null == none. * @return a GeoPolygon corresponding to what was specified, or null if a valid polygon cannot be generated * from this input. */ @@ -73,7 +74,8 @@ public class GeoPolygonFactory { * @param pointList is a list of the GeoPoints to build an arbitrary polygon out of. If points go * clockwise from a given pole, then that pole should be within the polygon. If points go * counter-clockwise, then that pole should be outside the polygon. - * @param holes is a list of polygons representing "holes" in the outside polygon. Null == none. + * @param holes is a list of polygons representing "holes" in the outside polygon. Holes describe the area outside + * each hole as being "in set". Null == none. * @param leniencyValue is the maximum distance (in units) that a point can be from the plane and still be considered as * belonging to the plane. Any value greater than zero may cause some of the provided points that are in fact outside * the strict definition of co-planarity, but are within this distance, to be discarded for the purposes of creating a