我正在尝试天真地获得一组点的k近邻,给定值k,用作中心的坐标和用作查找点内的最大距离的半径。我在MSSQL 2008数据库上使用地理点(SRID 4326)。
邻居们天真地发现,通过到点的距离来排序查询并限制结果。 我的麻烦始于限制给定半径的点数。距离函数返回的距离远大于预期,我理解这是由SRID 4326引起的。这是正常的,因为它仅用于排序,但是当我必须将这些值与相对距离进行比较时比如200米,这些大数字都不会。
我的问题是:是否有更聪明的方法使用NHibernate Spatial查询将点限制为半径,或者有没有办法将此半径转换为类似于距离函数使用的一些测量?
这是我现在查看的查询:
output = NHibernateSession.GetSession().CreateQuery(@"select p from POI p
where NHSP.Distance(p.PointCoord, :coord) <= :maxDistance
order by NHSP.Distance(p.PointCoord, :coord)")
.SetParameter("coord", coord,
NHibernateUtil.Custom(typeof(Wgs84GeographyType)))
.SetParameter<double>("maxDistance", radius)
.SetMaxResults(k)
.Enumerable<POI>();
作为一个例子,我有以下两点: 要点(7 1) 要点(7 3)
我的预期距离是2,但是mssql STDistance函数计算的距离得到221151.479533501。我无法理解这一点。
答案 0 :(得分:2)
这是因为地理数据类型和几何数据类型之间的差异。
最好用一个例子来解释。
declare @point1 as geography
declare @point2 as geography
set @point1 = geography::STGeomFromText('POINT (7 1)', 4326)
set @point2 = geography::STGeomFromText('POINT (7 3)', 4326)
select @point1.STDistance(@point2)
declare @point3 as geometry
declare @point4 as geometry
set @point3 = geometry::STGeomFromText('POINT (7 1)', 4326)
set @point4 = geometry::STGeomFromText('POINT (7 3)', 4326)
select @point3.STDistance(@point4)
如果直接在SQL Server Management Studio中运行,则在第一个结果中获得221151.479533501,在第二个结果中获得2个。
这基本上是因为在地理数据类型中,根据提供的SRID选择单位。在你的情况下,是4326,它以米为单位。所以,你要求坐标之间的距离(以米为单位)(lon:7; lat:1)和(lon:7; lat:3)。它返回大约221公里。
当使用几何类型(第二个例子)时,它是一个平面投影,其距离按预期工作,因此返回2.
关于您的NH Spatial代码,似乎没问题。只需提供以米为单位的maxDistance参数,你就可以了。