You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ds...@apache.org on 2013/01/02 22:34:58 UTC

svn commit: r1428068 - in /lucene/dev/branches/branch_4x: ./ solr/ solr/CHANGES.txt solr/core/ solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java

Author: dsmiley
Date: Wed Jan  2 21:34:57 2013
New Revision: 1428068

URL: http://svn.apache.org/viewvc?rev=1428068&view=rev
Log:
SOLR-4230 geofilt and bbox support for Solr 4 spatial

Modified:
    lucene/dev/branches/branch_4x/   (props changed)
    lucene/dev/branches/branch_4x/solr/   (props changed)
    lucene/dev/branches/branch_4x/solr/CHANGES.txt
    lucene/dev/branches/branch_4x/solr/core/   (props changed)
    lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java
    lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java

Modified: lucene/dev/branches/branch_4x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/CHANGES.txt?rev=1428068&r1=1428067&r2=1428068&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_4x/solr/CHANGES.txt Wed Jan  2 21:34:57 2013
@@ -162,6 +162,8 @@ New Features
   the distributed update processor, always include the log update processor
   so forwarded updates will still be logged. (yonik)
 
+* SOLR-4230: The new Solr 4 spatial fields now work with the {!geofilt} and
+  {!bbox} query parsers. The score local-param works too. (David Smiley)
 
 Optimizations
 ----------------------

Modified: lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java?rev=1428068&r1=1428067&r2=1428068&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/java/org/apache/solr/schema/AbstractSpatialFieldType.java Wed Jan  2 21:34:57 2013
@@ -22,7 +22,9 @@ import com.google.common.cache.Cache;
 import com.google.common.cache.CacheBuilder;
 import com.spatial4j.core.context.SpatialContext;
 import com.spatial4j.core.context.SpatialContextFactory;
+import com.spatial4j.core.distance.DistanceUtils;
 import com.spatial4j.core.exception.InvalidShapeException;
+import com.spatial4j.core.io.ParseUtils;
 import com.spatial4j.core.shape.Point;
 import com.spatial4j.core.shape.Rectangle;
 import com.spatial4j.core.shape.Shape;
@@ -43,6 +45,7 @@ import org.apache.solr.common.SolrExcept
 import org.apache.solr.common.params.SolrParams;
 import org.apache.solr.response.TextResponseWriter;
 import org.apache.solr.search.QParser;
+import org.apache.solr.search.SpatialOptions;
 import org.apache.solr.util.MapListener;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -57,7 +60,7 @@ import java.util.concurrent.ExecutionExc
  *
  * @lucene.experimental
  */
-public abstract class AbstractSpatialFieldType<T extends SpatialStrategy> extends FieldType {
+public abstract class AbstractSpatialFieldType<T extends SpatialStrategy> extends FieldType implements SpatialQueryable {
 
   /** A local-param with one of "none" (default), "distance", or "recipDistance". */
   public static final String SCORE_PARAM = "score";
@@ -160,6 +163,35 @@ public abstract class AbstractSpatialFie
   // Query Support
   //--------------------------------------------------------------
 
+  /**
+   * Implemented for compatibility with Solr 3 spatial geofilt & bbox query parsers:
+   * {@link SpatialQueryable}.
+   */
+  @Override
+  public Query createSpatialQuery(QParser parser, SpatialOptions options) {
+    //--WARNING: the code from here to the next marker is identical to LatLonType's impl.
+    double[] point = null;
+    try {
+      point = ParseUtils.parseLatitudeLongitude(options.pointStr);
+    } catch (InvalidShapeException e) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, e);
+    }
+
+    // lat & lon in degrees
+    double latCenter = point[0];
+    double lonCenter = point[1];
+
+    double distDeg = DistanceUtils.dist2Degrees(options.distance, options.radius);
+    //--END-WARNING
+
+    Shape shape = ctx.makeCircle(lonCenter, latCenter, distDeg);
+    if (options.bbox)
+      shape = shape.getBoundingBox();
+
+    SpatialArgs spatialArgs = new SpatialArgs(SpatialOperation.Intersects, shape);
+    return getQueryFromSpatialArgs(parser, options.field, spatialArgs);
+  }
+
   @Override
   public Query getRangeQuery(QParser parser, SchemaField field, String part1, String part2, boolean minInclusive, boolean maxInclusive) {
     if (!minInclusive || !maxInclusive)

Modified: lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java?rev=1428068&r1=1428067&r2=1428068&view=diff
==============================================================================
--- lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java (original)
+++ lucene/dev/branches/branch_4x/solr/core/src/test/org/apache/solr/search/TestSolr4Spatial.java Wed Jan  2 21:34:57 2013
@@ -149,7 +149,7 @@ public class TestSolr4Spatial extends So
 
     assertQ(req(
         "fl", "id," + fieldName, "q", "*:*", "rows", "1000",
-        "fq", "{!field needScore=false f="+fieldName+"}Intersects(Circle(89.9,-130 d=9))"),
+        "fq", "{!field f="+fieldName+"}Intersects(Circle(89.9,-130 d=9))"),
         "//result/doc/*[@name='" + fieldName + "']//text()='" + OUT + "'");
   }
 
