You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by mi...@apache.org on 2015/05/27 16:14:51 UTC
svn commit: r1682036 - in
/lucene/dev/branches/LUCENE-6481/lucene/sandbox/src:
java/org/apache/lucene/search/GeoBoundingBox.java
java/org/apache/lucene/search/GeoPointInPolygonQuery.java
test/org/apache/lucene/search/TestGeoPointQuery.java
Author: mikemccand
Date: Wed May 27 14:14:51 2015
New Revision: 1682036
URL: http://svn.apache.org/r1682036
Log:
LUCENE-6481: restrict random test cases to 'smallish' bbox; switch static factory for polygon query to ctor
Added:
lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoBoundingBox.java (with props)
Modified:
lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java
lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java
Added: lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoBoundingBox.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoBoundingBox.java?rev=1682036&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoBoundingBox.java (added)
+++ lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoBoundingBox.java Wed May 27 14:14:51 2015
@@ -0,0 +1,47 @@
+package org.apache.lucene.search;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.lucene.util.GeoUtils;
+
+/** NOTE: package private; just used so {@link GeoPointInBBoxQuery} can communicate its bounding box to {@link GeoPointInBBoxQuery}. */
+class GeoBoundingBox {
+ public final double minLon;
+ public final double maxLon;
+ public final double minLat;
+ public final double maxLat;
+
+ public GeoBoundingBox(double minLon, double maxLon, double minLat, double maxLat) {
+ if (GeoUtils.isValidLon(minLon) == false) {
+ throw new IllegalArgumentException("invalid minLon " + minLon);
+ }
+ if (GeoUtils.isValidLon(maxLon) == false) {
+ throw new IllegalArgumentException("invalid maxLon " + minLon);
+ }
+ if (GeoUtils.isValidLat(minLat) == false) {
+ throw new IllegalArgumentException("invalid minLat " + minLat);
+ }
+ if (GeoUtils.isValidLat(maxLat) == false) {
+ throw new IllegalArgumentException("invalid maxLat " + minLat);
+ }
+ this.minLon = minLon;
+ this.maxLon = maxLon;
+ this.minLat = minLat;
+ this.maxLat = maxLat;
+ }
+}
Modified: lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java?rev=1682036&r1=1682035&r2=1682036&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java (original)
+++ lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/java/org/apache/lucene/search/GeoPointInPolygonQuery.java Wed May 27 14:14:51 2015
@@ -55,8 +55,16 @@ public final class GeoPointInPolygonQuer
/**
* Constructs a new GeoPolygonQuery that will match encoded {@link org.apache.lucene.document.GeoPointField} terms
- * that fall within or on the boundary of the polygon defined by the input parameters. This constructor requires a
- * precomputed bounding box. As an alternative the {@link GeoPointInPolygonQuery#newPolygonQuery} static factory can
+ * 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);
+ }
+
+ /**
+ * Expert: constructs a new GeoPolygonQuery that will match encoded {@link org.apache.lucene.document.GeoPointField} terms
+ * that fall within or on the boundary of the polygon defined by the input parameters. This constructor requires a
+ * precomputed bounding box. As an alternative, {@link GeoPointInPolygonQuery(String,double[],double[])} can
* be used to compute the bounding box during construction
*
* @param field the field name
@@ -69,7 +77,14 @@ public final class GeoPointInPolygonQuer
*/
public GeoPointInPolygonQuery(final String field, final double minLon, final double minLat, final double maxLon,
final double maxLat, final double[] polyLons, final double[] polyLats) {
- super(field, minLon, minLat, maxLon, maxLat);
+ // TODO: should we remove this? It's dangerous .. app could accidentally provide too-small bbox?
+ // we should at least verify that bbox does in fact fully contain the poly?
+ this(field, new GeoBoundingBox(minLon, maxLon, minLat, maxLat), polyLons, polyLats);
+ }
+
+ /** Common constructor, used only internally. */
+ private GeoPointInPolygonQuery(final String field, GeoBoundingBox bbox, final double[] polyLons, final double[] polyLats) {
+ super(field, bbox.minLon, bbox.minLat, bbox.maxLon, bbox.maxLat);
if (polyLats.length != polyLons.length) {
throw new IllegalArgumentException("polyLats and polyLons must be equal length");
}
@@ -83,39 +98,10 @@ 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]);
}
- // nocommit we should at least assert that bbox does in fact fully contain the poly?
- for(int i=0;i<polyLons.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]);
- }
- }
this.x = polyLons;
this.y = polyLats;
}
- /**
- * Static method call to construct a
- * {@link #GeoPointInPolygonQuery(String, double, double, double, double, double[], double[])
- * GeoPolygonQuery(field, minLon, minLat, maxLon, maxLat, polyLons, polyLats)} by first computing the bounding
- * box lat/lon ranges
- */
- // TODO: change this to normal ctor ... silly java requiring super() first
- public static GeoPointInPolygonQuery newPolygonQuery(final String field, final double[] polyLons, final double[] polyLats) {
- assert polyLons.length == polyLats.length;
- double minLon, maxLon, minLat, maxLat;
- int i=1;
- for(minLon=maxLon=polyLons[0], minLat=maxLat=polyLats[0]; i<polyLons.length; ++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 GeoPointInPolygonQuery(field, minLon, minLat, maxLon, maxLat, polyLons, polyLats);
- }
-
@Override @SuppressWarnings("unchecked")
protected TermsEnum getTermsEnum(final Terms terms, AttributeSource atts) throws IOException {
final Long min = GeoUtils.mortonHash(minLon, minLat);
@@ -213,4 +199,30 @@ public final class GeoPointInPolygonQuer
return AcceptStatus.YES;
}
}
+
+ private static GeoBoundingBox 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 GeoBoundingBox(minLon, maxLon, minLat, maxLat);
+ }
}
Modified: lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java?rev=1682036&r1=1682035&r2=1682036&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java (original)
+++ lucene/dev/branches/LUCENE-6481/lucene/sandbox/src/test/org/apache/lucene/search/TestGeoPointQuery.java Wed May 27 14:14:51 2015
@@ -61,14 +61,20 @@ public class TestGeoPointQuery extends L
private static final String FIELD_NAME = "geoField";
- private static boolean smallBBox;
+ // Global bounding box we will "cover" in the random test; we have to make this "smallish" else the queries take very long:
+ private static double originLat;
+ private static double originLon;
+ private static double range;
@BeforeClass
public static void beforeClass() throws Exception {
directory = newDirectory();
- smallBBox = random().nextBoolean();
+ // Between 1.0 and 3.0:
+ range = 2*(random().nextDouble() + 0.5);
+ originLon = GeoUtils.MIN_LON_INCL + range + (GeoUtils.MAX_LON_INCL - GeoUtils.MIN_LON_INCL - 2*range) * random().nextDouble();
+ originLat = GeoUtils.MIN_LAT_INCL + range + (GeoUtils.MAX_LAT_INCL - GeoUtils.MIN_LAT_INCL - 2*range) * random().nextDouble();
if (VERBOSE) {
- System.out.println("TEST: smallBBox=" + smallBBox);
+ System.out.println("TEST: originLon=" + originLon + " originLat=" + originLat + " range=" + range);
}
RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
newIndexWriterConfig(new MockAnalyzer(random()))
@@ -112,7 +118,7 @@ public class TestGeoPointQuery extends L
}
private TopDocs polygonQuery(double[] lon, double[] lat, int limit) throws Exception {
- GeoPointInPolygonQuery q = GeoPointInPolygonQuery.newPolygonQuery(FIELD_NAME, lon, lat);
+ GeoPointInPolygonQuery q = new GeoPointInPolygonQuery(FIELD_NAME, lon, lat);
return searcher.search(q, limit);
}
@@ -401,18 +407,10 @@ public class TestGeoPointQuery extends L
}
private static double randomLat() {
- if (smallBBox) {
- return 2.0 * (random().nextDouble()-0.5);
- } else {
- return -90 + 180.0 * random().nextDouble();
- }
+ return originLat + range * (random().nextDouble()-0.5);
}
private static double randomLon() {
- if (smallBBox) {
- return 2.0 * (random().nextDouble()-0.5);
- } else {
- return -180 + 360.0 * random().nextDouble();
- }
+ return originLon + range * (random().nextDouble()-0.5);
}
}