diff --git a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java index b2c39c21b7f..0b96936d896 100644 --- a/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java +++ b/lucene/sandbox/src/java/org/apache/lucene/document/LatLonPoint.java @@ -26,6 +26,7 @@ import org.apache.lucene.search.BooleanClause; import org.apache.lucene.search.BooleanQuery; import org.apache.lucene.search.ConstantScoreQuery; import org.apache.lucene.search.FieldDoc; +import org.apache.lucene.search.MatchNoDocsQuery; import org.apache.lucene.search.PointRangeQuery; import org.apache.lucene.search.Query; import org.apache.lucene.search.SortField; @@ -285,6 +286,21 @@ public class LatLonPoint extends Field { * @throws IllegalArgumentException if {@code field} is null, or the box has invalid coordinates. */ public static Query newBoxQuery(String field, double minLatitude, double maxLatitude, double minLongitude, double maxLongitude) { + // exact double values of lat=90.0D and lon=180.0D must be treated special as they are not represented in the encoding + // and should not drag in extra bogus junk! TODO: should encodeCeil just throw ArithmeticException to be less trappy here? + if (minLatitude == 90.0) { + // range cannot match as 90.0 can never exist + return new MatchNoDocsQuery(); + } + if (minLongitude == 180.0) { + if (maxLongitude == 180.0) { + // range cannot match as 180.0 can never exist + return new MatchNoDocsQuery(); + } else if (maxLongitude < minLongitude) { + // encodeCeil() with dateline wrapping! + minLongitude = -180.0; + } + } byte[] lower = encodeCeil(minLatitude, minLongitude); byte[] upper = encode(maxLatitude, maxLongitude); // Crosses date line: we just rewrite into OR of two bboxes, with longitude as an open range: