MariaDB CONTAINS() 函数的基础用法与实例

MariaDB CONTAINS() 函数是一个空间函数,用于判断一个几何对象是否包含另一个几何对象。

发布于

MariaDB CONTAINS() 函数是一个空间函数,用于判断一个几何对象是否包含另一个几何对象。如果包含,返回 1,否则返回 0。该函数遵循 OGC 标准,只适用于平面坐标系。

语法

MariaDB CONTAINS() 函数的语法如下:

CONTAINS(g1, g2)

其中,g1g2 都是几何对象。g1 是外部对象,g2 是内部对象。如果 g1 包含 g2,则返回 1,否则返回 0

实例

Example 1: 点和多边形

假设我们有一个表 points,存储了一些点的坐标,如下:

CREATE TABLE points (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  location POINT
);

INSERT INTO points VALUES
(1, 'A', ST_GeomFromText('POINT(1 1)')),
(2, 'B', ST_GeomFromText('POINT(2 2)')),
(3, 'C', ST_GeomFromText('POINT(3 3)')),
(4, 'D', ST_GeomFromText('POINT(4 4)')),
(5, 'E', ST_GeomFromText('POINT(5 5)'));

我们还有一个多边形 polygon,定义如下:

SET @polygon = ST_GeomFromText('POLYGON((0 0, 0 6, 6 6, 6 0, 0 0))');

我们可以使用 CONTAINS() 函数来判断哪些点在多边形内,哪些点在多边形外,如下:

SELECT id, name, ST_AsText(location) AS location,
       CONTAINS(@polygon, location) AS is_inside
FROM points;

输出结果如下:

+----+------+------------+----------+
| id | name | location   | is_inside|
+----+------+------------+----------+
|  1 | A    | POINT(1 1) |        1 |
|  2 | B    | POINT(2 2) |        1 |
|  3 | C    | POINT(3 3) |        1 |
|  4 | D    | POINT(4 4) |        1 |
|  5 | E    | POINT(5 5) |        0 |
+----+------+------------+----------+

从结果可以看出,点 ABCD 都在多边形内,而点 E 在多边形外。

Example 2: 线和多边形

假设我们有一个表 lines,存储了一些线段的坐标,如下:

CREATE TABLE lines (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  location LINESTRING
);

INSERT INTO lines VALUES
(1, 'L1', ST_GeomFromText('LINESTRING(1 1, 5 5)')),
(2, 'L2', ST_GeomFromText('LINESTRING(2 2, 4 4)')),
(3, 'L3', ST_GeomFromText('LINESTRING(3 3, 7 7)')),
(4, 'L4', ST_GeomFromText('LINESTRING(4 4, 8 8)')),
(5, 'L5', ST_GeomFromText('LINESTRING(5 5, 9 9)'));

我们还使用同样的多边形 polygon,定义如下:

SET @polygon = ST_GeomFromText('POLYGON((0 0, 0 6, 6 6, 6 0, 0 0))');

我们可以使用 CONTAINS() 函数来判断哪些线段完全在多边形内,哪些线段部分或完全在多边形外,如下:

SELECT id, name, ST_AsText(location) AS location,
       CONTAINS(@polygon, location) AS is_inside
FROM lines;

输出结果如下:

+----+------+---------------------+----------+
| id | name | location            | is_inside|
+----+------+---------------------+----------+
|  1 | L1   | LINESTRING(1 1,5 5) |        1 |
|  2 | L2   | LINESTRING(2 2,4 4) |        1 |
|  3 | L3   | LINESTRING(3 3,7 7) |        0 |
|  4 | L4   | LINESTRING(4 4,8 8) |        0 |
|  5 | L5   | LINESTRING(5 5,9 9) |        0 |
+----+------+---------------------+----------+

从结果可以看出,线段 L1L2 都完全在多边形内,而线段 L3L4L5 都部分或完全在多边形外。

Example 3: 多边形和多边形

假设我们有一个表 polygons,存储了一些多边形的坐标,如下:

CREATE TABLE polygons (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  location POLYGON
);

INSERT INTO polygons VALUES
(1, 'P1', ST_GeomFromText('POLYGON((1 1, 1 5, 5 5, 5 1, 1 1))')),
(2, 'P2', ST_GeomFromText('POLYGON((2 2, 2 4, 4 4, 4 2, 2 2))')),
(3, 'P3', ST_GeomFromText('POLYGON((3 3, 3 7, 7 7, 7 3, 3 3))')),
(4, 'P4', ST_GeomFromText('POLYGON((4 4, 4 6, 6 6, 6 4, 4 4))')),
(5, 'P5', ST_GeomFromText('POLYGON((5 5, 5 9, 9 9, 9 5, 5 5))'));

我们还使用同样的多边形 polygon,定义如下:

SET @polygon = ST_GeomFromText('POLYGON((0 0, 0 6, 6 6, 6 0, 0 0))');

我们可以使用 CONTAINS() 函数来判断哪些多边形完全在多边形内,哪些多边形部分或完全在多边形外,如下:

SELECT id, name, ST_AsText(location) AS location,
       CONTAINS(@polygon, location) AS is_inside
FROM polygons;

输出结果如下:

+----+------+------------------------------------+----------+
| id | name | location                           | is_inside|
+----+------+------------------------------------+----------+
|  1 | P1   | POLYGON((1 1,1 5,5 5,5 1,1 1))     |        1 |
|  2 | P2   | POLYGON((2 2,2 4,4 4,4 2,2 2))     |        1 |
|  3 | P3   | POLYGON((3 3,3 7,7 7,7 3,3 3))     |        0 |
|  4 | P4   | POLYGON((4 4,4 6,6 6,6 4,4 4))     |        0 |
|  5 | P5   | POLYGON((5 5,5 9,9 9,9 5,5 5))     |        0 |
+----+------+------------------------------------+----------+

从结果可以看出,多边形 P1P2 都完全在多边形内,而多边形 P3P4P5 都部分或完全在多边形外。

Example 4: 点和圆

假设我们有一个表 points,存储了一些点的坐标,如下:

CREATE TABLE points (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  location POINT
);

INSERT INTO points VALUES
(1, 'A', ST_GeomFromText('POINT(1 1)')),
(2, 'B', ST_GeomFromText('POINT(2 2)')),
(3, 'C', ST_GeomFromText('POINT(3 3)')),
(4, 'D', ST_GeomFromText('POINT(4 4)')),
(5, 'E', ST_GeomFromText('POINT(5 5)'));

我们还有一个圆 circle,定义如下:

SET @circle = ST_Buffer(ST_GeomFromText('POINT(3 3)'), 2);

这个圆的中心是 (3, 3),半径是 2。我们可以使用 CONTAINS() 函数来判断哪些点在圆内,哪些点在圆外,如下:

SELECT id, name, ST_AsText(location) AS location,
       CONTAINS(@circle, location) AS is_inside
FROM points;

输出结果如下:

+----+------+------------+----------+
| id | name | location   | is_inside|
+----+------+------------+----------+
|  1 | A    | POINT(1 1) |        0 |
|  2 | B    | POINT(2 2) |        1 |
|  3 | C    | POINT(3 3) |        1 |
|  4 | D    | POINT(4 4) |        1 |
|  5 | E    | POINT(5 5) |        0 |
+----+------+------------+----------+

从结果可以看出,点 BCD 都在圆内,而点 AE 在圆外。

Example 5: 多边形和圆

假设我们有一个表 polygons,存储了一些多边形的坐标,如下:

CREATE TABLE polygons (
  id INT PRIMARY KEY,
  name VARCHAR(20),
  location POLYGON
);

