使用NHibernate Spatial获取半径内的空间点

时间:2012-03-29 00:09:05

标签: sql-server-2008 nhibernate hql spatial

我正在尝试天真地获得一组点的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。我无法理解这一点。

1 个答案:

答案 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参数,你就可以了。