lucenenet-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d...@apache.org
Subject svn commit: r890098 [1/2] - in /incubator/lucene.net/trunk/C#/contrib/Spatial.Net: Spatial.Net/ Spatial.Net/GeoHash/ Spatial.Net/Geometry/ Spatial.Net/Geometry/Shape/ Spatial.Net/Properties/ Spatial.Net/Tier/ Spatial.Net/Tier/Projectors/ Spatial.Net/Ut...
Date Sun, 13 Dec 2009 19:39:52 GMT
Author: digy
Date: Sun Dec 13 19:39:51 2009
New Revision: 890098

URL: http://svn.apache.org/viewvc?rev=890098&view=rev
Log:
Spatial.Net

Added:
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashDistanceFilter.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashUtils.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/CartesianPoint.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/DistanceUnits.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FixedLatLng.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FloatLatLng.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/LatLng.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Ellipse.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IGeometry2D.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IntersectCase.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LLRect.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LineSegment.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Point2D.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Rectangle.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Vector2D.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Overview.html
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Properties/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Properties/AssemblyInfo.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.csproj
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.sln
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.suo   (with props)
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianPolyFilterBuilder.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianShapeFilter.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceFieldComparatorSource.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceFilter.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceHandler.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceQueryBuilder.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceUtils.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/LatLongDistanceFilter.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/Package.html
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/Projectors/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/Projectors/CartesianTierPlotter.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/Projectors/IProjector.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/Projectors/SinusoidalProjector.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/Shape.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Utils/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Utils/BitwiseHelper.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Utils/MathHelper.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/AssemblyInfo.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/entries
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/prop-base/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/props/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/text-base/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/tmp/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/tmp/prop-base/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/tmp/props/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Properties/_svn/tmp/text-base/
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/TestCartesian.cs
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Tests.csproj
    incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Tests/Tests.sln

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashDistanceFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashDistanceFilter.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashDistanceFilter.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashDistanceFilter.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,134 @@
+/* 
+ * 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.Search;
+using Lucene.Net.Spatial.Tier;
+
+namespace Lucene.Net.Spatial.GeoHash
+{
+	public class GeoHashDistanceFilter : DistanceFilter
+	{
+
+		private readonly double _lat;
+		private readonly double _lng;
+		private readonly String _geoHashField;
+
+		/// <summary>
+		/// Provide a distance filter based from a center point with a radius in miles
+		/// </summary>
+		/// <param name="startingFilter">The starting filter.</param>
+		/// <param name="lat">The lat.</param>
+		/// <param name="lng">The LNG.</param>
+		/// <param name="miles">The miles.</param>
+		/// <param name="geoHashField">The geo hash field.</param>
+		public GeoHashDistanceFilter(Filter startingFilter, double lat, double lng, double miles, string geoHashField) : base(startingFilter, miles)
+		{
+			_lat = lat;
+			_lng = lng;
+			_geoHashField = geoHashField;
+		}
+
+		public override DocIdSet GetDocIdSet(Lucene.Net.Index.IndexReader reader)
+		{
+			var geoHashValues = FieldCache_Fields.DEFAULT.GetStrings(reader, _geoHashField);
+			
+			int docBase = NextDocBase;
+			NextDocBase += reader.MaxDoc();
+
+			return new GeoHashFilteredDocIdSet(StartingFilter.GetDocIdSet(reader), geoHashValues, DistanceLookupCache, _lat, _lng, docBase, Distance, Distances);
+		}
+
+		internal class GeoHashFilteredDocIdSet : FilteredDocIdSet
+		{
+			public GeoHashFilteredDocIdSet(DocIdSet innerSet, string[] geoHashValues, Dictionary<string, double> distanceLookupCache, double lat, double lng, int docBase, double distance, Dictionary<int, double> distances) : base(innerSet)
+			{
+				_geoHashValues = geoHashValues;
+				_distances = distances;
+				_distance = distance;
+				_docBase = docBase;
+				_lng = lng;
+				_lat = lat;
+				_distanceLookupCache = distanceLookupCache;
+			}
+
+			private readonly double _lat;
+			private readonly double _lng;
+			private readonly int _docBase;
+			private readonly string[] _geoHashValues;
+			private readonly Dictionary<int, double> _distances;
+			private readonly Dictionary<string, double> _distanceLookupCache;
+			private readonly double _distance;
+
+			public override bool Match(int docid)
+			{
+				String geoHash = _geoHashValues[docid];
+				double[] coords = GeoHashUtils.Decode(geoHash);
+				double x = coords[0];
+				double y = coords[1];
+
+				Double cachedDistance = _distanceLookupCache[geoHash];
+				double d;
+
+				if (cachedDistance > 0)
+				{
+					d = cachedDistance;
+				}
+				else
+				{
+					d = DistanceUtils.GetInstance().GetDistanceMi(_lat, _lng, x, y);
+					_distanceLookupCache[geoHash] = d;
+				}
+
+				if (d < _distance)
+				{
+					_distances[docid + _docBase] = d;
+					return true;
+				}
+				
+				return false;
+			}
+		}
+
+		public override bool Equals(object o)
+		{
+			if (this == o) return true;
+			if (!(o is GeoHashDistanceFilter)) return false;
+   
+			var other = (GeoHashDistanceFilter) o;
+
+			if (!StartingFilter.Equals(other.StartingFilter) || Distance != other.Distance || _lat != other._lat || _lng != other._lng || _geoHashField.Equals(other._geoHashField) ) 
+			{
+				return false;
+			}
+
+			return true;
+		}
+
+		public override int GetHashCode()
+		{
+			int h = Distance.GetHashCode();
+			h ^= StartingFilter.GetHashCode();
+			h ^= _lat.GetHashCode();
+			h ^= _lng.GetHashCode();
+			h ^= _geoHashField.GetHashCode();
+
+			return h;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashUtils.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashUtils.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashUtils.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/GeoHash/GeoHashUtils.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,185 @@
+/* 
+ * 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.Text;
+
+namespace Lucene.Net.Spatial.GeoHash
+{
+	public class GeoHashUtils
+	{
+		private static readonly char[] Base32 = {
+		                                        	'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+		                                        	'b', 'c', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm',
+		                                        	'n', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
+		                                        	'y', 'z'
+		                                        };
+
+		private static readonly Dictionary<char, int> Decodemap = new Dictionary<char, int>();
+		
+		private const int Precision = 12;
+		private static readonly int[] Bits = { 16, 8, 4, 2, 1 };
+
+
+		static GeoHashUtils()
+		{
+			int sz = Base32.Length;
+			for (int i = 0; i < sz; i++)
+			{
+				Decodemap[Base32[i]] = i;
+			}
+		}
+
+		public static String Encode(double latitude, double longitude)
+		{
+			double[] latInterval = { -90.0, 90.0 };
+			double[] lonInterval = { -180.0, 180.0 };
+
+			var geohash = new StringBuilder();
+			bool isEven = true;
+			int bit = 0, ch = 0;
+
+			while (geohash.Length < Precision)
+			{
+				double mid;
+				if (isEven)
+				{
+					mid = (lonInterval[0] + lonInterval[1]) / 2;
+					if (longitude > mid)
+					{
+						ch |= Bits[bit];
+						lonInterval[0] = mid;
+					}
+					else
+					{
+						lonInterval[1] = mid;
+					}
+
+				}
+				else
+				{
+					mid = (latInterval[0] + latInterval[1]) / 2;
+					if (latitude > mid)
+					{
+						ch |= Bits[bit];
+						latInterval[0] = mid;
+					}
+					else
+					{
+						latInterval[1] = mid;
+					}
+				}
+
+				isEven = isEven ? false : true;
+
+				if (bit < 4)
+				{
+					bit++;
+				}
+				else
+				{
+					geohash.Append(Base32[ch]);
+					bit = 0;
+					ch = 0;
+				}
+			}
+
+			return geohash.ToString();
+		}
+
+		public static double[] Decode(String geohash)
+		{
+			double[] ge = DecodeExactly(geohash);
+			double lat = ge[0];
+			double lon = ge[1];
+			double latErr = ge[2];
+			double lonErr = ge[3];
+
+			double latPrecision = Math.Max(1, Math.Round(-Math.Log10(latErr))) - 1;
+			double lonPrecision = Math.Max(1, Math.Round(-Math.Log10(lonErr))) - 1;
+
+			lat = GetPrecision(lat, latPrecision);
+			lon = GetPrecision(lon, lonPrecision);
+
+			return new [] { lat, lon };
+		}
+
+		public static double[] DecodeExactly(String geohash)
+		{
+			double[] latInterval = {-90.0, 90.0};
+			double[] lonInterval = {-180.0, 180.0};
+
+			double latErr = 90.0;
+			double lonErr = 180.0;
+			bool isEven = true;
+			int sz = geohash.Length;
+			int bsz = Bits.Length;
+			for (int i = 0; i < sz; i++)
+			{
+
+				int cd = Decodemap[geohash[i]];
+
+				for (int z = 0; z < bsz; z++)
+				{
+					int mask = Bits[z];
+					if (isEven)
+					{
+						lonErr /= 2;
+						if ((cd & mask) != 0)
+						{
+							lonInterval[0] = (lonInterval[0] + lonInterval[1])/2;
+						}
+						else
+						{
+							lonInterval[1] = (lonInterval[0] + lonInterval[1])/2;
+						}
+
+					}
+					else
+					{
+						latErr /= 2;
+
+						if ((cd & mask) != 0)
+						{
+							latInterval[0] = (latInterval[0] + latInterval[1])/2;
+						}
+						else
+						{
+							latInterval[1] = (latInterval[0] + latInterval[1])/2;
+						}
+					}
+					isEven = isEven ? false : true;
+				}
+
+			}
+			double latitude = (latInterval[0] + latInterval[1])/2;
+			double longitude = (lonInterval[0] + lonInterval[1])/2;
+
+			return new[] {latitude, longitude, latErr, lonErr};
+		}
+
+		public static double GetPrecision(double x, double precision)
+		{
+			double @base = Math.Pow(10, -precision);
+			double diff = x%@base;
+			return x - diff;
+		}
+
+
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/CartesianPoint.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/CartesianPoint.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/CartesianPoint.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/CartesianPoint.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,67 @@
+/* 
+ * 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.Spatial.Geometry
+{
+	/// <summary>
+	/// Represents lat/lngs as fixed point numbers translated so that all
+	/// world coordinates are in the first quadrant.  The same fixed point
+	/// scale as is used for FixedLatLng is employed.
+	/// </summary>
+	public class CartesianPoint
+	{
+		public CartesianPoint(int x, int y)
+		{
+			X = x;
+			Y = y;
+		}
+
+		public int X { get; set; }
+		public int Y { get; set; }
+
+		public CartesianPoint Translate(int deltaX, int deltaY)
+		{
+			return new CartesianPoint(X + deltaX, Y + deltaY);
+		}
+
+		public override string ToString()
+		{
+			return string.Format("Point({0},{1})", X, Y);
+		}
+
+		public override int GetHashCode()
+		{
+			const int prime = 31;
+			int result = 1;
+			result = prime * result + X;
+			result = prime * result + Y;
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj) return true;
+			if (obj == null) return false;
+			if (GetType() != obj.GetType()) return false;
+			
+			var other = (CartesianPoint)obj;
+
+			if (X != other.X) return false;
+			return Y == other.Y;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/DistanceUnits.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/DistanceUnits.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/DistanceUnits.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/DistanceUnits.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,25 @@
+/* 
+ * 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.Spatial.Geometry
+{
+	public enum DistanceUnits
+	{
+		MILES,
+		KILOMETERS,
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FixedLatLng.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/FixedLatLng.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FixedLatLng.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FixedLatLng.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,163 @@
+/* 
+ * 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.Data;
+
+namespace Lucene.Net.Spatial.Geometry
+{
+	public class FixedLatLng : LatLng
+	{
+		public const double ScaleFactor = 1000000;
+		public const int ScaleFactorInt = 1000000;
+
+		private int _lat;
+		private int _lng;
+		private bool _normalized;
+
+		public FixedLatLng(int lat, int lng)
+		{
+			SetLat(lat);
+			SetLng(lng);
+		}
+
+		public FixedLatLng(LatLng ll)
+		{
+			_lat = ll.GetFixedLat();
+			_lng = ll.GetFixedLng();
+		}
+
+		private void SetLat(int lat)
+		{
+			if (lat > 90 * ScaleFactor || lat < -90 * ScaleFactor)
+			{
+				throw new ConstraintException("Illegal lattitude");
+			}
+
+			_lat = lat;
+		}
+
+		protected void SetLng(int lng)
+		{
+			_lng = lng;
+		}
+
+		public static double FixedToDouble(int fixedInt) 
+		{
+			return fixedInt / ScaleFactor;
+		}
+		  
+		public static int DoubleToFixed(double d) 
+		{
+			return (int)(d*ScaleFactor);
+		}
+
+		public override bool IsNormalized()
+		{
+			return _normalized || (_lng >= -180 * ScaleFactorInt && _lng <= 180 * ScaleFactorInt);
+		}
+
+		public override bool IsFixedPoint()
+		{
+			return true;
+		}
+
+		public override LatLng Normalize()
+		{
+			if (IsNormalized()) return this;
+    
+			int delta = 0;
+			if (_lng < 0) delta = 360 * ScaleFactorInt;
+			if (_lng >= 0) delta =- 360 * ScaleFactorInt;
+		    
+			int newLng = _lng;
+			while (newLng <= -180 * ScaleFactorInt || newLng >= 180 * ScaleFactorInt)
+			{
+				newLng += delta;
+			}
+
+			var ret = new FixedLatLng(_lat, newLng)
+			          	{
+			          		_normalized = true
+			          	};
+
+			return ret;
+
+		}
+
+		public override int GetFixedLat()
+		{
+			return _lat;
+		}
+
+		public override int GetFixedLng()
+		{
+			return _lng;
+		}
+
+		public override double GetLat()
+		{
+			return FixedToDouble(_lat);
+		}
+
+		public override double GetLng()
+		{
+			return FixedToDouble(_lng);
+		}
+
+		public override LatLng Copy()
+		{
+			return new FixedLatLng(this);
+		}
+
+		public override FixedLatLng ToFixed()
+		{
+			return this;
+		}
+
+		public override FloatLatLng ToFloat()
+		{
+			return new FloatLatLng(this);
+		}
+
+		public override LatLng CalculateMidpoint(LatLng other)
+		{
+			return new FixedLatLng((_lat + other.GetFixedLat())/2, (_lng + other.GetFixedLng())/2);
+		}
+
+		public override int GetHashCode()
+		{
+			const int prime = 31;
+			int result = prime + _lat;
+			result = prime * result + _lng;
+			result = prime * result + (_normalized ? 1231 : 1237);
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj) return true;
+			if (GetType() != obj.GetType()) return false;
+			
+			var other = (FixedLatLng)obj;
+			
+			if (_lat != other._lat) return false;
+			if (_lng != other._lng) return false;
+			if (_normalized != other._normalized) return false;
+			return true;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FloatLatLng.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/FloatLatLng.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FloatLatLng.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/FloatLatLng.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,145 @@
+/* 
+ * 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.Data;
+using Lucene.Net.Spatial.Utils;
+
+namespace Lucene.Net.Spatial.Geometry
+{
+	public class FloatLatLng : LatLng
+	{
+		private readonly double _lat;
+		private readonly double _lng;
+		private bool _normalized;
+
+		public FloatLatLng(double lat, double lng)
+		{
+			if (lat > 90.0 || lat < -90.0)
+			{
+				throw new ConstraintException("Illegal latitude value " + lat);
+			}
+			
+			_lat = lat;
+			_lng = lng;
+		}
+
+		public FloatLatLng(LatLng ll)
+		{
+			_lat = ll.GetLat();
+			_lng = ll.GetLng();
+		}
+
+
+		public override bool IsNormalized()
+		{
+			return _normalized || (_lng >= -180 && _lng <= 180);
+		}
+
+		public override bool IsFixedPoint()
+		{
+			return false;
+		}
+
+		public override LatLng Normalize()
+		{
+			if (IsNormalized()) return this;
+
+			double delta = 0;
+			if (_lng < 0) delta = 360;
+			if (_lng >= 0) delta = -360;
+
+			double newLng = _lng;
+			while (newLng <= -180 || newLng >= 180)
+			{
+				newLng += delta;
+			}
+
+			var ret = new FloatLatLng(_lat, newLng)
+			          	{
+			          		_normalized = true
+			          	};
+			return ret;
+		}
+
+		public override int GetFixedLat()
+		{
+			return FixedLatLng.DoubleToFixed(_lat);
+		}
+
+		public override int GetFixedLng()
+		{
+			return FixedLatLng.DoubleToFixed(_lng);
+		}
+
+		public override double GetLat()
+		{
+			return _lat;
+		}
+
+		public override double GetLng()
+		{
+			return _lng;
+		}
+
+		public override LatLng Copy()
+		{
+			return new FloatLatLng(this);
+		}
+
+		public override FixedLatLng ToFixed()
+		{
+			return new FixedLatLng(this);
+		}
+
+		public override FloatLatLng ToFloat()
+		{
+			return this;
+		}
+
+		public override LatLng CalculateMidpoint(LatLng other)
+		{
+			return new FloatLatLng((_lat + other.GetLat()) / 2.0, (_lng + other.GetLng()) / 2.0);
+		}
+
+		public override int GetHashCode()
+		{
+			const int prime = 31;
+			long temp = Convert.ToInt64(_lat);
+			int result = prime + (int)(temp ^ BitwiseHelper.ZeroFillRightShift(temp, 32));
+    
+			temp = Convert.ToInt64(_lng);
+			result = prime * result + (int)(temp ^ BitwiseHelper.ZeroFillRightShift(temp, 32));
+			result = prime * result + (_normalized ? 1231 : 1237);
+			
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj) return true;
+			if (GetType() != obj.GetType()) return false;
+			
+			var other = (FloatLatLng)obj;
+
+			if (Convert.ToInt64(_lat) != Convert.ToInt64(other._lat)) return false;
+			if (Convert.ToInt64(_lng) != Convert.ToInt64(other._lng)) return false;
+			
+			return _normalized == other._normalized;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/LatLng.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/LatLng.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/LatLng.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/LatLng.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,137 @@
+/* 
+ * 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 Lucene.Net.Spatial.Utils;
+
+namespace Lucene.Net.Spatial.Geometry
+{
+	public abstract class LatLng
+	{
+		public abstract bool IsNormalized();
+		public abstract bool IsFixedPoint();
+		public abstract LatLng Normalize();
+		public abstract int GetFixedLat();
+		public abstract int GetFixedLng();
+		public abstract double GetLat();
+		public abstract double GetLng();
+		public abstract LatLng Copy();
+		public abstract FixedLatLng ToFixed();
+		public abstract FloatLatLng ToFloat();
+
+		/// <summary>
+		/// Convert the lat/lng into the cartesian coordinate plane such that all
+		/// world coordinates are represented in the first quadrant.
+		/// The x dimension corresponds to latitude and y corresponds to longitude.
+		/// The translation starts with the normalized latlng and adds 180 to the latitude and 
+		/// 90 to the longitude (subject to fixed point scaling).
+		/// </summary>
+		public CartesianPoint ToCartesian()
+		{
+			LatLng ll = Normalize();
+
+			int lat = ll.GetFixedLat();
+			int lng = ll.GetFixedLng();
+
+			return new CartesianPoint(
+				lng + 180 * FixedLatLng.ScaleFactorInt,
+				lat + 90 * FixedLatLng.ScaleFactorInt
+				);
+		}
+
+		/// <summary>
+		///The inverse of ToCartesian().  Always returns a FixedLatLng.
+		/// </summary>
+		public static LatLng FromCartesian(CartesianPoint pt)
+		{
+			int lat = pt.Y - 90 * FixedLatLng.ScaleFactorInt;
+			int lng = pt.X - 180 * FixedLatLng.ScaleFactorInt;
+
+			return new FixedLatLng(lat, lng);
+		}
+
+		/// <summary>
+		/// Calculates the distance between two lat/lng's in miles.
+		/// </summary>
+		/// <param name="latLng">The lat lng.</param>
+		/// <returns>Returns the distance in miles</returns>
+		public double ArcDistance(LatLng ll2)
+		{
+			return ArcDistance(ll2, DistanceUnits.MILES);
+		}
+
+		/// <summary>
+		///Calculates the distance between two lat/lng's in miles or meters.
+		/// </summary>
+		/// <param name="ll2">Second lat,lng position to calculate distance to.</param>
+		/// <param name="lUnits">Units to calculate distance, defaults to miles</param>
+		/// <returns>Returns the distance in meters or miles</returns>
+		public double ArcDistance(LatLng ll2, DistanceUnits lUnits)
+		{
+			LatLng ll1 = Normalize();
+			ll2 = ll2.Normalize();
+
+			double lat1 = ll1.GetLat(), lng1 = ll1.GetLng();
+			double lat2 = ll2.GetLat(), lng2 = ll2.GetLng();
+
+			// Check for same position
+			if (lat1 == lat2 && lng1 == lng2)
+				return 0.0;
+
+			// Get the m_dLongitude difference. Don't need to worry about
+			// crossing 180 since cos(x) = cos(-x)
+			double dLon = lng2 - lng1;
+
+			double a = Radians(90.0 - lat1);
+			double c = Radians(90.0 - lat2);
+			double cosB = (Math.Cos(a) * Math.Cos(c))
+			              + (Math.Sin(a) * Math.Sin(c) * Math.Cos(Radians(dLon)));
+
+			double radius = (lUnits == DistanceUnits.MILES) ? 3963.205 /* MILERADIUSOFEARTH */ : 6378.160187
+				/* KMRADIUSOFEARTH */;
+
+			// Find angle subtended (with some bounds checking) in radians and
+			// multiply by earth radius to find the arc distance
+			if (cosB < -1.0) return MathHelper.PI * radius;
+
+			if (cosB >= 1.0) return 0;
+
+			return Math.Acos(cosB) * radius;
+		}
+
+		private static double Radians(double a)
+		{
+			return a * 0.01745329251994;
+		}
+
+		public override string ToString()
+		{
+			return string.Format("[{0},{1}]", GetLat(), GetLng());
+		}
+
+		/// <summary>
+		/// Calculate the midpoint between this point an another.  Respects fixed vs floating point
+		/// </summary>
+		/// <param name="other">The other.</param>
+		/// <returns></returns>
+		public abstract LatLng CalculateMidpoint(LatLng other);
+
+		public abstract int GetHashCode();
+
+		public abstract bool Equals(Object obj);
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Ellipse.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Ellipse.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Ellipse.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Ellipse.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,238 @@
+/* 
+ * 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 Lucene.Net.Spatial.Utils;
+
+namespace Lucene.Net.Spatial.Geometry.Shape
+{
+	public class Ellipse : IGeometry2D
+	{
+		private readonly Point2D _center;
+		// Half length of major axis
+		private readonly double _a;
+		// Half length of minor axis
+		private readonly double _b;
+
+		private readonly double _k1;
+		private readonly double _k2;
+		private readonly double _k3;
+
+		// sin of rotation angle
+		private readonly double _s;
+		// cos of rotation angle
+		private readonly double _c;
+
+		public Ellipse()
+		{
+			_center = new Point2D(0, 0);
+		}
+
+		/// <summary>
+		/// Constructor given bounding rectangle and a rotation.
+		/// </summary>
+		/// <param name="p1">The point 1.</param>
+		/// <param name="p2">The point 2.</param>
+		/// <param name="angle">The angle.</param>
+		public Ellipse(Point2D p1, Point2D p2, double angle)
+		{
+			// Set the center
+			_center = new Point2D
+			          	{
+			          		X = (p1.X + p2.X)*0.5f, 
+			          		Y = (p1.Y + p2.Y)*0.5f
+			          	};
+
+            
+			// Find sin and cos of the angle
+			double angleRad = MathHelper.ToRadians(angle);
+			_c = Math.Cos(angleRad);
+			_s = Math.Sin(angleRad);
+
+			// Find the half lengths of the semi-major and semi-minor axes
+			double dx = Math.Abs(p2.X - p1.X) * 0.5;
+			double dy = Math.Abs(p2.Y - p1.Y) * 0.5;
+			
+			if (dx >= dy)
+			{
+				_a = dx;
+				_b = dy;
+			}
+			else
+			{
+				_a = dy;
+				_b = dx;
+			}
+
+			// Find _k1, _k2, _k3 - define when a point x,y is on the ellipse
+			_k1 = Sqr(_c / _a) + Sqr(_s / _b);
+			_k2 = 2 * _s * _c * ((1 / Sqr(_a)) - (1 / Sqr(_b)));
+			_k3 = Sqr(_s / _a) + Sqr(_c / _b);
+		}
+
+		private static double Sqr(double d)
+		{
+			return d * d;
+		}
+
+		public int Intersect(LineSegment seg, Point2D pt0, Point2D pt1)
+		{
+			if (pt0 == null)
+				pt0 = new Point2D();
+			if (pt1 == null)
+				pt1 = new Point2D();
+
+			// Solution is found by parameterizing the line segment and
+			// substituting those values into the ellipse equation.
+			// Results in a quadratic equation.
+			double x1 = _center.X;
+			double y1 = _center.Y;
+			double u1 = seg.A.X;
+			double v1 = seg.A.Y;
+			double u2 = seg.B.X;
+			double v2 = seg.B.Y;
+			double dx = u2 - u1;
+			double dy = v2 - v1;
+			double q0 = _k1 * Sqr(u1 - x1) + _k2 * (u1 - x1) * (v1 - y1) + _k3
+			                                                               * Sqr(v1 - y1) - 1;
+			double q1 = (2 * _k1 * dx * (u1 - x1)) + (_k2 * dx * (v1 - y1))
+			            + (_k2 * dy * (u1 - x1)) + (2 * _k3 * dy * (v1 - y1));
+			double q2 = (_k1 * Sqr(dx)) + (_k2 * dx * dy) + (_k3 * Sqr(dy));
+
+			// Compare q1^2 to 4*q0*q2 to see how quadratic solves
+			double d = Sqr(q1) - (4 * q0 * q2);
+			if (d < 0)
+			{
+				// Roots are complex valued. Line containing the segment does
+				// not intersect the ellipse
+				return 0;
+			}
+
+			if (d == 0)
+			{
+				// One real-valued root - line is tangent to the ellipse
+				double t = -q1 / (2 * q2);
+				if (0 <= t && t <= 1)
+				{
+					// Intersection occurs along line segment
+					pt0.X = u1 + t * dx;
+					pt0.Y = v1 + t * dy;
+					return 1;
+				}
+				
+				return 0;
+			}
+			else
+			{
+				// Two distinct real-valued roots. Solve for the roots and see if
+				// they fall along the line segment
+				int n = 0;
+				double q = Math.Sqrt(d);
+				double t = (-q1 - q) / (2 * q2);
+				if (0 <= t && t <= 1)
+				{
+					// Intersection occurs along line segment
+					pt0.X = u1 + t * dx;
+					pt0.Y = v1 + t * dy;
+					n++;
+				}
+
+				// 2nd root
+				t = (-q1 + q) / (2 * q2);
+				if (0 <= t && t <= 1)
+				{
+					if (n == 0)
+					{
+						pt0.X = u1 + t * dx;
+						pt0.Y = v1 + t * dy;
+						n++;
+					}
+					else
+					{
+						pt1.X = u1 + t * dx;
+						pt1.Y = v1 + t * dy;
+						n++;
+					}
+				}
+				return n;
+			}
+		}
+
+		public void Translate(Vector2D vector)
+		{
+			throw new NotSupportedException();
+		}
+
+		public bool Contains(Point2D point)
+		{
+			// Plug in equation for ellipse, If evaluates to <= 0 then the
+			// point is in or on the ellipse.
+			double dx = point.X - _center.X;
+			double dy = point.Y - _center.Y;
+			double eq = (((_k1 * Sqr(dx)) + (_k2 * dx * dy) + (_k3 * Sqr(dy)) - 1));
+
+			return eq <= 0;
+		}
+
+		public double Area()
+		{
+			throw new NotSupportedException();
+		}
+
+		public Point2D Centroid()
+		{
+			throw new NotSupportedException();
+		}
+
+		public IntersectCase Intersect(Rectangle rectangle)
+		{
+			// Test if all 4 corners of the rectangle are inside the ellipse
+			var ul = new Point2D(rectangle.MinPt.X, rectangle.MaxPt.Y);
+			var ur = new Point2D(rectangle.MaxPt.X, rectangle.MaxPt.Y);
+			var ll = new Point2D(rectangle.MinPt.X, rectangle.MinPt.Y);
+			var lr = new Point2D(rectangle.MaxPt.X, rectangle.MinPt.Y);
+			
+			if (Contains(ul) && Contains(ur) && Contains(ll) && Contains(lr)) return IntersectCase.CONTAINS;
+
+			// Test if any of the rectangle edges intersect
+			Point2D pt0 = new Point2D(), pt1 = new Point2D();
+
+			var bottom = new LineSegment(ll, lr);
+
+			if (Intersect(bottom, pt0, pt1) > 0)
+				return IntersectCase.INTERSECTS;
+
+			var top = new LineSegment(ul, ur);
+			if (Intersect(top, pt0, pt1) > 0)
+				return IntersectCase.INTERSECTS;
+
+			var left = new LineSegment(ll, ul);
+			if (Intersect(left, pt0, pt1) > 0)
+				return IntersectCase.INTERSECTS;
+
+			var right = new LineSegment(lr, ur);
+			if (Intersect(right, pt0, pt1) > 0)
+				return IntersectCase.INTERSECTS;
+
+			// Ellipse does not intersect any edge : since the case for the ellipse
+			// containing the rectangle was considered above then if the center
+			// is inside the ellipse is fully inside and if center is outside
+			// the ellipse is fully outside
+			return (rectangle.Contains(_center)) ? IntersectCase.WITHIN : IntersectCase.OUTSIDE;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IGeometry2D.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IGeometry2D.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IGeometry2D.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IGeometry2D.cs Sun Dec 13 19:39:51 2009
@@ -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.
+ */
+
+namespace Lucene.Net.Spatial.Geometry.Shape
+{
+	/// <summary>
+	/// Common set of operations available on 2d shapes
+	/// </summary>
+	interface IGeometry2D
+	{
+		/// <summary>
+		/// Translate according to the vector
+		/// </summary>
+		/// <param name="vector">The 2D vector.</param>
+		void Translate(Vector2D vector);
+
+		/// <summary>
+		/// Does the shape contain the given point
+		/// </summary>
+		/// <param name="point">The 2D point.</param>
+		/// <returns>
+		/// 	<c>true</c> if [contains] [the specified point]; otherwise, <c>false</c>.
+		/// </returns>
+		bool Contains(Point2D point);
+
+		/// <summary>
+		/// Return the area
+		/// </summary>
+		double Area();
+
+		/// <summary>
+		/// Return the centroid
+		/// </summary>
+		Point2D Centroid();
+
+		/// <summary>
+		/// Returns information about how this shape intersects the given rectangle
+		/// </summary>
+		/// <param name="rectangle">The rectangle.</param>
+		IntersectCase Intersect(Rectangle rectangle);
+		
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IntersectCase.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IntersectCase.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IntersectCase.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/IntersectCase.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,27 @@
+/* 
+ * 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.Spatial.Geometry.Shape
+{
+	public enum IntersectCase
+	{
+		WITHIN,
+		CONTAINS,
+		OUTSIDE,
+		INTERSECTS,
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LLRect.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LLRect.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LLRect.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LLRect.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,202 @@
+/* 
+ * 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 Lucene.Net.Spatial.Utils;
+
+namespace Lucene.Net.Spatial.Geometry.Shape
+{
+	/// <summary>
+	/// Lat-long rect.  Instances are mutable.
+	/// </summary>
+	public class LLRect
+	{
+		private LatLng _ll;
+		private LatLng _ur;
+
+		public LLRect(LatLng ll, LatLng ur)
+		{
+			_ll = ll;
+			_ur = ur;
+		}
+
+		public LLRect(LLRect other)
+		{
+			_ll = other._ll;
+			_ur = other._ur;
+		}
+
+		/// <summary>
+		/// Return the area in units of lat-lng squared.  This is a contrived unit
+		/// that only has value when comparing to something else.
+		/// </summary>
+		public double Area()
+		{
+			return Math.Abs((_ll.GetLat() - _ur.GetLat()) * (_ll.GetLng() - _ur.GetLng()));
+		}
+
+		public LatLng GetLowerLeft()
+		{
+			return _ll;
+		}
+
+		public LatLng GetUpperRight()
+		{
+			return _ur;
+		}
+
+		public LatLng GetMidpoint()
+		{
+			return _ll.CalculateMidpoint(_ur);
+		}
+
+		/// <summary>
+		/// Approximates a box centered at the given point with the given width and height in miles.
+		/// </summary>
+		/// <param name="center">The center.</param>
+		/// <param name="widthMi">The width mi.</param>
+		/// <param name="heightMi">The height mi.</param>
+		/// <returns></returns>
+		public static LLRect CreateBox(LatLng center, double widthMi, double heightMi)
+		{
+			double d = widthMi;
+			LatLng ur = BoxCorners(center, d, 45.0); // assume right angles
+			LatLng ll = BoxCorners(center, d, 225.0);
+
+			return new LLRect(ll, ur);
+		}
+
+		private static LatLng BoxCorners(LatLng center, double d, double brngdeg)
+		{
+			double a = center.GetLat();
+			double b = center.GetLng();
+			double R = 3963.0; // radius of earth in miles
+			double brng = (MathHelper.PI * brngdeg / 180);
+			double lat1 = (MathHelper.PI * a / 180);
+			double lon1 = (MathHelper.PI * b / 180);
+
+			// Haversine formula
+			double lat2 = Math.Asin(Math.Sin(lat1) * Math.Cos(d / R) +
+			                        Math.Cos(lat1) * Math.Sin(d / R) * Math.Cos(brng));
+			double lon2 = lon1 + Math.Atan2(Math.Sin(brng) * Math.Sin(d / R) * Math.Cos(lat1),
+			                                Math.Cos(d / R) - Math.Sin(lat1) * Math.Sin(lat2));
+
+			lat2 = (lat2 * 180) / MathHelper.PI;
+			lon2 = (lon2 * 180) / MathHelper.PI;
+
+			// normalize long first
+			LatLng ll = NormLng(lat2, lon2);
+
+			// normalize lat - could flip poles
+			ll = NormLat(ll.GetLat(), ll.GetLng());
+
+			return ll;
+		}
+
+		/// <summary>
+		/// Returns a normalized Lng rectangle shape for the bounding box
+		/// </summary>
+		private static LatLng NormLng(double lat, double lng)
+		{
+			if (lng > 180.0)
+			{
+				lng = -1.0 * (180.0 - (lng - 180.0));
+			}
+			else if (lng < -180.0)
+			{
+				lng = (lng + 180.0) + 180.0;
+			}
+			LatLng ll = new FloatLatLng(lat, lng);
+			return ll;
+		}
+
+		/// <summary>
+		/// Returns a normalized Lat rectangle shape for the bounding box
+		/// If you go over the poles, you need to flip the lng value too
+		/// </summary>
+		private static LatLng NormLat(double lat, double lng)
+		{
+			if (lat > 90.0)
+			{
+				lat = 90.0 - (lat - 90.0);
+				if (lng < 0)
+				{
+					lng = lng + 180;
+				}
+				else
+				{
+					lng = lng - 180;
+				}
+			}
+			else if (lat < -90.0)
+			{
+				lat = -90.0 - (lat + 90.0);
+				if (lng < 0)
+				{
+					lng = lng + 180;
+				}
+				else
+				{
+					lng = lng - 180;
+				}
+			}
+			LatLng ll = new FloatLatLng(lat, lng);
+			return ll;
+		}
+
+		public Rectangle ToRectangle()
+		{
+			return new Rectangle(_ll.GetLng(), _ll.GetLat(), _ur.GetLng(), _ur.GetLat());
+		}
+
+		public override string ToString()
+		{
+			return "{" + _ll +", " + _ur +"}";
+		}
+
+		public override int GetHashCode()
+		{
+			const int prime = 31;
+			int result = 1;
+			result = prime * result + ((_ll == null) ? 0 : _ll.GetHashCode());
+			result = prime * result + ((_ur == null) ? 0 : _ur.GetHashCode());
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj) return true;
+			if (obj == null) return false;
+			if (GetType() != obj.GetType()) return false;
+			
+			var other = (LLRect)obj;
+
+			if (_ll == null)
+			{
+				if (other._ll != null) return false;
+			}
+			else if (!_ll.Equals(other._ll)) return false;
+			if (_ur == null)
+			{
+				if (other._ur != null) return false;
+			}
+			else if (!_ur.Equals(other._ur)) return false;
+			
+			return true;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LineSegment.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LineSegment.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LineSegment.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/LineSegment.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,115 @@
+/* 
+ * 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.Spatial.Geometry.Shape
+{
+	/// <summary>
+	/// 2D line segment
+	/// </summary>
+	public class LineSegment
+	{
+		public readonly Point2D A = new Point2D();
+		public readonly Point2D B = new Point2D();
+
+		public LineSegment()
+		{
+			A.Set(0, 0);
+			B.Set(0, 0);
+		}
+
+		public LineSegment(Point2D p1, Point2D p2)
+		{
+			A.Set(p1);
+			B.Set(p2);
+		}
+
+		/// <summary>
+		/// Finds the distance of a specified point from the line segment and the
+		/// closest point on the segment to the specified point.
+		/// </summary>
+		/// <param name="p">The test point.</param>
+		/// <param name="closestPt">Closest point on the segment to c.</param>
+		/// <returns>Returns the distance from p to the closest point on the segment.</returns>
+		public double Distance(Point2D p, Point2D closestPt)
+		{
+			if (closestPt == null)
+				closestPt = new Point2D();
+
+			// Construct vector v (AB) and w (AP)
+			var v = new Vector2D(A, B);
+			var w = new Vector2D(A, p);
+
+			// Numerator of the component of w onto v. If <= 0 then A
+			// is the closest point. By separating into the numerator
+			// and denominator of the component we avoid a division unless
+			// it is necessary.
+			double n = w.Dot(v);
+			if (n <= 0.0f)
+			{
+				closestPt.Set(A);
+				return w.Norm();
+			}
+
+			// Get the denominator of the component. If the component >= 1
+			// (d <= n) then point B is the closest point
+			double d = v.Dot(v);
+			if (d <= n)
+			{
+				closestPt.Set(B);
+				return new Vector2D(B, p).Norm();
+			}
+
+			// Closest point is along the segment. The point is the projection of
+			// w onto v.
+			closestPt.Set(v.Mult(n / d));
+			closestPt.Add(A);
+			return new Vector2D(closestPt, p).Norm();
+		}
+
+		public override int GetHashCode()
+		{
+			const int prime = 31;
+			int result = 1;
+			result = prime * result + ((A == null) ? 0 : A.GetHashCode());
+			result = prime * result + ((B == null) ? 0 : B.GetHashCode());
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj) return true;
+			if (obj == null) return false;
+			if (GetType() != obj.GetType()) return false;
+			
+			var other = (LineSegment)obj;
+			
+			if (A == null)
+			{
+				if (other.A != null) return false;
+			}
+			else if (!A.Equals(other.A)) return false;
+			
+			if (B == null)
+			{
+				if (other.B != null) return false;
+			}
+			else if (!B.Equals(other.B)) return false;
+
+			return true;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Point2D.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Point2D.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Point2D.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Point2D.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,115 @@
+/* 
+ * 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 Lucene.Net.Spatial.Utils;
+
+namespace Lucene.Net.Spatial.Geometry.Shape
+{
+	/// <summary>
+	/// Point class.  This type is mutable.
+	/// </summary>
+	public class Point2D
+	{
+		public Point2D()
+		{
+			X = 0;
+			Y = 0;
+		}
+
+		public Point2D(double x, double y)
+		{
+			X = x;
+			Y = y;
+		}
+
+		public Point2D(Point2D other)
+		{
+			X = other.X;
+			Y = other.Y;
+		}
+
+		public double X { get; set; }
+		public double Y { get; set; }
+
+		public void Set(double x, double y)
+		{
+			X = x;
+			Y = y;
+		}
+
+		public void Add(Vector2D v)
+		{
+			X += v.X;
+			Y += v.Y;
+		}
+
+		public void Set(Point2D p1)
+		{
+			X = p1.X;
+			Y = p1.Y;
+		}
+
+		public void Add(Point2D a)
+		{
+			X += a.X;
+			Y += a.Y;
+		}
+
+		public void Set(Vector2D v)
+		{
+			X = v.X;
+			Y = v.Y;
+		}
+
+		public override string ToString()
+		{
+			return string.Format("({0},{1})", X, Y);
+		}
+
+		public override int GetHashCode()
+		{
+			const int prime = 31;
+			int result = 1;
+			
+			long temp = Convert.ToInt64(X);
+			result = prime * result + (int)(temp ^ BitwiseHelper.ZeroFillRightShift(temp, 32));
+			
+			temp = Convert.ToInt64(Y);
+			result = prime * result + (int)(temp ^ BitwiseHelper.ZeroFillRightShift(temp, 32));
+			
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj) return true;
+			if (obj == null) return false;
+			if (GetType() != obj.GetType()) return false;
+			
+			var other = (Point2D)obj;
+
+			if (Convert.ToInt64(X) != Convert.ToInt64(other.X)) return false;
+			
+			return Convert.ToInt64(Y) == Convert.ToInt64(other.Y);
+		}
+
+		
+		
+		
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Rectangle.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Rectangle.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Rectangle.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Rectangle.cs Sun Dec 13 19:39:51 2009
@@ -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.
+ */
+
+using System;
+
+namespace Lucene.Net.Spatial.Geometry.Shape
+{
+	public class Rectangle : IGeometry2D
+	{
+		public Rectangle()
+		{
+			MinPt = new Point2D(-1, 1);	
+			MaxPt = new Point2D(1, 1);	
+		}
+
+		public Rectangle(Point2D minPt, Point2D maxPt)
+		{
+			MinPt = new Point2D(minPt);
+			MaxPt = new Point2D(maxPt);
+		}
+
+		public Rectangle(double x1, double y1, double x2, double y2)
+		{
+			Set(x1, y1, x2, y2);
+		}
+
+		public Point2D MinPt { get; set; }
+		public Point2D MaxPt { get; set; }
+
+		private void Set(double x1, double y1, double x2, double y2)
+		{
+			MinPt = new Point2D(Math.Min(x1, x2), Math.Min(y1, y2));
+			MaxPt = new Point2D(Math.Max(x1, x2), Math.Max(y1, y2));
+		}
+
+		public void Translate(Vector2D vector)
+		{
+			MinPt.Add(vector);
+			MaxPt.Add(vector);
+		}
+
+		public bool Contains(Point2D point)
+		{
+			return point.X >= MinPt.X &&
+			       point.X <= MaxPt.X &&
+			       point.Y >= MinPt.Y &&
+			       point.Y <= MaxPt.Y;
+		}
+
+		public double Area()
+		{
+			return (MaxPt.X - MinPt.X) * (MaxPt.Y - MinPt.Y);
+		}
+
+		public Point2D Centroid()
+		{
+			return new Point2D((MinPt.X + MaxPt.X) / 2, (MinPt.Y + MaxPt.Y) / 2);
+		}
+
+		public IntersectCase Intersect(Rectangle rectangle)
+		{
+			throw new NotImplementedException();
+			//TODO
+		}
+
+		public override string ToString()
+		{
+			return string.Format("[{0},{1}]", MinPt, MaxPt);
+		}
+
+		public override int GetHashCode()
+		{
+			const int prime = 31;
+			int result = 1;
+			result = prime * result + ((MaxPt == null) ? 0 : MaxPt.GetHashCode());
+			result = prime * result + ((MinPt == null) ? 0 : MinPt.GetHashCode());
+			return result;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Vector2D.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Vector2D.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Vector2D.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Geometry/Shape/Vector2D.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,127 @@
+/* 
+ * 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 Lucene.Net.Spatial.Utils;
+
+namespace Lucene.Net.Spatial.Geometry.Shape
+{
+	/// <summary>
+	/// 2D Vector
+	/// </summary>
+	public class Vector2D
+	{
+		public Vector2D()
+		{
+			X = 0;
+			Y = 0;
+		}
+
+		/// <summary>
+		/// Create a vector from the origin of the coordinate system to the given point
+		/// </summary>
+		/// <param name="x">The x.</param>
+		/// <param name="y">The y.</param>
+		public Vector2D(double x, double y)
+		{
+			X = x;
+			Y = y;
+		}
+
+		/// <summary>
+		/// Create a vector from the origin of the coordinate system to the given point
+		/// </summary>
+		public Vector2D(Point2D p) : this(p.X, p.Y) {}
+
+		/// <summary>
+		/// Create a vector from one point to another
+		/// </summary>
+		public Vector2D(Point2D from, Point2D to) : this(to.X - from.X, to.Y - from.Y) {}
+
+		public Vector2D(Vector2D other)
+		{
+			X = other.X;
+			Y = other.Y;
+		}
+
+		public double X { get; set; }
+		public double Y { get; set; }
+
+		public void Set(double x, double y)
+		{
+			X = x;
+			Y = y;
+		}
+
+		public bool Equals(Vector2D other)
+		{
+			return other != null && X == other.X && Y == other.Y;
+		}
+
+		public double Dot(Vector2D v) 
+		{
+			return ((X) * v.X) + (Y * v.Y);
+		}
+
+		/// <summary>
+		/// Vector length (magnitude) squared
+		/// </summary>
+		public double NormSqr()
+		{
+			// Cast to F to prevent overflows
+			return (X * X) + (Y * Y);
+		}
+
+		public double Norm()
+		{
+			return Math.Sqrt(NormSqr());
+		}
+
+		public Vector2D Mult(double d)
+		{
+			return new Vector2D(X * d, Y * d);
+		}
+
+		public override int  GetHashCode()
+		{
+			const int prime = 31;
+			int result = 1;
+			
+			long temp = Convert.ToInt64(X);
+			result = prime * result + (int)(temp ^ BitwiseHelper.ZeroFillRightShift(temp, 32));
+			
+			temp = Convert.ToInt64(Y);
+			result = prime * result + (int)(temp ^ BitwiseHelper.ZeroFillRightShift(temp, 32));
+			
+			return result;
+		}
+
+		public override bool Equals(object obj)
+		{
+			if (this == obj) return true;
+			if (obj == null) return false;
+			if (GetType() != obj.GetType()) return false;
+
+			var other = (Vector2D)obj;
+
+			if (Convert.ToInt64(X) != Convert.ToInt64(other.X)) return false;
+
+			return Convert.ToInt64(Y) == Convert.ToInt64(other.Y);
+		}
+
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Overview.html
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Overview.html?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Overview.html (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Overview.html Sun Dec 13 19:39:51 2009
@@ -0,0 +1,41 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+
+<!--
+ 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.
+-->
+
+<html>
+	<head>
+		<title>Geographical filtering & sorting with Lucene</title>
+	</head>
+	<body>
+		<p>
+			This package makes it possible to filter and sort according to
+			geographical constraints.  For example, filter to include only
+			restaurants within 2 miles of a specified latitude/longitude, sorting
+			by distance ascending.
+		</p>
+		<p>
+			See <a href="http://www.nsshutdown.com/projects/lucene/whitepaper/locallucene_v2.html">here</a>
+			for details on the technical approach.
+		</p>
+		<p>
+			Unfortunately, this package is still very new, and has little to no
+			documentation.  It's best to look at the unit tests included in
+			the source distribution.
+		</p>
+	</body>
+</html>
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Properties/AssemblyInfo.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Properties/AssemblyInfo.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Properties/AssemblyInfo.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Properties/AssemblyInfo.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,60 @@
+/*
+ * 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.Reflection;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Apache Lucene.Net (Spatial)")]
+[assembly: AssemblyDescription("The Apache Software Foundation Lucene.Net a full-text search engine library")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Spatial.Net")]
+[assembly: AssemblyCopyright("Copyright 2009 The Apache Software Foundation")]
+[assembly: AssemblyTrademark("Copyright 2009 The Apache Software Foundation")]
+[assembly: AssemblyDefaultAlias("Lucene.Net.Spatial")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5c8e810f-4bf7-472f-9785-8d80a0de6ea8")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyInformationalVersionAttribute("2.9.0")]
+
+[assembly: AssemblyVersion("2.9.1.002")]
+[assembly: AssemblyFileVersion("2.9.1.002")]
+
+
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.csproj
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Spatial.Net.csproj?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.csproj (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.csproj Sun Dec 13 19:39:51 2009
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>9.0.21022</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{35C347F4-24B2-4BE5-8117-A0E3001551CE}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Lucene.Net.Spatial</RootNamespace>
+    <AssemblyName>Spatial.Net</AssemblyName>
+    <TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <TargetFrameworkSubset>
+    </TargetFrameworkSubset>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <DocumentationFile>bin\Debug\Spatial.Net.xml</DocumentationFile>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Lucene.Net, Version=2.9.1.2, Culture=neutral, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\src\Lucene.Net\bin\Release\Lucene.Net.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="GeoHash\GeoHashDistanceFilter.cs" />
+    <Compile Include="GeoHash\GeoHashUtils.cs" />
+    <Compile Include="Geometry\CartesianPoint.cs" />
+    <Compile Include="Geometry\DistanceUnits.cs" />
+    <Compile Include="Geometry\FixedLatLng.cs" />
+    <Compile Include="Geometry\FloatLatLng.cs" />
+    <Compile Include="Geometry\LatLng.cs" />
+    <Compile Include="Geometry\Shape\Ellipse.cs" />
+    <Compile Include="Geometry\Shape\IGeometry2D.cs" />
+    <Compile Include="Geometry\Shape\IntersectCase.cs" />
+    <Compile Include="Geometry\Shape\LineSegment.cs" />
+    <Compile Include="Geometry\Shape\LLRect.cs" />
+    <Compile Include="Geometry\Shape\Point2D.cs" />
+    <Compile Include="Geometry\Shape\Rectangle.cs" />
+    <Compile Include="Geometry\Shape\Vector2D.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Tier\CartesianPolyFilterBuilder.cs" />
+    <Compile Include="Tier\CartesianShapeFilter.cs" />
+    <Compile Include="Tier\DistanceFieldComparatorSource.cs" />
+    <Compile Include="Tier\DistanceFilter.cs" />
+    <Compile Include="Tier\DistanceHandler.cs" />
+    <Compile Include="Tier\DistanceQueryBuilder.cs" />
+    <Compile Include="Tier\DistanceUtils.cs" />
+    <Compile Include="Tier\LatLongDistanceFilter.cs" />
+    <Compile Include="Tier\Projectors\CartesianTierPlotter.cs" />
+    <Compile Include="Tier\Projectors\IProjector.cs" />
+    <Compile Include="Tier\Projectors\SinusoidalProjector.cs" />
+    <Compile Include="Tier\Shape.cs" />
+    <Compile Include="Utils\BitwiseHelper.cs" />
+    <Compile Include="Utils\MathHelper.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Content Include="Overview.html" />
+    <Content Include="Tier\Package.html" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.sln
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Spatial.Net.sln?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.sln (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.sln Sun Dec 13 19:39:51 2009
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spatial.Net", "Spatial.Net.csproj", "{35C347F4-24B2-4BE5-8117-A0E3001551CE}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tests", "..\Tests\Tests.csproj", "{19FC2A6B-4DE9-403F-8CEF-10850F57B96E}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{35C347F4-24B2-4BE5-8117-A0E3001551CE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{35C347F4-24B2-4BE5-8117-A0E3001551CE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{35C347F4-24B2-4BE5-8117-A0E3001551CE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{35C347F4-24B2-4BE5-8117-A0E3001551CE}.Release|Any CPU.Build.0 = Release|Any CPU
+		{19FC2A6B-4DE9-403F-8CEF-10850F57B96E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{19FC2A6B-4DE9-403F-8CEF-10850F57B96E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{19FC2A6B-4DE9-403F-8CEF-10850F57B96E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{19FC2A6B-4DE9-403F-8CEF-10850F57B96E}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.suo
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Spatial.Net.suo?rev=890098&view=auto
==============================================================================
Binary file - no diff available.

Propchange: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Spatial.Net.suo
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianPolyFilterBuilder.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Tier/CartesianPolyFilterBuilder.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianPolyFilterBuilder.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianPolyFilterBuilder.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,151 @@
+/* 
+ * 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 Lucene.Net.Search;
+using Lucene.Net.Spatial.Geometry;
+using Lucene.Net.Spatial.Geometry.Shape;
+using Lucene.Net.Spatial.Tier.Projectors;
+
+namespace Lucene.Net.Spatial.Tier
+{
+	public class CartesianPolyFilterBuilder
+	{
+		/// <summary>
+		/// Finer granularity than 1 mile isn't accurate with
+		/// standard C# math.  Also, there's already a 2nd
+		/// precise filter, if needed, in DistanceQueryBuilder,
+		/// that will make the filtering exact.
+		/// </summary>
+		public static double MilesFloor = 1.0;
+
+		private readonly IProjector _projector = new SinusoidalProjector();
+		private readonly string _tierPrefix;
+
+		public CartesianPolyFilterBuilder(string tierPrefix)
+		{
+			_tierPrefix = tierPrefix;
+		}
+
+		public Shape GetBoxShape(double latitude, double longitude, double miles)
+		{
+			if (miles < MilesFloor)
+			{
+				miles = MilesFloor;
+			}
+			//Rectangle box = DistanceUtils.GetInstance().GetBoundary(latitude, longitude, miles);
+			LLRect box1 = LLRect.CreateBox(new FloatLatLng(latitude, longitude), miles, miles);
+			LatLng ll = box1.GetLowerLeft();
+			LatLng ur = box1.GetUpperRight();
+
+			double latY = ur.GetLat();
+			double latX = ll.GetLat();
+			double longY = ur.GetLng();
+			double longX = ll.GetLng();
+			double longX2 = 0.0;
+
+			if (ur.GetLng() < 0.0 && ll.GetLng() > 0.0)
+			{
+				longX2 = ll.GetLng();
+				longX = -180.0;
+			}
+			if (ur.GetLng() > 0.0 && ll.GetLng() < 0.0)
+			{
+				longX2 = ll.GetLng();
+				longX = 0.0;
+			}
+
+			var ctp = new CartesianTierPlotter(2, _projector, _tierPrefix);
+			int bestFit = ctp.BestFit(miles);
+
+			ctp = new CartesianTierPlotter(bestFit, _projector, _tierPrefix);
+			
+			var shape = new Shape(ctp.GetTierFieldName());
+
+			// generate shape
+			// iterate from startX->endX
+			// iterate from startY -> endY
+			// shape.add(currentLat.currentLong);
+
+			shape = GetShapeLoop(shape, ctp, latX, longX, latY, longY);
+			if (longX2 != 0.0)
+			{
+				if (longX2 != 0.0)
+				{
+					if (longX == 0.0)
+					{
+						longX = longX2;
+						longY = 0.0;
+						shape = GetShapeLoop(shape, ctp, latX, longX, latY, longY);
+					}
+					else
+					{
+						longX = longX2;
+						longY = -180.0;
+						shape = GetShapeLoop(shape, ctp, latY, longY, latX, longX);
+					}
+				}
+			}
+
+			return shape;
+		}
+
+		public Shape GetShapeLoop(Shape shape, CartesianTierPlotter ctp, double latX, double longX, double latY, double longY)
+		{
+			double beginAt = ctp.GetTierBoxId(latX, longX);
+			double endAt = ctp.GetTierBoxId(latY, longY);
+
+			double tierVert = ctp.TierVerticalPosDivider;
+			
+			double startX = beginAt - (beginAt % 1);
+			double startY = beginAt - startX; //should give a whole number
+
+			double endX = endAt - (endAt % 1);
+			double endY = endAt - endX; //should give a whole number
+
+			int scale = (int) Math.Log10(tierVert);
+
+			endY = Math.Round(endY, scale, MidpointRounding.ToEven);
+			startY = Math.Round(startY, scale, MidpointRounding.ToEven);
+
+			double xInc = 1.0d / tierVert;
+			xInc = Math.Round(xInc, scale, MidpointRounding.ToEven);
+			
+			for (; startX <= endX; startX++)
+			{
+				double itY = startY;
+				
+				while (itY <= endY)
+				{
+					//create a boxId
+					// startX.startY
+					double boxId = startX + itY;
+					shape.AddBox(boxId);
+
+					itY += Math.Round(xInc, scale, MidpointRounding.ToEven);
+				}
+			}
+			return shape;
+		}
+
+		public Filter GetBoundingArea(double latitude, double longitude, double miles)
+		{
+			Shape shape = GetBoxShape(latitude, longitude, miles);
+			return new CartesianShapeFilter(shape, shape.TierId);
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianShapeFilter.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Tier/CartesianShapeFilter.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianShapeFilter.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/CartesianShapeFilter.cs Sun Dec 13 19:39:51 2009
@@ -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.Index;
+using Lucene.Net.Search;
+using Lucene.Net.Util;
+
+namespace Lucene.Net.Spatial.Tier
+{
+	public class CartesianShapeFilter : Filter
+	{
+		private readonly Shape _shape;
+		private readonly string _fieldName;
+
+		public CartesianShapeFilter(Shape shape, string fieldName)
+		{
+			_shape = shape;
+			_fieldName = fieldName;
+		}
+
+		public override DocIdSet GetDocIdSet(IndexReader reader)
+		{
+			var bits = new OpenBitSet(reader.MaxDoc());
+
+			TermDocs termDocs = reader.TermDocs();
+			List<double> area = _shape.Area;
+			int sz = area.Count;
+			
+			// iterate through each boxid
+			for (int i = 0; i < sz; i++)
+			{
+				double boxId = area[i];
+				termDocs.Seek(new Term(_fieldName, NumericUtils.DoubleToPrefixCoded(boxId)));
+
+				// iterate through all documents
+				// which have this boxId
+				while (termDocs.Next())
+				{
+					bits.FastSet(termDocs.Doc());
+				}
+			}
+
+			return bits;
+		}
+	}
+}
\ No newline at end of file

Added: incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceFieldComparatorSource.cs
URL: http://svn.apache.org/viewvc/incubator/lucene.net/trunk/C%23/contrib/Spatial.Net/Spatial.Net/Tier/DistanceFieldComparatorSource.cs?rev=890098&view=auto
==============================================================================
--- incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceFieldComparatorSource.cs (added)
+++ incubator/lucene.net/trunk/C#/contrib/Spatial.Net/Spatial.Net/Tier/DistanceFieldComparatorSource.cs Sun Dec 13 19:39:51 2009
@@ -0,0 +1,110 @@
+/* 
+ * 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 Lucene.Net.Search;
+
+namespace Lucene.Net.Spatial.Tier
+{
+	public class DistanceFieldComparatorSource : FieldComparatorSource
+	{
+		private readonly DistanceFilter _distanceFilter;
+		private DistanceScoreDocLookupComparator _dsdlc;
+
+		public DistanceFieldComparatorSource(DistanceFilter distanceFilter)
+		{
+			this._distanceFilter = distanceFilter;
+		}
+
+		public override FieldComparator NewComparator(string fieldname, int numHits, int sortPos, bool reversed)
+		{
+			return _dsdlc = new DistanceScoreDocLookupComparator(_distanceFilter, numHits);
+			
+		}
+
+		private class DistanceScoreDocLookupComparator : FieldComparator
+		{
+			private DistanceFilter _distanceFilter;
+			private readonly double[] _values;
+			private double _bottom;
+			private int _offset = 0;
+
+			public DistanceScoreDocLookupComparator(DistanceFilter distanceFilter, int numHits)
+			{
+				this._distanceFilter = distanceFilter;
+				_values = new double[numHits];
+				return;
+			}
+
+			public override int Compare(int slot1, int slot2)
+			{
+				double a = _values[slot1];
+				double b = _values[slot2];
+				if (a > b)
+					return 1;
+				if (a < b)
+					return -1;
+
+				return 0;
+			}
+
+			public override int CompareBottom(int doc)
+			{
+				double v2 = _distanceFilter.GetDistance(doc + _offset);
+
+				if (_bottom > v2)
+				{
+					return 1;
+				}
+				
+				if (_bottom < v2)
+				{
+					return -1;
+				}
+				
+				return 0;
+			}
+
+			public override void Copy(int slot, int doc)
+			{
+				_values[slot] = _distanceFilter.GetDistance(doc + _offset);
+			}
+
+			public override void SetBottom(int slot)
+			{
+				this._bottom = _values[slot];
+			}
+
+			public override void SetNextReader(Lucene.Net.Index.IndexReader reader, int docBase)
+			{
+				// each reader in a segmented base
+				// has an offset based on the maxDocs of previous readers
+				_offset = docBase;
+			}
+
+			public override IComparable Value(int slot)
+			{
+				return _values[slot];
+			}
+
+			public void CleanUp()
+			{
+				_distanceFilter = null;
+			}
+		}
+	}
+}



Mime
View raw message