You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by nk...@apache.org on 2015/10/28 14:54:37 UTC
svn commit: r1711014 - in
/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene:
search/GeoPointInPolygonQuery.java search/GeoPointTermsEnum.java
util/GeoUtils.java
Author: nknize
Date: Wed Oct 28 13:54:36 2015
New Revision: 1711014
URL: http://svn.apache.org/viewvc?rev=1711014&view=rev
Log:
LUCENE-6859: GeoPointInPolygonQuery would occasionally fail with incorrect ranges
Modified:
lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java
lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointTermsEnum.java
lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java
Modified: lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java?rev=1711014&r1=1711013&r2=1711014&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java (original)
+++ lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java Wed Oct 28 13:54:36 2015
@@ -56,7 +56,7 @@ public final class GeoPointInPolygonQuer
* that fall within or on the boundary of the polygon defined by the input parameters.
*/
public GeoPointInPolygonQuery(final String field, final double[] polyLons, final double[] polyLats) {
- this(field, computeBBox(polyLons, polyLats), polyLons, polyLats);
+ this(field, GeoUtils.polyToBBox(polyLons, polyLats), polyLons, polyLats);
}
/** Common constructor, used only internally. */
@@ -75,16 +75,8 @@ public final class GeoPointInPolygonQuer
throw new IllegalArgumentException("first and last points of the polygon must be the same (it must close itself): polyLons[0]=" + polyLons[0] + " polyLons[" + (polyLons.length-1) + "]=" + polyLons[polyLons.length-1]);
}
- // convert polygon vertices to coordinates within tolerance
- this.x = toleranceConversion(polyLons);
- this.y = toleranceConversion(polyLats);
- }
-
- private double[] toleranceConversion(double[] vals) {
- for (int i=0; i<vals.length; ++i) {
- vals[i] = ((int)(vals[i]/GeoUtils.TOLERANCE))*GeoUtils.TOLERANCE;
- }
- return vals;
+ this.x = polyLons;
+ this.y = polyLats;
}
@Override @SuppressWarnings("unchecked")
@@ -167,7 +159,8 @@ public final class GeoPointInPolygonQuer
@Override
protected boolean cellIntersectsShape(final double minLon, final double minLat, final double maxLon, final double maxLat) {
- return cellWithin(minLon, minLat, maxLon, maxLat) || cellCrosses(minLon, minLat, maxLon, maxLat);
+ return cellContains(minLon, minLat, maxLon, maxLat) || cellWithin(minLon, minLat, maxLon, maxLat)
+ || cellCrosses(minLon, minLat, maxLon, maxLat);
}
/**
@@ -183,32 +176,6 @@ public final class GeoPointInPolygonQuer
}
}
- private static GeoRect computeBBox(double[] polyLons, double[] polyLats) {
- if (polyLons.length != polyLats.length) {
- throw new IllegalArgumentException("polyLons and polyLats must be equal length");
- }
-
- double minLon = Double.POSITIVE_INFINITY;
- double maxLon = Double.NEGATIVE_INFINITY;
- double minLat = Double.POSITIVE_INFINITY;
- double maxLat = Double.NEGATIVE_INFINITY;
-
- for (int i=0;i<polyLats.length;i++) {
- if (GeoUtils.isValidLon(polyLons[i]) == false) {
- throw new IllegalArgumentException("invalid polyLons[" + i + "]=" + polyLons[i]);
- }
- if (GeoUtils.isValidLat(polyLats[i]) == false) {
- throw new IllegalArgumentException("invalid polyLats[" + i + "]=" + polyLats[i]);
- }
- minLon = Math.min(polyLons[i], minLon);
- maxLon = Math.max(polyLons[i], maxLon);
- minLat = Math.min(polyLats[i], minLat);
- maxLat = Math.max(polyLats[i], maxLat);
- }
-
- return new GeoRect(minLon, maxLon, minLat, maxLat);
- }
-
/**
* API utility method for returning the array of longitudinal values for this GeoPolygon
* The returned array is not a copy so do not change it!
Modified: lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointTermsEnum.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointTermsEnum.java?rev=1711014&r1=1711013&r2=1711014&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointTermsEnum.java (original)
+++ lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointTermsEnum.java Wed Oct 28 13:54:36 2015
@@ -62,6 +62,7 @@ abstract class GeoPointTermsEnum extends
DETAIL_LEVEL = (short)(((GeoUtils.BITS<<1)-computeMaxShift())/2);
computeRange(0L, (short) (((GeoUtils.BITS) << 1) - 1));
+ assert rangeBounds.isEmpty() == false;
Collections.sort(rangeBounds);
}
Modified: lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java?rev=1711014&r1=1711013&r2=1711014&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java (original)
+++ lucene/dev/trunk/lucene/sandbox/src/java/org/apache/lucene/util/GeoUtils.java Wed Oct 28 13:54:36 2015
@@ -46,31 +46,31 @@ public final class GeoUtils {
private GeoUtils() {
}
- public static Long mortonHash(final double lon, final double lat) {
+ public static final Long mortonHash(final double lon, final double lat) {
return BitUtil.interleave(scaleLon(lon), scaleLat(lat));
}
- public static double mortonUnhashLon(final long hash) {
+ public static final double mortonUnhashLon(final long hash) {
return unscaleLon(BitUtil.deinterleave(hash));
}
- public static double mortonUnhashLat(final long hash) {
+ public static final double mortonUnhashLat(final long hash) {
return unscaleLat(BitUtil.deinterleave(hash >>> 1));
}
- private static long scaleLon(final double val) {
+ private static final long scaleLon(final double val) {
return (long) ((val-MIN_LON_INCL) * LON_SCALE);
}
- private static long scaleLat(final double val) {
+ private static final long scaleLat(final double val) {
return (long) ((val-MIN_LAT_INCL) * LAT_SCALE);
}
- private static double unscaleLon(final long val) {
+ private static final double unscaleLon(final long val) {
return (val / LON_SCALE) + MIN_LON_INCL;
}
- private static double unscaleLat(final long val) {
+ private static final double unscaleLat(final long val) {
return (val / LAT_SCALE) + MIN_LAT_INCL;
}
@@ -182,7 +182,7 @@ public final class GeoUtils {
*/
public static boolean rectContains(final double aMinX, final double aMinY, final double aMaxX, final double aMaxY,
final double bMinX, final double bMinY, final double bMaxX, final double bMaxY) {
- return !(bMinX < aMinX || bMinY < aMinY || bMaxX > aMaxX || bMaxY > aMaxY);
+ return !(bMinX < aMinX || bMinY < aMinY || bMaxX > aMaxX || bMaxY > aMaxY);
}
/**
@@ -366,6 +366,33 @@ public final class GeoUtils {
StrictMath.toDegrees(minLat), StrictMath.toDegrees(maxLat));
}
+ public static GeoRect polyToBBox(double[] polyLons, double[] polyLats) {
+ if (polyLons.length != polyLats.length) {
+ throw new IllegalArgumentException("polyLons and polyLats must be equal length");
+ }
+
+ double minLon = Double.POSITIVE_INFINITY;
+ double maxLon = Double.NEGATIVE_INFINITY;
+ double minLat = Double.POSITIVE_INFINITY;
+ double maxLat = Double.NEGATIVE_INFINITY;
+
+ for (int i=0;i<polyLats.length;i++) {
+ if (GeoUtils.isValidLon(polyLons[i]) == false) {
+ throw new IllegalArgumentException("invalid polyLons[" + i + "]=" + polyLons[i]);
+ }
+ if (GeoUtils.isValidLat(polyLats[i]) == false) {
+ throw new IllegalArgumentException("invalid polyLats[" + i + "]=" + polyLats[i]);
+ }
+ minLon = Math.min(polyLons[i], minLon);
+ maxLon = Math.max(polyLons[i], maxLon);
+ minLat = Math.min(polyLats[i], minLat);
+ maxLat = Math.max(polyLats[i], maxLat);
+ }
+
+ return new GeoRect(GeoUtils.unscaleLon(GeoUtils.scaleLon(minLon)), GeoUtils.unscaleLon(GeoUtils.scaleLon(maxLon)),
+ GeoUtils.unscaleLat(GeoUtils.scaleLat(minLat)), GeoUtils.unscaleLat(GeoUtils.scaleLat(maxLat)));
+ }
+
/*
/**
* Computes whether or a 3dimensional line segment intersects or crosses a sphere