Added: incubator/lucene.net/trunk/test-files/spatial/states-Intersects-BBox.txt URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test-files/spatial/states-Intersects-BBox.txt?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test-files/spatial/states-Intersects-BBox.txt (added) +++ incubator/lucene.net/trunk/test-files/spatial/states-Intersects-BBox.txt Wed May 30 10:17:16 2012 @@ -0,0 +1,3 @@ +WY CO @ Intersects(-106.964844 39.460938 -105.734375 42.800781) +TX @ Intersects(-99.669922 30.583984 -98.439453 32.253906) +MS TX LA @ Intersects(-95.363281 29.792969 -90.133789 32.473633) Added: incubator/lucene.net/trunk/test-files/spatial/states-IsWithin-BBox.txt URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test-files/spatial/states-IsWithin-BBox.txt?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test-files/spatial/states-IsWithin-BBox.txt (added) +++ incubator/lucene.net/trunk/test-files/spatial/states-IsWithin-BBox.txt Wed May 30 10:17:16 2012 @@ -0,0 +1,4 @@ +KS @ IsWithin(-103.493164 36.208984 -93.825195 41.086914) +WA @ IsWithin(-126.916016 44.36084 -115.314453 50.688965) +MA CT RI @ IsWithin(-73.894043 40.825195 -69.521484 43.198242) +AL GA @ IsWithin(-89.472656 29.311523 -80.244141 35.90332) \ No newline at end of file Modified: incubator/lucene.net/trunk/test/contrib/Analyzers/Contrib.Analyzers.Test.csproj URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Analyzers/Contrib.Analyzers.Test.csproj?rev=1344182&r1=1344181&r2=1344182&view=diff ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Analyzers/Contrib.Analyzers.Test.csproj (original) +++ incubator/lucene.net/trunk/test/contrib/Analyzers/Contrib.Analyzers.Test.csproj Wed May 30 10:17:16 2012 @@ -202,4 +202,4 @@ --> - \ No newline at end of file + Added: incubator/lucene.net/trunk/test/contrib/Analyzers/Filters/ChainedFilterTest.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Analyzers/Filters/ChainedFilterTest.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Analyzers/Filters/ChainedFilterTest.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Analyzers/Filters/ChainedFilterTest.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,218 @@ +/** + * 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. + */ + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Lucene.Net.Documents; +using Lucene.Net.Index; +using Lucene.Net.Search; +using Lucene.Net.Store; +using Lucene.Net.Analysis; +using Lucene.Net.Util; + +using NUnit.Framework; + +namespace Lucene.Net.Analysis +{ + public class ChainedFilterTest : Lucene.Net.TestCase + { + public static int MAX = 500; + + private RAMDirectory directory; + private IndexSearcher searcher; + private Query query; + // private DateFilter dateFilter; DateFilter was deprecated and removed + private TermRangeFilter dateFilter; + private QueryWrapperFilter bobFilter; + private QueryWrapperFilter sueFilter; + + [SetUp] + public void SetUp() + { + directory = new RAMDirectory(); + IndexWriter writer = + new IndexWriter(directory, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED); + + DateTime cal = new DateTime(1041397200000L * TimeSpan.TicksPerMillisecond); // 2003 January 01 + + for (int i = 0; i < MAX; i++) + { + Document doc = new Document(); + doc.Add(new Field("key", "" + (i + 1), Field.Store.YES, Field.Index.NOT_ANALYZED)); + doc.Add(new Field("owner", (i < MAX / 2) ? "bob" : "sue", Field.Store.YES, Field.Index.NOT_ANALYZED)); + doc.Add(new Field("date", (cal.Ticks / TimeSpan.TicksPerMillisecond).ToString(), Field.Store.YES, Field.Index.NOT_ANALYZED)); + writer.AddDocument(doc); + + cal.AddMilliseconds(1); + } + + writer.Close(); + + searcher = new IndexSearcher(directory, true); + + // query for everything to make life easier + BooleanQuery bq = new BooleanQuery(); + bq.Add(new TermQuery(new Term("owner", "bob")), BooleanClause.Occur.SHOULD); + bq.Add(new TermQuery(new Term("owner", "sue")), BooleanClause.Occur.SHOULD); + query = bq; + + // date filter matches everything too + //Date pastTheEnd = parseDate("2099 Jan 1"); + // dateFilter = DateFilter.Before("date", pastTheEnd); + // just treat dates as strings and select the whole range for now... + dateFilter = new TermRangeFilter("date", "", "ZZZZ", true, true); + + bobFilter = new QueryWrapperFilter( + new TermQuery(new Term("owner", "bob"))); + sueFilter = new QueryWrapperFilter( + new TermQuery(new Term("owner", "sue"))); + } + + private ChainedFilter GetChainedFilter(Filter[] chain, ChainedFilter.Logic[] logic) + { + if (logic == null) + { + return new ChainedFilter(chain); + } + else + { + return new ChainedFilter(chain, logic); + } + } + + private ChainedFilter GetChainedFilter(Filter[] chain, ChainedFilter.Logic logic) + { + return new ChainedFilter(chain, logic); + } + + + [Test] + public void TestSingleFilter() + { + ChainedFilter chain = GetChainedFilter(new Filter[] { dateFilter }, null); + + int numHits = searcher.Search(query, chain, 1000).TotalHits; + Assert.AreEqual(MAX, numHits); + + chain = new ChainedFilter(new Filter[] { bobFilter }); + numHits = searcher.Search(query, chain, 1000).TotalHits; + Assert.AreEqual(MAX / 2, numHits); + + chain = GetChainedFilter(new Filter[] { bobFilter }, new ChainedFilter.Logic[] { ChainedFilter.Logic.AND }); + TopDocs hits = searcher.Search(query, chain, 1000); + numHits = hits.TotalHits; + Assert.AreEqual(MAX / 2, numHits); + Assert.AreEqual("bob", searcher.Doc(hits.ScoreDocs[0].doc).Get("owner")); + + chain = GetChainedFilter(new Filter[] { bobFilter }, new ChainedFilter.Logic[] { ChainedFilter.Logic.ANDNOT }); + hits = searcher.Search(query, chain, 1000); + numHits = hits.TotalHits; + Assert.AreEqual(MAX / 2, numHits); + Assert.AreEqual("sue", searcher.Doc(hits.ScoreDocs[0].doc).Get("owner")); + } + + [Test] + public void TestOR() + { + ChainedFilter chain = GetChainedFilter( + new Filter[] { sueFilter, bobFilter }, null); + + int numHits = searcher.Search(query, chain, 1000).TotalHits; + Assert.AreEqual(MAX, numHits, "OR matches all"); + } + + [Test] + public void TestAND() + { + ChainedFilter chain = GetChainedFilter( + new Filter[] { dateFilter, bobFilter }, ChainedFilter.Logic.AND); + + TopDocs hits = searcher.Search(query, chain, 1000); + Assert.AreEqual(MAX / 2, hits.TotalHits, "AND matches just bob"); + Assert.AreEqual("bob", searcher.Doc(hits.ScoreDocs[0].doc).Get("owner")); + } + + [Test] + public void TestXOR() + { + ChainedFilter chain = GetChainedFilter( + new Filter[] { dateFilter, bobFilter }, ChainedFilter.Logic.XOR); + + TopDocs hits = searcher.Search(query, chain, 1000); + Assert.AreEqual(MAX / 2, hits.TotalHits, "XOR matches sue"); + Assert.AreEqual("sue", searcher.Doc(hits.ScoreDocs[0].doc).Get("owner")); + } + + [Test] + public void TestANDNOT() + { + ChainedFilter chain = GetChainedFilter( + new Filter[] { dateFilter, sueFilter }, + new ChainedFilter.Logic[] { ChainedFilter.Logic.AND, ChainedFilter.Logic.ANDNOT }); + + TopDocs hits = searcher.Search(query, chain, 1000); + Assert.AreEqual(MAX / 2, hits.TotalHits, "ANDNOT matches just bob"); + Assert.AreEqual("bob", searcher.Doc(hits.ScoreDocs[0].doc).Get("owner")); + + chain = GetChainedFilter( + new Filter[] { bobFilter, bobFilter }, + new ChainedFilter.Logic[] { ChainedFilter.Logic.ANDNOT, ChainedFilter.Logic.ANDNOT }); + + hits = searcher.Search(query, chain, 1000); + Assert.AreEqual(MAX / 2, hits.TotalHits, "ANDNOT bob ANDNOT bob matches all sues"); + Assert.AreEqual("sue", searcher.Doc(hits.ScoreDocs[0].doc).Get("owner")); + } + + /* + private Date parseDate(String s) throws ParseException { + return new SimpleDateFormat("yyyy MMM dd", Locale.US).parse(s); + } + */ + + [Test] + public void TestWithCachingFilter() + { + Directory dir = new RAMDirectory(); + Analyzer analyzer = new WhitespaceAnalyzer(); + + IndexWriter writer = new IndexWriter(dir, analyzer, true, IndexWriter.MaxFieldLength.LIMITED); + writer.Close(); + + Searcher searcher = new IndexSearcher(dir, true); + + Query query = new TermQuery(new Term("none", "none")); + + QueryWrapperFilter queryFilter = new QueryWrapperFilter(query); + CachingWrapperFilter cachingFilter = new CachingWrapperFilter(queryFilter); + + searcher.Search(query, cachingFilter, 1); + + CachingWrapperFilter cachingFilter2 = new CachingWrapperFilter(queryFilter); + Filter[] chain = new Filter[2]; + chain[0] = cachingFilter; + chain[1] = cachingFilter2; + ChainedFilter cf = new ChainedFilter(chain); + + // throws java.lang.ClassCastException: org.apache.lucene.util.OpenBitSet cannot be cast to java.util.BitSet + searcher.Search(new MatchAllDocsQuery(), cf, 1); + } + + } +} \ No newline at end of file Added: incubator/lucene.net/trunk/test/contrib/Spatial/Compatibility/TestFixedBitSet.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Compatibility/TestFixedBitSet.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Compatibility/TestFixedBitSet.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Compatibility/TestFixedBitSet.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,360 @@ +/** + * 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. + */ + +using System; +using System.Collections; +using Lucene.Net.Search; +using Lucene.Net.Spatial.Util; +using Lucene.Net.Util; +using NUnit.Framework; + +namespace Lucene.Net.Contrib.Spatial.Test.Compatibility +{ + public static class BitArrayExtensions + { + public static int NextSetBit(this BitArray arr, int fromIndex) + { + if (fromIndex >= arr.Length) + throw new ArgumentException("Invalid fromIndex", "fromIndex"); + + for (var i = fromIndex; i < arr.Length; i++) + { + if (arr[i]) return i; + } + return -1; + } + } + + public class TestFixedBitSet : LuceneTestCase + { + private static readonly Random rnd = new Random((int)DateTimeOffset.Now.Ticks); + + void doGet(BitArray a, FixedBitSet b) + { + int max = b.Length(); + for (int i = 0; i < max; i++) + { + if (a.Get(i) != b.Get(i)) + { + Assert.Fail("mismatch: BitSet=[" + i + "]=" + a.Get(i)); + } + } + } + + void doNextSetBit(BitArray a, FixedBitSet b) + { + int aa = -1, bb = -1; + do + { + aa = a.NextSetBit(aa + 1); + bb = bb < b.Length() - 1 ? b.NextSetBit(bb + 1) : -1; + Assert.AreEqual(aa, bb); + } while (aa >= 0); + } + + void doPrevSetBit(BitArray a, FixedBitSet b) + { + int aa = a.Length + rnd.Next(100); + int bb = aa; + do + { + // aa = a.prevSetBit(aa-1); + aa--; + while ((aa >= 0) && (!a.Get(aa))) + { + aa--; + } + if (b.Length() == 0) + { + bb = -1; + } + else if (bb > b.Length() - 1) + { + bb = b.PrevSetBit(b.Length() - 1); + } + else if (bb < 1) + { + bb = -1; + } + else + { + bb = bb >= 1 ? b.PrevSetBit(bb - 1) : -1; + } + Assert.AreEqual(aa, bb); + } while (aa >= 0); + } + + // test interleaving different FixedBitSetIterator.next()/skipTo() + //void doIterate(BitArray a, FixedBitSet b, int mode) + //{ + // if (mode == 1) doIterate1(a, b); + // if (mode == 2) doIterate2(a, b); + //} + + //void doIterate1(BitArray a, FixedBitSet b) + //{ + // int aa = -1, bb = -1; + // DocIdSetIterator iterator = b.iterator(); + // do + // { + // aa = a.NextSetBit(aa + 1); + // bb = (bb < b.Length() && random().nextBoolean()) ? iterator.NextDoc() : iterator.Advance(bb + 1); + // Assert.AreEqual(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb); + // } while (aa >= 0); + //} + + //void doIterate2(BitArray a, FixedBitSet b) + //{ + // int aa = -1, bb = -1; + // DocIdSetIterator iterator = b.iterator(); + // do + // { + // aa = a.NextSetBit(aa + 1); + // bb = random().nextBoolean() ? iterator.NextDoc() : iterator.Advance(bb + 1); + // Assert.AreEqual(aa == -1 ? DocIdSetIterator.NO_MORE_DOCS : aa, bb); + // } while (aa >= 0); + //} + + //void doRandomSets(int maxSize, int iter, int mode) + //{ + // BitArray a0 = null; + // FixedBitSet b0 = null; + + // for (int i = 0; i < iter; i++) + // { + // int sz = _TestUtil.nextInt(random(), 2, maxSize); + // BitSet a = new BitSet(sz); + // FixedBitSet b = new FixedBitSet(sz); + + // // test the various ways of setting bits + // if (sz > 0) + // { + // int nOper = random().nextInt(sz); + // for (int j = 0; j < nOper; j++) + // { + // int idx; + + // idx = random().nextInt(sz); + // a.set(idx); + // b.set(idx); + + // idx = random().nextInt(sz); + // a.clear(idx); + // b.clear(idx); + + // idx = random().nextInt(sz); + // a.flip(idx); + // b.flip(idx, idx + 1); + + // idx = random().nextInt(sz); + // a.flip(idx); + // b.flip(idx, idx + 1); + + // boolean val2 = b.get(idx); + // boolean val = b.getAndSet(idx); + // assertTrue(val2 == val); + // assertTrue(b.get(idx)); + + // if (!val) b.clear(idx); + // assertTrue(b.get(idx) == val); + // } + // } + + // // test that the various ways of accessing the bits are equivalent + // doGet(a, b); + + // // test ranges, including possible extension + // int fromIndex, toIndex; + // fromIndex = random().nextInt(sz / 2); + // toIndex = fromIndex + random().nextInt(sz - fromIndex); + // BitSet aa = (BitSet)a.clone(); aa.flip(fromIndex, toIndex); + // FixedBitSet bb = b.clone(); bb.flip(fromIndex, toIndex); + + // doIterate(aa, bb, mode); // a problem here is from flip or doIterate + + // fromIndex = random().nextInt(sz / 2); + // toIndex = fromIndex + random().nextInt(sz - fromIndex); + // aa = (BitSet)a.clone(); aa.clear(fromIndex, toIndex); + // bb = b.clone(); bb.clear(fromIndex, toIndex); + + // doNextSetBit(aa, bb); // a problem here is from clear() or nextSetBit + + // doPrevSetBit(aa, bb); + + // fromIndex = random().nextInt(sz / 2); + // toIndex = fromIndex + random().nextInt(sz - fromIndex); + // aa = (BitSet)a.clone(); aa.set(fromIndex, toIndex); + // bb = b.clone(); bb.set(fromIndex, toIndex); + + // doNextSetBit(aa, bb); // a problem here is from set() or nextSetBit + + // doPrevSetBit(aa, bb); + + // if (b0 != null && b0.length() <= b.length()) + // { + // assertEquals(a.cardinality(), b.cardinality()); + + // BitSet a_and = (BitSet)a.clone(); a_and.and(a0); + // BitSet a_or = (BitSet)a.clone(); a_or.or(a0); + // BitSet a_andn = (BitSet)a.clone(); a_andn.andNot(a0); + + // FixedBitSet b_and = b.clone(); assertEquals(b, b_and); b_and.and(b0); + // FixedBitSet b_or = b.clone(); b_or.or(b0); + // FixedBitSet b_andn = b.clone(); b_andn.andNot(b0); + + // assertEquals(a0.cardinality(), b0.cardinality()); + // assertEquals(a_or.cardinality(), b_or.cardinality()); + + // doIterate(a_and, b_and, mode); + // doIterate(a_or, b_or, mode); + // doIterate(a_andn, b_andn, mode); + + // assertEquals(a_and.cardinality(), b_and.cardinality()); + // assertEquals(a_or.cardinality(), b_or.cardinality()); + // assertEquals(a_andn.cardinality(), b_andn.cardinality()); + // } + + // a0 = a; + // b0 = b; + // } + //} + + // large enough to flush obvious bugs, small enough to run in <.5 sec as part of a + // larger testsuite. + //public void testSmall() + //{ + // doRandomSets(atLeast(1200), atLeast(1000), 1); + // doRandomSets(atLeast(1200), atLeast(1000), 2); + //} + + // uncomment to run a bigger test (~2 minutes). + /* + public void testBig() { + doRandomSets(2000,200000, 1); + doRandomSets(2000,200000, 2); + } + */ + + [Test] + public void testEquals() + { + // This test can't handle numBits==0: + int numBits = rnd.Next(2000) + 1; + FixedBitSet b1 = new FixedBitSet(numBits); + FixedBitSet b2 = new FixedBitSet(numBits); + Assert.IsTrue(b1.Equals(b2)); + Assert.IsTrue(b2.Equals(b1)); + for (int iter = 0; iter < 10 * rnd.Next(500); iter++) + { + int idx = rnd.Next(numBits); + if (!b1.Get(idx)) + { + b1.Set(idx); + Assert.IsFalse(b1.Equals(b2)); + Assert.IsFalse(b2.Equals(b1)); + b2.Set(idx); + Assert.IsTrue(b1.Equals(b2)); + Assert.IsTrue(b2.Equals(b1)); + } + } + + // try different type of object + Assert.IsFalse(b1.Equals(new Object())); + } + + [Test] + public void testHashCodeEquals() + { + // This test can't handle numBits==0: + int numBits = rnd.Next(2000) + 1; + FixedBitSet b1 = new FixedBitSet(numBits); + FixedBitSet b2 = new FixedBitSet(numBits); + Assert.IsTrue(b1.Equals(b2)); + Assert.IsTrue(b2.Equals(b1)); + for (int iter = 0; iter < 10 * rnd.Next(500); iter++) + { + int idx = rnd.Next(numBits); + if (!b1.Get(idx)) + { + b1.Set(idx); + Assert.IsFalse(b1.Equals(b2)); + Assert.AreNotEqual(b1.GetHashCode(), b2.GetHashCode()); + b2.Set(idx); + Assert.AreEqual(b1, b2); + Assert.AreEqual(b1.GetHashCode(), b2.GetHashCode()); + } + } + } + + [Test] + public void testSmallBitSets() + { + // Make sure size 0-10 bit sets are OK: + for (int numBits = 0; numBits < 10; numBits++) + { + FixedBitSet b1 = new FixedBitSet(numBits); + FixedBitSet b2 = new FixedBitSet(numBits); + Assert.IsTrue(b1.Equals(b2)); + Assert.AreEqual(b1.GetHashCode(), b2.GetHashCode()); + Assert.AreEqual(0, b1.Cardinality()); + if (numBits > 0) + { + b1.Set(0, numBits); + Assert.AreEqual(numBits, b1.Cardinality()); + //b1.Flip(0, numBits); + //Assert.AreEqual(0, b1.Cardinality()); + } + } + } + + private FixedBitSet makeFixedBitSet(int[] a, int numBits) + { + FixedBitSet bs = new FixedBitSet(numBits); + foreach (int e in a) + { + bs.Set(e); + } + return bs; + } + + private BitArray makeBitSet(int[] a) + { + var bs = new BitArray(a.Length); + foreach (int e in a) + { + bs.Set(e, true); + } + return bs; + } + + private void checkPrevSetBitArray(int[] a, int numBits) + { + FixedBitSet obs = makeFixedBitSet(a, numBits); + BitArray bs = makeBitSet(a); + doPrevSetBit(bs, obs); + } + + [Test] + public void testPrevSetBit() + { + checkPrevSetBitArray(new int[] { }, 0); + checkPrevSetBitArray(new int[] { 0 }, 1); + checkPrevSetBitArray(new int[] { 0, 2 }, 3); + } + + } +} Modified: incubator/lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Test.csproj URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Test.csproj?rev=1344182&r1=1344181&r2=1344182&view=diff ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Test.csproj (original) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Contrib.Spatial.Test.csproj Wed May 30 10:17:16 2012 @@ -19,7 +19,6 @@ under the License. --> - Debug @@ -75,11 +74,33 @@ ..\..\..\lib\NUnit.org\NUnit\2.5.9\bin\net-2.0\framework\nunit.framework.dll + + False + ..\..\..\lib\Spatial4n\Spatial4n.Core.dll + + + LuceneTestCase.cs + + + Paths.cs + + + + + + - + + + + + + + + @@ -113,6 +134,9 @@ Lucene.Net + + + - \ No newline at end of file + Added: incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/BaseRecursivePrefixTreeStrategyTestCase.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/BaseRecursivePrefixTreeStrategyTestCase.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/BaseRecursivePrefixTreeStrategyTestCase.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/BaseRecursivePrefixTreeStrategyTestCase.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,106 @@ +/* + * 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. + */ + +using System.Collections.Generic; +using Lucene.Net.Documents; +using Lucene.Net.Spatial; +using Lucene.Net.Spatial.Prefix; +using Lucene.Net.Spatial.Prefix.Tree; +using Spatial4n.Core.Context; +using NUnit.Framework; +using Spatial4n.Core.Io.Samples; +using Spatial4n.Core.Query; +using Spatial4n.Core.Shapes; +using Spatial4n.Core.Shapes.Impl; + +namespace Lucene.Net.Contrib.Spatial.Test.Prefix +{ + public abstract class BaseRecursivePrefixTreeStrategyTestCase : StrategyTestCase + { + private int maxLength; + + protected abstract SpatialContext getSpatialContext(); + + [SetUp] + public override void SetUp() + { + base.SetUp(); + maxLength = GeohashPrefixTree.GetMaxLevelsPossible(); + // SimpleIO + this.ctx = getSpatialContext(); + this.strategy = new RecursivePrefixTreeStrategy(new GeohashPrefixTree( + ctx, maxLength)); + this.fieldInfo = new SimpleSpatialFieldInfo(GetType().Name); + } + + [Test] + public void testFilterWithVariableScanLevel() + { + 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); + } + } + + [Test] + public void minifiedTest() + { + var list = new List { new SampleData("G5391959 San Francisco -122.419420 37.774930") }; + + var documents = new List(); + foreach (var data in list) + { + var document = new Document(); + document.Add(new Field("id", data.id, Field.Store.YES, Field.Index.ANALYZED)); + document.Add(new Field("name", data.name, Field.Store.YES, Field.Index.ANALYZED)); + Shape shape = ctx.ReadShape(data.shape); + foreach (var f in strategy.CreateFields(fieldInfo, shape, true, storeShape)) + { + if (f != null) + { // null if incompatibleGeometry && ignore + document.Add(f); + } + } + documents.Add(document); + } + addDocumentsAndCommit(documents); + verifyDocumentsIndexed(documents.Count); + + ((RecursivePrefixTreeStrategy)strategy).SetPrefixGridScanLevel(0); + + const string line = "[San Francisco] G5391959 @ IsWithin(-122.524918 37.674973 -122.360123 37.817108)"; + var argsParser = new SpatialArgsParser(); + var queries = new List + { + new SpatialTestQuery + { + args = new SpatialArgs(SpatialOperation.IsWithin, ctx.ReadShape("-122.524918 37.674973 -122.360123 37.817108")), + line = line, + lineNumber = 0, + //testname = , + ids = new List {"G5391959"}, + } + }; + + runTestQueries(queries.GetEnumerator(), SpatialMatchConcern.FILTER); + } + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestRecursivePrefixTreeStrategy.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,35 @@ +/* + * 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. + */ + +using NUnit.Framework; +using Spatial4n.Core.Context; + +namespace Lucene.Net.Contrib.Spatial.Test.Prefix +{ + public class TestRecursivePrefixTreeStrategy : BaseRecursivePrefixTreeStrategyTestCase + { + [SetUp] + public override void SetUp() + { + base.SetUp(); + } + protected override SpatialContext getSpatialContext() + { + return SpatialContext.GEO_KM; + } + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestSpatialPrefixField.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestSpatialPrefixField.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestSpatialPrefixField.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestSpatialPrefixField.cs Wed May 30 10:17:16 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. + */ + +using System; +using System.Collections.Generic; +using Lucene.Net.Util; +using NUnit.Framework; + +namespace Lucene.Net.Contrib.Spatial.Test.Prefix +{ + /// + /// This is just a quick idea for *simple* tests + /// + public class TestSpatialPrefixField : LuceneTestCase + { + [Test] + public void testRawTokens() + { + // Ignoring geometry for now, and focus on what tokens need to match + + var docA = new List { "AAAAAA*", "AAAAAB+" }; + + var docB = new List { "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, params String[] expect) + { + // TODO, check that the query returns the docs in order + } + + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/TestTermQueryPrefixGridStrategy.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,61 @@ +/* + * 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. + */ + +using System.Collections.Generic; +using Lucene.Net.Documents; +using Lucene.Net.Spatial; +using Lucene.Net.Spatial.Prefix; +using Lucene.Net.Spatial.Prefix.Tree; +using NUnit.Framework; +using Spatial4n.Core.Context; +using Spatial4n.Core.Query; +using Spatial4n.Core.Shapes; +using Spatial4n.Core.Shapes.Impl; + +namespace Lucene.Net.Contrib.Spatial.Test.Prefix +{ + public class TestTermQueryPrefixGridStrategy : SpatialTestCase + { + [Test] + public void testNGramPrefixGridLosAngeles() + { + SimpleSpatialFieldInfo fieldInfo = new SimpleSpatialFieldInfo("geo"); + SpatialContext ctx = SpatialContext.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", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); + losAngeles.Add(prefixGridStrategy.CreateField(fieldInfo, point, true, true)); + + addDocumentsAndCommit(new List { 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: incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Prefix/Tree/SpatialPrefixTreeTest.cs Wed May 30 10:17:16 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. + */ + +using System.Collections.Generic; +using Lucene.Net.Spatial.Prefix.Tree; +using Lucene.Net.Util; +using NUnit.Framework; +using Spatial4n.Core.Context; +using Spatial4n.Core.Shapes; + +namespace Lucene.Net.Contrib.Spatial.Test.Prefix.Tree +{ + public class SpatialPrefixTreeTest : LuceneTestCase + { + //TODO plug in others and test them + private SpatialContext ctx; + private SpatialPrefixTree trie; + + [SetUp] + public override void SetUp() + { + base.SetUp(); + ctx = SpatialContext.GEO_KM; + trie = new GeohashPrefixTree(ctx, 4); + } + + [Test] + public void testNodeTraverse() + { + Node prevN = null; + Node n = trie.GetWorldNode(); + Assert.AreEqual(0, n.GetLevel()); + Assert.AreEqual(ctx.GetWorldBounds(), n.GetShape()); + while (n.GetLevel() < trie.GetMaxLevels()) + { + prevN = n; + var it = n.GetSubCells().GetEnumerator(); + it.MoveNext(); + n = it.Current; //TODO random which one? + + Assert.AreEqual(prevN.GetLevel() + 1, n.GetLevel()); + Rectangle prevNShape = (Rectangle) prevN.GetShape(); + Shape s = n.GetShape(); + Rectangle sbox = s.GetBoundingBox(); + Assert.IsTrue(prevNShape.GetWidth() > sbox.GetWidth()); + Assert.IsTrue(prevNShape.GetHeight() > sbox.GetHeight()); + } + } + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/SpatialMatchConcern.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/SpatialMatchConcern.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/SpatialMatchConcern.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/SpatialMatchConcern.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,35 @@ +/* + * 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. + */ + +namespace Lucene.Net.Contrib.Spatial.Test +{ + public class SpatialMatchConcern + { + public readonly bool orderIsImportant; + public readonly bool resultsAreSuperset; // if the strategy can not give exact answers, but used to limit results + + private SpatialMatchConcern(bool order, bool superset) + { + this.orderIsImportant = order; + this.resultsAreSuperset = superset; + } + + public static SpatialMatchConcern EXACT = new SpatialMatchConcern(true, false); + public static SpatialMatchConcern FILTER = new SpatialMatchConcern(false, false); + public static SpatialMatchConcern SUPERSET = new SpatialMatchConcern(false, true); + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestCase.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,168 @@ +/* + * 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. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using Lucene.Net.Analysis; +using Lucene.Net.Documents; +using Lucene.Net.Index; +using Lucene.Net.Search; +using Lucene.Net.Store; +using Lucene.Net.Util; +using NUnit.Framework; +using Directory = Lucene.Net.Store.Directory; + +namespace Lucene.Net.Contrib.Spatial.Test +{ + public class SpatialTestCase : LuceneTestCase + { + private DirectoryReader indexReader; + private IndexWriter indexWriter; + private Directory directory; + private IndexSearcher indexSearcher; + + [SetUp] + public override void SetUp() + { + base.SetUp(); + + directory = NewDirectory(); + + indexWriter = new IndexWriter(directory, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED); + } + + [TearDown] + public override void TearDown() + { + if (indexWriter != null) + { + indexWriter.Close(); + } + if (indexReader != null) + { + indexReader.Close(); + } + if (directory != null) + { + directory.Close(); + } + base.TearDown(); + } + // ================================================= Helper Methods ================================================ + + public static Directory NewDirectory() + { + return new RAMDirectory(); + } + + /// + /// create a new searcher over the reader. + /// + /// + /// + public static IndexSearcher newSearcher(IndexReader r) + { + return new IndexSearcher(r); + } + + protected void addDocument(Document doc) + { + indexWriter.AddDocument(doc); + } + + protected void addDocumentsAndCommit(List documents) + { + foreach (var document in documents) + { + indexWriter.AddDocument(document); + } + commit(); + } + + protected void deleteAll() + { + indexWriter.DeleteAll(); + } + + protected void commit() + { + indexWriter.Commit(); + if (indexReader == null) + { + indexReader = (DirectoryReader)IndexReader.Open(directory, true); + } + else + { + indexReader = (DirectoryReader)indexReader.Reopen(); + } + indexSearcher = newSearcher(indexReader); + } + + protected void verifyDocumentsIndexed(int numDocs) + { + Assert.AreEqual(numDocs, indexReader.NumDocs()); + } + + protected SearchResults executeQuery(Query query, int numDocs) + { + try + { + TopDocs topDocs = indexSearcher.Search(query, numDocs); + + var results = new List(); + foreach (ScoreDoc scoreDoc in topDocs.ScoreDocs) + { + results.Add(new SearchResult(scoreDoc.Score, indexSearcher.Doc(scoreDoc.Doc))); + } + return new SearchResults(topDocs.TotalHits, results); + } + catch (IOException ioe) + { + throw new Exception("IOException thrown while executing query", ioe); + } + } + + // ================================================= Inner Classes ================================================= + + protected class SearchResults + { + + public int numFound; + public List results; + + public SearchResults(int numFound, List results) + { + this.numFound = numFound; + this.results = results; + } + } + + protected class SearchResult + { + + public float score; + public Document document; + + public SearchResult(float score, Document document) + { + this.score = score; + this.document = document; + } + } + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestQuery.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestQuery.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestQuery.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/SpatialTestQuery.cs Wed May 30 10:17:16 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. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using Spatial4n.Core.Context; +using Spatial4n.Core.Io; +using Spatial4n.Core.Query; + +namespace Lucene.Net.Contrib.Spatial.Test +{ + /// + /// Helper class to execute queries + /// + public class SpatialTestQuery + { + public String testname; + public String line; + public int lineNumber = -1; + public SpatialArgs args; + public List ids = new List(); + + public class SpatialTestQueryLineReader : LineReader + { + private readonly SpatialArgsParser parser; + private readonly SpatialContext ctx; + + public SpatialTestQueryLineReader(Stream @in, SpatialArgsParser parser, SpatialContext ctx) + : base(@in) + { + this.parser = parser; + this.ctx = ctx; + } + + public SpatialTestQueryLineReader(StreamReader r, SpatialArgsParser parser, SpatialContext ctx) + : base(r) + { + this.parser = parser; + this.ctx = ctx; + } + + public override SpatialTestQuery ParseLine(string line) + { + var test = new SpatialTestQuery {line = line, lineNumber = GetLineNumber()}; + + // skip a comment + if (line.StartsWith("[")) + { + int idx0 = line.IndexOf(']'); + if (idx0 > 0) + { + line = line.Substring(idx0 + 1); + } + } + + int idx = line.IndexOf('@'); + + var pos = 0; + var st = line.Substring(0, idx).Split(new[] {' ', '\t', '\n', '\r', '\f'}, StringSplitOptions.RemoveEmptyEntries); + while (pos < st.Length) + { + test.ids.Add(st[pos++].Trim()); + } + test.args = parser.Parse(line.Substring(idx + 1).Trim(), ctx); + return test; + } + } + + /// + /// Get Test Queries + /// + /// + /// + /// + /// + /// + public static IEnumerator getTestQueries( + SpatialArgsParser parser, + SpatialContext ctx, + String name, + Stream @in) + { + return new SpatialTestQueryLineReader(new StreamReader(@in, Encoding.UTF8), parser, ctx); + + } + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/StrategyTestCase.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,170 @@ +/* + * 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. + */ + +using System; +using System.Collections.Generic; +using System.IO; +using Lucene.Net.Documents; +using Lucene.Net.Spatial; +using Lucene.Net.Util; +using NUnit.Framework; +using Spatial4n.Core.Context; +using Spatial4n.Core.Io.Samples; +using Spatial4n.Core.Query; +using Spatial4n.Core.Shapes; + +namespace Lucene.Net.Contrib.Spatial.Test +{ + public abstract class StrategyTestCase : SpatialTestCase where T : SpatialFieldInfo + { + public static readonly String DATA_STATES_POLY = "states-poly.txt"; + public static readonly String DATA_STATES_BBOX = "states-bbox.txt"; + public static readonly String DATA_COUNTRIES_POLY = "countries-poly.txt"; + public static readonly String DATA_COUNTRIES_BBOX = "countries-bbox.txt"; + public static readonly String DATA_WORLD_CITIES_POINTS = "world-cities-points.txt"; + + public static readonly String QTEST_States_IsWithin_BBox = "states-IsWithin-BBox.txt"; + public static readonly String QTEST_States_Intersects_BBox = "states-Intersects-BBox.txt"; + + public static readonly String QTEST_Cities_IsWithin_BBox = "cities-IsWithin-BBox.txt"; + + //private Logger log = Logger.getLogger(getClass().getName()); + + protected readonly SpatialArgsParser argsParser = new SpatialArgsParser(); + + protected SpatialStrategy strategy; + protected SpatialContext ctx; + protected T fieldInfo; + protected bool storeShape = true; + + protected void executeQueries(SpatialMatchConcern concern, params String[] testQueryFile) + { + Console.WriteLine("testing queried for strategy " + strategy); + foreach (String path in testQueryFile) + { + IEnumerator testQueryIterator = getTestQueries(path, ctx); + runTestQueries(testQueryIterator, concern); + } + } + + protected void getAddAndVerifyIndexedDocuments(String testDataFile) + { + List testDocuments = getDocuments(testDataFile); + addDocumentsAndCommit(testDocuments); + verifyDocumentsIndexed(testDocuments.Count); + } + + protected List getDocuments(String testDataFile) + { + IEnumerator sampleData = getSampleData(testDataFile); + var documents = new List(); + while (sampleData.MoveNext()) + { + SampleData data = sampleData.Current; + var document = new Document(); + document.Add(new Field("id", data.id, Field.Store.YES, Field.Index.ANALYZED)); + document.Add(new Field("name", data.name, Field.Store.YES, Field.Index.ANALYZED)); + Shape shape = ctx.ReadShape(data.shape); + foreach (var f in strategy.CreateFields(fieldInfo, shape, true, storeShape)) + { + if (f != null) + { // null if incompatibleGeometry && ignore + document.Add(f); + } + } + documents.Add(document); + } + return documents; + } + + protected IEnumerator getSampleData(String testDataFile) + { + var stream = File.OpenRead(Path.Combine(Paths.ProjectRootDirectory, @"test-files\spatial\data", testDataFile)); + return new SampleDataReader(stream); + } + + protected IEnumerator getTestQueries(String testQueryFile, SpatialContext ctx) + { + var @in = File.OpenRead(Path.Combine(Paths.ProjectRootDirectory, @"test-files\spatial", testQueryFile)); + return SpatialTestQuery.getTestQueries(argsParser, ctx, testQueryFile, @in); + } + + public void runTestQueries( + IEnumerator queries, + SpatialMatchConcern concern) + { + while (queries.MoveNext()) + { + SpatialTestQuery q = queries.Current; + + String msg = q.line; //"Query: " + q.args.toString(ctx); + SearchResults got = executeQuery(strategy.MakeQuery(q.args, fieldInfo), 100); + if (concern.orderIsImportant) + { + var ids = q.ids.GetEnumerator(); + foreach (var r in got.results) + { + String id = r.document.Get("id"); + ids.MoveNext(); + Assert.AreEqual("out of order: " + msg, ids.Current, id); + } + if (ids.MoveNext()) + { + Assert.Fail(msg + " :: expect more results then we got: " + ids.Current); + } + } + else + { + // We are looking at how the results overlap + if (concern.resultsAreSuperset) + { + var found = new HashSet(); + foreach (var r in got.results) + { + found.Add(r.document.Get("id")); + } + foreach (String s in q.ids) + { + if (!found.Contains(s)) + { + Assert.Fail("Results are mising id: " + s + " :: " + found); + } + } + } + else + { + var found = new List(); + foreach (SearchResult r in got.results) + { + found.Add(r.document.Get("id")); + } + + // sort both so that the order is not important + q.ids.Sort(); + found.Sort(); + Assert.AreEqual(q.ids.Count, found.Count); + for (var i = 0; i < found.Count; i++) + { + Assert.AreEqual(q.ids[i], found[i], msg); + } + } + } + } + } + + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/TestTestFramework.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/TestTestFramework.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/TestTestFramework.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/TestTestFramework.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,52 @@ +/* + * 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. + */ + +using System; +using System.Collections.Generic; +using Lucene.Net.Util; +using NUnit.Framework; + +namespace Lucene.Net.Contrib.Spatial.Test +{ + /// + /// Make sure we are reading the tests as expected + /// + public class TestTestFramework : LuceneTestCase + { + // public void testQueries() + // { + // String name = StrategyTestCase.QTEST_Cities_IsWithin_BBox; + + // InputStream @in = getClass().getClassLoader().getResourceAsStream(name); + // SpatialContext ctx = SimpleSpatialContext.GEO_KM; + // Iterator iter = SpatialTestQuery.getTestQueries( + // new SpatialArgsParser(), ctx, name, in ); + // List tests = new ArrayList(); + // 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: incubator/lucene.net/trunk/test/contrib/Spatial/Various.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Various.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Various.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Various.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,233 @@ +using System; +using System.IO; +using System.Linq; +using Lucene.Net.Analysis; +using Lucene.Net.Documents; +using Lucene.Net.Index; +using Lucene.Net.Search; +using Lucene.Net.Spatial; +using Lucene.Net.Spatial.Prefix; +using Lucene.Net.Spatial.Prefix.Tree; +using Lucene.Net.Store; +using NUnit.Framework; +using Spatial4n.Core.Context; +using Spatial4n.Core.Distance; +using Spatial4n.Core.Query; +using Spatial4n.Core.Shapes; +using Directory = Lucene.Net.Store.Directory; + +namespace Lucene.Net.Contrib.Spatial.Test +{ + [TestFixture] + public class Various + { + private Directory _directory; + private IndexSearcher _searcher; + private IndexWriter _writer; + protected SpatialStrategy strategy; + protected SimpleSpatialFieldInfo fieldInfo; + protected readonly SpatialContext ctx = SpatialContext.GEO_KM; + protected readonly bool storeShape = true; + private int maxLength; + + [SetUp] + protected void SetUp() + { + maxLength = GeohashPrefixTree.GetMaxLevelsPossible(); + fieldInfo = new SimpleSpatialFieldInfo(GetType().Name); + strategy = new RecursivePrefixTreeStrategy(new GeohashPrefixTree(ctx, maxLength)); + + _directory = new RAMDirectory(); + _writer = new IndexWriter(_directory, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED); + } + + private void AddPoint(IndexWriter writer, String name, double lat, double lng) + { + var doc = new Document(); + doc.Add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED)); + Shape shape = ctx.MakePoint(lng, lat); + foreach (var f in strategy.CreateFields(fieldInfo, shape, true, storeShape)) + { + if (f != null) + { // null if incompatibleGeometry && ignore + doc.Add(f); + } + } + writer.AddDocument(doc); + } + + [Test] + public void RadiusOf15Something() + { + // Origin + const double _lat = 45.829507799999988; + const double _lng = -73.800524699999983; + + //Locations + AddPoint(_writer, "The location doc we are after", _lat, _lng); + + _writer.Commit(); + _writer.Close(); + + _searcher = new IndexSearcher(_directory, true); + + ExecuteSearch(45.831909, -73.810322, ctx.GetUnits().Convert(150000, DistanceUnits.MILES), 1); + ExecuteSearch(45.831909, -73.810322, ctx.GetUnits().Convert(15000, DistanceUnits.MILES), 1); + ExecuteSearch(45.831909, -73.810322, ctx.GetUnits().Convert(1500, DistanceUnits.MILES), 1); + + _searcher.Close(); + _directory.Close(); + } + + private void ExecuteSearch(double lat, double lng, double radius, int expectedResults) + { + var dq = strategy.MakeQuery(new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(lng, lat, radius)), fieldInfo); + Console.WriteLine(dq); + + //var dsort = new DistanceFieldComparatorSource(dq.DistanceFilter); + //Sort sort = new Sort(new SortField("foo", dsort, false)); + + // Perform the search, using the term query, the distance filter, and the + // distance sort + TopDocs hits = _searcher.Search(dq, 10); + int results = hits.TotalHits; + ScoreDoc[] scoreDocs = hits.ScoreDocs; + + // Get a list of distances + //Dictionary distances = dq.DistanceFilter.Distances; + + //Console.WriteLine("Distance Filter filtered: " + distances.Count); + //Console.WriteLine("Results: " + results); + + //Assert.AreEqual(expectedResults, distances.Count); // fixed a store of only needed distances + Assert.AreEqual(expectedResults, results); + } + + [Test] + public void CheckIfSortingCorrectly() + { + // Origin + const double lat = 38.96939; + const double lng = -77.386398; + var radius = ctx.GetUnits().Convert(6.0, DistanceUnits.MILES); + + + AddPoint(_writer, "c/1", 38.9579000, -77.3572000); // 1.76 Miles away + AddPoint(_writer, "a/2", 38.9690000, -77.3862000); // 0.03 Miles away + AddPoint(_writer, "b/3", 38.9510000, -77.4107000); // 1.82 Miles away + + _writer.Commit(); + _writer.Close(); + + _searcher = new IndexSearcher(_directory, true); + + // create a distance query + var args = new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(lng, lat, radius)); + + var vs = strategy.MakeValueSource(args, fieldInfo); + var vals = vs.GetValues(_searcher.IndexReader); + + args.SetDistPrecision(0.0); + var dq = strategy.MakeQuery(args, fieldInfo); + Console.WriteLine(dq); + + TopDocs hits = _searcher.Search(dq, null, 1000, new Sort(new SortField("distance", SortField.SCORE, true))); + var results = hits.TotalHits; + Assert.AreEqual(3, results); + + var expectedOrder = new[] {"a/2", "c/1", "b/3"}; + for (int i = 0; i < hits.TotalHits; i++) + { + Assert.AreEqual(expectedOrder[i], _searcher.Doc(hits.ScoreDocs[i].Doc).GetField("name").StringValue); + } + } + + [Test] + public void LUCENENET462() + { + Console.WriteLine("LUCENENET462"); + + // Origin + const double _lat = 51.508129; + const double _lng = -0.128005; + + // Locations + AddPoint(_writer, "Location 1", 51.5073802128877, -0.124669075012207); + AddPoint(_writer, "Location 2", 51.5091, -0.1235); + AddPoint(_writer, "Location 3", 51.5093, -0.1232); + AddPoint(_writer, "Location 4", 51.5112531582845, -0.12509822845459); + AddPoint(_writer, "Location 5", 51.5107, -0.123); + AddPoint(_writer, "Location 6", 51.512, -0.1246); + AddPoint(_writer, "Location 8", 51.5088760101322, -0.143165588378906); + AddPoint(_writer, "Location 9", 51.5087958793819, -0.143508911132813); + + _writer.Commit(); + _writer.Close(); + + _searcher = new IndexSearcher(_directory, true); + + // create a distance query + var radius = ctx.GetUnits().Convert(2.0, DistanceUnits.MILES); + var dq = strategy.MakeQuery(new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(_lng, _lat, radius)), fieldInfo); + Console.WriteLine(dq); + + //var dsort = new DistanceFieldComparatorSource(dq.DistanceFilter); + //Sort sort = new Sort(new SortField("foo", dsort, false)); + + // Perform the search, using the term query, the distance filter, and the + // distance sort + TopDocs hits = _searcher.Search(dq, 1000); + var results = hits.TotalHits; + Assert.AreEqual(8, results); + + radius = ctx.GetUnits().Convert(1.0, DistanceUnits.MILES); + var spatialArgs = new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(_lng, _lat, radius)); + dq = strategy.MakeQuery(spatialArgs, fieldInfo); + Console.WriteLine(dq); + + //var dsort = new DistanceFieldComparatorSource(dq.DistanceFilter); + //Sort sort = new Sort(new SortField("foo", dsort, false)); + + // Perform the search, using the term query, the distance filter, and the + // distance sort + hits = _searcher.Search(dq, 1000); + results = hits.TotalHits; + + Assert.AreEqual(8, results); + + _searcher.Close(); + _directory.Close(); + } + + [Test] + public void LUCENENET483() + { + Console.WriteLine("LUCENENET483"); + + // Origin + const double _lat = 42.350153; + const double _lng = -71.061667; + + //Locations + AddPoint(_writer, "Location 1", 42.0, -71.0); //24 miles away from origin + AddPoint(_writer, "Location 2", 42.35, -71.06); //less than a mile + + _writer.Commit(); + _writer.Close(); + + _searcher = new IndexSearcher(_directory, true); + + // create a distance query + var radius = ctx.GetUnits().Convert(52.0, DistanceUnits.MILES); + var dq = strategy.MakeQuery(new SpatialArgs(SpatialOperation.IsWithin, ctx.MakeCircle(_lng, _lat, radius)), fieldInfo); + Console.WriteLine(dq); + + TopDocs hits = _searcher.Search(dq, 1000); + var results = hits.TotalHits; + Assert.AreEqual(2, results); + + _searcher.Close(); + _directory.Close(); + } + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/Vector/BaseTwoDoublesStrategyTestCase.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Vector/BaseTwoDoublesStrategyTestCase.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Vector/BaseTwoDoublesStrategyTestCase.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Vector/BaseTwoDoublesStrategyTestCase.cs Wed May 30 10:17:16 2012 @@ -0,0 +1,47 @@ +/* + * 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. + */ + +using Lucene.Net.Search; +using Lucene.Net.Spatial.Util; +using Lucene.Net.Spatial.Vector; +using NUnit.Framework; +using Spatial4n.Core.Context; + +namespace Lucene.Net.Contrib.Spatial.Test.Vector +{ + public abstract class BaseTwoDoublesStrategyTestCase : StrategyTestCase + { + protected abstract SpatialContext getSpatialContext(); + + [SetUp] + public override void SetUp() + { + base.SetUp(); + this.ctx = getSpatialContext(); + this.strategy = new TwoDoublesStrategy(ctx, + new NumericFieldInfo(), FieldCache_Fields.NUMERIC_UTILS_DOUBLE_PARSER); + this.fieldInfo = new TwoDoublesFieldInfo(GetType().Name); + } + + [Test] + public void testCitiesWithinBBox() + { + getAddAndVerifyIndexedDocuments(DATA_WORLD_CITIES_POINTS); + executeQueries(SpatialMatchConcern.FILTER, QTEST_Cities_IsWithin_BBox); + } + } +} Added: incubator/lucene.net/trunk/test/contrib/Spatial/Vector/TwoDoublesStrategyTestCase.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/contrib/Spatial/Vector/TwoDoublesStrategyTestCase.cs?rev=1344182&view=auto ============================================================================== --- incubator/lucene.net/trunk/test/contrib/Spatial/Vector/TwoDoublesStrategyTestCase.cs (added) +++ incubator/lucene.net/trunk/test/contrib/Spatial/Vector/TwoDoublesStrategyTestCase.cs Wed May 30 10:17:16 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. + */ + +using Spatial4n.Core.Context; + +namespace Lucene.Net.Contrib.Spatial.Test.Vector +{ + public class TwoDoublesStrategyTestCase : BaseTwoDoublesStrategyTestCase + { + protected override SpatialContext getSpatialContext() + { + return SpatialContext.GEO_KM; + } + } +} Modified: incubator/lucene.net/trunk/test/core/Util/LuceneTestCase.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/core/Util/LuceneTestCase.cs?rev=1344182&r1=1344181&r2=1344182&view=diff ============================================================================== --- incubator/lucene.net/trunk/test/core/Util/LuceneTestCase.cs (original) +++ incubator/lucene.net/trunk/test/core/Util/LuceneTestCase.cs Wed May 30 10:17:16 2012 @@ -88,7 +88,7 @@ namespace Lucene.Net.Util protected internal virtual System.String GetTestLabel() { - return Lucene.Net.TestCase.GetFullName(); + return NUnit.Framework.TestContext.CurrentContext.Test.FullName; } [TearDown] @@ -261,4 +261,4 @@ namespace Lucene.Net.Util [NonSerialized] private static readonly System.Random seedRnd = new System.Random(); } -} \ No newline at end of file +} Modified: incubator/lucene.net/trunk/test/core/Util/Paths.cs URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/test/core/Util/Paths.cs?rev=1344182&r1=1344181&r2=1344182&view=diff ============================================================================== --- incubator/lucene.net/trunk/test/core/Util/Paths.cs (original) +++ incubator/lucene.net/trunk/test/core/Util/Paths.cs Wed May 30 10:17:16 2012 @@ -188,4 +188,4 @@ namespace Lucene.Net.Util return path; } } -} \ No newline at end of file +}