Это, казалось бы, простой вопрос о геометрии SQL Server, который, как я думал, будет иметь готовое решение, но мне не повезло найти его.
Мое намерение состоит в том, чтобы выбрать все записи в одной таблице, которые имеют многоугольники, которые вложены (содержатся) в большем многоугольнике из другой таблицы. Я ожидал функций STWithin
и STContains
решений, которые мне были нужны, но, к сожалению, оба идентифицируют только внутренние многоугольники внутри тех, которые вложены в большой многоугольник, а не те вложенные многоугольники, которые касаются границы большего многоугольника. Смотрите изображение для примера.
Альтернативный вариант, который работал на мои нужды STIntersection
. Проблема с этой функцией, однако, заключается в том, что она возвращает только столбец геометрии! Я хотел бы получить идентификатор записи вместо этого. У кого-нибудь есть предложения о том, как это можно сделать?
STWithin
:
select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STWithin(b.shape) = 1
where b.mktname = 'Loop'
STContains
:
select a.bg10 from
gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on b.shape.STContains(a.shape) = 1
where b.mktname = 'Loop'
STIntersection
:
select a.shape.STIntersection(b.shape)
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'
Редактировать:
Одно из предложений было исключить STIntersection
и использовать исключительно STIntersects
следующим образом:
STIntersects
:
select a.bg10
from gis.usa_10_block_group a
join gis.usa_10_mkt_definition b
on a.shape.STIntersects(b.shape) = 1
where b.mktname = 'Loop'
Проблема с этим подходом заключается в том, что STIntersects
кажется, что все многоугольники выбираются внутри или снаружи и касаются большего многоугольника, а не только строго внутри. Смотрите изображение для примера.
источник
STContains
илиSTWithin
. Не очень хороший взлом, но даст вам результаты, которые вы хотите. Другим вариантом будет сделать STIntersects со сравнением области пересечения и области полигонов.Ответы:
Теоретически, запросы, которые вы сделали, должны вернуть полигоны, которые, как вы сказали, не были возвращены. Это заставляет меня подозревать, что вы можете столкнуться с ошибками с плавающей запятой, которые SQL Server имеет с пространственными типами данных. Отсюда мой комментарий о буферизации ограничивающего полигона минимальным количеством.
Таким образом, что-то вроде следующего должно получить желаемые результаты.
Вот быстрый пример ожидаемого поведения некоторых из пространственных методов.
Результаты
источник
Запрос на пересечение должен выглядеть следующим образом (при условии, что вы хотите вернуть все записи из «а»):
Если вы хотите, чтобы только области a пересекались с b (т. Е. Обрезали a до b), добавьте STIntersection.
Но это не дает вам многоугольники, которые находятся внутри б просто ...
Этот тип многоугольника в многоугольнике очень показателен с границами и их совпадением - чтобы быть «внутри», границы не могут совпадать с границами b - то же самое относится и к «содержит».
По этим определениям, сколько ваших полигонов в a на самом деле находятся в пределах b ...?
Итак, вы хотите буферизовать b, прежде чем выбрать полигоны в a, которые находятся внутри? Или сделать отрицательный буфер на?
Не уверен, что точный ответ здесь ...
источник