You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by di...@apache.org on 2011/07/06 19:24:45 UTC
[Lucene.Net] svn commit: r1143507 - in /incubator/lucene.net/branches/Lucene.Net_2_9_4g:
src/contrib/Spatial/ src/contrib/Spatial/Tier/Projectors/
test/contrib/Spatial/
Author: digy
Date: Wed Jul 6 17:24:44 2011
New Revision: 1143507
URL: http://svn.apache.org/viewvc?rev=1143507&view=rev
Log:
[LUCENENET-431] Spatial.Net Cartesian won't find docs in radius in certain cases
Modified:
incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Contrib.Spatial.csproj
incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/CartesianTierPlotter.cs
incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/IProjector.cs
incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/SinusoidalProjector.cs
incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/Contrib.Spatial.Test.csproj
incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/TestCartesian.cs
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Contrib.Spatial.csproj
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Contrib.Spatial.csproj?rev=1143507&r1=1143506&r2=1143507&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Contrib.Spatial.csproj (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Contrib.Spatial.csproj Wed Jul 6 17:24:44 2011
@@ -36,7 +36,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
- <OutputPath>..\..\..\bin\contrib\Spatial\Debug\</OutputPath>
+ <OutputPath>..\..\..\bin\contrib\Spatial\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/CartesianTierPlotter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/CartesianTierPlotter.cs?rev=1143507&r1=1143506&r2=1143507&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/CartesianTierPlotter.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/CartesianTierPlotter.cs Wed Jul 6 17:24:44 2011
@@ -22,14 +22,14 @@ namespace Lucene.Net.Spatial.Tier.Projec
public class CartesianTierPlotter
{
public const String DefaltFieldPrefix = "_tier_";
+ public static double EARTH_CIRC_MILES= 28892.0d;
private readonly int _tierLevel;
private int _tierLength;
private int _tierBoxes;
private readonly IProjector _projector;
private readonly string _fieldPrefix;
- private const double Idd = 180d;
-
+
public CartesianTierPlotter(int tierLevel, IProjector projector, string fieldPrefix)
{
_tierLevel = tierLevel;
@@ -72,20 +72,21 @@ namespace Lucene.Net.Spatial.Tier.Projec
public double GetTierBoxId(double latitude, double longitude)
{
double[] coords = _projector.Coords(latitude, longitude);
+ double[] ranges = _projector.Range();
- double id = GetBoxId(coords[0]) + (GetBoxId(coords[1]) / TierVerticalPosDivider);
+ double id = GetBoxCoord(coords[0], ranges[0]) + (GetBoxCoord(coords[1], ranges[1]) / TierVerticalPosDivider);
return id;
}
- private double GetBoxId(double coord)
+ private double GetBoxCoord(double coord, double range)
{
- return Math.Floor(coord / (Idd / _tierLength));
+ return Math.Floor(coord * (this._tierLength / range));
}
- private double GetBoxId(double coord, int tierLen)
- {
- return Math.Floor(coord / (Idd / tierLen));
- }
+ //private double GetBoxId(double coord, int tierLen)
+ //{
+ // return Math.Floor(coord / (Idd / tierLen));
+ //}
/// <summary>
/// Get the string name representing current tier _localTier<tiedId>
@@ -116,26 +117,41 @@ namespace Lucene.Net.Spatial.Tier.Projec
/// </summary>
/// <param name="miles">The miles.</param>
/// <returns></returns>
- public int BestFit(double miles)
- {
-
- //28,892 a rough circumference of the earth
- const int circ = 28892;
-
- double r = miles / 2.0;
-
- double corner = r - Math.Sqrt(Math.Pow(r, 2) / 2.0d);
- double times = circ / corner;
- int bestFit = (int)Math.Ceiling(Log2(times)) + 1;
-
- if (bestFit > 15)
- {
- // 15 is the granularity of about 1 mile
- // finer granularity isn't accurate with standard java math
- return 15;
- }
- return bestFit;
- }
+ public int BestFit(double range)
+ {
+ double times = EARTH_CIRC_MILES / (2.0d * range);
+
+ int bestFit = (int)Math.Ceiling(Math.Log(times, 2));
+
+ if (bestFit > 15)
+ {
+ // 15 is the granularity of about 1 mile
+ // finer granularity isn't accurate with standard java math
+ return 15;
+ }
+ return bestFit;
+ }
+ //public int BestFit(double miles)
+ //{
+
+ // //28,892 a rough circumference of the earth
+ // const int circ = 28892;
+
+ // double r = miles / 2.0;
+
+ // double corner = r - Math.Sqrt(Math.Pow(r, 2) / 2.0d);
+ // double times = circ / corner;
+ // int bestFit = (int)Math.Ceiling(Log2(times)) + 1;
+
+ // if (bestFit > 15)
+ // {
+ // // 15 is the granularity of about 1 mile
+ // // finer granularity isn't accurate with standard java math
+ // return 15;
+ // }
+ // return bestFit;
+ //}
+
/// <summary>
/// A log to the base 2 formula.
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/IProjector.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/IProjector.cs?rev=1143507&r1=1143506&r2=1143507&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/IProjector.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/IProjector.cs Wed Jul 6 17:24:44 2011
@@ -21,5 +21,6 @@ namespace Lucene.Net.Spatial.Tier.Projec
{
string CoordsAsString(double latitude, double longitude);
double[] Coords(double latitude, double longitude);
+ double[] Range();
}
}
\ No newline at end of file
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/SinusoidalProjector.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/SinusoidalProjector.cs?rev=1143507&r1=1143506&r2=1143507&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/SinusoidalProjector.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/contrib/Spatial/Tier/Projectors/SinusoidalProjector.cs Wed Jul 6 17:24:44 2011
@@ -26,6 +26,9 @@ namespace Lucene.Net.Spatial.Tier.Projec
/// </summary>
public class SinusoidalProjector : IProjector
{
+ public static double LATITUDE_RANGE= Math.PI;
+ public static double LONGITUDE_RANGE = 2* Math.PI;
+
public string CoordsAsString(double latitude, double longitude)
{
return null;
@@ -39,5 +42,10 @@ namespace Lucene.Net.Spatial.Tier.Projec
double[] r = {nlat, rlong};
return r;
}
+
+ public double[] Range() {
+ double[] ranges = { LATITUDE_RANGE, LONGITUDE_RANGE};
+ return ranges;
+ }
}
}
\ No newline at end of file
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/Contrib.Spatial.Test.csproj
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/Contrib.Spatial.Test.csproj?rev=1143507&r1=1143506&r2=1143507&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/Contrib.Spatial.Test.csproj (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/Contrib.Spatial.Test.csproj Wed Jul 6 17:24:44 2011
@@ -36,7 +36,7 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
- <OutputPath>..\..\..\bin\contrib\Spatial\Debug\</OutputPath>
+ <OutputPath>..\..\..\bin\contrib\Spatial\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
Modified: incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/TestCartesian.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/TestCartesian.cs?rev=1143507&r1=1143506&r2=1143507&view=diff
==============================================================================
--- incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/TestCartesian.cs (original)
+++ incubator/lucene.net/branches/Lucene.Net_2_9_4g/test/contrib/Spatial/TestCartesian.cs Wed Jul 6 17:24:44 2011
@@ -31,7 +31,7 @@ using Lucene.Net.Store;
using Lucene.Net.Util;
using NUnit.Framework;
-namespace Lucene.Net.Contrib.Spatial.Test
+namespace Lucene.Net.Spatial.Test
{
[TestFixture]
public class TestCartesian
@@ -182,4 +182,139 @@ namespace Lucene.Net.Contrib.Spatial.Tes
}
}
}
+
+ [TestFixture]
+ public class TestCartesian2
+ {
+ private Directory _directory;
+ private IndexSearcher _searcher;
+ // reston va
+ private double _lat = 55.6880508001;
+ private double _lng = 13.5871808352; // This passes: 13.6271808352
+ private const string LatField = "lat";
+ private const string LngField = "lng";
+ private readonly List<CartesianTierPlotter> _ctps = new List<CartesianTierPlotter>();
+
+ private readonly IProjector _projector = new SinusoidalProjector();
+
+ [SetUp]
+ protected void SetUp()
+ {
+ _directory = new RAMDirectory();
+
+ var writer = new IndexWriter(_directory, new WhitespaceAnalyzer(), true, IndexWriter.MaxFieldLength.UNLIMITED);
+
+ SetUpPlotter(2, 15);
+
+ AddData(writer);
+ }
+
+ private void SetUpPlotter(int @base, int top)
+ {
+
+ for (; @base <= top; @base++)
+ {
+ _ctps.Add(new CartesianTierPlotter(@base, _projector, CartesianTierPlotter.DefaltFieldPrefix));
+ }
+ }
+
+ private void AddData(IndexWriter writer)
+ {
+ AddPoint(writer, "Within radius", 55.6880508001, 13.5717346673);
+ AddPoint(writer, "Within radius", 55.6821978456, 13.6076183965);
+ AddPoint(writer, "Within radius", 55.673251569, 13.5946697607);
+ AddPoint(writer, "Close but not in radius", 55.8634157297, 13.5497731987);
+ AddPoint(writer, "Faar away", 40.7137578228, -74.0126901936);
+
+ writer.Commit();
+ writer.Close();
+ }
+
+ private void AddPoint(IndexWriter writer, String name, double lat, double lng)
+ {
+ Document doc = new Document();
+
+ doc.Add(new Field("name", name, Field.Store.YES, Field.Index.ANALYZED));
+
+ // convert the lat / long to lucene fields
+ doc.Add(new Field(LatField, NumericUtils.DoubleToPrefixCoded(lat), Field.Store.YES, Field.Index.NOT_ANALYZED));
+ doc.Add(new Field(LngField, NumericUtils.DoubleToPrefixCoded(lng), Field.Store.YES, Field.Index.NOT_ANALYZED));
+
+ // add a default meta field to make searching all documents easy
+ doc.Add(new Field("metafile", "doc", Field.Store.YES, Field.Index.ANALYZED));
+
+ int ctpsize = _ctps.Count;
+ for (int i = 0; i < ctpsize; i++)
+ {
+ CartesianTierPlotter ctp = _ctps[i];
+ var boxId = ctp.GetTierBoxId(lat, lng);
+ doc.Add(new Field(ctp.GetTierFieldName(),
+ NumericUtils.DoubleToPrefixCoded(boxId),
+ Field.Store.YES,
+ Field.Index.NOT_ANALYZED_NO_NORMS));
+ }
+ writer.AddDocument(doc);
+
+ }
+
+ [Test]
+ public void TestAntiM()
+ {
+ _searcher = new IndexSearcher(_directory, true);
+
+ const double miles = 5.0;
+
+ Console.WriteLine("testAntiM");
+ // create a distance query
+ var dq = new DistanceQueryBuilder(_lat, _lng, miles, LatField, LngField, CartesianTierPlotter.DefaltFieldPrefix, true);
+
+ Console.WriteLine(dq);
+ //create a term query to search against all documents
+ Query tq = new TermQuery(new Term("metafile", "doc"));
+
+ 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(tq, dq.Filter, 1000, sort);
+ int results = hits.TotalHits;
+ ScoreDoc[] scoreDocs = hits.ScoreDocs;
+
+ // Get a list of distances
+ Dictionary<int, Double> distances = dq.DistanceFilter.Distances;
+
+
+ Console.WriteLine("Distance Filter filtered: " + distances.Count);
+ Console.WriteLine("Results: " + results);
+ Console.WriteLine("=============================");
+ Console.WriteLine("Distances should be 3 " + distances.Count);
+ Console.WriteLine("Results should be 3 " + results);
+
+ Assert.AreEqual(3, distances.Count); // fixed a store of only needed distances
+ Assert.AreEqual(3, results);
+
+ double lastDistance = 0;
+ for (int i = 0; i < results; i++)
+ {
+ Document d = _searcher.Doc(scoreDocs[i].doc);
+
+ String name = d.Get("name");
+ double rsLat = NumericUtils.PrefixCodedToDouble(d.Get(LatField));
+ double rsLng = NumericUtils.PrefixCodedToDouble(d.Get(LngField));
+ Double geo_distance = distances[scoreDocs[i].doc];
+
+ double distance = DistanceUtils.GetInstance().GetDistanceMi(_lat, _lng, rsLat, rsLng);
+ double llm = DistanceUtils.GetInstance().GetLLMDistance(_lat, _lng, rsLat, rsLng);
+
+ Console.WriteLine("Name: " + name + ", Distance " + distance);
+
+ Assert.IsTrue(Math.Abs((distance - llm)) < 1);
+ Assert.IsTrue((distance < miles));
+ Assert.IsTrue(geo_distance >= lastDistance);
+
+ lastDistance = geo_distance;
+ }
+ }
+ }
}