2012-03-29 6 views
1

現在、値k、中心として使用する座標、および最大距離となる半径を指定して、点の集合のk最近傍を取得しようとしています内のポイントを見つける。私は地理的なポイント(SRID 4326)をMSSQL 2008データベースで使用しています。NHibernate Spatialを使用して半径内の空間点を取得する

隣人は、問合せをポイントまでの距離によって順序付けし、結果を限定することによって、簡単に見つけられます。 私の問題は、指定された半径で点を制限することから始まります。 Distance関数によって返される距離は、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>(); 

単なる例として、私はこれらの二つの点があります。 POINT(7 1) POINT(7 3)

私の予想距離があるが2となりますが、mssql STDistance関数で計算された距離は221151.479533501となります。私はちょうどこれについて理解するために私の心を得ることはできません。

答えて

2

これは、geographyデータ型とgeometryデータ型の違いのために発生します。

例を用いて説明してください。

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で直接これを実行する場合は、最初の結果と第二中2で221151.479533501を取得します。

これは基本的に地理データ型では、指定されたSRIDに従ってユニットが選択されるためです。あなたの場合、4326であり、そのメートルで表します。座標(lon:7; lat:1)と(lon:7; lat:3)の距離をメートル単位で求めています。それは約221キロメートルを返します。ジオメトリタイプ(第2例)を使用する場合

、それはこのようにあなたのNH空間コードについて2.

を返す、あなたが期待するように、距離が働く平面投影だ、OKらしいです。 maxDistanceパラメータをメートル単位で入力するだけで十分です。

関連する問題