lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From gsing...@apache.org
Subject svn commit: r962727 [2/2] - in /lucene/dev/trunk: lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geohash/ lucene/contrib/spatial/src/java/org/apache/lucene/spatial/geometry/ lucene/contrib/spatial/src/java/org/apache/lucene/spatial/tier/ luc...
Date Sat, 10 Jul 2010 00:12:42 GMT
Added: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java?rev=962727&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java Sat Jul
10 00:12:41 2010
@@ -0,0 +1,114 @@
+package org.apache.solr.search;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.geometry.DistanceUnits;
+import org.apache.lucene.spatial.tier.DistanceUtils;
+import org.apache.solr.common.SolrException;
+import org.apache.solr.common.params.CommonParams;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.params.SpatialParams;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.schema.FieldType;
+import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.SchemaField;
+import org.apache.solr.schema.SpatialQueryable;
+
+
+
+/**
+ * Creates a spatial Filter based on the type of spatial point used.
+ * <p/>
+ * The field must implement XXXX
+ * <p/>
+ * <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>units - The units of the distance.  K - kilometers, M - Miles.  Optional.  Default
is miles.</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>
+ */
+public class SpatialFilterQParser extends QParser {
+
+
+  public SpatialFilterQParser(String qstr, SolrParams localParams, SolrParams params, SolrQueryRequest
req) {
+    super(qstr, localParams, params, req);
+  }
+
+  
+
+  @Override
+  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);
+    if (fields == null || fields.length == 0) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, CommonParams.FL + " is
not properly specified");
+    }
+    String pointStr = params.get(SpatialParams.POINT);
+    if (pointStr == null) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, SpatialParams.POINT +
" is not properly specified");
+    }
+
+    double dist = params.getDouble(SpatialParams.DISTANCE, -1);
+    if (dist < 0) {
+      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, SpatialParams.DISTANCE
+ " must be >= 0");
+    }
+    IndexSchema schema = req.getSchema();
+
+    String measStr = localParams.get(SpatialParams.MEASURE);
+    //TODO: Need to do something with Measures
+    Query result = null;
+    //fields is valid at this point
+    if (fields.length == 1) {
+      SchemaField sf = schema.getField(fields[0]);
+      FieldType type = sf.getType();
+
+      if (type instanceof SpatialQueryable) {
+        double radius = localParams.getDouble(SpatialParams.SPHERE_RADIUS, DistanceUtils.EARTH_MEAN_RADIUS_KM);
+        SpatialOptions opts = new SpatialOptions(pointStr, dist, sf, measStr, radius, DistanceUnits.KILOMETERS);
+        result = ((SpatialQueryable)type).createSpatialQuery(this, opts);
+      } else {
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "The field " + fields[0]
+                + " does not support spatial filtering");
+      }
+    } else {// fields.length > 1
+      //TODO: Not sure about this just yet, is there a way to delegate, or do we just have
a helper class?
+      //Seems like we could just use FunctionQuery, but then what about scoring
+      /*List<ValueSource> sources = new ArrayList<ValueSource>(fields.length);
+      for (String field : fields) {
+        SchemaField sf = schema.getField(field);
+        sources.add(sf.getType().getValueSource(sf, this));
+      }
+      MultiValueSource vs = new VectorValueSource(sources);
+      ValueSourceRangeFilter rf = new ValueSourceRangeFilter(vs, "0", String.valueOf(dist),
true, true);
+      result = new SolrConstantScoreQuery(rf);*/
+    }
+
+    return result;
+  }
+}

Propchange: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java?rev=962727&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java
(added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java
Sat Jul 10 00:12:41 2010
@@ -0,0 +1,42 @@
+package org.apache.solr.search;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.util.NamedList;
+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}
+ */
+public class SpatialFilterQParserPlugin extends QParserPlugin {
+  public static String NAME = "sfilt";
+
+
+  @Override
+  public QParser createParser(String qstr, SolrParams localParams,
+                              SolrParams params, SolrQueryRequest req) {
+
+    return new SpatialFilterQParser(qstr, localParams, params, req);
+  }
+
+  public void init(NamedList args) {
+
+  }
+
+}

Propchange: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialFilterQParserPlugin.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialOptions.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialOptions.java?rev=962727&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialOptions.java (added)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialOptions.java Sat Jul 10 00:12:41
2010
@@ -0,0 +1,54 @@
+package org.apache.solr.search;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.solr.schema.SchemaField;
+import org.apache.lucene.spatial.geometry.DistanceUnits;
+
+
+/**
+ *
+ *
+ **/
+public class SpatialOptions {
+  public String pointStr;
+  public double distance;
+  public SchemaField field;
+  public String measStr;
+  public double radius;
+  public DistanceUnits units;
+
+
+  public SpatialOptions() {
+  }
+
+
+  public SpatialOptions(String pointStr, double dist, SchemaField sf, String measStr, double
radius) {
+    this(pointStr, dist, sf, measStr, radius, DistanceUnits.MILES);
+
+  }
+
+
+  public SpatialOptions(String pointStr, double dist, SchemaField sf, String measStr, double
radius, DistanceUnits units) {
+    this.pointStr = pointStr;
+    this.distance = dist;
+    this.field = sf;
+    this.measStr = measStr;
+    this.radius = radius;
+    this.units = units;
+  }
+}

Propchange: lucene/dev/trunk/solr/src/java/org/apache/solr/search/SpatialOptions.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/ValueSourceParser.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/ValueSourceParser.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/ValueSourceParser.java (original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/ValueSourceParser.java Sat Jul 10
00:12:41 2010
@@ -26,6 +26,7 @@ import org.apache.lucene.search.spell.Ja
 import org.apache.lucene.search.spell.LevensteinDistance;
 import org.apache.lucene.search.spell.NGramDistance;
 import org.apache.lucene.search.spell.StringDistance;
+import org.apache.lucene.spatial.tier.DistanceUtils;
 import org.apache.lucene.util.BytesRef;
 import org.apache.lucene.util.UnicodeUtil;
 import org.apache.solr.common.SolrException;
@@ -34,7 +35,6 @@ import org.apache.solr.schema.*;
 import org.apache.solr.search.function.*;
 
 import org.apache.solr.search.function.distance.*;
-import org.apache.solr.util.ByteUtils;
 import org.apache.solr.util.plugin.NamedListInitializedPlugin;
 
 import java.io.IOException;

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/Constants.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/Constants.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/Constants.java
(original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/Constants.java
Sat Jul 10 00:12:41 2010
@@ -1,27 +0,0 @@
-package org.apache.solr.search.function.distance;
-/**
- * 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.
- */
-
-
-/**
- *
- *
- **/
-public interface Constants {
-  public static final double EARTH_RADIUS_KM = 6378.160187;
-  public static final double EARTH_RADIUS_MI = 3963.205;
-}

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/DistanceUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/DistanceUtils.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/DistanceUtils.java
(original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/DistanceUtils.java
Sat Jul 10 00:12:41 2010
@@ -1,239 +0,0 @@
-package org.apache.solr.search.function.distance;
-
-import org.apache.solr.common.SolrException;
-/**
- * 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.
- */
-
-
-/**
- * Useful distance utiltities.
- * solr-internal: subject to change w/o notification.
- */
-public class DistanceUtils {
-  public static final double DEGREES_TO_RADIANS = Math.PI / 180.0;
-  public static final double RADIANS_TO_DEGREES = 180.0 / Math.PI;
-
-  public static final double KM_TO_MILES = 0.621371192;
-  public static final double MILES_TO_KM = 1.609344;
-
-  /**
-   * Calculate the p-norm (i.e. length) between two vectors
-   *
-   * @param vec1  The first vector
-   * @param vec2  The second vector
-   * @param power The power (2 for Euclidean distance, 1 for manhattan, etc.)
-   * @return The length.
-   *         <p/>
-   *         See http://en.wikipedia.org/wiki/Lp_space
-   * @see #vectorDistance(double[], double[], double, double)
-   */
-  public static double vectorDistance(double[] vec1, double[] vec2, double power) {
-    return vectorDistance(vec1, vec2, power, 1.0 / power);
-  }
-
-  /**
-   * Calculate the p-norm (i.e. length) between two vectors
-   *
-   * @param vec1         The first vector
-   * @param vec2         The second vector
-   * @param power        The power (2 for Euclidean distance, 1 for manhattan, etc.)
-   * @param oneOverPower If you've precalculated oneOverPower and cached it, use this method
to save one division operation over {@link #vectorDistance(double[], double[], double)}.
-   * @return The length.
-   */
-  public static double vectorDistance(double[] vec1, double[] vec2, double power, double
oneOverPower) {
-    double result = 0;
-
-    if (power == 0) {
-      for (int i = 0; i < vec1.length; i++) {
-        result += vec1[i] - vec2[i] == 0 ? 0 : 1;
-      }
-
-    } else if (power == 1.0) {
-      for (int i = 0; i < vec1.length; i++) {
-        result += vec1[i] - vec2[i];
-      }
-    } else if (power == 2.0) {
-      result = Math.sqrt(squaredEuclideanDistance(vec1, vec2));
-    } else if (power == Integer.MAX_VALUE || Double.isInfinite(power)) {//infininte norm?
-      for (int i = 0; i < vec1.length; i++) {
-        result = Math.max(result, Math.max(vec1[i], vec2[i]));
-      }
-    } else {
-      for (int i = 0; i < vec1.length; i++) {
-        result += Math.pow(vec1[i] - vec2[i], power);
-      }
-      result = Math.pow(result, oneOverPower);
-    }
-    return result;
-  }
-
-  public static double squaredEuclideanDistance(double[] vec1, double[] vec2) {
-    double result = 0;
-    for (int i = 0; i < vec1.length; i++) {
-      double v = vec1[i] - vec2[i];
-      result += v * v;
-    }
-    return result;
-  }
-
-  /**
-   * @param x1     The x coordinate of the first point
-   * @param y1     The y coordinate of the first point
-   * @param x2     The x coordinate of the second point
-   * @param y2     The y coordinate of the second point
-   * @param radius The radius of the sphere
-   * @return The distance between the two points, as determined by the Haversine formula.
-   * @see org.apache.solr.search.function.distance.HaversineFunction
-   */
-  public static double haversine(double x1, double y1, double x2, double y2, double radius)
{
-    double result = 0;
-    //make sure they aren't all the same, as then we can just return 0
-    if ((x1 != x2) || (y1 != y2)) {
-      double diffX = x1 - x2;
-      double diffY = y1 - y2;
-      double hsinX = Math.sin(diffX * 0.5);
-      double hsinY = Math.sin(diffY * 0.5);
-      double h = hsinX * hsinX +
-              (Math.cos(x1) * Math.cos(x2) * hsinY * hsinY);
-      result = (radius * 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h)));
-    }
-    return result;
-  }
-
-  /**
-   * Given a string containing <i>dimension</i> values encoded in it, separated
by commas, return a String array of length <i>dimension</i>
-   * containing the values.
-   *
-   * @param out         A preallocated array.  Must be size dimension.  If it is not it will
be resized.
-   * @param externalVal The value to parse
-   * @param dimension   The expected number of values for the point
-   * @return An array of the values that make up the point (aka vector)
-   * @throws {@link SolrException} if the dimension specified does not match the number of
values in the externalValue.
-   */
-  public static String[] parsePoint(String[] out, String externalVal, int dimension) {
-    //TODO: Should we support sparse vectors?
-    if (out == null || out.length != dimension) out = new String[dimension];
-    int idx = externalVal.indexOf(',');
-    int end = idx;
-    int start = 0;
-    int i = 0;
-    if (idx == -1 && dimension == 1 && externalVal.length() > 0) {//we
have a single point, dimension better be 1
-      out[0] = externalVal.trim();
-      i = 1;
-    } else if (idx > 0) {//if it is zero, that is an error
-      //Parse out a comma separated list of point values, as in: 73.5,89.2,7773.4
-      for (; i < dimension; i++) {
-        while (start < end && externalVal.charAt(start) == ' ') start++;
-        while (end > start && externalVal.charAt(end - 1) == ' ') end--;
-	if (start == end){
-	    break;
-        }
-        out[i] = externalVal.substring(start, end);
-        start = idx + 1;
-        end = externalVal.indexOf(',', start);
-	idx = end;
-        if (end == -1) {
-          end = externalVal.length();
-        }
-      }
-    }
-    if (i != dimension) {
-      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "incompatible dimension
(" + dimension +
-              ") and values (" + externalVal + ").  Only " + i + " values specified");
-    }
-    return out;
-  }
-
-  /**
-   * Given a string containing <i>dimension</i> values encoded in it, separated
by commas, return a double array of length <i>dimension</i>
-   * containing the values.
-   *
-   * @param out         A preallocated array.  Must be size dimension.  If it is not it will
be resized.
-   * @param externalVal The value to parse
-   * @param dimension   The expected number of values for the point
-   * @return An array of the values that make up the point (aka vector)
-   * @throws {@link SolrException} if the dimension specified does not match the number of
values in the externalValue.
-   */
-  public static double[] parsePointDouble(double[] out, String externalVal, int dimension)
{
-    if (out == null || out.length != dimension) out = new double[dimension];
-    int idx = externalVal.indexOf(',');
-    int end = idx;
-    int start = 0;
-    int i = 0;
-    if (idx == -1 && dimension == 1 && externalVal.length() > 0) {//we
have a single point, dimension better be 1
-      out[0] = Double.parseDouble(externalVal.trim());
-      i = 1;
-    } else if (idx > 0) {//if it is zero, that is an error
-      //Parse out a comma separated list of point values, as in: 73.5,89.2,7773.4
-      for (; i < dimension; i++) {
-        //TODO: abstract common code with other parsePoint
-        while (start < end && externalVal.charAt(start) == ' ') start++;
-        while (end > start && externalVal.charAt(end - 1) == ' ') end--;
-	if (start == end){
-	    break;
-        }
-        out[i] = Double.parseDouble(externalVal.substring(start, end));
-        start = idx + 1;
-        end = externalVal.indexOf(',', start);
-	idx = end;
-        if (end == -1) {
-          end = externalVal.length();
-        }
-      }
-    }
-    if (i != dimension) {
-      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "incompatible dimension
(" + dimension +
-              ") and values (" + externalVal + ").  Only " + i + " values specified");
-    }
-    return out;
-  }
-
-  /**
-   * extract (by calling {@link #parsePoint(String[], String, int)} and validate the latitude
and longitude contained
-   * in the String by making sure the latitude is between 90 & -90 and longitude is between
-180 and 180.
-   * <p/>
-   * The latitude is assumed to be the first part of the string and the longitude the second
part.
-   *
-   * @param latLon    A preallocated array to hold the result
-   * @param latLonStr The string to parse
-   * @return The lat long
-   */
-  public static final double[] parseLatitudeLongitude(double[] latLon, String latLonStr)
{
-    if (latLon == null) {
-      latLon = new double[2];
-    }
-    double[] toks = DistanceUtils.parsePointDouble(null, latLonStr, 2);
-    latLon[0] = Double.valueOf(toks[0]);
-
-    if (latLon[0] < -90.0 || latLon[0] > 90.0) {
-      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
-              "Invalid latitude: latitudes are range -90 to 90: provided lat: ["
-                      + latLon[0] + "]");
-    }
-
-    latLon[1] = Double.valueOf(toks[1]);
-
-    if (latLon[1] < -180.0 || latLon[1] > 180.0) {
-
-      throw new SolrException(SolrException.ErrorCode.BAD_REQUEST,
-              "Invalid longitude: longitudes are range -180 to 180: provided lon: ["
-                      + latLon[1] + "]");
-    }
-
-    return latLon;
-  }
-}

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java
(original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/GeohashHaversineFunction.java
Sat Jul 10 00:12:41 2010
@@ -17,6 +17,7 @@ package org.apache.solr.search.function.
  */
 
 
+import org.apache.lucene.spatial.tier.DistanceUtils;
 import org.apache.solr.search.function.ValueSource;
 import org.apache.solr.search.function.DocValues;
 import org.apache.lucene.index.IndexReader;
@@ -94,6 +95,8 @@ public class GeohashHaversineFunction ex
     String h1 = gh1DV.strVal(doc);
     String h2 = gh2DV.strVal(doc);
     if (h1 != null && h2 != null && h1.equals(h2) == false){
+      //TODO: If one of the hashes is a literal value source, seems like we could cache it
+      //and avoid decoding every time
       double[] h1Pair = GeoHashUtils.decode(h1);
       double[] h2Pair = GeoHashUtils.decode(h2);
       result = DistanceUtils.haversine(Math.toRadians(h1Pair[0]), Math.toRadians(h1Pair[1]),

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java
(original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/HaversineFunction.java
Sat Jul 10 00:12:41 2010
@@ -18,6 +18,7 @@ package org.apache.solr.search.function.
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.Searcher;
+import org.apache.lucene.spatial.tier.DistanceUtils;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.search.function.MultiValueSource;
 import org.apache.solr.search.function.DocValues;

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/SquaredEuclideanFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/SquaredEuclideanFunction.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/SquaredEuclideanFunction.java
(original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/SquaredEuclideanFunction.java
Sat Jul 10 00:12:41 2010
@@ -16,6 +16,7 @@ package org.apache.solr.search.function.
  * limitations under the License.
  */
 
+import org.apache.lucene.spatial.tier.DistanceUtils;
 import org.apache.solr.search.function.DocValues;
 import org.apache.solr.search.function.MultiValueSource;
 

Modified: lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java
(original)
+++ lucene/dev/trunk/solr/src/java/org/apache/solr/search/function/distance/VectorDistanceFunction.java
Sat Jul 10 00:12:41 2010
@@ -18,6 +18,7 @@ package org.apache.solr.search.function.
 
 import org.apache.lucene.index.IndexReader;
 import org.apache.lucene.search.Searcher;
+import org.apache.lucene.spatial.tier.DistanceUtils;
 import org.apache.solr.common.SolrException;
 import org.apache.solr.search.function.DocValues;
 import org.apache.solr.search.function.MultiValueSource;

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/schema/PolyFieldTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/schema/PolyFieldTest.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/schema/PolyFieldTest.java (original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/schema/PolyFieldTest.java Sat Jul 10 00:12:41
2010
@@ -22,6 +22,8 @@ import org.apache.lucene.search.BooleanQ
 import org.apache.lucene.search.Query;
 import org.apache.lucene.spatial.tier.CartesianPolyFilterBuilder;
 import org.apache.lucene.spatial.tier.Shape;
+import org.apache.lucene.spatial.tier.projections.CartesianTierPlotter;
+import org.apache.lucene.spatial.tier.projections.SinusoidalProjector;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.core.SolrCore;
 import org.apache.solr.common.SolrException;
@@ -185,39 +187,4 @@ public class PolyFieldTest extends SolrT
     clearIndex();
   }
 
-  @Test
-  public void testCartesian() throws Exception {
-    for (int i = 40; i < 50; i++) {
-      for (int j = -85; j < -79; j++) {
-        assertU(adoc("id", "" + i, "home_tier",
-                i + "," + j));
-      }
-    }
-    assertU(commit());
-    CartesianPolyFilterBuilder cpfb = new CartesianPolyFilterBuilder("", 4, 15);
-    //Get the box based on this point and our distance
-    final Shape shape = cpfb.getBoxShape(45, -80, 10);//There's a bit of a bug in here that
requires a small tier filter here.
-    final List<Double> boxIds = shape.getArea();
-    //do a box id search
-    StringBuilder qry = new StringBuilder();
-    boolean first = true;
-    for (Double boxId : boxIds) {
-      if (first == true){
-        first = false;
-      } else {
-        qry.append(" OR ");
-      }
-      qry.append("home_tier:");
-      if (boxId < 0) {
-        qry.append('\\').append(boxId);
-      } else {
-        qry.append(boxId);
-      }
-    }
-
-    assertQ(req("fl", "*,score", "indent", "true", "q", qry.toString()),
-            "//*[@numFound='1']");
-    clearIndex();
-  }
-
 }
\ No newline at end of file

Added: lucene/dev/trunk/solr/src/test/org/apache/solr/search/SpatialFilterTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/search/SpatialFilterTest.java?rev=962727&view=auto
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/search/SpatialFilterTest.java (added)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/search/SpatialFilterTest.java Sat Jul 10
00:12:41 2010
@@ -0,0 +1,147 @@
+package org.apache.solr.search;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ *
+ *
+ **/
+public class SpatialFilterTest extends SolrTestCaseJ4 {
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig.xml", "schema.xml");
+  }
+
+  private void setupDocs(String fieldName) {
+    clearIndex();
+    assertU(adoc("id", "1", fieldName, "32.7693246, -79.9289094"));
+    assertU(adoc("id", "2", fieldName, "33.7693246, -80.9289094"));
+    assertU(adoc("id", "3", fieldName, "-32.7693246, 50.9289094"));
+    assertU(adoc("id", "4", fieldName, "-50.7693246, 60.9289094"));
+    assertU(adoc("id", "5", fieldName, "0,0"));
+    assertU(adoc("id", "6", fieldName, "0.1,0.1"));
+    assertU(adoc("id", "7", fieldName, "-0.1,-0.1"));
+    assertU(adoc("id", "8", fieldName, "0,179.9"));
+    assertU(adoc("id", "9", fieldName, "0,-179.9"));
+    assertU(adoc("id", "10", fieldName, "89.9,50"));
+    assertU(adoc("id", "11", fieldName, "89.9,-130"));
+    assertU(adoc("id", "12", fieldName, "-89.9,50"));
+    assertU(adoc("id", "13", fieldName, "-89.9,-130"));
+    assertU(commit());
+  }
+  
+  @Test
+  public void testPoints() throws Exception {
+    String fieldName = "home";
+    setupDocs(fieldName);
+    //Try some edge cases
+    checkHits(fieldName, "1,1", 100, 5, 3, 4, 5, 6, 7);
+    checkHits(fieldName, "0,179.8", 200, 5, 3, 4, 8, 10, 12);
+    checkHits(fieldName, "89.8, 50", 200, 9);
+    //try some normal cases
+    checkHits(fieldName, "33.0,-80.0", 300, 12);
+    //large distance
+    checkHits(fieldName, "33.0,-80.0", 5000, 13);
+  }
+
+  @Test
+  public void testGeoHash() throws Exception {
+    String fieldName = "home_gh";
+    setupDocs(fieldName);
+    //try some normal cases
+    checkHits(fieldName, "33.0,-80.0", 300, 2, 1, 2);
+    //large distance
+    checkHits(fieldName, "33.0,-80.0", 5000, 2, 1, 2);
+    //Try some edge cases
+    checkHits(fieldName, "0,179.8", 200, 2);
+    checkHits(fieldName, "1,1", 180, 3, 5, 6, 7);
+    checkHits(fieldName, "89.8, 50", 200, 2);
+    checkHits(fieldName, "-89.8, 50", 200, 2);//this goes over the south pole
+  }
+
+  @Test
+  public void testLatLonType() throws Exception {
+    String fieldName = "home_ll";
+    setupDocs(fieldName);
+    //Try some edge cases
+    checkHits(fieldName, "1,1", 175, 3, 5, 6, 7);
+    checkHits(fieldName, "0,179.8", 200, 2, 8, 9);
+    checkHits(fieldName, "89.8, 50", 200, 2, 10, 11);//this goes over the north pole
+    checkHits(fieldName, "-89.8, 50", 200, 2, 12, 13);//this goes over the south pole
+    //try some normal cases
+    checkHits(fieldName, "33.0,-80.0", 300, 2);
+    //large distance
+    checkHits(fieldName, "1,1", 5000, 3, 5, 6, 7);
+    //Try alternate distance
+    checkHits(fieldName, "0.1,0.1", 15, 1, 6);
+
+  }
+
+  private void checkHits(String fieldName, String pt, double distance, int count, int ...
docIds) {
+    String [] tests = new String[docIds != null && docIds.length > 0 ? docIds.length
+ 1 : 1];
+    tests[0] = "*[count(//doc)=" + count + "]";
+    if (docIds != null && docIds.length > 0) {
+      int i = 1;
+      for (int docId : docIds) {
+        tests[i++] = "//result/doc/int[@name='id'][.='" + docId + "']";
+      }
+    }
+    assertQ(req("fl", "id", "q","*:*", "rows", "1000", "fq", "{!sfilt fl=" +fieldName +"}",
+            "pt", pt, "d", String.valueOf(distance)),
+            tests);//
+  }
+
+
+}
+ /*public void testSpatialQParser() throws Exception {
+    ModifiableSolrParams local = new ModifiableSolrParams();
+    local.add(CommonParams.FL, "home");
+    ModifiableSolrParams params = new ModifiableSolrParams();
+    params.add(SpatialParams.POINT, "5.0,5.0");
+    params.add(SpatialParams.DISTANCE, "3");
+    SolrQueryRequest req = new LocalSolrQueryRequest(h.getCore(), "", "", 0, 10, new HashMap());
+    SpatialFilterQParserPlugin parserPlugin;
+    Query query;
+
+    parserPlugin = new SpatialFilterQParserPlugin();
+    QParser parser = parserPlugin.createParser("'foo'", local, params, req);
+    query = parser.parse();
+    assertNotNull("Query is null", query);
+    assertTrue("query is not an instanceof "
+            + BooleanQuery.class,
+            query instanceof BooleanQuery);
+    local = new ModifiableSolrParams();
+    local.add(CommonParams.FL, "x");
+    params = new ModifiableSolrParams();
+    params.add(SpatialParams.POINT, "5.0");
+    params.add(SpatialParams.DISTANCE, "3");
+    req = new LocalSolrQueryRequest(h.getCore(), "", "", 0, 10, new HashMap());
+    parser = parserPlugin.createParser("'foo'", local, params, req);
+    query = parser.parse();
+    assertNotNull("Query is null", query);
+    assertTrue(query.getClass() + " is not an instanceof "
+            + NumericRangeQuery.class,
+            query instanceof NumericRangeQuery);
+    req.close();
+  }*/
\ No newline at end of file

Propchange: lucene/dev/trunk/solr/src/test/org/apache/solr/search/SpatialFilterTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: lucene/dev/trunk/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java
(original)
+++ lucene/dev/trunk/solr/src/test/org/apache/solr/search/function/distance/DistanceFunctionTest.java
Sat Jul 10 00:12:41 2010
@@ -17,6 +17,7 @@ package org.apache.solr.search.function.
  */
 
 import org.apache.lucene.spatial.geohash.GeoHashUtils;
+import org.apache.lucene.spatial.tier.DistanceUtils;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.common.SolrException;
 import org.junit.BeforeClass;
@@ -55,17 +56,17 @@ public class DistanceFunctionTest extend
 
     //Geo Hash Haversine
     //Can verify here: http://www.movable-type.co.uk/scripts/latlong.html, but they use a
slightly different radius for the earth, so just be close
-    assertQ(req("fl", "*,score", "q", "{!func}ghhsin(" + Constants.EARTH_RADIUS_KM + ", gh_s,
\"" + GeoHashUtils.encode(32, -79) +
-            "\",)", "fq", "id:1"), "//float[@name='score']='122.309006'");
+    assertQ(req("fl", "*,score", "q", "{!func}ghhsin(" + DistanceUtils.EARTH_MEAN_RADIUS_KM
+ ", gh_s, \"" + GeoHashUtils.encode(32, -79) +
+            "\",)", "fq", "id:1"), "//float[@name='score']='122.171875'");
 
-    assertQ(req("fl", "id,point_hash,score", "q", "{!func}recip(ghhsin(" + Constants.EARTH_RADIUS_KM
+ ", point_hash, \"" + GeoHashUtils.encode(32, -79) + "\"), 1, 1, 0)"),
+    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
             );
 
 
-    assertQ(req("fl", "*,score", "q", "{!func}ghhsin(" + Constants.EARTH_RADIUS_KM + ", gh_s,
geohash(32, -79))", "fq", "id:1"), "//float[@name='score']='122.309006'");
+    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

Modified: lucene/dev/trunk/solr/src/test/test-files/solr/conf/schema.xml
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/src/test/test-files/solr/conf/schema.xml?rev=962727&r1=962726&r2=962727&view=diff
==============================================================================
--- lucene/dev/trunk/solr/src/test/test-files/solr/conf/schema.xml (original)
+++ lucene/dev/trunk/solr/src/test/test-files/solr/conf/schema.xml Sat Jul 10 00:12:41 2010
@@ -373,11 +373,14 @@
     
     <!-- Try out some point types -->
   <fieldType name="xy" class="solr.PointType" dimension="2" subFieldType="double"/>
+  <fieldType name="x" class="solr.PointType" dimension="1" subFieldType="double"/>
   <fieldType name="tenD" class="solr.PointType" dimension="10" subFieldType="double"/>
     <!-- Use the sub field suffix -->
   <fieldType name="xyd" class="solr.PointType" dimension="2" subFieldSuffix="*_d"/>
+    <fieldtype name="geohash" class="solr.GeoHashField"/>
 
-  <fieldType name="tier" class="solr.SpatialTileField" start="4" end="15" subFieldType="double"/>
+
+  <fieldType name="latLon" class="solr.LatLonType" subFieldType="double"/>
 
  </types>
 
@@ -406,11 +409,14 @@
    <!-- Test points -->
       <!-- Test points -->
    <field name="home" type="xy" indexed="true" stored="true" multiValued="false"/>
+   <field name="x" type="x" indexed="true" stored="true" multiValued="false"/>
    <field name="homed" type="xyd" indexed="true" stored="true" multiValued="false"/>
    <field name="home_ns" type="xy" indexed="true" stored="false" multiValued="false"/>
    <field name="work" type="xy" indexed="true" stored="true" multiValued="false"/>
 
-   <field name="home_tier" type="tier" indexed="true" stored="true" multiValued="false"/>
+   <field name="home_ll" type="latLon" indexed="true" stored="true" multiValued="false"/>
+   <field name="home_gh" type="geohash" indexed="true" stored="true" multiValued="false"/>
+
 
    <field name="point10" type="tenD" indexed="true" stored="true" multiValued="false"/>
 



Mime
View raw message