跳到主要内容

空间运算函数

空间运算函数用于生成几何图形。seekdb 当前所支持的空间运算函数包括 ST_Buffer()ST_Buffer_Strategy()ST_Transform()ST_Difference()ST_Union()ST_SymDifference()_ST_ClipByBox2D()

ST_Buffer

ST_Buffer() 返回表示与几何值 g 的距离小于或等于距离 d 的所有点。结果与几何参数在相同的 SRS 中。语法如下:

ST_Buffer(g, d [, strategy1 [, strategy2 [, strategy3]]])

d 参数不能小于 0.1,否则报错。如果参数为空,则 ST_Buffer() 返回一个空值。如果距离为 0,则 ST_Buffer() 返回几何参数 g

示例如下:

SET @pt = ST_GeomFromText('POINT(1 1)');
Query OK, 0 rows affected (0.000 sec)

SELECT ST_AsText(ST_Buffer(@pt, 0));
+------------------------------+
| ST_AsText(ST_Buffer(@pt, 0)) |
+------------------------------+
| POINT(1 1) |
+------------------------------+
1 row in set (0.001 sec)

ST_Buffer() 允许在距离参数 d 之后最多有三个可选的 strategy 参数,策略会影响缓冲区计算。这些参数是 ST_Buffer_Strategy() 函数生成的字节字符串值,用于点、连接和结束策略:

  • 点策略适用于点和多点几何。如果未指定点策略,则默认为 ST_Buffer_Strategy('point_circle', 32)
  • 连接策略适用于 LineString、MultiLineString、Polygon 和 MultiPolygon。如果未指定连接策略,则默认为 ST_Buffer_Strategy('join_round', 32)
  • 结束策略适用于 LineString 和 MultiLineString。如果未指定结束策略,则默认为 ST_Buffer_Strategy('end_round', 32)

每种类型最多可以指定一个策略,并且没有顺序要求。

如果缓冲区策略无效,则会报错 ER_WRONG_ARGUMENTS。以下任何情况下策略均为无效:

  • 为给定类型指定了多种策略(点、连接或结束)。
  • 不是策略的值(例如任意二进制字符串或数字)作为 strategy 参数传递。
  • 传递了一个 Point 策略,并且几何不包含 PointMultiPoint 值。
  • 传递了结束或连接策略,并且不包含 LineStringPolygonMultiLinestringMultiPolygon 值。

示例如下:

SET @pt_strategy = ST_Buffer_Strategy('point_square');
Query OK, 0 rows affected (0.000 sec)

SELECT ST_AsText(ST_Buffer(@pt, 1, @pt_strategy));
+--------------------------------------------+
| ST_AsText(ST_Buffer(@pt, 1, @pt_strategy)) |
+--------------------------------------------+
| POLYGON((-1 -1,1 -1,1 1,-1 1,-1 -1)) |
+--------------------------------------------+
1 row in set (0.001 sec)

SET @ls = ST_GeomFromText('LINESTRING(0 0,0 5,5 5)');
Query OK, 0 rows affected (0.000 sec)

SET @end_strategy = ST_Buffer_Strategy('end_flat');
Query OK, 0 rows affected (0.000 sec)

SET @join_strategy = ST_Buffer_Strategy('join_round', 5);
Query OK, 0 rows affected (0.000 sec)

SELECT ST_AsText(ST_Buffer(@ls,3, @end_strategy, @join_strategy));
+------------------------------------------------------------------------------------+
| ST_AsText(ST_Buffer(@ls,3, @end_strategy, @join_strategy)) |
+------------------------------------------------------------------------------------+
| POLYGON((3 2,5 2,5 8,0 8,-2.1213203435596424 7.121320343559643,-3 5,-3 0,3 0,3 2)) |
+------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

ST_Buffer_Strategy

ST_Buffer_Strategy() 函数返回一个策略的字符串,用于 ST_Buffer() 的缓冲区计算。

ST_Buffer_Strategy(strategy [, points_per_circle])

第一个参数必须是指示策略选项的字符串:

  • 对于点策略,允许的值为 point_circlepoint_square
  • 对于连接策略,允许的值为 join_roundjoin_miter
  • 对于结束策略,允许的值为 end_roundend_flat

如果第一个参数是 point_circlejoin_roundjoin_miterend_round,则 points_per_circle 参数必须是正数值。points_per_circle 最大值是 max_points_in_geometry 系统变量的值。

ST_Buffer_Strategy() 的参数需要额外注意:

  • 如果任何参数无效,则会报错 ER_WRONG_ARGUMENTS
  • 如果第一个参数是 point_squareend_flat,则不能指定 points_per_circle 参数,否则会发生 ER_WRONG_ARGUMENTS 错误。

ST_Transform

ST_Transform() 函数用于将几何对象从一个空间参考系统 (SRS) 转换为另一个空间参考系统。返回值是与输入几何对象具有相同类型的几何对象,所有坐标都转换为目标 SRID,即 target_srid。该函数的转换支持仅限于地理 SRS,只有当几何参数的 SRID 与目标 SRID 值相同时,会直接将带有效 SRID 的输入对象返回。

ST_Transform() 的参数需注意以下事项:

  • 具有地理 SRS 的 SRID 值的几何参数不会产生错误。
  • 如果几何或目标 SRID 参数具有引用未定义空间参考系统 (SRS) 的 SRID 值,则会报错 ER_SRS_NOT_FOUND
  • 如果几何对象位于 ST_Transform() 无法转换的 SRS 中,则会报错ER_TRANSFORM_SOURCE_SRS_NOT_SUPPORTED
  • 如果目标 SRID 位于 ST_Transform() 无法转换到的 SRS 中,则会报错 ER_TRANSFORM_TARGET_SRS_NOT_SUPPORTED
  • 如果几何对象位于非 WGS 84 且没有 TOWGS84 子句的 SRS 中,则会报错 ER_TRANSFORM_SOURCE_SRS_MISSING_TOWGS84
  • 如果目标 SRID 位于非 WGS 84 且没有 TOWGS84 子句的 SRS 中,则会报错 ER_TRANSFORM_TARGET_SRS_MISSING_TOWGS84

ST_SRID(g, target_srid)ST_Transform(g, target_srid) 的区别如下:

  • ST_SRID() 更改几何 SRID 值而不转换其坐标。
  • ST_Transform() 除了更改其 SRID 值外,还转换几何坐标。

示例如下:

SET @pt = ST_GeomFromText('POINT(52.381389 13.064444)', 4326);
Query OK, 0 rows affected (0.000 sec)

SELECT ST_AsText(@pt);
+----------------------------+
| ST_AsText(@pt) |
+----------------------------+
| POINT(52.381389 13.064444) |
+----------------------------+
1 row in set (0.001 sec)

SET @pt = ST_Transform(@pt, 4230);
Query OK, 0 rows affected (0.000 sec)

SELECT ST_AsText(@pt);
+---------------------------------------------+
| ST_AsText(@pt) |
+---------------------------------------------+
| POINT(52.38208611407426 13.065520672345304) |
+---------------------------------------------+
1 row in set (0.001 sec)

ST_Difference

ST_Difference(g1, g2) 函数用于从一个几何对象 g1 中减去与另一个几何对象 g2 相交的部分,等价于 A - ST_Intersection(A, B)。它返回的是几何对象 g1 中不与几何对象 g2 相交的部分。

使用限制:

  • 几何对象 g1g2 必须在同一坐标空间中。
  • g1g2 应当是有效的几何对象。
  • 如果 g1g2 不相交,则 ST_Difference(g1, g2) 返回的将是 g1 的一个完整副本。
  • 如果 g1 完全包含于 g2 中,则 ST_Difference(g1, g2) 返回的将是一个空几何对象。

语法如下:

ST_Difference(geometry g1, geometry g2)

示例如下:

SELECT ST_AsText(ST_Difference(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)')));

在这个示例中,ST_Difference 函数用来计算两个线性几何对象的差集。在这个例子中,第一个 LineString 从点 (50 100) 到点 (50 200),第二个 LineString 从点 (50 50) 到点 (50 150)。这两个线段有一段重叠区域,从点 (50 100) 到点 (50 150)。

当第二个线段从第一个线段中减去后,剩下的是从点 (50 150) 到点 (50 200) 的线段。这是因为这部分线段只存在于第一个 LineString 中,而不在第二个 LineString 中。查询结果使用 ST_AsText 函数转换为了 WKT 格式的字符串。

返回结果如下:

+----------------------------------------------------------------------------------------------------------------------+
| ST_AsText(ST_Difference(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)'))) |
+----------------------------------------------------------------------------------------------------------------------+
| LINESTRING(50 150,50 200) |
+----------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

ST_Union

ST_Union(g1, g2) 函数用于合并两个几何对象 g1g2 的空间内容,并返回这两个几何对象的并集。并集是所有属于 g1g2 或同时属于两者的点的集合。

ST_Union 函数将创建一个新的几何对象,这个对象包括 g1g2 中的所有点。如果 g1g2 是相交的或相邻的多边形,结果将是一个合并后的多边形;如果它们是线或点集,结果将包括所有的线和点。

使用限制:

  • g1g2 必须在相同的坐标空间中。
  • g1g2 必须是有效的几何对象,即它们没有自相交或其他非法几何结构。
  • 如果 g1g2 是不连续的几何对象,那么结果将是一个多几何对象(MultiGeometry),例如 MULTIPOLYGONMULTILINESTRING

语法如下:

ST_Union(geometry g1, geometry g2)

示例如下:

SELECT ST_AsText(ST_Union(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)')));

在这个示例中,ST_Union 函数用来计算两条线性几何对象的并集。第一个 LineString 从点 (50 100) 到点 (50 200),第二个 LineString 从点 (50 50) 到点 (50 150)。这两个线段有一段重叠区域,从点 (50 100) 到点 (50 150)。

ST_Union 函数合并这两个线段,并返回一个 MULTILINESTRING 几何对象,该对象包含两条不重叠的线段:一条线段从 (50 100) 到 (50 200),另一条线段从 (50 50) 到 (50 100)。这两条线段共同构成了原始线段覆盖的空间范围。查询结果使用 ST_AsText 函数转换为了 WKT 格式的字符串。

返回结果如下:

+-----------------------------------------------------------------------------------------------------------------+
| ST_AsText(ST_Union(ST_GeomFromText('LINESTRING(50 100, 50 200)'),ST_GeomFromText('LINESTRING(50 50, 50 150)'))) |
+-----------------------------------------------------------------------------------------------------------------+
| MULTILINESTRING((50 100,50 200),(50 50,50 100)) |
+-----------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

ST_SymDifference

ST_SymDifference 函数表示对称差集(Symmetric Difference),用于返回两个几何对象 geomAgeomB 中不重叠的部分。对称差集是指那些属于 geomAgeomB 但不属于它们交集的所有点的集合。

这个函数的结果相当于首先计算 geomAgeomB 的并集(ST_Union(geomA, geomB)),然后从并集中减去它们的交集(ST_Intersection(geomA, geomB)),即 ST_Difference(ST_Union(geomA, geomB), ST_Intersection(geomA, geomB))

使用限制:

  • geomAgeomB 应使用相同的坐标参考系统(CRS)。
  • geomAgeomB 必须是有效的几何对象,无自相交或其他拓扑错误。

对称差集可能产生不同于原始几何类型的结果。例如,两个交叠的多边形的对称差集可能是两个分离的多边形,或者是一个多多边形(MULTIPOLYGON)。

如果 geomAgeomB 之间没有重叠(即交集为空),对称差集相当于它们的简单组合。

如果 geomAgeomB 完全相同,则对称差集将是一个空几何对象。

语法如下:

ST_SymDifference(geometry geomA, geometry geomB)

示例如下:

SET @g1 = ST_GeomFromText('MULTIPOINT(5 0,15 10,15 25)');
Query OK, 0 rows affected (0.001 sec)

SET @g2 = ST_GeomFromText('MULTIPOINT(1 1,15 10,15 25)');
Query OK, 0 rows affected (0.001 sec)

SELECT ST_AsText(ST_SymDifference(@g1, @g2));

在这里示例中,首先使用 ST_GeomFromText 函数创建了两个 MULTIPOINT 类型的几何对象,并将它们存储在变量 @g1@g2 中。这两个几何对象分别是 MULTIPOINT(5 0,15 10,15 25)MULTIPOINT(1 1,15 10,15 25)

然后,通过 ST_SymDifference 函数计算 @g1@g2 的对称差集,这意味着找出两个 MULTIPOINT 几何对象中不共享的点。在这个例子中,点 (15 10) 和 (15 25) 是共享的,因此它们不包含在对称差集中。

最后,ST_AsText 函数被用来将几何对象转换成 WKT 格式。查询的结果是 MULTIPOINT((1 1),(5 0)),它表明 @g1@g2 之间唯一的差异在于点 (1 1) 和 (5 0),而这正是它们不共享的点。

返回结果如下:

+---------------------------------------+
| ST_AsText(ST_SymDifference(@g1, @g2)) |
+---------------------------------------+
| MULTIPOINT((1 1),(5 0)) |
+---------------------------------------+
1 row in set (0.001 sec)

_ST_ClipByBox2D

_ST_ClipByBox2D 函数用于几何剪裁。该函数将输入的几何对象 geom 与一个二维边界框(box2d)box 相交,并返回交集部分作为新的几何对象。这个操作类似于使用一把“剪刀”沿着边界框剪裁几何对象。

由于 _ST_ClipByBox2D 是一个快速剪裁函数,它的设计目的是提供高性能的剪裁操作,但这也带来了一些限制和注意事项:

使用限制:

该函数不会检查输入几何体 geom 的合法性,因此如果输入的几何对象本身就是无效的,输出的结果也可能是无效的。 同样,该函数也不保证输出的几何体是合法的,所以输出的几何对象可能需要进一步的处理才能确保其合法性。 由于是快速剪裁,可能不适用于需要精确剪裁或者剪裁结果必须是合法几何体的场景。

语法如下:

_ST_ClipByBox2D(geometry geom, box2d box);

参数解释:

  • geom:要被剪裁的原始几何对象。
  • box:用于剪裁的二维边界框。尽管参数名为 box2d,实际上可以接受任意几何对象,函数将把它转换为对应的边界框。

示例如下:

SELECT ST_ASTEXT(_ST_ClipByBox2D(ST_GEOMFROMTEXT('POLYGON((-2 -2, -2 11, 11 11, 11 -2, -2 -2))'), _ST_MakeEnvelope(0,0,10,10)));

在这个示例中,首先使用 ST_GeomFromText 创建了一个多边形几何对象,这个多边形有四个边,分别从 (-2 -2) 到 (-2 11),再到 (11 11),然后到 (11 -2),并闭合于 (-2 -2)。

然后使用 _ST_MakeEnvelope 创建了一个边界框,这个边界框在坐标 (0, 0) 和 (10, 10) 之间定义了一个矩形。

接着 _ST_ClipByBox2D 函数使用创建的边界框对多边形进行剪裁,只保留多边形与边界框相交的部分。

最后,ST_AsText 函数将剪裁后的多边形转换成了 WKT 格式的字符串。查询的结果显示剪裁后的多边形也是一个矩形,它的边与边界框重合,即为左下角在 (0, 0)、右上角在 (10, 10) 的矩形。

返回结果如下:

+--------------------------------------------------------------------------------------------------------------------------+
| ST_ASTEXT(_ST_ClipByBox2D(ST_GEOMFROMTEXT('POLYGON((-2 -2, -2 11, 11 11, 11 -2, -2 -2))'), _ST_MakeEnvelope(0,0,10,10))) |
+--------------------------------------------------------------------------------------------------------------------------+
| POLYGON((0 0,0 10,10 10,10 0,0 0)) |
+--------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)