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/11/25 17:38:58 UTC
svn commit: r1716478 - in
/lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src:
java/org/apache/lucene/search/ java/org/apache/lucene/util/
test/org/apache/lucene/search/
Author: nknize
Date: Wed Nov 25 16:38:57 2015
New Revision: 1716478
URL: http://svn.apache.org/viewvc?rev=1716478&view=rev
Log:
LUCENE-6905: Unwrap center longitude for dateline crossing GeoPointDistanceQuery.
Modified:
lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQuery.java
lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQueryImpl.java
lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/util/GeoDistanceUtils.java
lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java
Modified: lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQuery.java?rev=1716478&r1=1716477&r2=1716478&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQuery.java (original)
+++ lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQuery.java Wed Nov 25 16:38:57 2015
@@ -20,9 +20,9 @@ package org.apache.lucene.search;
import java.io.IOException;
import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.util.GeoDistanceUtils;
import org.apache.lucene.util.GeoRect;
import org.apache.lucene.util.GeoUtils;
-import org.apache.lucene.util.SloppyMath;
/** Implements a simple point distance query on a GeoPoint field. This is based on
* {@link org.apache.lucene.search.GeoPointInBBoxQuery} and is implemented using a two phase approach. First,
@@ -55,7 +55,7 @@ public class GeoPointDistanceQuery exten
super(field, bbox.minLon, bbox.minLat, bbox.maxLon, bbox.maxLat);
{
// check longitudinal overlap (limits radius)
- final double maxRadius = SloppyMath.haversin(centerLat, centerLon, centerLat, (180.0 + centerLon) % 360)*1000.0;
+ final double maxRadius = GeoDistanceUtils.maxRadialDistanceMeters(centerLon, centerLat);
if (radiusMeters > maxRadius) {
throw new IllegalArgumentException("radiusMeters " + radiusMeters + " exceeds maxRadius [" + maxRadius
+ "] at location [" + centerLon + " " + centerLat + "]");
@@ -84,18 +84,31 @@ public class GeoPointDistanceQuery exten
if (getBoost() != 1f) {
return super.rewrite(reader);
}
+ // query crosses dateline; split into left and right queries
if (maxLon < minLon) {
BooleanQuery.Builder bqb = new BooleanQuery.Builder();
- GeoPointDistanceQueryImpl left = new GeoPointDistanceQueryImpl(field, this, new GeoRect(GeoUtils.MIN_LON_INCL, maxLon,
- minLat, maxLat));
+ // unwrap the longitude iff outside the specified min/max lon range
+ double unwrappedLon = centerLon;
+ if (unwrappedLon > maxLon) {
+ // unwrap left
+ unwrappedLon += -360.0D;
+ }
+ GeoPointDistanceQueryImpl left = new GeoPointDistanceQueryImpl(field, this, unwrappedLon,
+ new GeoRect(GeoUtils.MIN_LON_INCL, maxLon, minLat, maxLat));
bqb.add(new BooleanClause(left, BooleanClause.Occur.SHOULD));
- GeoPointDistanceQueryImpl right = new GeoPointDistanceQueryImpl(field, this, new GeoRect(minLon, GeoUtils.MAX_LON_INCL,
- minLat, maxLat));
+
+ if (unwrappedLon < maxLon) {
+ // unwrap right
+ unwrappedLon += 360.0D;
+ }
+ GeoPointDistanceQueryImpl right = new GeoPointDistanceQueryImpl(field, this, unwrappedLon,
+ new GeoRect(minLon, GeoUtils.MAX_LON_INCL, minLat, maxLat));
bqb.add(new BooleanClause(right, BooleanClause.Occur.SHOULD));
+
return bqb.build();
}
- return new GeoPointDistanceQueryImpl(field, this, new GeoRect(this.minLon, this.maxLon, this.minLat, this.maxLat));
+ return new GeoPointDistanceQueryImpl(field, this, centerLon, new GeoRect(this.minLon, this.maxLon, this.minLat, this.maxLat));
}
@Override
Modified: lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQueryImpl.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQueryImpl.java?rev=1716478&r1=1716477&r2=1716478&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQueryImpl.java (original)
+++ lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointDistanceQueryImpl.java Wed Nov 25 16:38:57 2015
@@ -33,10 +33,13 @@ import org.apache.lucene.util.SloppyMath
*/
final class GeoPointDistanceQueryImpl extends GeoPointInBBoxQueryImpl {
private final GeoPointDistanceQuery query;
+ private final double centerLon;
- GeoPointDistanceQueryImpl(final String field, final GeoPointDistanceQuery q, final GeoRect bbox) {
+ GeoPointDistanceQueryImpl(final String field, final GeoPointDistanceQuery q, final double centerLonUnwrapped,
+ final GeoRect bbox) {
super(field, bbox.minLon, bbox.minLat, bbox.maxLon, bbox.maxLat);
query = q;
+ centerLon = centerLonUnwrapped;
}
@Override @SuppressWarnings("unchecked")
@@ -74,12 +77,12 @@ final class GeoPointDistanceQueryImpl ex
@Override
protected boolean cellCrosses(final double minLon, final double minLat, final double maxLon, final double maxLat) {
- return GeoUtils.rectCrossesCircle(minLon, minLat, maxLon, maxLat, query.centerLon, query.centerLat, query.radiusMeters);
+ return GeoUtils.rectCrossesCircle(minLon, minLat, maxLon, maxLat, centerLon, query.centerLat, query.radiusMeters);
}
@Override
protected boolean cellWithin(final double minLon, final double minLat, final double maxLon, final double maxLat) {
- return GeoUtils.rectWithinCircle(minLon, minLat, maxLon, maxLat, query.centerLon, query.centerLat, query.radiusMeters);
+ return GeoUtils.rectWithinCircle(minLon, minLat, maxLon, maxLat, centerLon, query.centerLat, query.radiusMeters);
}
@Override
@@ -96,7 +99,7 @@ final class GeoPointDistanceQueryImpl ex
*/
@Override
protected boolean postFilter(final double lon, final double lat) {
- return (SloppyMath.haversin(query.centerLat, query.centerLon, lat, lon) * 1000.0 <= query.radiusMeters);
+ return (SloppyMath.haversin(query.centerLat, centerLon, lat, lon) * 1000.0 <= query.radiusMeters);
}
}
Modified: lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/util/GeoDistanceUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/util/GeoDistanceUtils.java?rev=1716478&r1=1716477&r2=1716478&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/util/GeoDistanceUtils.java (original)
+++ lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/java/org/apache/lucene/util/GeoDistanceUtils.java Wed Nov 25 16:38:57 2015
@@ -149,6 +149,14 @@ public class GeoDistanceUtils {
}
}
+ /** Returns the maximum distance/radius (in meters) from the point 'center' before overlapping */
+ public static double maxRadialDistanceMeters(final double centerLon, final double centerLat) {
+ if (Math.abs(centerLat) == GeoUtils.MAX_LAT_INCL) {
+ return SloppyMath.haversin(centerLat, centerLon, 0, centerLon)*1000.0;
+ }
+ return SloppyMath.haversin(centerLat, centerLon, centerLat, (GeoUtils.MAX_LON_INCL + centerLon) % 360)*1000.0;
+ }
+
/**
* Compute the inverse haversine to determine distance in degrees longitude for provided distance in meters
* @param lat latitude to compute delta degrees lon
Modified: lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java?rev=1716478&r1=1716477&r2=1716478&view=diff
==============================================================================
--- lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java (original)
+++ lucene/dev/branches/lucene_solr_5_4/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java Wed Nov 25 16:38:57 2015
@@ -95,7 +95,7 @@ public class TestGeoPointQuery extends B
new GeoPointField(FIELD_NAME, -96.4538113027811, 32.94823588839368, storedPoint),
new GeoPointField(FIELD_NAME, -96.65084838867188, 33.06047141970814, storedPoint),
new GeoPointField(FIELD_NAME, -96.7772, 32.778650, storedPoint),
- new GeoPointField(FIELD_NAME, -83.99724648980559, 58.29438379542874, storedPoint),
+ new GeoPointField(FIELD_NAME, -177.23537676036358, -88.56029371730983, storedPoint),
new GeoPointField(FIELD_NAME, -26.779373834241003, 33.541429799076354, storedPoint),
new GeoPointField(FIELD_NAME, -77.35379276106497, 26.774024500421728, storedPoint),
new GeoPointField(FIELD_NAME, -14.796283808944777, -90.0, storedPoint),
@@ -289,6 +289,12 @@ public class TestGeoPointQuery extends B
assertEquals("GeoDistanceQuery failed", 2, td.totalHits);
}
+ /** see https://issues.apache.org/jira/browse/LUCENE-6905 */
+ public void testNonEmptyTermsEnum() throws Exception {
+ TopDocs td = geoDistanceQuery(-177.23537676036358, -88.56029371730983, 7757.999232959935, 20);
+ assertEquals("GeoDistanceQuery failed", 2, td.totalHits);
+ }
+
public void testMultiValuedQuery() throws Exception {
TopDocs td = bboxQuery(-96.4538113027811, 32.7559529921407, -96.7706036567688, 32.7756745755423, 20);
// 3 single valued docs + 2 multi-valued docs
@@ -308,7 +314,7 @@ public class TestGeoPointQuery extends B
*/
public void testGeoDistanceQueryHuge() throws Exception {
TopDocs td = geoDistanceQuery(-96.4538113027811, 32.94823588839368, 6000000, 20);
- assertEquals("GeoDistanceQuery failed",18, td.totalHits);
+ assertEquals("GeoDistanceQuery failed", 16, td.totalHits);
}
public void testGeoDistanceQueryCrossDateline() throws Exception {