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/02/20 23:45:37 UTC
svn commit: r1291499 [5/12] - in
/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene:
./ src/ src/main/ src/main/java/ src/main/java/org/
src/main/java/org/apache/ src/main/java/org/apache/lucene/
src/main/java/org/apache/lucene/s...
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/StrategyTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/StrategyTestCase.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/StrategyTestCase.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/StrategyTestCase.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial;
+
+
+import junit.framework.Assert;
+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.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.io.sample.SampleData;
+import org.apache.lucene.spatial.base.io.sample.SampleDataReader;
+import org.apache.lucene.spatial.base.query.SpatialArgsParser;
+import org.apache.lucene.spatial.base.shape.Shape;
+import org.apache.lucene.spatial.strategy.SpatialFieldInfo;
+import org.apache.lucene.spatial.strategy.SpatialStrategy;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.*;
+
+public abstract class StrategyTestCase<T extends SpatialFieldInfo> extends SpatialTestCase {
+
+ public static final String DATA_STATES_POLY = "states-poly.txt";
+ public static final String DATA_STATES_BBOX = "states-bbox.txt";
+ public static final String DATA_COUNTRIES_POLY = "countries-poly.txt";
+ public static final String DATA_COUNTRIES_BBOX = "countries-bbox.txt";
+ public static final String DATA_WORLD_CITIES_POINTS = "world-cities-points.txt";
+
+ public static final String QTEST_States_IsWithin_BBox = "states-IsWithin-BBox.txt";
+ public static final String QTEST_States_Intersects_BBox = "states-Intersects-BBox.txt";
+
+ public static final String QTEST_Cities_IsWithin_BBox = "cities-IsWithin-BBox.txt";
+
+ protected final Logger log = LoggerFactory.getLogger(getClass());
+
+ protected final SpatialArgsParser argsParser = new SpatialArgsParser();
+
+ protected SpatialStrategy<T> strategy;
+ protected SpatialContext ctx;
+ protected T fieldInfo;
+ protected boolean storeShape = true;
+
+ protected void executeQueries(SpatialMatchConcern concern, String... testQueryFile) throws IOException {
+ log.info("testing queried for strategy "+strategy);
+ for( String path : testQueryFile ) {
+ Iterator<SpatialTestQuery> testQueryIterator = getTestQueries(path, ctx);
+ runTestQueries(testQueryIterator, concern);
+ }
+ }
+
+ protected void getAddAndVerifyIndexedDocuments(String testDataFile) throws IOException {
+ List<Document> testDocuments = getDocuments(testDataFile);
+ addDocumentsAndCommit(testDocuments);
+ verifyDocumentsIndexed(testDocuments.size());
+ }
+
+ protected List<Document> getDocuments(String testDataFile) throws IOException {
+ Iterator<SampleData> sampleData = getSampleData(testDataFile);
+ List<Document> documents = new ArrayList<Document>();
+ while (sampleData.hasNext()) {
+ SampleData data = sampleData.next();
+ Document document = new Document();
+ document.add(new Field("id", data.id, StringField.TYPE_STORED));
+ document.add(new Field("name", data.name, StringField.TYPE_STORED));
+ Shape shape = ctx.readShape(data.shape);
+ for (IndexableField f : strategy.createFields(fieldInfo, shape, true, storeShape)) {
+ if( f != null ) { // null if incompatibleGeometry && ignore
+ document.add(f);
+ }
+ }
+ documents.add(document);
+ }
+ return documents;
+ }
+
+ protected Iterator<SampleData> getSampleData(String testDataFile) throws IOException {
+ return new SampleDataReader(
+ getClass().getClassLoader().getResourceAsStream("data/"+testDataFile) );
+ }
+
+ protected Iterator<SpatialTestQuery> getTestQueries(String testQueryFile, SpatialContext ctx) throws IOException {
+ InputStream in = getClass().getClassLoader().getResourceAsStream(testQueryFile);
+ return SpatialTestQuery.getTestQueries(
+ argsParser, ctx, testQueryFile, in );
+ }
+
+ public void runTestQueries(
+ Iterator<SpatialTestQuery> queries,
+ SpatialMatchConcern concern) {
+ while (queries.hasNext()) {
+ SpatialTestQuery q = queries.next();
+
+ String msg = q.line; //"Query: " + q.args.toString(ctx);
+ SearchResults got = executeQuery(strategy.makeQuery(q.args, fieldInfo), 100);
+ if (concern.orderIsImportant) {
+ Iterator<String> ids = q.ids.iterator();
+ for (SearchResult r : got.results) {
+ String id = r.document.get("id");
+ Assert.assertEquals( "out of order: " + msg, ids.next(), id);
+ }
+ if (ids.hasNext()) {
+ Assert.fail(msg + " :: expect more results then we got: " + ids.next());
+ }
+ } else {
+ // We are looking at how the results overlap
+ if( concern.resultsAreSuperset ) {
+ Set<String> found = new HashSet<String>();
+ for (SearchResult r : got.results) {
+ found.add(r.document.get("id"));
+ }
+ for( String s : q.ids ) {
+ if( !found.contains( s ) ) {
+ Assert.fail( "Results are mising id: "+s + " :: " + found );
+ }
+ }
+ }
+ else {
+ List<String> found = new ArrayList<String>();
+ for (SearchResult r : got.results) {
+ found.add(r.document.get("id"));
+ }
+
+ // sort both so that the order is not important
+ Collections.sort(q.ids);
+ Collections.sort(found);
+ Assert.assertEquals(msg, q.ids.toString(), found.toString());
+ }
+ }
+ }
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/TestTestFramework.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/TestTestFramework.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/TestTestFramework.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/TestTestFramework.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.query.SpatialArgsParser;
+import org.apache.lucene.spatial.base.query.SpatialOperation;
+import org.apache.lucene.spatial.base.shape.Rectangle;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * Make sure we are reading the tests as expected
+ */
+public class TestTestFramework {
+
+ @Test
+ public void testQueries() throws IOException {
+ String name = StrategyTestCase.QTEST_Cities_IsWithin_BBox;
+
+ InputStream in = getClass().getClassLoader().getResourceAsStream(name);
+ SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+ Iterator<SpatialTestQuery> iter = SpatialTestQuery.getTestQueries(
+ new SpatialArgsParser(), ctx, name, in );
+ List<SpatialTestQuery> tests = new ArrayList<SpatialTestQuery>();
+ while( iter.hasNext() ) {
+ tests.add( iter.next() );
+ }
+ Assert.assertEquals( 3, tests.size() );
+
+ SpatialTestQuery sf = tests.get(0);
+ // assert
+ Assert.assertEquals( 1, sf.ids.size() );
+ Assert.assertTrue( sf.ids.get(0).equals( "G5391959" ) );
+ Assert.assertTrue( sf.args.getShape() instanceof Rectangle);
+ Assert.assertEquals( SpatialOperation.IsWithin, sf.args.getOperation() );
+ }
+
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/BaseSpatialContextTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/BaseSpatialContextTestCase.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/BaseSpatialContextTestCase.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/BaseSpatialContextTestCase.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,169 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.context;
+
+import org.apache.lucene.spatial.base.query.SpatialArgs;
+import org.apache.lucene.spatial.base.query.SpatialArgsParser;
+import org.apache.lucene.spatial.base.query.SpatialOperation;
+import org.apache.lucene.spatial.base.shape.MultiShape;
+import org.apache.lucene.spatial.base.shape.Point;
+import org.apache.lucene.spatial.base.shape.Rectangle;
+import org.apache.lucene.spatial.base.shape.Shape;
+import org.apache.lucene.spatial.base.shape.simple.CircleImpl;
+import org.apache.lucene.spatial.base.shape.simple.PointImpl;
+import org.apache.lucene.spatial.base.shape.simple.RectangleImpl;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+/**
+ */
+@SuppressWarnings("unchecked")
+public abstract class BaseSpatialContextTestCase {
+
+ protected abstract SpatialContext getSpatialContext();
+
+ public static void checkArgParser(SpatialContext ctx) {
+ SpatialArgsParser parser = new SpatialArgsParser();
+
+ String arg = SpatialOperation.IsWithin + "(-10 -20 10 20)";
+ SpatialArgs out = parser.parse(arg, ctx);
+ assertEquals(SpatialOperation.IsWithin, out.getOperation());
+ Rectangle bounds = (Rectangle) out.getShape();
+ assertEquals(-10.0, bounds.getMinX(), 0D);
+ assertEquals(10.0, bounds.getMaxX(), 0D);
+
+ // Disjoint should not be scored
+ arg = SpatialOperation.IsDisjointTo + " (-10 10 -20 20)";
+ out = parser.parse(arg, ctx);
+ assertEquals(SpatialOperation.IsDisjointTo, out.getOperation());
+
+ try {
+ parser.parse(SpatialOperation.IsDisjointTo + "[ ]", ctx);
+ fail("spatial operations need args");
+ }
+ catch (Exception ex) {//expected
+ }
+
+ try {
+ parser.parse("XXXX(-10 10 -20 20)", ctx);
+ fail("unknown operation!");
+ }
+ catch (Exception ex) {//expected
+ }
+ }
+
+ public static void checkShapesImplementEquals( Class[] classes ) {
+
+ for( Class clazz : classes ) {
+ try {
+ clazz.getDeclaredMethod( "equals", Object.class );
+ } catch (Exception e) {
+ Assert.fail( "Shape needs to define 'equals' : " + clazz.getName() );
+ }
+ try {
+ clazz.getDeclaredMethod( "hashCode" );
+ } catch (Exception e) {
+ Assert.fail( "Shape needs to define 'hashCode' : " + clazz.getName() );
+ }
+ }
+ }
+
+ public static interface WriteReader {
+ Shape writeThenRead( Shape s ) throws IOException;
+ }
+
+ public static void checkBasicShapeIO( SpatialContext ctx, WriteReader help ) throws Exception {
+
+ // Simple Point
+ Shape s = ctx.readShape("10 20");
+ assertEquals(s,ctx.readShape("20,10"));//check comma for y,x format
+ assertEquals(s,ctx.readShape("20, 10"));//test space
+ Point p = (Point) s;
+ assertEquals(10.0, p.getX(), 0D);
+ assertEquals(20.0, p.getY(), 0D);
+ p = (Point) help.writeThenRead(s);
+ assertEquals(10.0, p.getX(), 0D);
+ assertEquals(20.0, p.getY(), 0D);
+ Assert.assertFalse(s.hasArea());
+
+ // BBOX
+ s = ctx.readShape("-10 -20 10 20");
+ Rectangle b = (Rectangle) s;
+ assertEquals(-10.0, b.getMinX(), 0D);
+ assertEquals(-20.0, b.getMinY(), 0D);
+ assertEquals(10.0, b.getMaxX(), 0D);
+ assertEquals(20.0, b.getMaxY(), 0D);
+ b = (Rectangle) help.writeThenRead(s);
+ assertEquals(-10.0, b.getMinX(), 0D);
+ assertEquals(-20.0, b.getMinY(), 0D);
+ assertEquals(10.0, b.getMaxX(), 0D);
+ assertEquals(20.0, b.getMaxY(), 0D);
+ Assert.assertTrue(s.hasArea());
+
+ // Point/Distance
+ s = ctx.readShape("Circle( 1.23 4.56 distance=7.89)");
+ CircleImpl circle = (CircleImpl)s;
+ assertEquals(1.23, circle.getCenter().getX(), 0D);
+ assertEquals(4.56, circle.getCenter().getY(), 0D);
+ assertEquals(7.89, circle.getDistance(), 0D);
+ Assert.assertTrue(s.hasArea());
+
+ Shape s2 = ctx.readShape("Circle( 4.56,1.23 d=7.89 )"); // use lat,lon and use 'd' abbreviation
+ assertEquals(s,s2);
+ }
+
+ //--------------------------------------------------------------
+ // Actual tests
+ //--------------------------------------------------------------
+
+ @Test
+ public void testArgsParser() throws Exception {
+ checkArgParser( getSpatialContext() );
+ }
+
+ @Test
+ public void testImplementsEqualsAndHash() throws Exception {
+ checkShapesImplementEquals( new Class[] {
+ PointImpl.class,
+ CircleImpl.class,
+ RectangleImpl.class,
+ MultiShape.class,
+ });
+ }
+
+ @Test
+ public void testSimpleShapeIO() throws Exception {
+ final SpatialContext io = getSpatialContext();
+ checkBasicShapeIO( io, new WriteReader() {
+ @Override
+ public Shape writeThenRead(Shape s) {
+ String buff = io.toString( s );
+ return io.readShape( buff );
+ }
+ });
+ }
+
+ //Looking for more tests? Shapes are tested in TestShapes2D.
+
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextFactoryTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextFactoryTest.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextFactoryTest.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextFactoryTest.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,94 @@
+package org.apache.lucene.spatial.base.context;/*
+ * 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.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.distance.DistanceUnits;
+import org.apache.lucene.spatial.base.distance.CartesianDistCalc;
+import org.apache.lucene.spatial.base.distance.GeodesicSphereDistCalc;
+import org.apache.lucene.spatial.base.shape.simple.RectangleImpl;
+import org.junit.After;
+import org.junit.Test;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static junit.framework.Assert.assertEquals;
+
+/**
+ * @author dsmiley
+ */
+public class SpatialContextFactoryTest {
+ public static final String PROP = "SpatialContextFactory";
+
+ @After
+ public void tearDown() {
+ System.getProperties().remove(PROP);
+ }
+
+ private SpatialContext call(String... argsStr) {
+ Map<String,String> args = new HashMap<String,String>();
+ for (int i = 0; i < argsStr.length; i+=2) {
+ String key = argsStr[i];
+ String val = argsStr[i+1];
+ args.put(key,val);
+ }
+ return SpatialContextFactory.makeSpatialContext(args, getClass().getClassLoader());
+ }
+
+ @Test
+ public void testDefault() {
+ SpatialContext s = SimpleSpatialContext.GEO_KM;
+ SpatialContext t = call();//default
+ assertEquals(s.getClass(),t.getClass());
+ assertEquals(s.getUnits(),t.getUnits());
+ assertEquals(s.getDistCalc(),t.getDistCalc());
+ assertEquals(s.getWorldBounds(),t.getWorldBounds());
+ }
+
+ @Test
+ public void testCustom() {
+ SpatialContext sc = call("units","u");
+ assertEquals(DistanceUnits.CARTESIAN,sc.getUnits());
+ assertEquals(new CartesianDistCalc(),sc.getDistCalc());
+
+ sc = call("units","u",
+ "distCalculator","cartesian^2",
+ "worldBounds","-100 0 75 200");//West South East North
+ assertEquals(new CartesianDistCalc(true),sc.getDistCalc());
+ assertEquals(new RectangleImpl(-100,75,0,200),sc.getWorldBounds());
+
+ sc = call("units","miles",
+ "distCalculator","lawOfCosines");
+ assertEquals(DistanceUnits.MILES,sc.getUnits());
+ assertEquals(new GeodesicSphereDistCalc.LawOfCosines(sc.getUnits().earthRadius()),
+ sc.getDistCalc());
+ }
+
+ @Test
+ public void testSystemPropertyLookup() {
+ System.setProperty(PROP,DSCF.class.getName());
+ assertEquals(DistanceUnits.CARTESIAN,call().getUnits());//DSCF returns this
+ }
+
+ public static class DSCF extends SpatialContextFactory {
+
+ @Override
+ protected SpatialContext newSpatialContext() {
+ return new SimpleSpatialContext(DistanceUnits.CARTESIAN);
+ }
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextTestCase.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextTestCase.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/context/SpatialContextTestCase.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.context;
+
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+
+
+/**
+ */
+public class SpatialContextTestCase extends BaseSpatialContextTestCase {
+
+ @Override
+ protected SpatialContext getSpatialContext() {
+ return SimpleSpatialContext.GEO_KM;
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/distance/TestDistances.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/distance/TestDistances.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/distance/TestDistances.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/distance/TestDistances.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,269 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.distance;
+
+import org.apache.lucene.spatial.RandomSeed;
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.shape.SpatialRelation;
+import org.apache.lucene.spatial.base.shape.Point;
+import org.apache.lucene.spatial.base.shape.Rectangle;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Random;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author David Smiley - dsmiley@mitre.org
+ */
+public class TestDistances {
+
+ private final Random random = new Random(RandomSeed.seed());
+ //NOTE! These are sometimes modified by tests.
+ private SpatialContext ctx;
+ private double EPS;
+
+ @Before
+ public void beforeTest() {
+ ctx = new SimpleSpatialContext(DistanceUnits.KILOMETERS);
+ EPS = 10e-4;//delta when doing double assertions. Geo eps is not that small.
+ }
+
+ private DistanceCalculator dc() {
+ return ctx.getDistCalc();
+ }
+
+ @Test
+ public void testSomeDistances() {
+ //See to verify: from http://www.movable-type.co.uk/scripts/latlong.html
+ Point ctr = pLL(0,100);
+ assertEquals(11100, dc().distance(ctr, pLL(10, 0)),3);
+ assertEquals(11100, dc().distance(ctr, pLL(10, -160)),3);
+
+ assertEquals(314.40338, dc().distance(pLL(1, 2), pLL(3, 4)),EPS);
+ }
+
+ @Test
+ public void testCalcBoxByDistFromPt() {
+ //first test regression
+ {
+ double d = 6894.1;
+ Point pCtr = pLL(-20, 84);
+ Point pTgt = pLL(-42, 15);
+ assertTrue(dc().distance(pCtr, pTgt) < d);
+ //since the pairwise distance is less than d, a bounding box from ctr with d should contain pTgt.
+ Rectangle r = dc().calcBoxByDistFromPt(pCtr, d, ctx);
+ assertEquals(SpatialRelation.CONTAINS,r.relate(pTgt, ctx));
+ checkBBox(pCtr,d);
+ }
+
+ assertEquals("0 dist, horiz line",
+ -45,dc().calcBoxByDistFromPtHorizAxis(ctx.makePoint(-180,-45),0,ctx),0);
+
+ double MAXDIST = ctx.getUnits().earthCircumference() / 2;
+ checkBBox(ctx.makePoint(0,0), MAXDIST);
+ checkBBox(ctx.makePoint(0,0), MAXDIST *0.999999);
+ checkBBox(ctx.makePoint(0,0),0);
+ checkBBox(ctx.makePoint(0,0),0.000001);
+ checkBBox(ctx.makePoint(0,90),0.000001);
+ checkBBox(ctx.makePoint(-32.7,-5.42),9829);
+ checkBBox(ctx.makePoint(0,90-20),ctx.getDistCalc().degreesToDistance(20));
+ {
+ double d = 0.010;//10m
+ checkBBox(ctx.makePoint(0,90-ctx.getDistCalc().distanceToDegrees(d+0.001)),d);
+ }
+
+ for (int T = 0; T < 100; T++) {
+ double lat = -90 + random.nextDouble()*180;
+ double lon = -180 + random.nextDouble()*360;
+ Point ctr = ctx.makePoint(lon, lat);
+ double dist = MAXDIST*random.nextDouble();
+ checkBBox(ctr, dist);
+ }
+
+ }
+
+ private void checkBBox(Point ctr, double dist) {
+ String msg = "ctr: "+ctr+" dist: "+dist;
+
+ Rectangle r = dc().calcBoxByDistFromPt(ctr, dist, ctx);
+ double horizAxisLat = dc().calcBoxByDistFromPtHorizAxis(ctr,dist, ctx);
+ if (!Double.isNaN(horizAxisLat))
+ assertTrue(r.relate_yRange(horizAxisLat, horizAxisLat, ctx).intersects());
+
+ //horizontal
+ if (r.getWidth() >= 180) {
+ double calcDist = dc().distance(ctr,r.getMinX(), r.getMaxY() == 90 ? 90 : -90 );
+ assertTrue(msg,calcDist <= dist+EPS);
+ //horizAxisLat is meaningless in this context
+ } else {
+ Point tPt = findClosestPointOnVertToPoint(r.getMinX(), r.getMinY(), r.getMaxY(), ctr);
+ double calcDist = dc().distance(ctr,tPt);
+ assertEquals(msg,dist,calcDist,EPS);
+ assertEquals(msg,tPt.getY(),horizAxisLat,EPS);
+ }
+
+ //vertical
+ double topDist = dc().distance(ctr,ctr.getX(),r.getMaxY());
+ if (r.getMaxY() == 90)
+ assertTrue(msg,topDist <= dist+EPS);
+ else
+ assertEquals(msg,dist,topDist,EPS);
+ double botDist = dc().distance(ctr,ctr.getX(),r.getMinY());
+ if (r.getMinY() == -90)
+ assertTrue(msg,botDist <= dist+EPS);
+ else
+ assertEquals(msg,dist,botDist,EPS);
+ }
+
+ private Point findClosestPointOnVertToPoint(double lon, double lowLat, double highLat, Point ctr) {
+ //A binary search algorithm to find the point along the vertical lon between lowLat & highLat that is closest
+ // to ctr, and returns the distance.
+ double midLat = (highLat - lowLat)/2 + lowLat;
+ double midLatDist = ctx.getDistCalc().distance(ctr,lon,midLat);
+ for(int L = 0; L < 100 && (highLat - lowLat > 0.001|| L < 20); L++) {
+ boolean bottom = (midLat - lowLat > highLat - midLat);
+ double newMid = bottom ? (midLat - lowLat)/2 + lowLat : (highLat - midLat)/2 + midLat;
+ double newMidDist = ctx.getDistCalc().distance(ctr,lon,newMid);
+ if (newMidDist < midLatDist) {
+ if (bottom) {
+ highLat = midLat;
+ } else {
+ lowLat = midLat;
+ }
+ midLat = newMid;
+ midLatDist = newMidDist;
+ } else {
+ if (bottom) {
+ lowLat = newMid;
+ } else {
+ highLat = newMid;
+ }
+ }
+ }
+ return ctx.makePoint(lon,midLat);
+ }
+
+ @Test
+ public void testDistCalcPointOnBearing_cartesian() {
+ ctx = new SimpleSpatialContext(DistanceUnits.CARTESIAN);
+ EPS = 10e-6;//tighter epsilon (aka delta)
+ for(int i = 0; i < 1000; i++) {
+ testDistCalcPointOnBearing(random.nextInt(100));
+ }
+ }
+
+ @Test
+ public void testDistCalcPointOnBearing_geo() {
+ //The haversine formula has a higher error if the points are near antipodal. We adjust EPS tolerance for this case.
+ //TODO Eventually we should add the Vincenty formula for improved accuracy, or try some other cleverness.
+
+ //test known high delta
+// {
+// Point c = ctx.makePoint(-103,-79);
+// double angRAD = Math.toRadians(236);
+// double dist = 20025;
+// Point p2 = dc().pointOnBearingRAD(c, dist, angRAD, ctx);
+// //Pt(x=76.61200011750923,y=79.04946929870962)
+// double calcDist = dc().distance(c, p2);
+// assertEqualsRatio(dist, calcDist);
+// }
+ double maxDist = ctx.getUnits().earthCircumference() / 2;
+ for(int i = 0; i < 1000; i++) {
+ int dist = random.nextInt((int) maxDist);
+ EPS = (dist < maxDist*0.75 ? 10e-6 : 10e-3);
+ testDistCalcPointOnBearing(dist);
+ }
+ }
+
+ private void testDistCalcPointOnBearing(double dist) {
+ for(int angDEG = 0; angDEG < 360; angDEG += random.nextInt(20)+1) {
+ Point c = ctx.makePoint(random.nextInt(360),-90+random.nextInt(181));
+
+ //0 distance means same point
+ Point p2 = dc().pointOnBearing(c, 0, angDEG, ctx);
+ assertEquals(c,p2);
+
+ p2 = dc().pointOnBearing(c, dist, angDEG, ctx);
+ double calcDist = dc().distance(c, p2);
+ assertEqualsRatio(dist, calcDist);
+ }
+ }
+
+ private void assertEqualsRatio(double expected, double actual) {
+ double delta = Math.abs(actual - expected);
+ double base = Math.min(actual, expected);
+ double deltaRatio = base==0 ? delta : Math.min(delta,delta / base);
+ assertEquals(0,deltaRatio, EPS);
+ }
+
+ @Test
+ public void testNormLat() {
+ double[][] lats = new double[][] {
+ {1.23,1.23},//1.23 might become 1.2299999 after some math and we want to ensure that doesn't happen
+ {-90,-90},{90,90},{0,0}, {-100,-80},
+ {-90-180,90},{-90-360,-90},{90+180,-90},{90+360,90},
+ {-12+180,12}};
+ for (double[] pair : lats) {
+ assertEquals("input "+pair[0],pair[1],ctx.normY(pair[0]),0);
+ }
+ Random random = new Random(RandomSeed.seed());
+ for(int i = -1000; i < 1000; i += random.nextInt(10)*10) {
+ double d = ctx.normY(i);
+ assertTrue(i + " " + d, d >= -90 && d <= 90);
+ }
+ }
+
+ @Test
+ public void testNormLon() {
+ double[][] lons = new double[][] {
+ {1.23,1.23},//1.23 might become 1.2299999 after some math and we want to ensure that doesn't happen
+ {-180,-180},{180,-180},{0,0}, {-190,170},
+ {-180-360,-180},{-180-720,-180},{180+360,-180},{180+720,-180}};
+ for (double[] pair : lons) {
+ assertEquals("input "+pair[0],pair[1],ctx.normX(pair[0]),0);
+ }
+ Random random = new Random(RandomSeed.seed());
+ for(int i = -1000; i < 1000; i += random.nextInt(10)*10) {
+ double d = ctx.normX(i);
+ assertTrue(i + " " + d, d >= -180 && d < 180);
+ }
+ }
+
+ @Test
+ public void testDistToRadians() {
+ assertDistToRadians(0);
+ assertDistToRadians(500);
+ assertDistToRadians(ctx.getUnits().earthRadius());
+ }
+
+ private void assertDistToRadians(double dist) {
+ double radius = ctx.getUnits().earthRadius();
+ assertEquals(
+ DistanceUtils.pointOnBearingRAD(0, 0, DistanceUtils.dist2Radians(dist, radius), DistanceUtils.DEG_90_AS_RADS, null)[1],
+ DistanceUtils.dist2Radians(dist, radius),10e-5);
+ }
+
+ private Point pLL(double lat, double lon) {
+ return ctx.makePoint(lon,lat);
+ }
+
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/SpatialPrefixTreeTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/SpatialPrefixTreeTest.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/SpatialPrefixTreeTest.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/SpatialPrefixTreeTest.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.prefix;
+
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.prefix.geohash.GeohashPrefixTree;
+import org.apache.lucene.spatial.base.shape.Rectangle;
+import org.apache.lucene.spatial.base.shape.Shape;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author David Smiley - dsmiley@mitre.org
+ */
+public class SpatialPrefixTreeTest {
+
+ //TODO plug in others and test them
+ private SimpleSpatialContext ctx;
+ private SpatialPrefixTree trie;
+
+ @Before
+ public void setUp() throws Exception {
+ ctx = SimpleSpatialContext.GEO_KM;
+ trie = new GeohashPrefixTree(ctx,4);
+ }
+
+ @Test
+ public void testNodeTraverse() {
+ Node prevN = null;
+ Node n = trie.getWorldNode();
+ assertEquals(0,n.getLevel());
+ assertEquals(ctx.getWorldBounds(),n.getShape());
+ while(n.getLevel() < trie.getMaxLevels()) {
+ prevN = n;
+ n = n.getSubCells().iterator().next();//TODO random which one?
+
+ assertEquals(prevN.getLevel()+1,n.getLevel());
+ Rectangle prevNShape = (Rectangle) prevN.getShape();
+ Shape s = n.getShape();
+ Rectangle sbox = s.getBoundingBox();
+ assertTrue(prevNShape.getWidth() > sbox.getWidth());
+ assertTrue(prevNShape.getHeight() > sbox.getHeight());
+ }
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/TestGridMatchInfo.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/TestGridMatchInfo.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/TestGridMatchInfo.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/TestGridMatchInfo.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.prefix;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.distance.DistanceUnits;
+import org.apache.lucene.spatial.base.prefix.quad.QuadPrefixTree;
+import org.apache.lucene.spatial.base.shape.Shape;
+import org.apache.lucene.spatial.base.shape.simple.PointImpl;
+import org.apache.lucene.spatial.base.shape.simple.RectangleImpl;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import java.util.List;
+
+
+/**
+ */
+public class TestGridMatchInfo {
+
+ @Test @Ignore
+ public void testMatchInfo() {
+ // Check Validation
+ SpatialContext ctx = new SimpleSpatialContext(DistanceUnits.CARTESIAN,null,new RectangleImpl(0,10,0,10));
+ QuadPrefixTree grid = new QuadPrefixTree(ctx, 2);
+
+
+// GeometricShapeFactory gsf = new GeometricShapeFactory();
+// gsf.setCentre( new com.vividsolutions.jts.geom.Coordinate( 5,5 ) );
+// gsf.setSize( 9.5 );
+// Shape shape = new JtsGeometry( gsf.createCircle() );
+
+ Shape shape = new RectangleImpl(0, 6, 5, 10);
+
+ shape = new PointImpl(3, 3);
+
+ //TODO UPDATE BASED ON NEW API
+ List<String> m = SpatialPrefixTree.nodesToTokenStrings(grid.getNodes(shape,3,false));
+ System.out.println(m);
+
+ for (CharSequence s : m) {
+ System.out.println(s);
+ }
+
+
+// // query should intersect everything one level down
+// ArrayList<String> descr = new ArrayList<String>();
+// descr.add( "AAA*" );
+// descr.add( "AABC*" );
+// System.out.println( descr );
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/geohash/TestGeohashUtils.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/geohash/TestGeohashUtils.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/geohash/TestGeohashUtils.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/prefix/geohash/TestGeohashUtils.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,103 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.prefix.geohash;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.distance.DistanceUnits;
+import org.apache.lucene.spatial.base.shape.Point;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Tests for {@link GeohashUtils}
+ */
+public class TestGeohashUtils {
+ SpatialContext ctx = new SimpleSpatialContext( DistanceUnits.KILOMETERS );
+
+ /**
+ * Pass condition: lat=42.6, lng=-5.6 should be encoded as "ezs42e44yx96",
+ * lat=57.64911 lng=10.40744 should be encoded as "u4pruydqqvj8"
+ */
+ @Test
+ public void testEncode() {
+ String hash = GeohashUtils.encodeLatLon(42.6, -5.6);
+ assertEquals("ezs42e44yx96", hash);
+
+ hash = GeohashUtils.encodeLatLon(57.64911, 10.40744);
+ assertEquals("u4pruydqqvj8", hash);
+ }
+
+ /**
+ * Pass condition: lat=52.3738007, lng=4.8909347 should be encoded and then
+ * decoded within 0.00001 of the original value
+ */
+ @Test
+ public void testDecodePreciseLongitudeLatitude() {
+ String hash = GeohashUtils.encodeLatLon(52.3738007, 4.8909347);
+
+ Point point = GeohashUtils.decode(hash,ctx);
+
+ assertEquals(52.3738007, point.getY(), 0.00001D);
+ assertEquals(4.8909347, point.getX(), 0.00001D);
+ }
+
+ /**
+ * Pass condition: lat=84.6, lng=10.5 should be encoded and then decoded
+ * within 0.00001 of the original value
+ */
+ @Test
+ public void testDecodeImpreciseLongitudeLatitude() {
+ String hash = GeohashUtils.encodeLatLon(84.6, 10.5);
+
+ Point point = GeohashUtils.decode(hash, ctx);
+
+ assertEquals(84.6, point.getY(), 0.00001D);
+ assertEquals(10.5, point.getX(), 0.00001D);
+ }
+
+ /*
+ * see https://issues.apache.org/jira/browse/LUCENE-1815 for details
+ */
+ @Test
+ public void testDecodeEncode() {
+ String geoHash = "u173zq37x014";
+ assertEquals(geoHash, GeohashUtils.encodeLatLon(52.3738007, 4.8909347));
+ Point point = GeohashUtils.decode(geoHash,ctx);
+ assertEquals(52.37380061d, point.getY(), 0.000001d);
+ assertEquals(4.8909343d, point.getX(), 0.000001d);
+
+ assertEquals(geoHash, GeohashUtils.encodeLatLon(point.getY(), point.getX()));
+
+ geoHash = "u173";
+ point = GeohashUtils.decode("u173",ctx);
+ geoHash = GeohashUtils.encodeLatLon(point.getY(), point.getX());
+ final Point point2 = GeohashUtils.decode(geoHash, ctx);
+ assertEquals(point.getY(), point2.getY(), 0.000001d);
+ assertEquals(point.getX(), point2.getX(), 0.000001d);
+ }
+
+ /** see the table at http://en.wikipedia.org/wiki/Geohash */
+ @Test
+ public void testHashLenToWidth() {
+ double[] box = GeohashUtils.lookupDegreesSizeForHashLen(3);
+ assertEquals(1.40625,box[0],0.0001);
+ assertEquals(1.40625,box[1],0.0001);
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/AbstractTestShapes.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/AbstractTestShapes.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/AbstractTestShapes.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/AbstractTestShapes.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,261 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.shape;
+
+import org.apache.lucene.spatial.RandomSeed;
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.distance.DistanceCalculator;
+import org.junit.Before;
+
+import java.util.Random;
+
+import static org.apache.lucene.spatial.base.shape.SpatialRelation.CONTAINS;
+import static org.apache.lucene.spatial.base.shape.SpatialRelation.DISJOINT;
+import static org.apache.lucene.spatial.base.shape.SpatialRelation.WITHIN;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * @author David Smiley - dsmiley@mitre.org
+ */
+public abstract class AbstractTestShapes {
+ protected Random random;
+
+ protected SpatialContext ctx;
+ private static final double EPS = 10e-9;
+
+ @Before
+ public void beforeClass() {
+ random = new Random(RandomSeed.seed());
+ ctx = getContext();
+ }
+
+ protected void assertRelation(String msg, SpatialRelation expected, Shape a, Shape b) {
+ msg = a+" intersect "+b;//use different msg
+ _assertIntersect(msg,expected,a,b);
+ //check flipped a & b w/ transpose(), while we're at it
+ _assertIntersect("(transposed) " + msg, expected.transpose(), b, a);
+ }
+
+ private void _assertIntersect(String msg, SpatialRelation expected, Shape a, Shape b) {
+ SpatialRelation sect = a.relate(b, ctx);
+ if (sect == expected)
+ return;
+ if (expected == WITHIN || expected == CONTAINS) {
+ if (a.getClass().equals(b.getClass())) // they are the same shape type
+ assertEquals(msg,a,b);
+ else {
+ //they are effectively points or lines that are the same location
+ assertTrue(msg,!a.hasArea());
+ assertTrue(msg,!b.hasArea());
+
+ Rectangle aBBox = a.getBoundingBox();
+ Rectangle bBBox = b.getBoundingBox();
+ if (aBBox.getHeight() == 0 && bBBox.getHeight() == 0
+ && (aBBox.getMaxY() == 90 && bBBox.getMaxY() == 90
+ || aBBox.getMinY() == -90 && bBBox.getMinY() == -90))
+ ;//== a point at the pole
+ else
+ assertEquals(msg, aBBox, bBBox);
+ }
+ } else {
+ assertEquals(msg,expected,sect);
+ }
+ }
+
+ private void assertEqualsRatio(String msg, double expected, double actual) {
+ double delta = Math.abs(actual - expected);
+ double base = Math.min(actual, expected);
+ double deltaRatio = base==0 ? delta : Math.min(delta,delta / base);
+ assertEquals(msg,0,deltaRatio, EPS);
+ }
+
+ protected void testRectangle(double minX, double width, double minY, double height) {
+ Rectangle r = ctx.makeRect(minX, minX + width, minY, minY+height);
+ //test equals & hashcode of duplicate
+ Rectangle r2 = ctx.makeRect(minX, minX + width, minY, minY+height);
+ assertEquals(r,r2);
+ assertEquals(r.hashCode(),r2.hashCode());
+
+ String msg = r.toString();
+
+ assertEquals(msg, width != 0 && height != 0, r.hasArea());
+ assertEquals(msg, width != 0 && height != 0, r.getArea() > 0);
+
+ assertEqualsRatio(msg, height, r.getHeight());
+ assertEqualsRatio(msg, width, r.getWidth());
+ Point center = r.getCenter();
+ msg += " ctr:"+center;
+ //System.out.println(msg);
+ assertRelation(msg, CONTAINS, r, center);
+
+ DistanceCalculator dc = ctx.getDistCalc();
+ double dUR = dc.distance(center, r.getMaxX(), r.getMaxY());
+ double dLR = dc.distance(center, r.getMaxX(), r.getMinY());
+ double dUL = dc.distance(center, r.getMinX(), r.getMaxY());
+ double dLL = dc.distance(center, r.getMinX(), r.getMinY());
+
+ assertEquals(msg,width != 0 || height != 0, dUR != 0);
+ if (dUR != 0)
+ assertTrue(dUR > 0 && dLL > 0);
+ assertEqualsRatio(msg, dUR, dUL);
+ assertEqualsRatio(msg, dLR, dLL);
+ if (!ctx.isGeo() || center.getY() == 0)
+ assertEqualsRatio(msg, dUR, dLL);
+ }
+
+ protected void testRectIntersect() {
+ final double INCR = 45;
+ final double Y = 10;
+ for(double left = -180; left <= 180; left += INCR) {
+ for(double right = left; right - left <= 360; right += INCR) {
+ Rectangle r = ctx.makeRect(left,right,-Y,Y);
+
+ //test contains (which also tests within)
+ for(double left2 = left; left2 <= right; left2 += INCR) {
+ for(double right2 = left2; right2 <= right; right2 += INCR) {
+ Rectangle r2 = ctx.makeRect(left2,right2,-Y,Y);
+ assertRelation(null, SpatialRelation.CONTAINS, r, r2);
+ }
+ }
+ //test point contains
+ assertRelation(null, SpatialRelation.CONTAINS, r, ctx.makePoint(left, Y));
+
+ //test disjoint
+ for(double left2 = right+INCR; left2 - left < 360; left2 += INCR) {
+ for(double right2 = left2; right2 - left < 360; right2 += INCR) {
+ Rectangle r2 = ctx.makeRect(left2,right2,-Y,Y);
+ assertRelation(null, SpatialRelation.DISJOINT, r, r2);
+
+ //test point disjoint
+ assertRelation(null, SpatialRelation.DISJOINT, r, ctx.makePoint(left2, Y));
+ }
+ }
+ //test intersect
+ for(double left2 = left+INCR; left2 <= right; left2 += INCR) {
+ for(double right2 = right+INCR; right2 - left < 360; right2 += INCR) {
+ Rectangle r2 = ctx.makeRect(left2,right2,-Y,Y);
+ assertRelation(null, SpatialRelation.INTERSECTS, r, r2);
+ }
+ }
+
+ }
+ }
+ }
+
+ protected void testCircle(double x, double y, double dist) {
+ Circle c = ctx.makeCircle(x, y, dist);
+ String msg = c.toString();
+ final Circle c2 = ctx.makeCircle(ctx.makePoint(x, y), dist);
+ assertEquals(c, c2);
+ assertEquals(c.hashCode(),c2.hashCode());
+
+ assertEquals(msg,dist > 0, c.hasArea());
+ final Rectangle bbox = c.getBoundingBox();
+ assertEquals(msg,dist > 0, bbox.getArea() > 0);
+ if (!ctx.isGeo()) {
+ //if not geo then units of dist == units of x,y
+ assertEqualsRatio(msg, bbox.getHeight(), dist * 2);
+ assertEqualsRatio(msg, bbox.getWidth(), dist * 2);
+ }
+ assertRelation(msg, CONTAINS, c, c.getCenter());
+ assertRelation(msg, CONTAINS, bbox, c);
+ }
+
+ protected void testCircleIntersect() {
+ //Now do some randomized tests:
+ int i_C = 0, i_I = 0, i_W = 0, i_O = 0;//counters for the different intersection cases
+ int laps = 0;
+ int MINLAPSPERCASE = 20;
+ while(i_C < MINLAPSPERCASE || i_I < MINLAPSPERCASE || i_W < MINLAPSPERCASE || i_O < MINLAPSPERCASE) {
+ laps++;
+ double cX = randRange(-180,179);
+ double cY = randRange(-90,90);
+ double cR = randRange(0, 180);
+ double cR_dist = ctx.getDistCalc().distance(ctx.makePoint(0, 0), 0, cR);
+ Circle c = ctx.makeCircle(cX, cY, cR_dist);
+
+ double rX = randRange(-180,179);
+ double rW = randRange(0,360);
+ double rY1 = randRange(-90,90);
+ double rY2 = randRange(-90,90);
+ double rYmin = Math.min(rY1,rY2);
+ double rYmax = Math.max(rY1,rY2);
+ Rectangle r = ctx.makeRect(rX, rX+rW, rYmin, rYmax);
+
+ SpatialRelation ic = c.relate(r, ctx);
+
+ Point p;
+ switch (ic) {
+ case CONTAINS:
+ i_C++;
+ p = randomPointWithin(random,r,ctx);
+ assertEquals(CONTAINS,c.relate(p, ctx));
+ break;
+ case INTERSECTS:
+ i_I++;
+ //hard to test anything here; instead we'll test it separately
+ break;
+ case WITHIN:
+ i_W++;
+ p = randomPointWithin(random,c,ctx);
+ assertEquals(CONTAINS,r.relate(p, ctx));
+ break;
+ case DISJOINT:
+ i_O++;
+ p = randomPointWithin(random,r,ctx);
+ assertEquals(DISJOINT,c.relate(p, ctx));
+ break;
+ default: fail(""+ic);
+ }
+ }
+ System.out.println("Laps: "+laps);
+
+ //TODO deliberately test INTERSECTS based on known intersection point
+ }
+
+ /** Returns a random integer between [start, end] with a limited number of possibilities instead of end-start+1. */
+ private int randRange(int start, int end) {
+ //I tested this.
+ double r = random.nextDouble();
+ final int BUCKETS = 91;
+ int ir = (int) Math.round(r*(BUCKETS-1));//put into buckets
+ int result = (int)((double)((end - start) * ir) / (double)(BUCKETS-1) + (double)start);
+ assert result >= start && result <= end;
+ return result;
+ }
+
+ private Point randomPointWithin(Random random, Circle c, SpatialContext ctx) {
+ double d = c.getDistance() * random.nextDouble();
+ double angleDEG = 360*random.nextDouble();
+ Point p = ctx.getDistCalc().pointOnBearing(c.getCenter(), d, angleDEG, ctx);
+ assertEquals(CONTAINS,c.relate(p, ctx));
+ return p;
+ }
+
+ private Point randomPointWithin(Random random, Rectangle r, SpatialContext ctx) {
+ double x = r.getMinX() + random.nextDouble()*r.getWidth();
+ double y = r.getMinY() + random.nextDouble()*r.getHeight();
+ Point p = ctx.makePoint(x,y);
+ assertEquals(CONTAINS,r.relate(p, ctx));
+ return p;
+ }
+
+ protected abstract SpatialContext getContext();
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapes2D.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapes2D.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapes2D.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapes2D.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.shape;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.distance.DistanceUnits;
+import org.junit.Test;
+
+import static org.apache.lucene.spatial.base.shape.SpatialRelation.*;
+import static org.junit.Assert.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author dsmiley
+ */
+public class TestShapes2D extends AbstractTestShapes {
+
+ @Override
+ protected SpatialContext getContext() {
+ return new SimpleSpatialContext(DistanceUnits.CARTESIAN);
+ }
+
+ @Test
+ public void testSimplePoint() {
+ Point pt = ctx.makePoint(0,0);
+ String msg = pt.toString();
+
+ //test equals & hashcode
+ Point pt2 = ctx.makePoint(0,0);
+ assertEquals(msg, pt, pt2);
+ assertEquals(msg, pt.hashCode(), pt2.hashCode());
+
+ assertFalse(msg,pt.hasArea());
+ assertEquals(msg,pt.getCenter(),pt);
+ Rectangle bbox = pt.getBoundingBox();
+ assertFalse(msg,bbox.hasArea());
+ assertEquals(msg,pt,bbox.getCenter());
+
+ assertRelation(msg, CONTAINS, pt, pt2);
+ assertRelation(msg, DISJOINT, pt, ctx.makePoint(0, 1));
+ assertRelation(msg, DISJOINT, pt, ctx.makePoint(1, 0));
+ assertRelation(msg, DISJOINT, pt, ctx.makePoint(1, 1));
+ }
+
+ @Test
+ public void testSimpleRectangle() {
+ double[] minXs = new double[]{-1000,-360,-180,-20,0,20,180,1000};
+ for (double minX : minXs) {
+ double[] widths = new double[]{0,10,180,360,400};
+ for (double width : widths) {
+ testRectangle(minX, width, 0, 0);
+ testRectangle(minX, width, -10, 10);
+ testRectangle(minX, width, 5, 10);
+ }
+ }
+
+ testRectIntersect();
+ }
+
+ @Test
+ public void testSimpleCircle() {
+ double[] theXs = new double[]{-10,0,10};
+ for (double x : theXs) {
+ double[] theYs = new double[]{-20,0,20};
+ for (double y : theYs) {
+ testCircle(x, y, 0);
+ testCircle(x, y, 5);
+ }
+ }
+ //INTERSECTION:
+ //Start with some static tests that have shown to cause failures at some point:
+ assertEquals("getX not getY",INTERSECTS,ctx.makeCircle(107,-81,147).relate(ctx.makeRect(92, 121, -89, 74), ctx));
+
+ testCircleIntersect();
+ }
+
+
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapesGeo.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapesGeo.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapesGeo.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/base/shape/TestShapesGeo.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,165 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.base.shape;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.distance.*;
+import org.junit.Ignore;
+import org.junit.Test;
+
+import static org.apache.lucene.spatial.base.shape.SpatialRelation.*;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author David Smiley - dsmiley@mitre.org
+ */
+public abstract class TestShapesGeo extends AbstractTestShapes {
+
+ @Test
+ public void testGeoRectangle() {
+ double[] lons = new double[]{0,45,160,180,-45,-175, -180};//minX
+ for (double lon : lons) {
+ double[] lonWs = new double[]{0,20,180,200,355, 360};//width
+ for (double lonW : lonWs) {
+ testRectangle(lon, lonW, 0, 0);
+ testRectangle(lon, lonW, -10, 10);
+ testRectangle(lon, lonW, 80, 10);//polar cap
+ testRectangle(lon, lonW, -90, 180);//full lat range
+ }
+ }
+
+ //Test geo rectangle intersections
+ testRectIntersect();
+ }
+
+
+ @Test
+ public void testGeoCircle() {
+ //--Start with some static tests that once failed:
+
+ //Bug: numeric edge at pole, fails to init
+ ctx.makeCircle(
+ 110,-12,ctx.getDistCalc().degreesToDistance(90 + 12));
+
+ //Bug: horizXAxis not in enclosing rectangle, assertion
+ ctx.makeCircle(-44,16,degToDist(106));
+ ctx.makeCircle(-36,-76,degToDist(14));
+ ctx.makeCircle(107,82,degToDist(172));
+
+// TODO need to update this test to be valid
+// {
+// //Bug in which distance was being confused as being in the same coordinate system as x,y.
+// double distDeltaToPole = 0.001;//1m
+// double distDeltaToPoleDEG = ctx.getDistCalc().distanceToDegrees(distDeltaToPole);
+// double dist = 1;//1km
+// double distDEG = ctx.getDistCalc().distanceToDegrees(dist);
+// Circle c = ctx.makeCircle(0,90-distDeltaToPoleDEG-distDEG,dist);
+// Rectangle cBBox = c.getBoundingBox();
+// Rectangle r = ctx.makeRect(cBBox.getMaxX()*0.99,cBBox.getMaxX()+1,c.getCenter().getY(),c.getCenter().getY());
+// assertEquals(INTERSECTS,c.getBoundingBox().relate(r, ctx));
+// assertEquals("dist != xy space",INTERSECTS,c.relate(r,ctx));//once failed here
+// }
+
+ assertEquals("wrong estimate", DISJOINT,ctx.makeCircle(-166,59,5226.2).relate(ctx.makeRect(36, 66, 23, 23), ctx));
+
+ assertEquals("bad CONTAINS (dateline)",INTERSECTS,ctx.makeCircle(56,-50,12231.5).relate(ctx.makeRect(108, 26, 39, 48), ctx));
+
+ assertEquals("bad CONTAINS (backwrap2)",INTERSECTS,
+ ctx.makeCircle(112,-3,degToDist(91)).relate(ctx.makeRect(-163, 29, -38, 10), ctx));
+
+ assertEquals("bad CONTAINS (r x-wrap)",INTERSECTS,
+ ctx.makeCircle(-139,47,degToDist(80)).relate(ctx.makeRect(-180, 180, -3, 12), ctx));
+
+ assertEquals("bad CONTAINS (pwrap)",INTERSECTS,
+ ctx.makeCircle(-139,47,degToDist(80)).relate(ctx.makeRect(-180, 179, -3, 12), ctx));
+
+ assertEquals("no-dist 1",WITHIN,
+ ctx.makeCircle(135,21,0).relate(ctx.makeRect(-103, -154, -47, 52), ctx));
+
+ assertEquals("bbox <= >= -90 bug",CONTAINS,
+ ctx.makeCircle(-64,-84,degToDist(124)).relate(ctx.makeRect(-96, 96, -10, -10), ctx));
+
+ //The horizontal axis line of a geo circle doesn't necessarily pass through c's ctr.
+ assertEquals("c's horiz axis doesn't pass through ctr",INTERSECTS,
+ ctx.makeCircle(71,-44,degToDist(40)).relate(ctx.makeRect(15, 27, -62, -34), ctx));
+
+ assertEquals("pole boundary",INTERSECTS,
+ ctx.makeCircle(-100,-12,degToDist(102)).relate(ctx.makeRect(143, 175, 4, 32), ctx));
+
+ assertEquals("full circle assert",CONTAINS,
+ ctx.makeCircle(-64,32,degToDist(180)).relate(ctx.makeRect(47, 47, -14, 90), ctx));
+
+ //--Now proceed with systematic testing:
+
+ double distToOpposeSide = ctx.getUnits().earthRadius()*Math.PI;
+ assertEquals(ctx.getWorldBounds(),ctx.makeCircle(0,0,distToOpposeSide).getBoundingBox());
+ //assertEquals(ctx.makeCircle(0,0,distToOpposeSide/2 - 500).getBoundingBox());
+
+ double[] theXs = new double[]{-180,-45,90};
+ for (double x : theXs) {
+ double[] theYs = new double[]{-90,-45,0,45,90};
+ for (double y : theYs) {
+ testCircle(x, y, 0);
+ testCircle(x, y, 500);
+ testCircle(x, y, degToDist(90));
+ testCircle(x, y, ctx.getUnits().earthRadius()*6);
+ }
+ }
+
+ testCircleIntersect();
+ }
+
+ private double degToDist(int deg) {
+ return ctx.getDistCalc().degreesToDistance(deg);
+ }
+
+ @Ignore
+ public static class TestLawOfCosines extends TestShapesGeo {
+
+ @Override
+ protected SpatialContext getContext() {
+ DistanceUnits units = DistanceUnits.KILOMETERS;
+ return new SimpleSpatialContext(units,
+ new GeodesicSphereDistCalc.LawOfCosines(units.earthRadius()),
+ SpatialContext.GEO_WORLDBOUNDS);
+ }
+ }
+
+ public static class TestHaversine extends TestShapesGeo {
+
+ @Override
+ protected SpatialContext getContext() {
+ DistanceUnits units = DistanceUnits.KILOMETERS;
+ return new SimpleSpatialContext(units,
+ new GeodesicSphereDistCalc.Haversine(units.earthRadius()),
+ SpatialContext.GEO_WORLDBOUNDS);
+ }
+ }
+
+ public static class TestVincentySphere extends TestShapesGeo {
+
+ @Override
+ protected SpatialContext getContext() {
+ DistanceUnits units = DistanceUnits.KILOMETERS;
+ return new SimpleSpatialContext(units,
+ new GeodesicSphereDistCalc.Vincenty(units.earthRadius()),
+ SpatialContext.GEO_WORLDBOUNDS);
+ }
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/BaseRecursivePrefixTreeStrategyTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/BaseRecursivePrefixTreeStrategyTestCase.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/BaseRecursivePrefixTreeStrategyTestCase.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/BaseRecursivePrefixTreeStrategyTestCase.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,57 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.strategy.prefix;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.prefix.geohash.GeohashPrefixTree;
+import org.apache.lucene.spatial.strategy.SimpleSpatialFieldInfo;
+import org.apache.lucene.spatial.SpatialMatchConcern;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.junit.Test;
+
+import java.io.IOException;
+
+
+public abstract class BaseRecursivePrefixTreeStrategyTestCase extends StrategyTestCase<SimpleSpatialFieldInfo> {
+
+ private int maxLength;
+
+ protected abstract SpatialContext getSpatialContext();
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ maxLength = GeohashPrefixTree.getMaxLevelsPossible();
+ // SimpleIO
+ this.ctx = getSpatialContext();
+ this.strategy = new RecursivePrefixTreeStrategy(new GeohashPrefixTree(
+ ctx, maxLength ));
+ this.fieldInfo = new SimpleSpatialFieldInfo( getClass().getSimpleName() );
+ }
+
+ @Test
+ public void testFilterWithVariableScanLevel() throws IOException {
+ getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
+
+ //execute queries for each prefix grid scan level
+ for(int i = 0; i <= maxLength; i++) {
+ ((RecursivePrefixTreeStrategy)strategy).setPrefixGridScanLevel(i);
+ executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_IsWithin_BBox);
+ }
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/RecursivePrefixTreeStrategyTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/RecursivePrefixTreeStrategyTestCase.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/RecursivePrefixTreeStrategyTestCase.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/RecursivePrefixTreeStrategyTestCase.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.strategy.prefix;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.junit.Before;
+
+
+public class RecursivePrefixTreeStrategyTestCase extends BaseRecursivePrefixTreeStrategyTestCase {
+
+ @Before
+ public void setUp() throws Exception {
+ super.setUp();
+ }
+
+ @Override
+ protected SpatialContext getSpatialContext() {
+ return SimpleSpatialContext.GEO_KM;
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestSpatialPrefixField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestSpatialPrefixField.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestSpatialPrefixField.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestSpatialPrefixField.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.strategy.prefix;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+
+
+/**
+ * This is just a quick idea for *simple* tests
+ */
+public class TestSpatialPrefixField {
+
+ @Test
+ public void testRawTokens() {
+ // Ignoring geometry for now, and focus on what tokens need to match
+
+ List<String> docA = Arrays.asList(
+ "AAAAAA*",
+ "AAAAAB+"
+ );
+
+ List<String> docB = Arrays.asList(
+ "A*",
+ "BB*"
+ );
+
+ // Assumptions:
+ checkQuery("AAAAA", "docA", "docB");
+ checkQuery("AAAAA*", "docA", "docB"); // for now * and + are essentially identical
+ checkQuery("AAAAA+", "docA", "docB"); // down the road, there may be a difference between 'covers' and an edge
+
+ checkQuery("AA*", "docB", "docA"); // Bigger input query
+
+ checkQuery("AAAAAAAAAAAA*", "docA", "docB"); // small
+
+ checkQuery("BC"); // nothing
+ checkQuery("XX"); // nothing
+
+ // match only B
+ checkQuery("B", "docB");
+ checkQuery("BBBB", "docB");
+ checkQuery("B*", "docB");
+ checkQuery("BBBB*", "docB");
+ }
+
+ void checkQuery(String query, String... expect) {
+ // TODO, check that the query returns the docs in order
+ }
+
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestTermQueryPrefixGridStrategy.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestTermQueryPrefixGridStrategy.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestTermQueryPrefixGridStrategy.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/prefix/TestTermQueryPrefixGridStrategy.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.strategy.prefix;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.document.StringField;
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+import org.apache.lucene.spatial.base.prefix.quad.QuadPrefixTree;
+import org.apache.lucene.spatial.base.query.SpatialArgsParser;
+import org.apache.lucene.spatial.base.shape.Shape;
+import org.apache.lucene.spatial.base.shape.simple.PointImpl;
+import org.apache.lucene.spatial.strategy.SimpleSpatialFieldInfo;
+import org.apache.lucene.spatial.SpatialTestCase;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+
+public class TestTermQueryPrefixGridStrategy extends SpatialTestCase {
+
+ @Test
+ public void testNGramPrefixGridLosAngeles() throws IOException {
+ SimpleSpatialFieldInfo fieldInfo = new SimpleSpatialFieldInfo("geo");
+ SpatialContext ctx = SimpleSpatialContext.GEO_KM;
+ TermQueryPrefixTreeStrategy prefixGridStrategy = new TermQueryPrefixTreeStrategy(new QuadPrefixTree(ctx));
+
+ Shape point = new PointImpl(-118.243680, 34.052230);
+
+ Document losAngeles = new Document();
+ losAngeles.add(new Field("name", "Los Angeles", StringField.TYPE_STORED));
+ losAngeles.add(prefixGridStrategy.createField(fieldInfo, point, true, true));
+
+ addDocumentsAndCommit(Arrays.asList(losAngeles));
+
+ // This won't work with simple spatial context...
+ SpatialArgsParser spatialArgsParser = new SpatialArgsParser();
+ // TODO... use a non polygon query
+// SpatialArgs spatialArgs = spatialArgsParser.parse(
+// "IsWithin(POLYGON((-127.00390625 39.8125,-112.765625 39.98828125,-111.53515625 31.375,-125.94921875 30.14453125,-127.00390625 39.8125)))",
+// new SimpleSpatialContext());
+
+// Query query = prefixGridStrategy.makeQuery(spatialArgs, fieldInfo);
+// SearchResults searchResults = executeQuery(query, 1);
+// assertEquals(1, searchResults.numFound);
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/BaseTwoDoublesStrategyTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/BaseTwoDoublesStrategyTestCase.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/BaseTwoDoublesStrategyTestCase.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/BaseTwoDoublesStrategyTestCase.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.strategy.vector;
+
+import org.apache.lucene.search.FieldCache;
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.strategy.util.NumericFieldInfo;
+import org.apache.lucene.spatial.SpatialMatchConcern;
+import org.apache.lucene.spatial.StrategyTestCase;
+import org.junit.Test;
+
+import java.io.IOException;
+
+
+public abstract class BaseTwoDoublesStrategyTestCase extends StrategyTestCase<TwoDoublesFieldInfo> {
+
+ protected abstract SpatialContext getSpatialContext();
+
+ @Override
+ public void setUp() throws Exception {
+ super.setUp();
+ this.ctx = getSpatialContext();
+ this.strategy = new TwoDoublesStrategy(ctx,
+ new NumericFieldInfo(), FieldCache.NUMERIC_UTILS_DOUBLE_PARSER);
+ this.fieldInfo = new TwoDoublesFieldInfo(getClass().getSimpleName());
+ }
+
+ @Test
+ public void testCitiesWithinBBox() throws IOException {
+ getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS);
+ executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_IsWithin_BBox);
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/TwoDoublesStrategyTestCase.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/TwoDoublesStrategyTestCase.java?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/TwoDoublesStrategyTestCase.java (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/java/org/apache/lucene/spatial/strategy/vector/TwoDoublesStrategyTestCase.java Mon Feb 20 22:45:32 2012
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.spatial.strategy.vector;
+
+import org.apache.lucene.spatial.base.context.SpatialContext;
+import org.apache.lucene.spatial.base.context.simple.SimpleSpatialContext;
+
+public class TwoDoublesStrategyTestCase extends BaseTwoDoublesStrategyTestCase {
+
+ @Override
+ protected SpatialContext getSpatialContext() {
+ return SimpleSpatialContext.GEO_KM;
+ }
+}
Added: lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/resources/cities-IsWithin-BBox.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/resources/cities-IsWithin-BBox.txt?rev=1291499&view=auto
==============================================================================
--- lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/resources/cities-IsWithin-BBox.txt (added)
+++ lucene/dev/branches/lucene3795_lsp_spatial_module/modules/spatial-lucene/src/test/resources/cities-IsWithin-BBox.txt Mon Feb 20 22:45:32 2012
@@ -0,0 +1,7 @@
+[San Francisco] G5391959 @ IsWithin(-122.524918 37.674973 -122.360123 37.817108)
+[Wellington] G2179537 @ IsWithin(174.711456 -41.360779 174.854279 -41.213837)
+[Barcelona] G6544100 G3128760 @ IsWithin(2.127228 41.333313 2.226105 41.408844)
+
+
+
+