Получите пространственные точки в радиусе, используя NHibernate Spatial - PullRequest
1 голос
/ 29 марта 2012

В настоящее время я пытаюсь наивно получить k-ближайших соседей из набора точек, учитывая значение k, координату для использования в качестве центра и радиус, служащий максимальным расстоянием для поиска точек внутри. Я использую географические точки (SRID 4326) в базе данных MSSQL 2008.

Наивно найдены соседи, упорядочивающие запрос по расстоянию до точки и ограничивающие результат. Моя проблема начинается с ограничения точек заданным радиусом. Расстояния, возвращаемые функцией «Расстояние», намного больше ожидаемых, что, как я понимаю, вызвано SRID 4326. Это нормально, поскольку используется только для заказа, но когда мне нужно сравнить эти значения с относительным расстоянием скажем, 200 метров, эти большие числа не сделают.

Тогда у меня возникает вопрос: существует ли более разумный способ ограничения точек радиусом с помощью запросов NHibernate Spatial, или есть ли способ преобразовать этот радиус в некоторый мера, подобный тому, который используется функцией Distance?

Это мой запрос, как он выглядит сейчас:

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 Ответ

2 голосов
/ 30 марта 2012

это происходит из-за разницы между типом данных географии и типом данных геометрии.

Лучше всего объяснить на примере.

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, это в метрах. Итак, вы спрашиваете расстояние в метрах между координатами (долгота: 7; широта: 1) и (долгота: 7; широта: 3). Возвращает около 221 км.

При использовании типа геометрии (второй пример) это плоская проекция, в которой расстояние работает так, как вы ожидаете, и возвращает 2.

Что касается вашего кода NH Spatial, кажется, все в порядке. Просто укажите параметр maxDistance в метрах, и все будет в порядке.

...