@@ -175,26 +175,37 @@ public class TestSolr4Spatial extends So
     // that there may be a more specific detailed id to investigate.
     tests[i++] = "*[count(//doc)=" + count + "]";
 
-    //never actually need the score but lets test
-    String score = new String[]{null, "none","distance","recipDistance"}[random().nextInt(4)];
+    //Test using the Solr 4 syntax
+    {
+      //never actually need the score but lets test
+      String score = new String[]{null, "none","distance","recipDistance"}[random().nextInt(4)];
+
+      double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+      String circleStr = "Circle(" + ptStr.replaceAll(" ", "") + " d=" + distDEG + ")";
+      String shapeStr;
+      if (exact) {
+        shapeStr = circleStr;
+      } else {//bbox
+        //the GEO is an assumption
+        SpatialContext ctx = SpatialContext.GEO;
+        shapeStr = ctx.toString( ctx.readShape(circleStr).getBoundingBox() );
+      }
 
-    double distDEG = DistanceUtils.dist2Degrees(distKM, DistanceUtils.EARTH_MEAN_RADIUS_KM);
-    String circleStr = "Circle(" + ptStr.replaceAll(" ", "") + " d=" + distDEG + ")";
-    String shapeStr;
-    if (exact) {
-      shapeStr = circleStr;
-    } else {//bbox
-      //the GEO is an assumption
-      SpatialContext ctx = SpatialContext.GEO;
-      shapeStr = ctx.toString( ctx.readShape(circleStr).getBoundingBox() );
+      //FYI default distErrPct=0.025 works with the tests in this file
+      assertQ(req(
+            "fl", "id", "q","*:*", "rows", "1000",
+            "fq", "{!field f=" + fieldName + (score==null?"":" score="+score)
+              + "}Intersects(" + shapeStr + ")"),
+          tests);
+    }
+    //Test using the Solr 3 syntax
+    {
+      assertQ(req(
+          "fl", "id", "q", "*:*", "rows", "1000",
+          "fq", "{!" + (exact ? "geofilt" : "bbox") + " sfield=" + fieldName + " pt='" + ptStr + "' d=" + distKM + "}"),
+          tests);
     }
 
-    //FYI default distErrPct=0.025 works with the tests in this file
-    assertQ(req(
-          "fl", "id", "q","*:*", "rows", "1000",
-          "fq", "{!field f=" + fieldName + (score==null?"":" score="+score)
-            + "}Intersects(" + shapeStr + ")"),
-        tests);
   }
 
   @Test
@@ -203,10 +214,11 @@ public class TestSolr4Spatial extends So
     //match docId 1
     int docId = 1;
     int count = 1;
-    boolean needScore = random().nextBoolean();//never actually need the score but lets test
+
+    String score = random().nextBoolean() ? "none" : "distance";//never actually need the score but lets test
     assertQ(req(
         "fl", "id", "q","*:*", "rows", "1000",
-        "fq", "{! needScore="+needScore+" df="+fieldName+"}[32,-80 TO 33,-79]"),//lower-left to upper-right
+        "fq", "{! score="+score+" df="+fieldName+"}[32,-80 TO 33,-79]"),//lower-left to upper-right
 
         "//result/doc/*[@name='id'][.='" + docId + "']",
         "*[count(//doc)=" + count + "]");