SQL 服务器地理测试点是否在边界内 - STWithin() 做什么?
SQL Server geography testing if a point is within a bounds - what does STWithin() do?
我正在测试各种 SQL 地理类型方法 - 具体来说,我想了解 STContains()
和 STWithin()
之间的区别。
根据文档:
StWithin()
- Returns 1 如果一个地理实例在空间上位于另一个地理实例内;
STContains()
- 指定调用地理实例是否在空间上包含传递给方法的地理实例。
我在微软总部周围创建了一个简单的 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
多边形声明(使用左手法则)如下,并检查是否有效:
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 Returns:
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 Returns:
STContains STIntersects STOverlaps STWithin
True True False False
注意: 我原以为 STWithin
是 True
,但结果发现中心点不是 "within" 边界?
接下来,我检查SW角点是否被认为是"in"边界,如下:
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 Returns:
STContains STIntersects STOverlaps STWithin
False True False False
注意:在这种情况下,STContains()
returns False
(这是预期的),但STIntersects()
returns 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 Returns:
STContains STIntersects STOverlaps STWithin
False False False False
在上述所有测试中,即测试边界内、边界边缘和边界外的点,STWithin()
returns False
- STWithin()
到returnTrue
需要什么条件? (或者,STWithin()
根本不起作用吗?)
此外,在某些情况下,我希望 STOverlaps()
到 return 正确,但如果有人可以对该方法发表评论,它也会有所帮助。
如有任何建议,我们将不胜感激。
What condition is required for STWithin() to return True? (Or, does
STWithin() simply not work?)
STWithin, STContains : OGC 标准方法,return 1 或 0,它们表示一个实例的所有点是否完全存在于另一个实例中。
对于您的示例,点可以存在于多边形内,但多边形不能存在于点内。将 within 视为包含的 "inverse":如果 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
Also, I was expecting STOverlaps() to return true in some cases
这在 the documentation 中有点模糊(对于几何,但它也适用于地理):
备注
如果表示其交集的区域与实例具有相同的维度并且区域 不等于任何一个实例 .
,则两个几何实例重叠
点与多边形重叠 --> 重叠是点(==等于任一实例)--> 0。
您可以通过 "cloning" 相同的空间实例来测试它并检查它是否与自身重叠:
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 );
例如以下查询(测试中心点是否在边界内):
DECLARE @point geography;
SET @point = geography::Point( 47.6423318, -122.1391189, 4326 );
SELECT @bounds.STContains( @point) AS 'STContains',
@point.STWithin( @bounds ) AS 'STWithin';
Returns:
STContains STWithin
True True
我正在测试各种 SQL 地理类型方法 - 具体来说,我想了解 STContains()
和 STWithin()
之间的区别。
根据文档:
StWithin()
- Returns 1 如果一个地理实例在空间上位于另一个地理实例内;
STContains()
- 指定调用地理实例是否在空间上包含传递给方法的地理实例。
我在微软总部周围创建了一个简单的 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
多边形声明(使用左手法则)如下,并检查是否有效:
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 Returns:
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 Returns:
STContains STIntersects STOverlaps STWithin
True True False False
注意: 我原以为 STWithin
是 True
,但结果发现中心点不是 "within" 边界?
接下来,我检查SW角点是否被认为是"in"边界,如下:
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 Returns:
STContains STIntersects STOverlaps STWithin
False True False False
注意:在这种情况下,STContains()
returns False
(这是预期的),但STIntersects()
returns 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 Returns:
STContains STIntersects STOverlaps STWithin
False False False False
在上述所有测试中,即测试边界内、边界边缘和边界外的点,STWithin()
returns False
- STWithin()
到returnTrue
需要什么条件? (或者,STWithin()
根本不起作用吗?)
此外,在某些情况下,我希望 STOverlaps()
到 return 正确,但如果有人可以对该方法发表评论,它也会有所帮助。
如有任何建议,我们将不胜感激。
What condition is required for STWithin() to return True? (Or, does STWithin() simply not work?)
STWithin, STContains : OGC 标准方法,return 1 或 0,它们表示一个实例的所有点是否完全存在于另一个实例中。
对于您的示例,点可以存在于多边形内,但多边形不能存在于点内。将 within 视为包含的 "inverse":如果 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
Also, I was expecting STOverlaps() to return true in some cases
这在 the documentation 中有点模糊(对于几何,但它也适用于地理):
备注 如果表示其交集的区域与实例具有相同的维度并且区域 不等于任何一个实例 .
,则两个几何实例重叠点与多边形重叠 --> 重叠是点(==等于任一实例)--> 0。
您可以通过 "cloning" 相同的空间实例来测试它并检查它是否与自身重叠:
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 );
例如以下查询(测试中心点是否在边界内):
DECLARE @point geography;
SET @point = geography::Point( 47.6423318, -122.1391189, 4326 );
SELECT @bounds.STContains( @point) AS 'STContains',
@point.STWithin( @bounds ) AS 'STWithin';
Returns:
STContains STWithin
True True