Ответ 1
Вы можете сохранить свои объекты в столбце GEOGRAPHY
и создать SPATIAL INDEX
над этим столбцом.
К сожалению, 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
километров и т.д., каждый раз, используя индекс.
Update:
Если у вас несколько точек в таблице и вы хотите найти ближайшую точку для каждого из них:
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