INSERT INTO polygons VALUES
(1, 'P1', ST_GeomFromText('POLYGON((1 1, 1 5, 5 5, 5 1, 1 1))')),
(2, 'P2', ST_GeomFromText('POLYGON((2 2, 2 4, 4 4, 4 2, 2 2))')),
(3, 'P3', ST_GeomFromText('POLYGON((3 3, 3 7, 7 7, 7 3, 3 3))')),
(4, 'P4', ST_GeomFromText('POLYGON((4 4, 4 6, 6 6, 6 4, 4 4))')),
(5, 'P5', ST_GeomFromText('POLYGON((5 5, 5 9, 9 9, 9 5, 5 5))'));

我们还使用同样的圆 circle,定义如下:

SET @circle = ST_Buffer(ST_GeomFromText('POINT(3 3)'), 2);

我们可以使用 CONTAINS() 函数来判断哪些多边形完全在圆内,哪些多边形部分或完全在圆外,如下:

SELECT id, name, ST_AsText(location) AS location,
       CONTAINS(@circle, location) AS is_inside
FROM polygons;

输出结果如下:

+----+------+------------------------------------+-----------+
| id | name | location                           | is_inside |
+----+------+------------------------------------+-----------+
|  1 | P1   | POLYGON((1 1,1 5,5 5,5 1,1 1))     |         0 |
|  2 | P2   | POLYGON((2 2,2 4,4 4,4 2,2 2))     |         1 |
|  3 | P3   | POLYGON((3 3,3 7,7 7,7 3,3 3))     |         0 |
|  4 | P4   | POLYGON((4 4,4 6,6 6,6 4,4 4))     |         0 |
|  5 | P5   | POLYGON((5 5,5 9,9 9,9 5,5 5))     |         0 |
+----+------+------------------------------------+-----------+

从结果可以看出,多边形 P2 完全在圆内,而多边形 P1P3P4P5 都部分或完全在圆外。

相关函数

除了 CONTAINS() 函数,MariaDB 还提供了一些其他的空间函数,用于判断几何对象之间的空间关系,如下:

  • ST_Contains(g1, g2):与 CONTAINS(g1, g2) 等价,遵循 OGC 标准,只适用于平面坐标系。
  • MBRContains(g1, g2):判断 g1 的最小边界矩形是否包含 g2 的最小边界矩形,适用于球面坐标系。
  • ST_Within(g1, g2):判断 g1 是否在 g2 内,相当于 CONTAINS(g2, g1),遵循 OGC 标准,只适用于平面坐标系。
  • MBRWithin(g1, g2):判断 g1 的最小边界矩形是否在 g2 的最小边界矩形内,适用于球面坐标系。
  • ST_Intersects(g1, g2):判断 g1g2 是否相交,即是否有公共点,遵循 OGC 标准,只适用于平面坐标系。
  • MBRIntersects(g1, g2):判断 g1g2 的最小边界矩形是否相交,适用于球面坐标系。

例如,我们可以使用 ST_Intersects() 函数来判断哪些多边形与圆相交,如下:

SELECT id, name, ST_AsText(location) AS location,
       ST_Intersects(@circle, location) AS is_intersect
FROM polygons;

输出结果如下:

+----+------+------------------------------------+-------------+
| id | name | location                           | is_intersect|
+----+------+------------------------------------+-------------+
|  1 | P1   | POLYGON((1 1,1 5,5 5,5 1,1 1))     |           1 |
|  2 | P2   | POLYGON((2 2,2 4,4 4,4 2,2 2))     |           1 |
|  3 | P3   | POLYGON((3 3,3 7,7 7,7 3,3 3))     |           1 |
|  4 | P4   | POLYGON((4 4,4 6,6 6,6 4,4 4))     |           1 |
|  5 | P5   | POLYGON((5 5,5 9,9 9,9 5,5 5))     |           0 |
+----+------+------------------------------------+-------------+

从结果可以看出,多边形 P1P2P3P4 都与圆相交,而多边形 P5 与圆不相交。

结论

本文介绍了 MariaDB CONTAINS() 函数的基础用法与实例,该函数用于判断一个几何对象是否包含另一个几何对象。我们还介绍了一些与该函数相关的空间函数,用于判断几何对象之间的其他空间关系。