bdc*_*der 5 sql-server geography
我正在测试各种 SQL 地理类型方法 - 具体来说,我想了解STContains()和STWithin().
根据文档:
StWithin() - 如果地理实例在空间上位于另一个地理实例内,则返回 1;
STContains() - 指定调用 geography 实例是否在空间上包含传递给该方法的 geography 实例。
我在微软总部周围创建了一个简单的 1 km x 1 km POLYGON(实际上是一个正方形),从视觉上看,它看起来像这样:
使用的数据点如下:
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
Run Code Online (Sandbox Code Playgroud)
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';
Run Code Online (Sandbox Code Playgroud)
SQL 返回:
STIsValid STIsClosed
True True
Run Code Online (Sandbox Code Playgroud)
接下来,我检查中心点是否在边界内(应该是),如下
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';
Run Code Online (Sandbox Code Playgroud)
SQL 返回:
STContains STIntersects STOverlaps STWithin
True True False False
Run Code Online (Sandbox Code Playgroud)
注意:我原以为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';
Run Code Online (Sandbox Code Playgroud)
SQL 返回:
STContains STIntersects STOverlaps STWithin
False True False False
Run Code Online (Sandbox Code Playgroud)
注意:在这种情况下,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';
Run Code Online (Sandbox Code Playgroud)
SQL 返回:
STContains STIntersects STOverlaps STWithin
False False False False
Run Code Online (Sandbox Code Playgroud)
在上述所有的测试,就是测试了点里面的界限,在界限,内外界限的边缘,STWithin()回报False-需要什么条件STWithin()来回报True?(或者,STWithin()根本不起作用?)
另外,我希望STOverlaps()在某些情况下返回 true,但如果有人可以评论该方法,它也会有所帮助。
任何意见,将不胜感激。
好的,看来以下内容是正确的:
@point.STWithin( @bounds ) == @bounds.STContains( @point );
Run Code Online (Sandbox Code Playgroud)
例如,以下查询(测试中心点是否在边界内):
DECLARE @point geography;
SET @point = geography::Point( 47.6423318, -122.1391189, 4326 );
SELECT @bounds.STContains( @point) AS 'STContains',
@point.STWithin( @bounds ) AS 'STWithin';
Run Code Online (Sandbox Code Playgroud)
返回:
STContains STWithin
True True
Run Code Online (Sandbox Code Playgroud)