Ближайшая точка типа данных SQL Server Geography на линии - PullRequest
10 голосов
/ 10 января 2010

Я пытаюсь создать запрос, но у меня возникли некоторые трудности.

У меня есть база данных SQL Server 2008 с таблицей, которая включает, помимо прочего, поле географии, которое описывает сегменты дороги. (Эти данные были импортированы из данных TIGER / Line из переписи США.)

У меня есть другая фиксированная точка, описывающая местоположение пользователя. Я хочу найти ближайший участок дороги в базе данных на данный момент, но я не могу понять, как это сделать. Кроме того, я хочу найти ближайшую точку в этом сегменте к точке расположения пользователя. Это то, что я хочу выбрать и вернуть обратно в своем запросе.

Кто-нибудь может мне помочь с географией / геометрией?

Спасибо!

Ответы [ 2 ]

18 голосов
/ 10 января 2010

Вы можете сохранить свои объекты в столбце 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 километров и т. Д. Каждый раз, используя индекс.

Обновление:

Если у вас есть несколько точек в таблице и вы хотите найти ближайшую точку для каждой из них:

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
0 голосов
/ 10 января 2010

Как хранятся ваши участки дороги? широчайший и длинный? если это так, вы можете преобразовать их в радианы и выполнить математические вычисления:

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...