Vous pouvez stocker vos objets dans une GEOGRAPHY
colonne et créez un SPATIAL INDEX
sur cette colonne.
Malheureusement, SQL Server
implémente des index spatiaux en pavage de la surface et en stockant les identifiants de tuiles dans un B-Tree
simple index, donc simple ORDER BY STDistance
ne fonctionnera pas (enfin, cela fonctionnera mais n'utilisera pas l'index).
Au lieu de cela, vous devrez faire une requête similaire à celle-ci :
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
De cette façon, SQL Server
recherchera d'abord les routes dans 1
kilomètre de votre point, puis dans un rayon de 2
kilomètres, etc., en utilisant à chaque fois l'index.
Mise à jour :
Si vous avez plusieurs points dans un tableau et que vous souhaitez trouver le point le plus proche pour chacun d'eux :
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