Sql server SQL Server地理测试点是否在边界内-STWithin()做什么?

Sql server SQL Server地理测试点是否在边界内-STWithin()做什么?,sql-server,geography,Sql Server,Geography,我正在测试各种SQL地理类型的方法——具体来说,我想了解STContains()和STWithin()之间的区别 根据文件: -如果一个地理实例在空间上位于另一个地理实例内,则返回1 -指定调用的地理实例是否在空间上包含传递给方法的地理实例 我在微软总部周围创建了一个简单的1km x 1km多边形(实际上是一个正方形),从视觉上看,它如下所示: 使用的数据点如下: Center point: 47.6423318, -122.1391189 Polygon (Square) corner p

我正在测试各种SQL地理类型的方法——具体来说,我想了解
STContains()
STWithin()
之间的区别

根据文件:

-如果一个地理实例在空间上位于另一个地理实例内,则返回1

-指定调用的地理实例是否在空间上包含传递给方法的地理实例

我在微软总部周围创建了一个简单的1km x 1km多边形(实际上是一个正方形),从视觉上看,它如下所示:

使用的数据点如下:

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
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';
多边形的声明(使用左手规则)如下所示,并检查其是否有效:

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
STContains  STIntersects    STOverlaps  STWithin
True        True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       False           False       False
接下来,我检查中心点是否在边界内(应该是),如下所示

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返回:

STIsValid   STIsClosed
True        True
STContains  STIntersects    STOverlaps  STWithin
True        True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       False           False       False
注意:我原以为
STWithin
True
,但事实证明中心点不在“界限”之内

接下来,我检查SW角点是否被视为“在”边界内,如下所示:

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
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返回:

STIsValid   STIsClosed
True        True
STContains  STIntersects    STOverlaps  STWithin
True        True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       False           False       False
注意:在这种情况下,
STContains()
返回
False
(这是预期的),但
STIntersects()
返回
True
;如果需要考虑边缘点是“在”范围内,则有用。 最后一次测试-边界外的点:

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返回:

STIsValid   STIsClosed
True        True
STContains  STIntersects    STOverlaps  STWithin
True        True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       True            False       False
STContains  STIntersects    STOverlaps  STWithin
False       False           False       False
在上述所有测试中,即测试边界内、边界边缘和边界外的点,
STWithin()
返回
False
-需要什么条件才能
STWithin()
返回
True
?(或者,
STWithin()
根本不起作用吗?)

另外,我希望在某些情况下
STOverlaps()
会返回true,但如果有人可以对该方法进行评论,也会有所帮助

如有任何建议,将不胜感激

STWithin()返回True需要什么条件?(或 STWithin()根本不起作用?)

STWithin,STContains:OGC标准方法,返回1或0,它们指示一个实例的所有点是否完全存在于另一个实例中

例如,点可以存在于多边形内,但多边形不能存在于点内。将in视为包含的“逆”:如果x在y内,则y包含x。-->若多边形包含点,则点位于多边形内:

SELECT 
@bounds.STContains( @point) AS 'bounds contains point',  --if this is true...
@point.STWithin( @bounds ) AS 'point is within bounds'; --...then this is also true
另外,我希望STOverlaps()在某些情况下返回true

这在以下方面有点模糊(对于几何而言,但也适用于地理):

评论 如果表示其交点的区域具有与实例相同的尺寸,且区域不等于任一实例,则两个几何体实例将重叠

点与多边形重叠-->重叠为点(=等于任一实例)-->0

您可以通过“克隆”相同的空间实例并检查其是否重叠来测试这一点:

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 );
DECLARE @boundsclone geography=@bounds;

select @bounds.STOverlaps(@boundsclone), @boundsclone.STOverlaps(@bounds);

好吧,看来下面的说法是正确的:

@point.STWithin( @bounds ) == @bounds.STContains( @point );
例如,以下查询(测试中心点是否在边界内):

返回:

STContains  STWithin
True        True

lptr-谢谢-仍然有些困惑-可能是因为名称(STWithin)-如果它是STContains的反义词,人们会认为像STNotContains这样的名称更合适。简而言之:a.STWithin(b)==b.STContains(a)--对吗?看起来像。使用您的示例点,我运行
选择@point.STWithin(@bounds)作为'STWithin'
并返回true。