You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by gs...@apache.org on 2010/12/02 19:24:22 UTC

svn commit: r1041512 - in /lucene/dev/branches/branch_3x: ./ lucene/ solr/ solr/src/java/org/apache/solr/schema/ solr/src/java/org/apache/solr/search/ solr/src/java/org/apache/solr/search/function/ solr/src/java/org/apache/solr/search/function/distance...

Author: gsingers
Date: Thu Dec  2 18:24:22 2010
New Revision: 1041512

URL: http://svn.apache.org/viewvc?rev=1041512&view=rev
Log:
SOLR-1568: friendly geodist function [from revision 1002739]

Added:
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/ConstNumberSource.java
      - copied unchanged from r1002739, lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/ConstNumberSource.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java
      - copied unchanged from r1002739, lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/DoubleConstValueSource.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java
      - copied unchanged from r1002739, lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/HaversineConstFunction.java
Modified:
    lucene/dev/branches/branch_3x/   (props changed)
    lucene/dev/branches/branch_3x/lucene/   (props changed)
    lucene/dev/branches/branch_3x/solr/   (props changed)
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/LatLonType.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/PointType.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/SpatialQueryable.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/QParser.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/ValueSourceParser.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/ConstValueSource.java
    lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/VectorValueSource.java
    lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/SpatialFilterTest.java
    lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java
    lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema11.xml
    lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema12.xml

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/LatLonType.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/LatLonType.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/LatLonType.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/LatLonType.java Thu Dec  2 18:24:22 2010
@@ -43,8 +43,6 @@ import java.util.Set;
 
 /**
  * Represents a Latitude/Longitude as a 2 dimensional point.  Latitude is <b>always</b> specified first.
- * Can also, optionally, integrate in Spatial Tile capabilities.  The default is for tile fields from 4 - 15,
- * just as in the SpatialTileField that we are extending.
  */
 public class LatLonType extends AbstractSubTypeFieldType implements SpatialQueryable {
   protected static final int LAT = 0;
@@ -511,7 +509,7 @@ class SpatialDistanceQuery extends Query
   {
     float boost = getBoost();
     return (boost!=1.0?"(":"") +
-            "sfilt(latlonSource="+origField +"(" + latSource + "," + lonSource + ")"
+            "geofilt(latlonSource="+origField +"(" + latSource + "," + lonSource + ")"
             +",latCenter="+latCenter+",lonCenter="+lonCenter
             +",dist=" + dist
             +",latMin=" + latMin + ",latMax="+latMax

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/PointType.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/PointType.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/PointType.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/PointType.java Thu Dec  2 18:24:22 2010
@@ -41,11 +41,8 @@ import java.util.List;
 import java.util.ArrayList;
 
 /**
- * A point type that indexes a point in an n-dimensional space as separate fields and uses
- * range queries for bounding box calculations.
- * <p/>
- * <p/>
- * NOTE: There can only be one sub type
+ * A point type that indexes a point in an n-dimensional space as separate fields and supports range queries.
+ * See {@link LatLonType} for geo-spatial queries.
  */
 public class PointType extends CoordinateFieldType implements SpatialQueryable {
 

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/SpatialQueryable.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/SpatialQueryable.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/SpatialQueryable.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/schema/SpatialQueryable.java Thu Dec  2 18:24:22 2010
@@ -25,8 +25,8 @@ import org.apache.solr.search.SpatialOpt
 
 /**
  * Indicate that the implementing class is capable of generating a Query against spatial resources.
- * For example, the PointType is capable of creating a query that restricts the document space down
- * to documents that are within a certain distance of a given point. *
+ * For example, the LatLonType is capable of creating a query that restricts the document space down
+ * to documents that are within a certain distance of a given point on Earth. *
  *
  **/
 public interface SpatialQueryable {

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/QParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/QParser.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/QParser.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/QParser.java Thu Dec  2 18:24:22 2010
@@ -157,7 +157,7 @@ public abstract class QParser {
   //                       $x+=foo (append to global for limited scope)
 
   /** check both local and global params */
-  protected String getParam(String name) {
+  public String getParam(String name) {
     String val;
     if (localParams != null) {
       val = localParams.get(name);

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java Thu Dec  2 18:24:22 2010
@@ -33,24 +33,7 @@ import org.apache.solr.schema.SpatialQue
 
 
 /**
- * Creates a spatial Filter based on the type of spatial point used.
- * <p/>
- * The field must implement {@link org.apache.solr.schema.SpatialQueryable}
- * <p/>
- * All units are in Kilometers
- * <p/>
- * <p/>
- * Syntax:
- * <pre>{!sfilt fl=location [units=[K|M]] [meas=[0-INF|hsin|sqe]] }&pt=49.32,-79.0&d=20</pre>
- * <p/>
- * Parameters:
- * <ul>
- * <li>fl - The fields to filter on.  Must implement XXXX. Required.  If more than one, XXXX</li>
- * <li>pt - The point to use as a reference.  Must match the dimension of the field. Required.</li>
- * <li>d - The distance in the units specified. Required.</li>
- * <li>meas - The distance measure to use.  Default is Euclidean (2-norm).  If a number between 0-INF is used, then the Vector Distance is used.  hsin = Haversine, sqe = Squared Euclidean</li>
- * </ul> *
- *
+ * @see {@link SpatialFilterQParserPlugin}
  */
 public class SpatialFilterQParser extends QParser {
   boolean bbox;  // do bounding box only
@@ -66,17 +49,17 @@ public class SpatialFilterQParser extend
   public Query parse() throws ParseException {
     //if more than one, we need to treat them as a point...
     //TODO: Should we accept multiple fields
-    String[] fields = localParams.getParams(CommonParams.FL);
+    String[] fields = localParams.getParams("f");
     if (fields == null || fields.length == 0) {
       String field = getParam(SpatialParams.FIELD);
       if (field == null)
-        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, " missing field for spatial request");
+        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, " missing sfield for spatial request");
       fields = new String[] {field};
     }
     
     String pointStr = getParam(SpatialParams.POINT);
     if (pointStr == null) {
-      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, SpatialParams.POINT + " is not properly specified");
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, SpatialParams.POINT + " missing.");
     }
 
     double dist = -1;

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java Thu Dec  2 18:24:22 2010
@@ -21,11 +21,35 @@ import org.apache.solr.common.util.Named
 import org.apache.solr.request.SolrQueryRequest;
 
 /**
- * Creates a {@link org.apache.solr.search.QParser} that can create Spatial {@link org.apache.lucene.search.Filter}s.
- * The filters are tied to implementations of {@link org.apache.solr.schema.SpatialQueryable}
+ * Creates a spatial Filter based on the type of spatial point used.
+ * <p/>
+ * The field must implement {@link org.apache.solr.schema.SpatialQueryable}
+ * <p/>
+ * All units are in Kilometers
+ * <p/>
+ * <p/>
+ * Syntax:
+ * <pre>{!geofilt sfield=&lt;location_field&gt; pt=&lt;lat,lon&gt; d=&lt;distance&gt;}</pre>
+ * <p/>
+ * Parameters:
+ * <ul>
+ * <li>sfield - The field to filter on. Required.</li>
+ * <li>pt - The point to use as a reference.  Must match the dimension of the field. Required.</li>
+ * <li>d - The distance in km.  Requited.</li>
+ * </ul>
+ * The distance measure used currently depends on the FieldType.  LatLonType defaults to using haversine, PointType defaults to Euclidean (2-norm).
+ *
+ * <p/>
+ * Examples:
+ * <pre>fq={!geofilt sfield=store pt=10.312,-20.556 d=3.5}</pre>
+ * <pre>fq={!geofilt sfield=store}&pt=10.312,-20&d=3.5</pre>
+ * <pre>fq={!geofilt}&sfield=store&pt=10.312,-20&d=3.5</pre>
+ * <p/>
+ * Note: The geofilt for LatLonType is capable of also producing scores equal to the computed distance from the point
+ * to the field, making it useful as a component of the main query or a boosting query.
  */
 public class SpatialFilterQParserPlugin extends QParserPlugin {
-  public static String NAME = "sfilt";
+  public static String NAME = "geofilt";
 
   @Override
   public QParser createParser(String qstr, SolrParams localParams,

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/ValueSourceParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/ValueSourceParser.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/ValueSourceParser.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/ValueSourceParser.java Thu Dec  2 18:24:22 2010
@@ -31,28 +31,56 @@ import org.apache.solr.schema.DateField;
 import org.apache.solr.schema.LegacyDateField;
 import org.apache.solr.schema.SchemaField;
 import org.apache.solr.schema.TrieDateField;
-import org.apache.solr.search.function.*;
-
-import org.apache.solr.search.function.distance.*;
+import org.apache.solr.search.function.BoostedQuery;
+import org.apache.solr.search.function.ConstNumberSource;
+import org.apache.solr.search.function.DivFloatFunction;
+import org.apache.solr.search.function.DocValues;
+import org.apache.solr.search.function.DoubleConstValueSource;
+import org.apache.solr.search.function.DualFloatFunction;
+import org.apache.solr.search.function.LinearFloatFunction;
+import org.apache.solr.search.function.LiteralValueSource;
+import org.apache.solr.search.function.MaxFloatFunction;
+import org.apache.solr.search.function.MultiValueSource;
+import org.apache.solr.search.function.OrdFieldSource;
+import org.apache.solr.search.function.ProductFloatFunction;
+import org.apache.solr.search.function.QueryValueSource;
+import org.apache.solr.search.function.RangeMapFloatFunction;
+import org.apache.solr.search.function.ReciprocalFloatFunction;
+import org.apache.solr.search.function.ReverseOrdFieldSource;
+import org.apache.solr.search.function.ScaleFloatFunction;
+import org.apache.solr.search.function.SimpleFloatFunction;
+import org.apache.solr.search.function.SingleFunction;
+import org.apache.solr.search.function.SumFloatFunction;
+import org.apache.solr.search.function.TopValueSource;
+import org.apache.solr.search.function.ValueSource;
+import org.apache.solr.search.function.VectorValueSource;
+import org.apache.solr.search.function.distance.GeohashFunction;
+import org.apache.solr.search.function.distance.GeohashHaversineFunction;
+import org.apache.solr.search.function.distance.HaversineConstFunction;
+import org.apache.solr.search.function.distance.HaversineFunction;
+import org.apache.solr.search.function.distance.SquaredEuclideanFunction;
+import org.apache.solr.search.function.distance.StringDistanceFunction;
+import org.apache.solr.search.function.distance.VectorDistanceFunction;
 import org.apache.solr.util.plugin.NamedListInitializedPlugin;
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.Collections;
 
 /**
  * A factory that parses user queries to generate ValueSource instances.
- * Intented usage is to create pluggable, named functions for use in function queries.
+ * Intended usage is to create pluggable, named functions for use in function queries.
  */
 public abstract class ValueSourceParser implements NamedListInitializedPlugin {
   /**
    * Initialize the plugin.
    */
-  public void init(NamedList args) {}
+  public void init(NamedList args) {
+  }
 
   /**
    * Parse the user input into a ValueSource.
@@ -65,15 +93,17 @@ public abstract class ValueSourceParser 
   /* standard functions */
   public static Map<String, ValueSourceParser> standardValueSourceParsers = new HashMap<String, ValueSourceParser>();
 
-  /** Adds a new parser for the name and returns any existing one that was overriden.
-   *  This is not thread safe.
+  /**
+   * Adds a new parser for the name and returns any existing one that was overriden.
+   * This is not thread safe.
    */
   public static ValueSourceParser addParser(String name, ValueSourceParser p) {
     return standardValueSourceParsers.put(name, p);
   }
 
-  /** Adds a new parser for the name and returns any existing one that was overriden.
-   *  This is not thread safe.
+  /**
+   * Adds a new parser for the name and returns any existing one that was overriden.
+   * This is not thread safe.
    */
   public static ValueSourceParser addParser(NamedParser p) {
     return standardValueSourceParsers.put(p.name(), p);
@@ -179,7 +209,7 @@ public abstract class ValueSourceParser 
         return new SumFloatFunction(sources.toArray(new ValueSource[sources.size()]));
       }
     });
-    alias("sum","add");    
+    alias("sum", "add");
 
     addParser("product", new ValueSourceParser() {
       public ValueSource parse(FunctionQParser fp) throws ParseException {
@@ -187,7 +217,7 @@ public abstract class ValueSourceParser 
         return new ProductFloatFunction(sources.toArray(new ValueSource[sources.size()]));
       }
     });
-    alias("product","mul");
+    alias("product", "mul");
 
     addParser("sub", new ValueSourceParser() {
       public ValueSource parse(FunctionQParser fp) throws ParseException {
@@ -204,8 +234,8 @@ public abstract class ValueSourceParser 
         };
       }
     });
-    addParser("vector", new ValueSourceParser(){
-      public ValueSource parse(FunctionQParser fp) throws ParseException{
+    addParser("vector", new ValueSourceParser() {
+      public ValueSource parse(FunctionQParser fp) throws ParseException {
         return new VectorValueSource(fp.parseValueSourceList());
       }
     });
@@ -228,13 +258,16 @@ public abstract class ValueSourceParser 
         return new QueryValueSource(bq, 0.0f);
       }
     });
+
+    addParser("geodist", HaversineConstFunction.parser);
+
     addParser("hsin", new ValueSourceParser() {
       public ValueSource parse(FunctionQParser fp) throws ParseException {
 
         double radius = fp.parseDouble();
         //SOLR-2114, make the convert flag required, since the parser doesn't support much in the way of lookahead or the ability to convert a String into a ValueSource
         boolean convert = Boolean.parseBoolean(fp.parseArg());
-        
+
         MultiValueSource pv1;
         MultiValueSource pv2;
 
@@ -255,7 +288,7 @@ public abstract class ValueSourceParser 
           pv2 = new VectorValueSource(s2);
         } else {
           //check to see if we have multiValue source
-          if (one instanceof MultiValueSource && two instanceof MultiValueSource){
+          if (one instanceof MultiValueSource && two instanceof MultiValueSource) {
             pv1 = (MultiValueSource) one;
             pv2 = (MultiValueSource) two;
           } else {
@@ -443,7 +476,7 @@ public abstract class ValueSourceParser 
     });
     addParser("ms", new DateValueSourceParser());
 
-    
+
     addParser("pi", new ValueSourceParser() {
       public ValueSource parse(FunctionQParser fp) throws ParseException {
         return new DoubleConstValueSource(Math.PI);
@@ -607,7 +640,8 @@ class DateValueSourceParser extends Valu
 
 
 // Private for now - we need to revisit how to handle typing in function queries
-class LongConstValueSource extends ValueSource {
+
+class LongConstValueSource extends ConstNumberSource {
   final long constant;
   final double dv;
   final float fv;
@@ -659,70 +693,41 @@ class LongConstValueSource extends Value
     LongConstValueSource other = (LongConstValueSource) o;
     return this.constant == other.constant;
   }
-}
 
-// Private for now - we need to revisit how to handle typing in function queries
-class DoubleConstValueSource extends ValueSource {
-  final double constant;
-  private final float fv;
-  private final long lv;
-
-  public DoubleConstValueSource(double constant) {
-    this.constant = constant;
-    this.fv = (float)constant;
-    this.lv = (long)constant;
+  @Override
+  public int getInt() {
+    return (int) constant;
   }
 
-  public String description() {
-    return "const(" + constant + ")";
+  @Override
+  public long getLong() {
+    return constant;
   }
 
-  public DocValues getValues(Map context, IndexReader reader) throws IOException {
-    return new DocValues() {
-      public float floatVal(int doc) {
-        return fv;
-      }
-
-      public int intVal(int doc) {
-        return (int) lv;
-      }
-
-      public long longVal(int doc) {
-        return lv;
-      }
-
-      public double doubleVal(int doc) {
-        return constant;
-      }
-
-      public String strVal(int doc) {
-        return Double.toString(constant);
-      }
-
-      public String toString(int doc) {
-        return description();
-      }
-    };
+  @Override
+  public float getFloat() {
+    return fv;
   }
 
-  public int hashCode() {
-    long bits = Double.doubleToRawLongBits(constant);
-    return (int)(bits ^ (bits >>> 32));
+  @Override
+  public double getDouble() {
+    return dv;
   }
 
-  public boolean equals(Object o) {
-    if (DoubleConstValueSource.class != o.getClass()) return false;
-    DoubleConstValueSource other = (DoubleConstValueSource) o;
-    return this.constant == other.constant;
+  @Override
+  public Number getNumber() {
+    return constant;
   }
 }
 
 
 abstract class NamedParser extends ValueSourceParser {
   private final String name;
+
   public NamedParser(String name) {
     this.name = name;
   }
+
   public String name() {
     return name;
   }
@@ -751,23 +756,28 @@ abstract class DoubleParser extends Name
 
     @Override
     public DocValues getValues(Map context, IndexReader reader) throws IOException {
-      final DocValues vals =  source.getValues(context, reader);
+      final DocValues vals = source.getValues(context, reader);
       return new DocValues() {
         public float floatVal(int doc) {
-          return (float)doubleVal(doc);
+          return (float) doubleVal(doc);
         }
+
         public int intVal(int doc) {
-          return (int)doubleVal(doc);
+          return (int) doubleVal(doc);
         }
+
         public long longVal(int doc) {
-          return (long)doubleVal(doc);
+          return (long) doubleVal(doc);
         }
+
         public double doubleVal(int doc) {
           return func(doc, vals);
         }
+
         public String strVal(int doc) {
           return Double.toString(doubleVal(doc));
         }
+
         public String toString(int doc) {
           return name() + '(' + vals.toString(doc) + ')';
         }
@@ -792,9 +802,9 @@ abstract class Double2Parser extends Nam
     private final ValueSource a;
     private final ValueSource b;
 
-   /**
-     * @param   a  the base.
-     * @param   b  the exponent.
+    /**
+     * @param a the base.
+     * @param b the exponent.
      */
     public Function(ValueSource a, ValueSource b) {
       this.a = a;
@@ -806,24 +816,29 @@ abstract class Double2Parser extends Nam
     }
 
     public DocValues getValues(Map context, IndexReader reader) throws IOException {
-      final DocValues aVals =  a.getValues(context, reader);
-      final DocValues bVals =  b.getValues(context, reader);
+      final DocValues aVals = a.getValues(context, reader);
+      final DocValues bVals = b.getValues(context, reader);
       return new DocValues() {
         public float floatVal(int doc) {
-          return (float)doubleVal(doc);
+          return (float) doubleVal(doc);
         }
+
         public int intVal(int doc) {
-          return (int)doubleVal(doc);
+          return (int) doubleVal(doc);
         }
+
         public long longVal(int doc) {
-          return (long)doubleVal(doc);
+          return (long) doubleVal(doc);
         }
+
         public double doubleVal(int doc) {
           return func(doc, aVals, bVals);
         }
+
         public String strVal(int doc) {
           return Double.toString(doubleVal(doc));
         }
+
         public String toString(int doc) {
           return name() + '(' + aVals.toString(doc) + ',' + bVals.toString(doc) + ')';
         }
@@ -832,8 +847,8 @@ abstract class Double2Parser extends Nam
 
     @Override
     public void createWeight(Map context, Searcher searcher) throws IOException {
-      a.createWeight(context,searcher);
-      b.createWeight(context,searcher);
+      a.createWeight(context, searcher);
+      b.createWeight(context, searcher);
     }
 
     public int hashCode() {
@@ -847,9 +862,9 @@ abstract class Double2Parser extends Nam
 
     public boolean equals(Object o) {
       if (this.getClass() != o.getClass()) return false;
-      Function other = (Function)o;
+      Function other = (Function) o;
       return this.a.equals(other.a)
-          && this.b.equals(other.b);
+              && this.b.equals(other.b);
     }
   }
 

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/ConstValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/ConstValueSource.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/ConstValueSource.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/ConstValueSource.java Thu Dec  2 18:24:22 2010
@@ -25,7 +25,7 @@ import java.util.Map;
 /**
  * <code>ConstValueSource</code> returns a constant for all documents
  */
-public class ConstValueSource extends ValueSource {
+public class ConstValueSource extends ConstNumberSource {
   final float constant;
   private final double dv;
 
@@ -66,8 +66,33 @@ public class ConstValueSource extends Va
   }
 
   public boolean equals(Object o) {
-    if (ConstValueSource.class != o.getClass()) return false;
+    if (!(o instanceof ConstValueSource)) return false;
     ConstValueSource other = (ConstValueSource)o;
     return  this.constant == other.constant;
   }
+
+  @Override
+  public int getInt() {
+    return (int)constant;
+  }
+
+  @Override
+  public long getLong() {
+    return (long)constant;
+  }
+
+  @Override
+  public float getFloat() {
+    return constant;
+  }
+
+  @Override
+  public double getDouble() {
+    return dv;
+  }
+
+  @Override
+  public Number getNumber() {
+    return constant;
+  }
 }

Modified: lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/VectorValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/VectorValueSource.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/VectorValueSource.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/java/org/apache/solr/search/function/VectorValueSource.java Thu Dec  2 18:24:22 2010
@@ -33,7 +33,7 @@ import java.util.Map;
  */
 //Not crazy about the name, but...
 public class VectorValueSource extends MultiValueSource {
-  protected List<ValueSource> sources;
+  protected final List<ValueSource> sources;
 
 
   public VectorValueSource(List<ValueSource> sources) {

Modified: lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/SpatialFilterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/SpatialFilterTest.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/SpatialFilterTest.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/SpatialFilterTest.java Thu Dec  2 18:24:22 2010
@@ -134,9 +134,9 @@ public class SpatialFilterTest extends S
       }
     }
 
-    String method = exact ? "sfilt" : "bbox";
+    String method = exact ? "geofilt" : "bbox";
 
-    assertQ(req("fl", "id", "q","*:*", "rows", "1000", "fq", "{!"+method+" fl=" +fieldName +"}",
+    assertQ(req("fl", "id", "q","*:*", "rows", "1000", "fq", "{!"+method+" sfield=" +fieldName +"}",
               "pt", pt, "d", String.valueOf(distance)),
               tests);
   }

Modified: lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java (original)
+++ lucene/dev/branches/branch_3x/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java Thu Dec  2 18:24:22 2010
@@ -30,7 +30,7 @@ import org.junit.Test;
 public class DistanceFunctionTest extends SolrTestCaseJ4 {
   @BeforeClass
   public static void beforeClass() throws Exception {
-    initCore("solrconfig-functionquery.xml", "schema11.xml");
+    initCore("solrconfig.xml", "schema12.xml");
   }
 
   @Test
@@ -61,14 +61,57 @@ public class DistanceFunctionTest extend
 
     assertQ(req("fl", "id,point_hash,score", "q", "{!func}recip(ghhsin(" + DistanceUtils.EARTH_MEAN_RADIUS_KM + ", point_hash, \"" + GeoHashUtils.encode(32, -79) + "\"), 1, 1, 0)"),
             "//*[@numFound='7']", 
-            "//result/doc[1]/float[@name='id'][.='6.0']",
-            "//result/doc[2]/float[@name='id'][.='7.0']"//all the rest don't matter
+            "//result/doc[1]/str[@name='id'][.='6']",
+            "//result/doc[2]/str[@name='id'][.='7']"//all the rest don't matter
             );
 
 
     assertQ(req("fl", "*,score", "q", "{!func}ghhsin(" + DistanceUtils.EARTH_MEAN_RADIUS_KM + ", gh_s, geohash(32, -79))", "fq", "id:1"), "//float[@name='score']='122.171875'");
   }
 
+
+  @Test
+  public void testLatLon() throws Exception {
+    assertU(adoc("id", "100", "store", "1,2"));
+    assertU(commit());
+   
+    assertJQ(req("defType","func", "q","geodist(1,2,3,4)","fq","id:100","fl","id,score")
+      ,"/response/docs/[0]/score==314.40338"
+    );
+
+    // throw in some decimal points
+    assertJQ(req("defType","func", "q","geodist(1.0,2,3,4.0)","fq","id:100","fl","id,score")
+      ,"/response/docs/[0]/score==314.40338"
+    );
+
+    // default to reading pt
+    assertJQ(req("defType","func", "q","geodist(1,2)","pt","3,4", "fq","id:100","fl","id,score")
+      ,"/response/docs/[0]/score==314.40338"
+    );
+
+    // default to reading pt first
+    assertJQ(req("defType","func", "q","geodist(1,2)","pt","3,4", "sfield","store", "fq","id:100","fl","id,score")
+      ,"/response/docs/[0]/score==314.40338"
+    );
+
+    // if pt missing, use sfield
+    assertJQ(req("defType","func", "q","geodist(3,4)","sfield","store", "fq","id:100","fl","id,score")
+      ,"/response/docs/[0]/score==314.40338"
+    );
+
+    // read both pt and sfield
+    assertJQ(req("defType","func", "q","geodist()","pt","3,4","sfield","store", "fq","id:100","fl","id,score")
+      ,"/response/docs/[0]/score==314.40338"
+    );
+
+    // param substitution
+    assertJQ(req("defType","func", "q","geodist($a,$b)","a","3,4","b","store", "fq","id:100","fl","id,score")
+      ,"/response/docs/[0]/score==314.40338"
+    );
+
+  }
+
+  
   @Test
   public void testVector() throws Exception {
     clearIndex();

Modified: lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema11.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema11.xml?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema11.xml (original)
+++ lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema11.xml Thu Dec  2 18:24:22 2010
@@ -257,9 +257,15 @@
     <!-- Poly field -->
     <fieldType name="xy" class="solr.PointType" dimension="2" subFieldType="double"/>
     <fieldType name="xyd" class="solr.PointType" dimension="2" subFieldSuffix="*_d"/>
-
     <fieldtype name="geohash" class="solr.GeoHashField"/>
 
+    <fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
+
+    <!-- A specialized field for geospatial search. If indexed, this fieldType must not be multi
+valued. -->
+    <fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
+
+
  </types>
 
 

Modified: lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema12.xml
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema12.xml?rev=1041512&r1=1041511&r2=1041512&view=diff
==============================================================================
--- lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema12.xml (original)
+++ lucene/dev/branches/branch_3x/solr/src/test/test-files/solr/conf/schema12.xml Thu Dec  2 18:24:22 2010
@@ -418,6 +418,15 @@
 
   <fieldType name="random" class="solr.RandomSortField" indexed="true" />  
   
+    <!-- Poly field -->
+    <fieldType name="xy" class="solr.PointType" dimension="2" subFieldType="double"/>
+    <fieldType name="xyd" class="solr.PointType" dimension="2" subFieldSuffix="*_d"/>
+    <fieldtype name="geohash" class="solr.GeoHashField"/>
+
+   <fieldType name="point" class="solr.PointType" dimension="2" subFieldSuffix="_d"/>
+    <!-- A specialized field for geospatial search. If indexed, this fieldType must not be multivalued. -->
+    <fieldType name="location" class="solr.LatLonType" subFieldSuffix="_coordinate"/>
+
  </types>
 
 
@@ -508,7 +517,12 @@
    -->
    <field name="timestamp" type="date" indexed="true" stored="true"/>
 
-
+   <!-- Test a point field for distances -->
+   <field name="point" type="xy" indexed="true" stored="true" multiValued="false"/>
+   <field name="pointD" type="xyd" indexed="true" stored="true" multiValued="false"/>
+   <field name="point_hash" type="geohash" indexed="true" stored="true" multiValued="false"/>
+   <field name="store" type="location" indexed="true" stored="true"/>
+   <dynamicField name="*_coordinate"  type="tdouble" indexed="true"  stored="false"/>
 
 
    <dynamicField name="*_si"  type="sint"  indexed="true"  stored="true"/>