Я тестирую различные SQL методы типа географии - в частности, я хочу понять разницу между STContains()
и STWithin()
.
Согласно документам:
StWithin()
- Возвращает 1, если экземпляр географии пространственно находится в другом экземпляре географии;
STContains()
- Указывает, содержит ли вызывающий экземпляр географии пространственно содержащий экземпляр географии, переданный методу.
Я создал простой ПОЛИГОН размером 1 x 1 км (a на самом деле) вокруг штаб-квартиры Microsoft, визуально это выглядит так:
Использовались следующие точки данных:
Center point: 47.6423318, -122.1391189
Polygon (Square) corner points:
SE: 47.6378402235794, -122.13244353271
NE: 47.6468233764206, -122.13244353271
NW: 47.6468233764206, -122.14577646729
SW: 47.6378402235794, -122.14577646729
POLYGON был объявлен (с использованием правила левой руки) следующим образом и проверен, если он действителен:
DECLARE @bounds geography;
SET @bounds = geography::STPolyFromText('POLYGON((-122.13244353271 47.6378402235794, -122.13244353271 47.6468233764206, -122.14577646729 47.6468233764206, -122.14577646729 47.6378402235794, -122.13244353271 47.6378402235794))', 4326 );
SELECT @bounds.STIsValid() AS 'STIsValid', @bounds.STIsClosed() AS 'STIsClosed';
SQL Возвращает:
STIsValid STIsClosed
True True
Далее я проверяю, центральная точка находится в пределах (должно быть), как показано ниже:
DECLARE @point geography;
SET @point = geography::Point( 47.6423318, -122.1391189, 4326 );
SELECT @bounds.STContains( @point) AS 'STContains',
@bounds.STIntersects( @point ) AS 'STIntersects',
@bounds.STOverlaps( @point ) AS 'STOverlaps',
@bounds.STWithin( @point ) AS 'STWithin';
SQL Возвращает:
STContains STIntersects STOverlaps STWithin
True True False False
Примечание: Я ожидал STWithin
быть True
, но оказывается, что центральная точка НЕ находится "в пределах" границ?
Далее я проверяю, считается ли угловая точка SW "в" границах, следующим образом:
SET @point = geography::Point( 47.6378402235794, -122.14577646729, 4326 );
SELECT @bounds.STContains( @point) AS 'STContains',
@bounds.STIntersects( @point ) AS 'STIntersects',
@bounds.STOverlaps( @point ) AS 'STOverlaps',
@bounds.STWithin( @point ) AS 'STWithin';
SQL Возвращает:
STContains STIntersects STOverlaps STWithin
False True False False
Примечание: В этом случае STContains()
возвращает False
(что ожидается), но STIntersects()
ret урны True
; полезно, если вам нужно рассматривать граничные точки как находящиеся в границах "in" или нет.
Последний тест - точка ВНЕ границ:
SET @point = geography::Point( 47.647, -122.13244353271, 4326 );
SELECT @bounds.STContains( @point) AS 'STContains',
@bounds.STIntersects( @point ) AS 'STIntersects',
@bounds.STOverlaps( @point ) AS 'STOverlaps',
@bounds.STWithin( @point ) AS 'STWithin';
SQL Возвращает:
STContains STIntersects STOverlaps STWithin
False False False False
Во всех вышеперечисленных тестах, то есть при проверке точки ВНУТРИ границ, КРАЯ границ и ВНЕ границ, STWithin()
возвращает False
- Какое условие требуется для STWithin()
чтобы вернуть True
? (Или STWithin()
просто не работает?)
Кроме того, я ожидал, что в некоторых случаях STOverlaps()
вернет true, но если кто-то может прокомментировать этот метод, это также поможет.
Любой совет будет оценен.