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 2012/07/02 08:47:50 UTC
svn commit: r1356081 - in /lucene/dev/trunk/lucene/spatial/src:
java/org/apache/lucene/spatial/query/
java/org/apache/lucene/spatial/vector/ test/org/apache/lucene/spatial/
test/org/apache/lucene/spatial/prefix/
Author: dsmiley
Date: Mon Jul 2 06:47:49 2012
New Revision: 1356081
URL: http://svn.apache.org/viewvc?rev=1356081&view=rev
Log:
LUCENE-4157 Ported the Solr 3 spatial test to Lucene spatial. Did a few minor other things too.
Added:
lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
Removed:
lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/prefix/TestSpatialPrefixField.java
Modified:
lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java?rev=1356081&r1=1356080&r2=1356081&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/query/SpatialOperation.java Mon Jul 2 06:47:49 2012
@@ -25,6 +25,11 @@ import java.util.*;
/**
* A clause that compares a stored geometry to a supplied geometry.
*
+ * @see <a href="http://edndoc.esri.com/arcsde/9.1/general_topics/understand_spatial_relations.htm">
+ * ESRI's docs on spatial relations</a>
+ * @see <a href="http://docs.geoserver.org/latest/en/user/filter/ecql_reference.html#spatial-predicate">
+ * GeoServer ECQL Spatial Predicates</a>
+ *
* @lucene.experimental
*/
public class SpatialOperation implements Serializable {
Modified: lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java?rev=1356081&r1=1356080&r2=1356081&view=diff
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java (original)
+++ lucene/dev/trunk/lucene/spatial/src/java/org/apache/lucene/spatial/vector/DistanceValueSource.java Mon Jul 2 06:47:49 2012
@@ -1,3 +1,5 @@
+package org.apache.lucene.spatial.vector;
+
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
@@ -15,11 +17,8 @@
* limitations under the License.
*/
-package org.apache.lucene.spatial.vector;
-
import com.spatial4j.core.distance.DistanceCalculator;
import com.spatial4j.core.shape.Point;
-import com.spatial4j.core.shape.simple.PointImpl;
import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.queries.function.FunctionValues;
@@ -84,8 +83,7 @@ public class DistanceValueSource extends
public double doubleVal(int doc) {
// make sure it has minX and area
if (validX.get(doc) && validY.get(doc)) {
- PointImpl pt = new PointImpl( ptX[doc], ptY[doc] );
- return calculator.distance(from, pt);
+ return calculator.distance(from, ptX[doc], ptY[doc]);
}
return 0;
}
Added: lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java?rev=1356081&view=auto
==============================================================================
--- lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java (added)
+++ lucene/dev/trunk/lucene/spatial/src/test/org/apache/lucene/spatial/PortedSolr3Test.java Mon Jul 2 06:47:49 2012
@@ -0,0 +1,220 @@
+package org.apache.lucene.spatial;
+
+/*
+ * 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 com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
+import com.spatial4j.core.context.SpatialContext;
+import com.spatial4j.core.context.simple.SimpleSpatialContext;
+import com.spatial4j.core.shape.Point;
+import com.spatial4j.core.shape.Shape;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.index.IndexableField;
+import org.apache.lucene.search.FilteredQuery;
+import org.apache.lucene.search.MatchAllDocsQuery;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.spatial.prefix.RecursivePrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.TermQueryPrefixTreeStrategy;
+import org.apache.lucene.spatial.prefix.tree.GeohashPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.QuadPrefixTree;
+import org.apache.lucene.spatial.prefix.tree.SpatialPrefixTree;
+import org.apache.lucene.spatial.query.SpatialArgs;
+import org.apache.lucene.spatial.query.SpatialOperation;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Based off of Solr 3's SpatialFilterTest.
+ * @author dsmiley
+ */
+public class PortedSolr3Test extends StrategyTestCase {
+
+ @ParametersFactory
+ public static Iterable<Object[]> parameters() {
+ List<Object[]> ctorArgs = new ArrayList<Object[]>();
+
+ SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+ SpatialPrefixTree grid;
+ SpatialStrategy strategy;
+
+ grid = new GeohashPrefixTree(ctx,12);
+ strategy = new RecursivePrefixTreeStrategy(grid);
+ ctorArgs.add(new Object[]{"recursive_geohash",strategy});
+
+ grid = new QuadPrefixTree(ctx,25);
+ strategy = new RecursivePrefixTreeStrategy(grid);
+ ctorArgs.add(new Object[]{"recursive_quad",strategy});
+
+ grid = new GeohashPrefixTree(ctx,12);
+ strategy = new TermQueryPrefixTreeStrategy(grid);
+ ctorArgs.add(new Object[]{"termquery_geohash",strategy});
+
+ return ctorArgs;
+ }
+
+// private String fieldName;
+
+ public PortedSolr3Test(String fieldName, SpatialStrategy strategy) {
+ ctx = strategy.getSpatialContext();
+ this.strategy = strategy;
+// this.fieldName = fieldName;
+ fieldInfo = new SimpleSpatialFieldInfo( fieldName );
+ }
+
+ private void setupDocs() throws IOException {
+ super.deleteAll();
+ adoc("1", "32.7693246, -79.9289094");
+ adoc("2", "33.7693246, -80.9289094");
+ adoc("3", "-32.7693246, 50.9289094");
+ adoc("4", "-50.7693246, 60.9289094");
+ adoc("5", "0,0");
+ adoc("6", "0.1,0.1");
+ adoc("7", "-0.1,-0.1");
+ adoc("8", "0,179.9");
+ adoc("9", "0,-179.9");
+ adoc("10", "89.9,50");
+ adoc("11", "89.9,-130");
+ adoc("12", "-89.9,50");
+ adoc("13", "-89.9,-130");
+ commit();
+ }
+
+
+ @Test
+ public void testIntersections() throws Exception {
+ setupDocs();
+ //Try some edge cases
+ checkHitsCircle("1,1", 175, 3, 5, 6, 7);
+ checkHitsCircle("0,179.8", 200, 2, 8, 9);
+ checkHitsCircle("89.8, 50", 200, 2, 10, 11);//this goes over the north pole
+ checkHitsCircle("-89.8, 50", 200, 2, 12, 13);//this goes over the south pole
+ //try some normal cases
+ checkHitsCircle("33.0,-80.0", 300, 2);
+ //large distance
+ checkHitsCircle("1,1", 5000, 3, 5, 6, 7);
+ //Because we are generating a box based on the west/east longitudes and the south/north latitudes, which then
+ //translates to a range query, which is slightly more inclusive. Thus, even though 0.0 is 15.725 kms away,
+ //it will be included, b/c of the box calculation.
+ checkHitsBBox("0.1,0.1", 15, 2, 5, 6);
+ //try some more
+ deleteAll();
+ adoc("14", "0,5");
+ adoc("15", "0,15");
+ //3000KM from 0,0, see http://www.movable-type.co.uk/scripts/latlong.html
+ adoc("16", "18.71111,19.79750");
+ adoc("17", "44.043900,-95.436643");
+ commit();
+
+ checkHitsCircle("0,0", 1000, 1, 14);
+ checkHitsCircle("0,0", 2000, 2, 14, 15);
+ checkHitsBBox("0,0", 3000, 3, 14, 15, 16);
+ checkHitsCircle("0,0", 3001, 3, 14, 15, 16);
+ checkHitsCircle("0,0", 3000.1, 3, 14, 15, 16);
+
+ //really fine grained distance and reflects some of the vagaries of how we are calculating the box
+ checkHitsCircle("43.517030,-96.789603", 109, 0);
+
+ // falls outside of the real distance, but inside the bounding box
+ checkHitsCircle("43.517030,-96.789603", 110, 0);
+ checkHitsBBox("43.517030,-96.789603", 110, 1, 17);
+ }
+
+ /**
+ * This test is similar to a Solr 3 spatial test.
+ */
+ @Test
+ public void testDistanceOrder() throws IOException {
+ adoc("100","1,2");
+ adoc("101","4,-1");
+ commit();
+
+ //query closer to #100
+ checkHitsOrdered("Intersects(Circle(3,4 d=1000))", "101", "100");
+ //query closer to #101
+ checkHitsOrdered("Intersects(Circle(4,0 d=1000))", "100", "101");
+ }
+
+ private void checkHitsOrdered(String spatialQ, String... ids) {
+ SpatialArgs args = this.argsParser.parse(spatialQ,ctx);
+ Query query = strategy.makeQuery(args, fieldInfo);
+ SearchResults results = executeQuery(query, 100);
+ String[] resultIds = new String[results.numFound];
+ int i = 0;
+ for (SearchResult result : results.results) {
+ resultIds[i++] = result.document.get("id");
+ }
+ assertArrayEquals("order matters",ids, resultIds);
+ }
+
+ //---- these are similar to Solr test methods
+
+ private void adoc(String idStr, String shapeStr) throws IOException {
+ Shape shape = ctx.readShape(shapeStr);
+ addDocument(newDoc(idStr,shape));
+ }
+
+ @SuppressWarnings("unchecked")
+ private Document newDoc(String id, Shape shape) {
+ Document doc = new Document();
+ doc.add(new StringField("id", id, Field.Store.YES));
+ for (IndexableField f : strategy.createFields(fieldInfo, shape, true, storeShape)) {
+ doc.add(f);
+ }
+ return doc;
+ }
+
+ private void checkHitsCircle(String ptStr, double dist, int assertNumFound, int... assertIds) {
+ _checkHits(SpatialOperation.Intersects, ptStr, dist, assertNumFound, assertIds);
+ }
+ private void checkHitsBBox(String ptStr, double dist, int assertNumFound, int... assertIds) {
+ _checkHits(SpatialOperation.BBoxIntersects, ptStr, dist, assertNumFound, assertIds);
+ }
+
+ @SuppressWarnings("unchecked")
+ private void _checkHits(SpatialOperation op, String ptStr, double dist, int assertNumFound, int... assertIds) {
+ Point pt = (Point) ctx.readShape(ptStr);
+ Shape shape = ctx.makeCircle(pt,dist);
+
+ SpatialArgs args = new SpatialArgs(op,shape);
+ //args.setDistPrecision(0.025);
+ Query query;
+ if (random().nextBoolean()) {
+ query = strategy.makeQuery(args, fieldInfo);
+ } else {
+ query = new FilteredQuery(new MatchAllDocsQuery(),strategy.makeFilter(args, fieldInfo));
+ }
+ SearchResults results = executeQuery(query, 100);
+ assertEquals(""+shape,assertNumFound,results.numFound);
+ if (assertIds != null) {
+ Set<Integer> resultIds = new HashSet<Integer>();
+ for (SearchResult result : results.results) {
+ resultIds.add(Integer.valueOf(result.document.get("id")));
+ }
+ for (int assertId : assertIds) {
+ assertTrue("has " + assertId, resultIds.contains(assertId));
+ }
+ }
+ }
+
+}