diff --git a/contrib/spatial/build.xml b/contrib/spatial/build.xml
index 261e47954f8..060ea02aac9 100644
--- a/contrib/spatial/build.xml
+++ b/contrib/spatial/build.xml
@@ -25,8 +25,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+ Misc building dependency ${misc.jar}
+
+
+
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/ISerialChainFilter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/ISerialChainFilter.java
deleted file mode 100644
index eb3c3b88a9d..00000000000
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/ISerialChainFilter.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.lucene.spatial;
-
-import java.io.IOException;
-import java.util.BitSet;
-
-import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.Filter;
-
-/**
- * Provide an optimized filter, by allowing the bitset from
- * previous filters in the bitset to be used in the next part of the chain.
- *
- */
-public abstract class ISerialChainFilter extends Filter {
- public abstract BitSet bits(IndexReader reader, BitSet bits) throws CorruptIndexException, IOException, Exception;
-}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/SerialChainFilter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/SerialChainFilter.java
deleted file mode 100644
index 3be3f188852..00000000000
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/SerialChainFilter.java
+++ /dev/null
@@ -1,214 +0,0 @@
-/**
- * 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.
- */
-
-package org.apache.lucene.spatial;
-
-import java.io.IOException;
-import java.util.BitSet;
-
-import org.apache.lucene.index.CorruptIndexException;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.DocIdSet;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.util.DocIdBitSet;
-
-/**
- *
- * Provide a serial chain filter, passing the bitset in with the
- * index reader to each of the filters in an ordered fashion.
- *
- * Based off chain filter, but with some improvements to allow a narrowed down
- * filtering. Traditional filter required iteration through an IndexReader.
- *
- * By implementing the ISerialChainFilter class, you can create a bits(IndexReader reader, BitSet bits)
- * @see org.apache.lucene.search.ISerialChainFilter
- *
- */
-public class SerialChainFilter extends Filter {
-
- /**
- * $Id: SerialChainFilter.java 136 2008-12-17 16:16:38Z ryantxu $
- */
- private static final long serialVersionUID = 1L;
- private Filter chain[];
- public static final int SERIALAND = 1;
- public static final int SERIALOR = 2;
- public static final int AND = 3; // regular filters may be used first
- public static final int OR = 4; // regular filters may be used first
- public static final int DEFAULT = SERIALOR;
-
- private int actionType[];
-
- public SerialChainFilter(Filter chain[]){
- this.chain = chain;
- this.actionType = new int[] {DEFAULT};
- }
-
- public SerialChainFilter(Filter chain[], int actionType[]){
- this.chain= chain;
- this.actionType = actionType;
- }
-
- /* (non-Javadoc)
- * @see org.apache.lucene.search.Filter#bits(org.apache.lucene.index.IndexReader)
- */
- @Override
- public BitSet bits(IndexReader reader) throws IOException {
- return ((DocIdBitSet)getDocIdSet(reader)).getBitSet();
- }
-
-
- /* (non-Javadoc)
- * @see org.apache.lucene.search.Filter#getDocIdSet(org.apache.lucene.index.IndexReader)
- */
- @Override
- public DocIdSet getDocIdSet(IndexReader reader) throws CorruptIndexException, IOException {
-
- BitSet bits = new BitSet(reader.maxDoc());
- int chainSize = chain.length;
- int actionSize = actionType.length;
- int i = 0;
-
- /**
- * taken from ChainedFilter, first and on an empty bitset results in 0
- */
- if (actionType[i] == AND){
- try {
- //System.out.println(chain[i] );
- bits = (BitSet) ((DocIdBitSet)chain[i].getDocIdSet(reader)).getBitSet().clone();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- ++i;
- }
-
- for( ; i < chainSize; i++) {
-
- int action = (i < actionSize)? actionType[i]: DEFAULT;
- //System.out.println(chain[i] + ": "+ action);
- switch (action){
-
- case (SERIALAND):
- try {
- bits.and(((ISerialChainFilter) chain[i]).bits(reader, bits));
- } catch (CorruptIndexException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (IOException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- break;
- case (SERIALOR):
- try {
- bits.or(((ISerialChainFilter) chain[i]).bits(reader,bits));
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- break;
- case (AND):
- bits.and(chain[i].bits(reader));
- break;
- case (OR):
- bits.or(((DocIdBitSet)chain[i].getDocIdSet(reader)).getBitSet());
- break;
- }
- }
-
-// System.out.println("++++++====================");
-// new Exception().printStackTrace();
-
- return new DocIdBitSet(bits);
- }
-
- /**
- * @return the chain
- */
- Filter[] getChain() {
- return chain;
- }
-
- /**
- * @return the actionType
- */
- int[] getActionType() {
- return actionType;
- }
-
- /**
- * Returns true if o
is equal to this.
- *
- * @see org.apache.lucene.search.RangeFilter#equals
- */
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof SerialChainFilter)) return false;
- SerialChainFilter other = (SerialChainFilter) o;
-
- if (this.chain.length != other.getChain().length ||
- this.actionType.length != other.getActionType().length)
- return false;
-
- for (int i = 0; i < this.chain.length; i++) {
- if (this.actionType[i] != other.getActionType()[i] ||
- (!this.chain[i].equals(other.getChain()[i])))
- return false;
- }
- return true;
- }
-
- /**
- * Returns a hash code value for this object.
- *
- * @see org.apache.lucene.search.RangeFilter#hashCode
- */
- @Override
- public int hashCode() {
- if (chain.length == 0)
- return 0;
-
- int h = chain[0].hashCode() ^ new Integer(actionType[0]).hashCode();
- for (int i = 1; i < this.chain.length; i++) {
- h ^= chain[i].hashCode();
- h ^= new Integer(actionType[i]).hashCode();
- }
- return h;
- }
-
- @Override
- public String toString() {
- StringBuffer buf = new StringBuffer();
- buf.append("SerialChainFilter(");
- for (int i = 0; i < chain.length; i++) {
- switch(actionType[i]) {
- case (SERIALAND): buf.append("SERIALAND"); break;
- case (SERIALOR): buf.append("SERIALOR"); break;
- case (AND): buf.append("AND"); break;
- case (OR): buf.append("OR"); break;
- default: buf.append(actionType[i]);
- }
- buf.append(" " + chain[i].toString() + " ");
- }
- return buf.toString().trim() + ")";
- }
-}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java
index bb22ba8e57d..73244858123 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/GeoHashDistanceFilter.java
@@ -18,17 +18,14 @@
package org.apache.lucene.spatial.geohash;
import java.io.IOException;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.logging.Logger;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.FieldCache;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.DocIdSet;
+import org.apache.lucene.search.FilteredDocIdSet;
import org.apache.lucene.spatial.tier.DistanceFilter;
import org.apache.lucene.spatial.tier.DistanceUtils;
-import org.apache.lucene.spatial.tier.DistanceHandler.Precision;
@@ -39,167 +36,62 @@ public class GeoHashDistanceFilter extends DistanceFilter {
*/
private static final long serialVersionUID = 1L;
- private double distance;
private double lat;
private double lng;
private String geoHashField;
- private Logger log = Logger.getLogger(getClass().getName());
-
- private Map distances = null;
- private Precision precise = null;
- int offset = 0;
- int nextOffset;
-
/**
* Provide a distance filter based from a center point with a radius
* in miles
+ * @param startingFilter
* @param lat
* @param lng
* @param miles
- * @param latField
- * @param lngField
*/
- public GeoHashDistanceFilter(double lat, double lng, double miles, String geoHashField){
- distance = miles;
+ public GeoHashDistanceFilter(Filter startingFilter, double lat, double lng, double miles, String geoHashField) {
+ super(startingFilter, miles);
this.lat = lat;
this.lng = lng;
this.geoHashField = geoHashField;
-
}
-
-
- public Map getDistances(){
- return distances;
- }
-
- public Double getDistance(int docid){
- return distances.get(docid);
- }
-
+
@Override
- public BitSet bits(IndexReader reader) throws IOException {
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
- /* Create a BitSet to store the result */
- int maxdocs = reader.numDocs();
- BitSet bits = new BitSet(maxdocs);
-
- setPrecision(maxdocs);
- // create an intermediate cache to avoid recomputing
- // distances for the same point
- // TODO: Why is this a WeakHashMap?
- WeakHashMap cdistance = new WeakHashMap(maxdocs);
-
- String[] geoHashCache = FieldCache.DEFAULT.getStrings(reader, geoHashField);
-
+ final String[] geoHashValues = FieldCache.DEFAULT.getStrings(reader, geoHashField);
- /* store calculated distances for reuse by other components */
- distances = new HashMap(maxdocs);
- for (int i = 0 ; i < maxdocs; i++) {
-
- String geoHash = geoHashCache[i];
- double[] coords = GeoHashUtils.decode(geoHash);
- double x = coords[0];
- double y = coords[1];
-
- // round off lat / longs if necessary
-// x = DistanceHandler.getPrecision(x, precise);
-// y = DistanceHandler.getPrecision(y, precise);
-
-
- Double cachedDistance = cdistance.get(geoHash);
-
-
- double d;
-
- if(cachedDistance != null){
- d = cachedDistance.doubleValue();
- } else {
- d = DistanceUtils.getInstance().getDistanceMi(lat, lng, x, y);
- cdistance.put(geoHash, d);
- }
- distances.put(i, d);
-
- if (d < distance){
- bits.set(i);
- }
-
- }
-
- return bits;
- }
+ final int docBase = nextDocBase;
+ nextDocBase += reader.maxDoc();
-
- @Override
- public BitSet bits(IndexReader reader, BitSet bits) throws Exception {
-
-
- /* Create a BitSet to store the result */
- int size = bits.cardinality();
- BitSet result = new BitSet(size);
-
-
- /* create an intermediate cache to avoid recomputing
- distances for the same point */
- HashMap cdistance = new HashMap(size);
-
-
- /* store calculated distances for reuse by other components */
- offset += reader.maxDoc();
- if (distances == null)
- distances = new HashMap(size);
-
- long start = System.currentTimeMillis();
- String[] geoHashCache = FieldCache.DEFAULT.getStrings(reader, geoHashField);
-
- /* loop over all set bits (hits from the boundary box filters) */
- int i = bits.nextSetBit(0);
- while (i >= 0){
-
- // if we have a completed
- // filter chain, lat / lngs can be retrived from
- // memory rather than document base.
-
- String geoHash = geoHashCache[i];
- double[] coords = GeoHashUtils.decode(geoHash);
- double x = coords[0];
- double y = coords[1];
-
- // round off lat / longs if necessary
-// x = DistanceHandler.getPrecision(x, precise);
-// y = DistanceHandler.getPrecision(y, precise);
-
-
- Double cachedDistance = cdistance.get(geoHash);
- double d;
-
- if(cachedDistance != null){
- d = cachedDistance.doubleValue();
+ return new FilteredDocIdSet(startingFilter.getDocIdSet(reader)) {
+ public boolean match(int doc) {
- } else {
- d = DistanceUtils.getInstance().getDistanceMi(lat, lng, x, y);
- //d = DistanceUtils.getLLMDistance(lat, lng, x, y);
- cdistance.put(geoHash, d);
- }
+ String geoHash = geoHashValues[doc];
+ double[] coords = GeoHashUtils.decode(geoHash);
+ double x = coords[0];
+ double y = coords[1];
- distances.put(i, d);
-
- if (d < distance){
- result.set(i);
- }
- i = bits.nextSetBit(i+1);
- }
-
- long end = System.currentTimeMillis();
- log.fine("Time taken : "+ (end - start) +
- ", results : "+ distances.size() +
- ", cached : "+ cdistance.size() +
- ", incoming size: "+ size);
-
+ // round off lat / longs if necessary
+ // x = DistanceHandler.getPrecision(x, precise);
+ // y = DistanceHandler.getPrecision(y, precise);
+ Double cachedDistance = distanceLookupCache.get(geoHash);
+ double d;
+
+ if (cachedDistance != null) {
+ d = cachedDistance.doubleValue();
+ } else {
+ d = DistanceUtils.getInstance().getDistanceMi(lat, lng, x, y);
+ distanceLookupCache.put(geoHash, d);
+ }
- cdistance = null;
- nextOffset += offset;
- return result;
+ if (d < distance){
+ distances.put(doc+docBase, d);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
}
/** Returns true if o
is equal to this. */
@@ -209,7 +101,8 @@ public class GeoHashDistanceFilter extends DistanceFilter {
if (!(o instanceof GeoHashDistanceFilter)) return false;
GeoHashDistanceFilter other = (GeoHashDistanceFilter) o;
- if (this.distance != other.distance ||
+ if (!this.startingFilter.equals(other.startingFilter) ||
+ this.distance != other.distance ||
this.lat != other.lat ||
this.lng != other.lng ||
!this.geoHashField.equals(other.geoHashField) ) {
@@ -222,26 +115,11 @@ public class GeoHashDistanceFilter extends DistanceFilter {
@Override
public int hashCode() {
int h = new Double(distance).hashCode();
+ h ^= startingFilter.hashCode();
h ^= new Double(lat).hashCode();
h ^= new Double(lng).hashCode();
h ^= geoHashField.hashCode();
return h;
}
-
- private void setPrecision(int maxDocs) {
- precise = Precision.EXACT;
-
- if (maxDocs > 1000 && distance > 10) {
- precise = Precision.TWENTYFEET;
- }
-
- if (maxDocs > 10000 && distance > 10){
- precise = Precision.TWOHUNDREDFEET;
- }
- }
-
- public void setDistances(Map distances) {
- this.distances = distances;
- }
}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/CartesianPoint.java b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/CartesianPoint.java
index 44449c50a73..ec44f91f95f 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/CartesianPoint.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/CartesianPoint.java
@@ -46,9 +46,6 @@ public class CartesianPoint {
/**
* Return a new point translated in the x and y dimensions
- * @param i
- * @param translation
- * @return
*/
public CartesianPoint translate(int deltaX, int deltaY) {
return new CartesianPoint(this.x+deltaX, this.y+deltaY);
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLng.java b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLng.java
index 5e8efc5a569..259fa89853a 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLng.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/LatLng.java
@@ -22,7 +22,6 @@ package org.apache.lucene.spatial.geometry;
* Abstract base lat-lng class which can manipulate fixed point or floating
* point based coordinates. Instances are immutable.
*
- * @see FixedLatLngTest
* @see FloatLatLng
*
*/
@@ -62,8 +61,6 @@ public abstract class LatLng {
* The x dimension corresponds to latitude and y corresponds to longitude.
* The translation starts with the normalized latlng and adds 180 to the latitude and
* 90 to the longitude (subject to fixed point scaling).
- *
- * @return
*/
public CartesianPoint toCartesian() {
LatLng ll=normalize();
@@ -80,7 +77,6 @@ public abstract class LatLng {
/**
* The inverse of toCartesian(). Always returns a FixedLatLng.
* @param pt
- * @return
*/
public static LatLng fromCartesian(CartesianPoint pt) {
int lat=pt.getY() - 90 * FixedLatLng.SCALE_FACTOR_INT;
@@ -158,7 +154,6 @@ public abstract class LatLng {
/**
* Calculate the midpoint between this point an another. Respects fixed vs floating point
* @param other
- * @return
*/
public abstract LatLng calculateMidpoint(LatLng other);
}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Ellipse.java b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Ellipse.java
index 1f9b916cb6a..767b3bf9a33 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Ellipse.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Ellipse.java
@@ -56,9 +56,6 @@ public class Ellipse implements Geometry2D {
/**
* Constructor given bounding rectangle and a rotation.
- *
- * @param
- * @param
*/
public Ellipse(Point2D p1, Point2D p2, double angle) {
center = new Point2D();
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Geometry2D.java b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Geometry2D.java
index f7354ef6ebb..978507b1227 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Geometry2D.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/Geometry2D.java
@@ -31,26 +31,22 @@ public interface Geometry2D {
/**
* Does the shape contain the given point
* @param p
- * @return
*/
public boolean contains(Point2D p);
/**
* Return the area
- * @return
*/
public double area();
/**
* Return the centroid
- * @return
*/
public Point2D centroid();
/**
* Returns information about how this shape intersects the given rectangle
* @param r
- * @return
*/
public IntersectCase intersect(Rectangle r);
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LLRect.java b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LLRect.java
index 0a3e001b519..ab6f2349ce9 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LLRect.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/shape/LLRect.java
@@ -41,7 +41,6 @@ public class LLRect {
/**
* Return the area in units of lat-lng squared. This is a contrived unit
* that only has value when comparing to something else.
- * @return
*/
public double area() {
return Math.abs((ll.getLat()-ur.getLat()) * (ll.getLng()-ur.getLng()));
@@ -79,7 +78,6 @@ public class LLRect {
* @param center
* @param widthMi
* @param heightMi
- * @return
*/
public static LLRect createBox(LatLng center, double widthMi, double heightMi) {
double miplatdeg=DistanceApproximation.getMilesPerLngDeg(center.getLat());
@@ -97,7 +95,6 @@ public class LLRect {
/**
* Returns a rectangle shape for the bounding box
- * @return
*/
public Rectangle toRectangle() {
return new Rectangle(ll.getLng(), ll.getLat(), ur.getLng(), ur.getLat());
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/BoundaryBoxFilter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/BoundaryBoxFilter.java
index 08c3efe9074..6431e83258d 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/BoundaryBoxFilter.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/BoundaryBoxFilter.java
@@ -18,7 +18,6 @@
package org.apache.lucene.spatial.tier;
import java.io.IOException;
-import java.util.BitSet;
import java.util.logging.Logger;
import org.apache.lucene.index.IndexReader;
@@ -26,7 +25,9 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.util.NumericUtils;
+import org.apache.lucene.util.OpenBitSet;
@@ -84,15 +85,15 @@ public class BoundaryBoxFilter extends Filter {
/**
- * Returns a BitSet with true for documents which should be
+ * Returns a DocIdSet with true for documents which should be
* permitted in search results, and false for those that should
* not.
*/
@Override
- public BitSet bits(IndexReader reader) throws IOException {
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
long start = System.currentTimeMillis();
- BitSet bits = new BitSet(reader.maxDoc());
+ OpenBitSet bits = new OpenBitSet(reader.maxDoc());
TermEnum enumerator =
(null != lowerTerm
? reader.terms(new Term(fieldName, lowerTerm))
@@ -128,7 +129,7 @@ public class BoundaryBoxFilter extends Filter {
// we have a good term, find the docs
termDocs.seek(enumerator.term());
while (termDocs.next()) {
- bits.set(termDocs.doc());
+ bits.fastSet(termDocs.doc());
}
}
}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianPolyFilterBuilder.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianPolyFilterBuilder.java
index 212dc518253..f6e0b12a3e8 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianPolyFilterBuilder.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianPolyFilterBuilder.java
@@ -33,6 +33,12 @@ import org.apache.lucene.spatial.tier.projections.SinusoidalProjector;
*/
public class CartesianPolyFilterBuilder {
+ // Finer granularity than 1 mile isn't accurate with
+ // standard java math. Also, there's already a 2nd
+ // precise filter, if needed, in DistanceQueryBuilder,
+ // that will make the filtering exact.
+ public static final double MILES_FLOOR = 1.0;
+
private IProjector projector = new SinusoidalProjector();
private Logger log = Logger.getLogger(getClass().getName());
@@ -42,10 +48,12 @@ public class CartesianPolyFilterBuilder {
this.tierPrefix = tierPrefix;
}
- public Shape getBoxShape(double latitude, double longitude, int miles)
+ public Shape getBoxShape(double latitude, double longitude, double miles)
{
+ if (miles < MILES_FLOOR) {
+ miles = MILES_FLOOR;
+ }
Rectangle box = DistanceUtils.getInstance().getBoundary(latitude, longitude, miles);
-
double latY = box.getMaxPoint().getY();//box.getY();
double latX = box.getMinPoint().getY() ; //box.getMaxY();
@@ -104,7 +112,7 @@ public class CartesianPolyFilterBuilder {
return shape;
}
- public Filter getBoundingArea(double latitude, double longitude, int miles)
+ public Filter getBoundingArea(double latitude, double longitude, double miles)
{
Shape shape = getBoxShape(latitude, longitude, miles);
return new CartesianShapeFilter(shape, shape.getTierId());
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java
index 1cc3c43ffd8..5b4b18a60ea 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/CartesianShapeFilter.java
@@ -17,7 +17,6 @@
package org.apache.lucene.spatial.tier;
import java.io.IOException;
-import java.util.BitSet;
import java.util.List;
import java.util.logging.Logger;
@@ -25,7 +24,9 @@ import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.util.NumericUtils;
+import org.apache.lucene.util.OpenBitSet;
public class CartesianShapeFilter extends Filter {
@@ -43,16 +44,16 @@ public class CartesianShapeFilter extends Filter {
}
@Override
- public BitSet bits(IndexReader reader) throws IOException {
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
long start = System.currentTimeMillis();
- BitSet bits = new BitSet(reader.maxDoc());
+ OpenBitSet bits = new OpenBitSet(reader.maxDoc());
TermDocs termDocs = reader.termDocs();
List area = shape.getArea();
int sz = area.size();
log.fine("Area size "+ sz);
-
+
// iterate through each boxid
for (int i =0; i< sz; i++) {
double boxId = area.get(i).doubleValue();
@@ -62,7 +63,7 @@ public class CartesianShapeFilter extends Filter {
// iterate through all documents
// which have this boxId
while (termDocs.next()) {
- bits.set(termDocs.doc());
+ bits.fastSet(termDocs.doc());
}
}
@@ -70,5 +71,4 @@ public class CartesianShapeFilter extends Filter {
log.fine("BoundaryBox Time Taken: "+ (end - start) + " found: "+bits.cardinality()+" candidates");
return bits;
}
-
}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFilter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFilter.java
index 0dcb3d10d6d..b83bef101d5 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFilter.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceFilter.java
@@ -16,38 +16,81 @@
package org.apache.lucene.spatial.tier;
-import java.io.IOException;
-import java.util.BitSet;
import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.HashMap;
-import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.spatial.ISerialChainFilter;
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.spatial.tier.DistanceHandler.Precision;
+public abstract class DistanceFilter extends Filter {
-public abstract class DistanceFilter extends ISerialChainFilter {
+ final protected Filter startingFilter;
+ protected Precision precise;
+ protected Map distances;
+ protected double distance;
- public DistanceFilter() {
- super();
- }
+ protected int nextDocBase;
+ protected final WeakHashMap distanceLookupCache;
- public abstract Map getDistances();
+ /** Filters the startingFilter by precise distance
+ * checking filter */
+ public DistanceFilter(Filter startingFilter, double distance) {
+ if (startingFilter == null) {
+ throw new IllegalArgumentException("please provide a non-null startingFilter; you can use QueryWrapperFilter(MatchAllDocsQuery) as a no-op filter");
+ }
+ this.startingFilter = startingFilter;
+ this.distance = distance;
- public abstract Double getDistance(int docid);
+ // NOTE: neither of the distance filters use precision
+ // now - if we turn that on, we'll need to pass top
+ // reader into here
+ // setPrecision(reader.maxDoc());
- @Override
- public abstract BitSet bits(IndexReader reader) throws IOException;
+ /* store calculated distances for reuse by other components */
+ distances = new HashMap();
- @Override
- public abstract BitSet bits(IndexReader reader, BitSet bits) throws Exception;
+ // create an intermediate cache to avoid recomputing
+ // distances for the same point
+ // TODO: Why is this a WeakHashMap?
+ distanceLookupCache = new WeakHashMap();
+ }
- /** Returns true if o
is equal to this. */
- @Override
- public abstract boolean equals(Object o);
+ public Map getDistances(){
+ return distances;
+ }
+
+ public Double getDistance(int docid){
+ return distances.get(docid);
+ }
+
+ public void setDistances(Map distances) {
+ this.distances = distances;
+ }
- /** Returns a hash code value for this object.*/
- @Override
- public abstract int hashCode();
+ /** You must call this before re-using this DistanceFilter
+ * across searches */
+ public void reset() {
+ nextDocBase = 0;
+ }
- public abstract void setDistances(Map distances);
+ /** Returns true if o
is equal to this. */
+ public abstract boolean equals(Object o);
-}
\ No newline at end of file
+ /** Returns a hash code value for this object.*/
+ public abstract int hashCode();
+
+ /*
+ private void setPrecision(int maxDocs) {
+ precise = Precision.EXACT;
+
+ if (maxDocs > 1000 && distance > 10) {
+ precise = Precision.TWENTYFEET;
+ }
+
+ if (maxDocs > 10000 && distance > 10){
+ precise = Precision.TWOHUNDREDFEET;
+ }
+ }
+ */
+}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceQueryBuilder.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceQueryBuilder.java
index bbc7ba33a1a..9003729e37f 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceQueryBuilder.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceQueryBuilder.java
@@ -21,8 +21,8 @@ import org.apache.lucene.search.ConstantScoreQuery;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryWrapperFilter;
-import org.apache.lucene.spatial.SerialChainFilter;
import org.apache.lucene.spatial.geohash.GeoHashDistanceFilter;
+import org.apache.lucene.misc.ChainedFilter;
public class DistanceQueryBuilder {
@@ -31,39 +31,39 @@ public class DistanceQueryBuilder {
public BoundaryBoxFilter latFilter;
public BoundaryBoxFilter lngFilter;
- public DistanceFilter distanceFilter;
private final double lat;
private final double lng;
private final double miles;
- private Filter cartesianFilter;
- private boolean needPrecision = true;
+ private final Filter filter;
+ final DistanceFilter distanceFilter;
+
/**
* Create a distance query using
* a boundary box wrapper around a more precise
* DistanceFilter.
*
- * @see SerialChainFilter
* @param lat
* @param lng
* @param miles
*/
public DistanceQueryBuilder (double lat, double lng, double miles,
- String latField, String lngField, String tierFieldPrefix,boolean needPrecise){
+ String latField, String lngField, String tierFieldPrefix, boolean needPrecise) {
this.lat = lat;
this.lng = lng;
this.miles = miles;
- this.needPrecision = needPrecise;
-
CartesianPolyFilterBuilder cpf = new CartesianPolyFilterBuilder(tierFieldPrefix);
- cartesianFilter = cpf.getBoundingArea(lat, lng, (int)miles);
+ Filter cartesianFilter = cpf.getBoundingArea(lat, lng, miles);
/* create precise distance filter */
- if( needPrecise)
- distanceFilter = new LatLongDistanceFilter(lat, lng, miles, latField, lngField);
-
+ if (needPrecise) {
+ filter = distanceFilter = new LatLongDistanceFilter(cartesianFilter, lat, lng, miles, latField, lngField);
+ } else {
+ filter = cartesianFilter;
+ distanceFilter = null;
+ }
}
/**
@@ -71,80 +71,54 @@ public class DistanceQueryBuilder {
* a boundary box wrapper around a more precise
* DistanceFilter.
*
- * @see SerialChainFilter
* @param lat
* @param lng
* @param miles
*/
public DistanceQueryBuilder (double lat, double lng, double miles,
- String geoHashFieldPrefix, String tierFieldPrefix,boolean needPrecise){
+ String geoHashFieldPrefix, String tierFieldPrefix, boolean needPrecise){
this.lat = lat;
this.lng = lng;
this.miles = miles;
- this.needPrecision = needPrecise;
CartesianPolyFilterBuilder cpf = new CartesianPolyFilterBuilder(tierFieldPrefix);
- cartesianFilter = cpf.getBoundingArea(lat, lng, (int)miles);
+ Filter cartesianFilter = cpf.getBoundingArea(lat, lng, miles);
/* create precise distance filter */
- if( needPrecise)
- distanceFilter = new GeoHashDistanceFilter(lat, lng, miles, geoHashFieldPrefix);
-
+ if (needPrecise) {
+ filter = distanceFilter = new GeoHashDistanceFilter(cartesianFilter, lat, lng, miles, geoHashFieldPrefix);
+ } else {
+ filter = cartesianFilter;
+ distanceFilter = null;
+ }
}
- /**
+ /**
* Create a distance query using
* a boundary box wrapper around a more precise
* DistanceFilter.
- *
- * @see SerialChainFilter
- * @param lat
- * @param lng
- * @param miles
*/
public Filter getFilter() {
- Filter [] f;
- int [] chain;
-
- if (needPrecision){
- f = new Filter[]{cartesianFilter, distanceFilter};
- chain = new int[] {SerialChainFilter.AND,
- SerialChainFilter.SERIALAND};
- }else{
- f= new Filter[]{cartesianFilter};
- chain = new int[] {SerialChainFilter.AND};
- }
- return new SerialChainFilter( f, chain );
+ if (distanceFilter != null) {
+ distanceFilter.reset();
+ }
+ return filter;
}
public Filter getFilter(Query query) {
+ // Chain the Query (as filter) with our distance filter
+ if (distanceFilter != null) {
+ distanceFilter.reset();
+ }
QueryWrapperFilter qf = new QueryWrapperFilter(query);
-
- Filter [] f;
- int [] chain;
-
- if (needPrecision){
- f = new Filter[]{cartesianFilter, qf, distanceFilter};
- chain = new int[] {SerialChainFilter.AND,
- SerialChainFilter.AND,
- SerialChainFilter.SERIALAND};
- }else{
- f= new Filter[]{cartesianFilter, qf};
- chain = new int[] {SerialChainFilter.AND,
- SerialChainFilter.AND};
- }
- return new SerialChainFilter(f,chain);
+ return new ChainedFilter(new Filter[] {qf, filter},
+ ChainedFilter.AND);
}
-// public Query getQuery() {
-// return new ConstantScoreQuery(getFilter());
-// }
-
-
public Query getQuery(Query query){
- return new ConstantScoreQuery(getFilter(query));
+ return new ConstantScoreQuery(getFilter(query));
}
public double getLat() {
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceSortSource.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceSortSource.java
index ccf05643f84..26805081cf0 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceSortSource.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/DistanceSortSource.java
@@ -71,19 +71,10 @@ public class DistanceSortSource implements SortComparatorSource {
public int compare(ScoreDoc aDoc, ScoreDoc bDoc) {
-
-// if (this.distances == null) {
-// distances = distanceFilter.getDistances();
-// }
- //System.out.println("comparing : "+ aDoc.doc+ " - "+ bDoc.doc);
- try {
- double a = distanceFilter.getDistance(aDoc.doc);
- double b = distanceFilter.getDistance(bDoc.doc);
- if (a > b) return 1;
- if (a < b )return -1;
- } catch (Exception e){
- System.out.println(" Failed with sort with "+ aDoc.doc +" - "+bDoc.doc);
- }
+ double a = distanceFilter.getDistance(aDoc.doc);
+ double b = distanceFilter.getDistance(bDoc.doc);
+ if (a > b) return 1;
+ if (a < b) return -1;
return 0;
}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java
index fedd8d32ffa..bdf6183c38e 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/LatLongDistanceFilter.java
@@ -18,19 +18,11 @@
package org.apache.lucene.spatial.tier;
import java.io.IOException;
-import java.util.BitSet;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.logging.Logger;
-
import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.index.TermDocs;
+import org.apache.lucene.search.FilteredDocIdSet;
import org.apache.lucene.search.FieldCache;
-import org.apache.lucene.util.NumericUtils;
-import org.apache.lucene.spatial.tier.DistanceHandler.Precision;
-
-
+import org.apache.lucene.search.Filter;
+import org.apache.lucene.search.DocIdSet;
public class LatLongDistanceFilter extends DistanceFilter {
@@ -40,192 +32,70 @@ public class LatLongDistanceFilter extends DistanceFilter {
*/
private static final long serialVersionUID = 1L;
- double distance;
double lat;
double lng;
String latField;
String lngField;
- Logger log = Logger.getLogger(getClass().getName());
int nextOffset = 0;
- Map distances = null;
- private Precision precise = null;
-
/**
* Provide a distance filter based from a center point with a radius
- * in miles
+ * in miles.
+ * @param startingFilter Filter to start from
* @param lat
* @param lng
* @param miles
* @param latField
* @param lngField
*/
- public LatLongDistanceFilter(double lat, double lng, double miles, String latField, String lngField){
- distance = miles;
+ public LatLongDistanceFilter(Filter startingFilter, double lat, double lng, double miles, String latField, String lngField) {
+ super(startingFilter, miles);
this.lat = lat;
this.lng = lng;
this.latField = latField;
this.lngField = lngField;
}
-
- public Map getDistances(){
- return distances;
- }
-
- public Double getDistance(int docid){
- return distances.get(docid);
- }
-
@Override
- public BitSet bits(IndexReader reader) throws IOException {
+ public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
- /* Create a BitSet to store the result */
- int maxdocs = reader.maxDoc();
- BitSet bits = new BitSet(maxdocs);
-
- setPrecision(maxdocs);
- // create an intermediate cache to avoid recomputing
- // distances for the same point
- // TODO: Why is this a WeakHashMap?
- WeakHashMap cdistance = new WeakHashMap(maxdocs);
- long start = System.currentTimeMillis();
- double[] latIndex = FieldCache.DEFAULT.getDoubles(reader, latField);
- double[] lngIndex = FieldCache.DEFAULT.getDoubles(reader, lngField);
+ final double[] latIndex = FieldCache.DEFAULT.getDoubles(reader, latField);
+ final double[] lngIndex = FieldCache.DEFAULT.getDoubles(reader, lngField);
- /* store calculated distances for reuse by other components */
- distances = new HashMap(maxdocs);
-
- if (distances == null){
- distances = new HashMap();
- }
+ final int docBase = nextDocBase;
+ nextDocBase += reader.maxDoc();
- TermDocs td = reader.termDocs(null);
- while(td.next()) {
- int doc = td.doc();
+ return new FilteredDocIdSet(startingFilter.getDocIdSet(reader)) {
+ protected boolean match(int doc) {
+ double x = latIndex[doc];
+ double y = lngIndex[doc];
- double x = latIndex[doc];
- double y = lngIndex[doc];
+ // round off lat / longs if necessary
+ // x = DistanceHandler.getPrecision(x, precise);
+ // y = DistanceHandler.getPrecision(y, precise);
- // round off lat / longs if necessary
-// x = DistanceHandler.getPrecision(x, precise);
-// y = DistanceHandler.getPrecision(y, precise);
-
- String ck = new Double(x).toString()+","+new Double(y).toString();
- Double cachedDistance = cdistance.get(ck);
-
-
- double d;
-
- if(cachedDistance != null){
- d = cachedDistance.doubleValue();
- } else {
- d = DistanceUtils.getInstance().getDistanceMi(lat, lng, x, y);
- cdistance.put(ck, d);
+ String ck = Double.toString(x)+","+Double.toString(y);
+ Double cachedDistance = distanceLookupCache.get(ck);
+
+ double d;
+ if (cachedDistance != null){
+ d = cachedDistance.doubleValue();
+ } else {
+ d = DistanceUtils.getInstance().getDistanceMi(lat, lng, x, y);
+ distanceLookupCache.put(ck, d);
+ }
+
+ if (d < distance) {
+ // Save distances, so they can be pulled for
+ // sorting after filtering is done:
+ distances.put(doc+docBase, d);
+ return true;
+ } else {
+ return false;
+ }
}
-
- // why was i storing all distances again?
- if (d < distance){
- bits.set(doc);
- distances.put(doc+ nextOffset, d); // include nextOffset for multi segment reader
- }
- }
- int size = bits.cardinality();
- nextOffset += reader.maxDoc(); // this should be something that's part of indexReader
- long end = System.currentTimeMillis();
- log.fine("Bits 1: Time taken : "+ (end - start) +
- ", results : "+ distances.size() +
- ", cached : "+ cdistance.size() +
- ", incoming size: "+ size+
- ", nextOffset: "+ nextOffset);
-
- return bits;
- }
-
-
- @Override
- public BitSet bits(IndexReader reader, BitSet bits) throws Exception {
-
-
- /* Create a BitSet to store the result */
-
- int size = bits.cardinality();
- BitSet result = new BitSet(size);
-
-
- /* create an intermediate cache to avoid recomputing
- distances for the same point */
- HashMap cdistance = new HashMap(size);
-
-
-
- if (distances == null){
- distances = new HashMap();
- }
-
- long start = System.currentTimeMillis();
- double[] latIndex = FieldCache.DEFAULT.getDoubles(reader, latField);
- double[] lngIndex = FieldCache.DEFAULT.getDoubles(reader, lngField);
-
- /* loop over all set bits (hits from the boundary box filters) */
- int i = bits.nextSetBit(0);
- while (i >= 0){
-
- if (reader.isDeleted(i)) {
- i = bits.nextSetBit(i+1);
- continue;
- }
-
- double x,y;
-
- // if we have a completed
- // filter chain, lat / lngs can be retrived from
- // memory rather than document base.
-
- x = latIndex[i];
- y = lngIndex[i];
-
- // round off lat / longs if necessary
-// x = DistanceHandler.getPrecision(x, precise);
-// y = DistanceHandler.getPrecision(y, precise);
-
- String ck = new Double(x).toString()+","+new Double(y).toString();
- Double cachedDistance = cdistance.get(ck);
- double d;
-
- if(cachedDistance != null){
- d = cachedDistance.doubleValue();
-
- } else {
- d = DistanceUtils.getInstance().getDistanceMi(lat, lng, x, y);
- //d = DistanceUtils.getLLMDistance(lat, lng, x, y);
- cdistance.put(ck, d);
- }
-
- // why was i storing all distances again?
- if (d < distance){
- result.set(i);
- int did = i + nextOffset;
- distances.put(did, d); // include nextOffset for multi segment reader
-
- }
- i = bits.nextSetBit(i+1);
- }
-
- long end = System.currentTimeMillis();
- nextOffset += reader.maxDoc(); // this should be something that's part of indexReader
- log.fine("Time taken : "+ (end - start) +
- ", results : "+ distances.size() +
- ", cached : "+ cdistance.size() +
- ", incoming size: "+ size+
- ", nextOffset: "+ nextOffset);
-
-
- cdistance = null;
-
-
- return result;
+ };
}
/** Returns true if o
is equal to this. */
@@ -235,7 +105,8 @@ public class LatLongDistanceFilter extends DistanceFilter {
if (!(o instanceof LatLongDistanceFilter)) return false;
LatLongDistanceFilter other = (LatLongDistanceFilter) o;
- if (this.distance != other.distance ||
+ if (!this.startingFilter.equals(other.startingFilter) ||
+ this.distance != other.distance ||
this.lat != other.lat ||
this.lng != other.lng ||
!this.latField.equals(other.latField) ||
@@ -249,28 +120,11 @@ public class LatLongDistanceFilter extends DistanceFilter {
@Override
public int hashCode() {
int h = new Double(distance).hashCode();
+ h ^= startingFilter.hashCode();
h ^= new Double(lat).hashCode();
h ^= new Double(lng).hashCode();
h ^= latField.hashCode();
h ^= lngField.hashCode();
return h;
}
-
-
-
- public void setDistances(Map distances) {
- this.distances = distances;
- }
-
- void setPrecision(int maxDocs) {
- precise = Precision.EXACT;
-
- if (maxDocs > 1000 && distance > 10) {
- precise = Precision.TWENTYFEET;
- }
-
- if (maxDocs > 10000 && distance > 10){
- precise = Precision.TWOHUNDREDFEET;
- }
- }
}
diff --git a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/CartesianTierPlotter.java b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/CartesianTierPlotter.java
index 17dd6708e50..bcd82b4c79b 100644
--- a/contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/CartesianTierPlotter.java
+++ b/contrib/spatial/src/java/org/apache/lucene/spatial/tier/projections/CartesianTierPlotter.java
@@ -82,7 +82,6 @@ public class CartesianTierPlotter {
*
* @param latitude
* @param longitude
- * @return
*/
public double getTierBoxId (double latitude, double longitude) {
@@ -106,7 +105,6 @@ public class CartesianTierPlotter {
/**
* get the string name representing current tier
* _localTier<tiedId>
- * @return
*/
public String getTierFieldName (){
@@ -117,7 +115,6 @@ public class CartesianTierPlotter {
* get the string name representing tierId
* _localTier<tierId>
* @param tierId
- * @return
*/
public String getTierFieldName (int tierId){
@@ -133,12 +130,8 @@ public class CartesianTierPlotter {
*
* Distances less than a mile return 15, finer granularity is
* in accurate
- *
- * @param latitude
- * @param longitude
- * @return
*/
- public int bestFit(int miles){
+ public int bestFit(double miles){
//28,892 a rough circumference of the earth
int circ = 28892;
@@ -146,7 +139,6 @@ public class CartesianTierPlotter {
double r = miles / 2.0;
double corner = r - Math.sqrt(Math.pow(r, 2) / 2.0d);
- System.out.println("corner "+ corner);
double times = circ / corner;
int bestFit = (int)Math.ceil(log2(times)) + 1;
@@ -162,7 +154,6 @@ public class CartesianTierPlotter {
* a log to the base 2 formula
* Math.log(value) / Math.log(2)
* @param value
- * @return
*/
public double log2(double value) {
diff --git a/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java b/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java
index 5d43a06ba38..a6ce027e829 100644
--- a/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java
+++ b/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestCartesian.java
@@ -145,168 +145,178 @@ public class TestCartesian extends TestCase{
public void testRange() throws IOException, InvalidGeoException {
searcher = new IndexSearcher(directory);
+
+ final double[] milesToTest = new double[] {6.0, 0.5, 0.001, 0.0};
+ final int[] expected = new int[] {7, 1, 0, 0};
+
+ for(int x=0;x distances = dq.distanceFilter.getDistances();
+
+ // distances calculated from filter first pass must be less than total
+ // docs, from the above test of 20 items, 12 will come from the boundary box
+ // filter, but only 5 are actually in the radius of the results.
+
+ // Note Boundary Box filtering, is not accurate enough for most systems.
+
+
+ System.out.println("Distance Filter filtered: " + distances.size());
+ System.out.println("Results: " + results);
+ System.out.println("=============================");
+ System.out.println("Distances should be 7 "+ distances.size());
+ System.out.println("Results should be 7 "+ results);
+
+ assertEquals(expected[x], distances.size()); // fixed a store of only needed distances
+ assertEquals(expected[x], results);
+ double lastDistance = 0;
+ for(int i =0 ; i < results; i++){
+ Document d = hits.doc(i);
+
+ String name = d.get("name");
+ double rsLat = NumericUtils.prefixCodedToDouble(d.get(latField));
+ double rsLng = NumericUtils.prefixCodedToDouble(d.get(lngField));
+ Double geo_distance = distances.get(hits.id(i));
+
+ double distance = DistanceUtils.getInstance().getDistanceMi(lat, lng, rsLat, rsLng);
+ double llm = DistanceUtils.getInstance().getLLMDistance(lat, lng, rsLat, rsLng);
+ System.out.println("Name: "+ name +", Distance "+ distance); //(res, ortho, harvesine):"+ distance +" |"+ geo_distance +"|"+ llm +" | score "+ hits.score(i));
+ assertTrue(Math.abs((distance - llm)) < 1);
+ assertTrue((distance < miles ));
+ assertTrue(geo_distance > lastDistance);
+ lastDistance = geo_distance;
}
- };
- // Create a distance sort
- // As the radius filter has performed the distance calculations
- // already, pass in the filter to reuse the results.
- //
- DistanceFieldComparatorSource dsort = new DistanceFieldComparatorSource(dq.distanceFilter);
- Sort sort = new Sort(new SortField("foo", dsort,false));
-
- // Perform the search, using the term query, the serial chain filter, and the
- // distance sort
- Hits hits = searcher.search(customScore,null,sort);
-
- int results = hits.length();
-
- // Get a list of distances
- Map distances = dq.distanceFilter.getDistances();
-
- // distances calculated from filter first pass must be less than total
- // docs, from the above test of 20 items, 12 will come from the boundary box
- // filter, but only 5 are actually in the radius of the results.
-
- // Note Boundary Box filtering, is not accurate enough for most systems.
-
-
- System.out.println("Distance Filter filtered: " + distances.size());
- System.out.println("Results: " + results);
- System.out.println("=============================");
- System.out.println("Distances should be 7 "+ distances.size());
- System.out.println("Results should be 7 "+ results);
-
- assertEquals(7, distances.size()); // fixed a store of only needed distances
- assertEquals(7, results);
- double lastDistance = 0;
- for(int i =0 ; i < results; i++){
- Document d = hits.doc(i);
-
- String name = d.get("name");
- double rsLat = NumericUtils.prefixCodedToDouble(d.get(latField));
- double rsLng = NumericUtils.prefixCodedToDouble(d.get(lngField));
- Double geo_distance = distances.get(hits.id(i));
-
- double distance = DistanceUtils.getInstance().getDistanceMi(lat, lng, rsLat, rsLng);
- double llm = DistanceUtils.getInstance().getLLMDistance(lat, lng, rsLat, rsLng);
- System.out.println("Name: "+ name +", Distance "+ distance); //(res, ortho, harvesine):"+ distance +" |"+ geo_distance +"|"+ llm +" | score "+ hits.score(i));
- assertTrue(Math.abs((distance - llm)) < 1);
- assertTrue((distance < miles ));
- assertTrue(geo_distance > lastDistance);
- lastDistance = geo_distance;
}
}
public void testGeoHashRange() throws IOException, InvalidGeoException {
- searcher = new IndexSearcher(directory);
+ searcher = new IndexSearcher(directory);
- final double miles = 6.0;
+ final double[] milesToTest = new double[] {6.0, 0.5, 0.001, 0.0};
+ final int[] expected = new int[] {7, 1, 0, 0};
+
+ for(int x=0;x distances = dq.distanceFilter.getDistances();
+ // Get a list of distances
+ Map distances = dq.distanceFilter.getDistances();
- // distances calculated from filter first pass must be less than total
- // docs, from the above test of 20 items, 12 will come from the boundary box
- // filter, but only 5 are actually in the radius of the results.
+ // distances calculated from filter first pass must be less than total
+ // docs, from the above test of 20 items, 12 will come from the boundary box
+ // filter, but only 5 are actually in the radius of the results.
- // Note Boundary Box filtering, is not accurate enough for most systems.
+ // Note Boundary Box filtering, is not accurate enough for most systems.
- System.out.println("Distance Filter filtered: " + distances.size());
- System.out.println("Results: " + results);
- System.out.println("=============================");
- System.out.println("Distances should be 14 "+ distances.size());
- System.out.println("Results should be 7 "+ results);
+ System.out.println("Distance Filter filtered: " + distances.size());
+ System.out.println("Results: " + results);
+ System.out.println("=============================");
+ System.out.println("Distances should be 14 "+ distances.size());
+ System.out.println("Results should be 7 "+ results);
- assertEquals(14, distances.size());
- assertEquals(7, results);
+ assertEquals(expected[x], distances.size());
+ assertEquals(expected[x], results);
- for(int i =0 ; i < results; i++){
- Document d = hits.doc(i);
+ for(int i =0 ; i < results; i++){
+ Document d = hits.doc(i);
- String name = d.get("name");
- double rsLat = NumericUtils.prefixCodedToDouble(d.get(latField));
- double rsLng = NumericUtils.prefixCodedToDouble(d.get(lngField));
- Double geo_distance = distances.get(hits.id(i));
+ String name = d.get("name");
+ double rsLat = NumericUtils.prefixCodedToDouble(d.get(latField));
+ double rsLng = NumericUtils.prefixCodedToDouble(d.get(lngField));
+ Double geo_distance = distances.get(hits.id(i));
- double distance = DistanceUtils.getInstance().getDistanceMi(lat, lng, rsLat, rsLng);
- double llm = DistanceUtils.getInstance().getLLMDistance(lat, lng, rsLat, rsLng);
- System.out.println("Name: "+ name +", Distance (res, ortho, harvesine):"+ distance +" |"+ geo_distance +"|"+ llm +" | score "+ hits.score(i));
- assertTrue(Math.abs((distance - llm)) < 1);
- assertTrue((distance < miles ));
+ double distance = DistanceUtils.getInstance().getDistanceMi(lat, lng, rsLat, rsLng);
+ double llm = DistanceUtils.getInstance().getLLMDistance(lat, lng, rsLat, rsLng);
+ System.out.println("Name: "+ name +", Distance (res, ortho, harvesine):"+ distance +" |"+ geo_distance +"|"+ llm +" | score "+ hits.score(i));
+ assertTrue(Math.abs((distance - llm)) < 1);
+ assertTrue((distance < miles ));
- }
- }
-
+ }
+ }
+ }
}
diff --git a/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java b/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java
index 9d0a135d9c3..a1b919b21c7 100644
--- a/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java
+++ b/contrib/spatial/src/test/org/apache/lucene/spatial/tier/TestDistance.java
@@ -17,7 +17,6 @@
package org.apache.lucene.spatial.tier;
import java.io.IOException;
-import java.util.BitSet;
import junit.framework.TestCase;
@@ -27,10 +26,9 @@ import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.IndexReader;
-import org.apache.lucene.search.Filter;
-import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.QueryWrapperFilter;
+import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.util.NumericUtils;
-import org.apache.lucene.spatial.tier.LatLongDistanceFilter;
import org.apache.lucene.store.RAMDirectory;
@@ -41,7 +39,6 @@ public class TestDistance extends TestCase{
private RAMDirectory directory;
- private IndexSearcher searcher;
// reston va
private double lat = 38.969398;
private double lng= -77.386398;
@@ -103,13 +100,13 @@ public class TestDistance extends TestCase{
public void testLatLongFilterOnDeletedDocs() throws Exception {
writer.deleteDocuments(new Term("name", "Potomac"));
IndexReader r = writer.getReader();
- LatLongDistanceFilter f = new LatLongDistanceFilter(lat, lng, 1.0, latField, lngField);
- f.bits(r);
+ LatLongDistanceFilter f = new LatLongDistanceFilter(new QueryWrapperFilter(new MatchAllDocsQuery()),
+ lat, lng, 1.0, latField, lngField);
- BitSet allSet = new BitSet(r.maxDoc());
- allSet.set(0, r.maxDoc());
- f.bits(r, allSet);
- r.close();
+ IndexReader[] readers = r.getSequentialSubReaders();
+ for(int i=0;i