Я пытаюсь создать запрос, но я испытываю некоторые затруднения.
У меня есть база данных SQL Server 2008 с таблицей, которая включает среди других полей, поля географии, которое описывает дорожные сегменты. (Эти данные были импортированы из данных ТИГРА/СТРОКИ из американской переписи.)
У меня есть другая фиксированная точка, описывающая местоположение пользователя. Я хочу найти самый близкий дорожный сегмент в базе данных к той точке, но я, может казаться, не выясняю, как выполнить это. Кроме того, я хочу найти самую близкую точку на том сегменте к пользовательской точке местоположения. Это - то, что я хочу выбрать и возвратить назад в моем запросе.
У кого-либо есть опыт с функциональностью географии/геометрии, которая может помочь мне?
Спасибо!
Вы можете хранить свои объекты в столбце ГЕОГРАФИЯ
и создать СПАТИАЛЬНЫЙ ИНДЕКС
над этим столбцом.
К сожалению, SQL Server
реализует пространственные индексы, выкладывая поверхность и сохраняя идентификаторы плиток в обычном B-Tree
индексе, поэтому обычный ORDER BY STDistance
не будет работать (ну, он будет работать, но не будет использовать индекс).
Вместо этого вам придется сделать запрос, похожий на этот:
DECLARE @mypoint GEOGRAPHY
SET @mypoint = geography::STGeomFromText('POINT(@mylat, @mylon)', 4326);
WITH num (distance) AS
(
SELECT 1000
UNION ALL
SELECT distance + 1000
FROM num
WHERE distance <= 50000
)
SELECT TOP 1 m.*
FROM num
CROSS APPLY
(
SELECT TOP 1 *
FROM mytable
WHERE myroad.STDistance(@mypoint) <= distance
ORDER BY
STDistance(@mypoint)
) m
Таким образом, SQL Server
будет сначала искать дороги в пределах 1
километров от вашей точки, затем в пределах 2
километров и т.д., каждый раз используя индекс.
Обновление:
Если у вас несколько точек в таблице и вы хотите найти ближайшую точку для каждой из них:
WITH num (distance) AS
(
SELECT 1000
UNION ALL
SELECT distance + 1000
FROM num
WHERE distance <= 50000
)
SELECT mp.mypoint, m.*
FROM @mypoints mp
CROSS APPLY
(
SELECT TOP 1 m.*
FROM num
CROSS APPLY
(
SELECT TOP 1 *
FROM mytable
WHERE myroad.STDistance(@mypoint) <= distance
ORDER BY
STDistance(@mypoint)
) m
) m
Как хранятся ваши дорожные сегменты? лат и длина? если да, то вы можете преобразовать их в радиан, и произвести расчеты: