空间关系函数
空间关系函数来测试两个几何值 g1 和 g2 之间的关系,使用精确的对象形状。返回值 1 和 0 分别表示真和假,除了距离函数返回距离值。
seekdb 当前所支持的空间关系函数包括 ST_Intersects()、ST_Contains()、ST_Distance()、ST_Distance_Sphere()、ST_Within()、ST_Crosses()、ST_Overlaps()、_ST_Touches() 和 ST_Equals()。
ST_Intersects
ST_Intersects() 函数返回 1 或 0 以指示 g1 是否在空间上与 g2 相交。语法如下:
ST_Intersects(g1, g2)
ST_Contains
ST_Contains() 函数返回 1 或 0 以指示 g1 是否完全包含 g2。语法如下:
ST_Contains(g1, g2)
ST_Distance
ST_Distance() 函数返回 g1 和 g2 之间的距离,以几何参数的空间参考系统 (SRS) 的长度单位测量。语法如下:
ST_Distance(g1, g2 [, unit])
ST_Distance() 支持一个可选的 unit 参数,该参数指定返回距离值的线性单位。如果指定 unit 参数,则以可选 unit参数的单位测量。
如果任何参数在几何上无效,则结果可能返回任何数字,或者发生报错。如果中间或最终结果产生 NaN 或负数,则会报错 ER_GIS_INVALID_DATA。
示例如下:
SET @geo1 = ST_GeomFromText('POINT(1 1)', 4230);
Query OK, 0 rows affected (0.001 sec)
SET @geo2 = ST_GeomFromText('POINT(3 3)', 4230);
Query OK, 0 rows affected (0.001 sec)
SELECT ST_Distance(@geo1, @geo2);
+---------------------------+
| ST_Distance(@geo1, @geo2) |
+---------------------------+
| 313709.8158791322 |
+---------------------------+
1 row in set (0.001 sec)
SELECT ST_Distance(@geo1, @geo2, 'metre');
+------------------------------------+
| ST_Distance(@geo1, @geo2, 'metre') |
+------------------------------------+
| 313709.8158791322 |
+------------------------------------+
1 row in set (0.001 sec)
SELECT ST_Distance(@geo1, @geo2, 'foot');
+-----------------------------------+
| ST_Distance(@geo1, @geo2, 'foot') |
+-----------------------------------+
| 1029231.6793934782 |
+-----------------------------------+
1 row in set (0.001 sec)
ST_Distance_Sphere
ST_Distance_Sphere() 函数返回球体上 Point 或 MultiPoint 参数之间的最小球面距离,以米为单位。语法如下:
ST_Distance_Sphere(g1, g2 [, radius])
可选的 radius 参数应以米为单位。如果 radius 参数存在但不是正数,则会发生报错 ER_NONPOSITIVE_RADIUS;如果距离超出双精度数的范围,则会发生报错 ER_STD_OVERFLOW_ERROR。
如果两个几何参数都是地理空间参考系统 (SRS) 中有效的 Point 或 MultiPoint 值,则返回值是球体上(半径为 radius)两个几何对象之间的最短距离。如果省略,则默认半径等于平均半径,定义为 (2a+b)/3,其中 a 是 SRS 的长半轴,b 是短半轴。
ST_Distance_Sphere() 支持的几何参数组合是 Point 和 Point, 或者 Point 和 MultiPoint(以任何参数顺序)。如果至少有一个几何对象既不是 Point 也不是 MultiPoint,并且其 SRID 为 0,则会发生报错 ER_NOT_IMPLEMENTED_FOR_CARTESIAN_SRS。如果至少有一个几何既不是 Point 或者 MultiPoint,并且其 SRID 指的是地理 SRS,则会发生报错 ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRS。如果任何几何图形引用投影的 SRS,则会发生报错 ER_NOT_IMPLEMENTED_FOR_PROJECTED_SRS。
示例如下:
SET @pt1 = ST_GeomFromText('POINT(0 0)');
Query OK, 0 rows affected (0.001 sec)
SET @pt2 = ST_GeomFromText('POINT(180 0)');
Query OK, 0 rows affected (0.001 sec)
SELECT ST_Distance_Sphere(@pt1, @pt2);
+--------------------------------+
| ST_Distance_Sphere(@pt1, @pt2) |
+--------------------------------+
| 20015042.813723423 |
+--------------------------------+
1 row in set (0.001 sec)
ST_IsValid
如果 ST_IsValid() 函数的参数几何有效,则返回 1;如果参数几何无效,则返回 0。几何有效性由 OGC 规范定义。语法如下:
ST_IsValid(g)
唯一有效的空几何对象以空几何对象集合值的形式表示。在这种情况下,ST_IsValid() 返回 1,不支持 GIS EMPTY 值,例如 POINT EMPTY。
SET @ls_test1 = ST_GeomFromText('LINESTRING(0 0,-0.00 0,0.0 0)');
Query OK, 0 rows affected (0.001 sec)
SET @ls_test2 = ST_GeomFromText('LINESTRING(0 0, 1 1)');
Query OK, 0 rows affected (0.001 sec)
SELECT ST_IsValid(@ls_test1);
+------------------+
| ST_IsValid(@ls1) |
+------------------+
| 0 |
+------------------+
1 row in set (0.001 sec)
SELECT ST_IsValid(@ls_test2);
+------------------+
| ST_IsValid(@ls2) |
+------------------+
| 1 |
+------------------+
1 row in set (0.001 sec)
ST_Within
ST_Within() 返回 1 或 0 以指示 g1 在空间上是否在 g2 内。与 ST_Contains() 具有相反的关系。语法如下:
ST_Within(g1, g2)
ST_Crosses
ST_Crosses 函数返回 1 或 0 以指示 g1 是否在空间上与 g2 交叉。如果 g1 和 g2 交叉,则返回 1;如果 g1 和 g2 不交叉,则返回 0。且 ST_Crosses 函数支持空间索引。
ST_Crosses(g1, g2) 和 ST_Intersects(g1, g2) 都是空间关系函数,用于判断两个几何对象在空间上的关系,但它们的定义和用途略有不同。
-
ST_Intersects(g1, g2)函数用于确定两个几何对象是否在空间上相交,意味着它们共享至少一个公共点(这包括边界和内部)。只要两个对象有任何重叠的部分,无论是点、线还是面,
ST_Intersects(g1, g2)都返回 1。 -
ST_Crosses(g1, g2)函数用于确定两个几何对象是否“交叉”,在几何学中有特定的定义:一个对象必须部分内部穿过另一个对象的内部。
具体来说,对于两个线几何对象,当它们在两个点以上相交并在内部相交时,ST_Crosses(g1, g2) 返回 1;对于线和面几何对象,当线穿过面的内部时,ST_Crosses(g1, g2) 返回 1。
与 ST_Intersects(g1, g2) 不同,ST_Crosses(g1, g2) 并不考虑两个对象的完全重叠或边界触摸情况。
ST_Intersects(g1, g2) 检测两个几何对象是否有任何类型的交集,而 ST_Crosses(g1, g2) 专门检测一个对象是否穿过另一个对象。例如,如果你想知道一条路是否穿过一块土地,使用 ST_Crosses(g1, g2);如果你需要找出所有覆盖或触及该土地的路线,则使用 ST_Intersects(g1, g2)。
语法如下:
ST_Crosses(g1,g2)
示例如下:
select st_crosses(st_geomfromtext('LINESTRING(1 1, 11 11)'), st_geomfromtext('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));
在这个示例中,ST_Crosses 判断一个线性几何对象(在这个例子中是从点 (1,1) 到点 (11,11) 的直线)是否穿过了一个多边形几何对象(这里是一个由点 (0,0), (0,10), (10,10), (10,0) 和 (0,0) 构成的正方形)。返回结果是 1,表示线穿过了多边形。
返回结果如下:
+------------------------------------------------------------------------------------------------------------------+
| st_crosses(st_geomfromtext('LINESTRING(1 1, 11 11)'), st_geomfromtext('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))')) |
+------------------------------------------------------------------------------------------------------------------+
| 1 |
+------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)
ST_Overlaps
ST_Overlaps(g1,g2) 函数返回 1 或 0 以确定两个几何对象 g1 和 g2 是否在空间上部分重叠,但并不完全互相包含。如果 g1 和 g2 重叠,则返回 1;如果 g1 和 g2 不重叠或者有一个完全包含另一个,则返回 0。且 ST_Overlaps(g1,g2) 函数支持空间索引。
对于两个线几何对象而言,当它们共享一段线段,但没有一条线完全包含另一条线,ST_Overlaps(g1,g2) 返回 1。
对于面几何对象(如多边形),当两个多边形至少部分地重叠,同时每个多边形都有一部分不与另一个重叠,ST_Overlaps(g1,g2) 返回 1。
语法如下:
ST_Overlaps(g1,g2)
示例如下:
SELECT ST_OVERLAPS(ST_GEOMFROMTEXT('POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2))'), ST_GEOMFROMTEXT('POLYGON((0 0,0 5,5 5,5 0,0 0))'));
在这个示例中,ST_Overlaps 函数判断两个多边形是否重叠。第一个多边形 POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2)) 是一个 10 ✖️ 10 的正方形,内部有一个 2✖️2 的洞(空间内的小正方形),而第二个多边形 POLYGON((0 0,0 5,5 5,5 0,0 0)) 是一个 5✖️5 的正方形,位于第一个多边形的左下角。第二个多边形与第一个多边形的内部区域重叠但又不被完全包含,那么 ST_Overlaps 函数返回 1。
返回结果如下:
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_OVERLAPS(ST_GEOMFROMTEXT('POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2))'), ST_GEOMFROMTEXT('POLYGON((0 0,0 5,5 5,5 0,0 0))')) |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)
_ST_Touches
_ST_Touches(geometry A, geometry B) 函数用来判断两个几何对象 A 和 B 边界是否至少有一 个共同点,且内部不相交。且 _ST_Touches(geometry A, geometry B) 函数支持空间索引。
这里需要注意的是,如果两个几何对象都是点 Point 类型,那么 _ST_Touches(geometry A, geometry B) 函数将返回 0。这是因为点几何对象没有边界,所以两个点不能被认为是“接触”的;它们要么是相同的(即位置完全一致),要么是完全独立的。
语法如下:
_ST_Touches(geometry A, geometry B)
示例如下:
SELECT _ST_Touches(st_geomfromtext('LINESTRING(0 0, 1 1, 0 2)'), st_geomfromtext('POINT(0 2)'));