PostGIS之几何有效性

postgis,几何,有效性 · 浏览次数 : 169

小编点评

**PostGIS 中的几何有效性** PostGIS 是一个空间数据库扩展,它允许在 SQL 中运行空间查询地理对象。几何有效性是指一个几何图形是否满足几何有效性规则。 **数据准备** 在使用 PostGIS 中的几何有效性功能之前,您需要将空间数据加载到数据库中。您可以使用以下两种方法加载数据: * **`ST_GeometryFromText()` 函数**:您可以使用 `ST_GeometryFromText()` 函数将字符串表示的几何图形转换为 PostGIS 格式。 * **`ST_AsText()` 函数**:您可以使用 `ST_AsText()` 函数将 PostGIS 格式的几何图形转换为字符串表示。 **有效性检测** PostGIS 提供以下幾何有效性检测函数: * `ST_IsValid()`:该函数检查一个几何图形是否有效。 * `ST_IsValidReason()`:该函数返回有效性检测结果的详细原因。 * `ST_AsText()`:该函数返回一个有效性检测结果的字符串表示。 **修复无效几何图形** PostGIS 提供以下函数可以修复无效几何图形: * `ST_MakeValid()`:该函数尝试将无效的几何图形修复为有效图形。 * `ST_AsText()`:该函数将修复后的图形转换为字符串表示。 **参考资料** * [1] PostGIS 官方教程:PostGIS 简介 — Introduction to PostGIS * [2] Introduction to PostGIS | PostGISPostGIS官方教程:PostGIS 简介 * [3] PostGIS 15:几何图形的有效性 — 知乎 * [4] PostGIS Cheat Sheet。归纳总结以上内容

正文

1. 概述

PostGIS 是PostgreSQL数据库一个空间数据库扩展,它添加了对地理对象的支持,允许在 SQL 中运行空间查询

PostGIS官网:About PostGIS | PostGIS

PostGIS官方教程:PostGIS 简介 — Introduction to PostGIS

PostGIS相关教程:文章目录汇总 - 知乎 (zhihu.com)

本文基于官方教程描述PostGIS中的几何有效性

数据准备可参考:

数据介绍可参考:

2. 几何有效性

2.1 几何有效性的定义

几何图形可能是无效的,比如下面这种:

SELECT ST_GeometryFromText(
         'POLYGON((0 0, 0 1, 1 1, 2 1, 2 2, 1 2, 1 1, 1 0, 0 0))'
);

image-20230105171550106

这种几何图形能显示,但是查询其面积,面积为0:

image-20230105171656055

这显然是不合理的,因为这个几何图形是无效的,它存在自相交,对于无效的几何图形,PostGIS将无法正确进行运算

PostGIS所遵循的OGC SFSQL标准所定义的多边形有效性的规则有:

  • 多边形的环必须闭合
  • 内环必须位于外环的内部
  • 环不能自相交(它们不能相互接触,也不能交叉)
  • 除了在某个点接触,环不能与其他环接触

2.2 检测有效性

PostGIS提供了几何有效性检测函数:

  • ST_IsValid(g) Tests if a geometry is well-formed in 2D
  • ST_IsValidDetail (geom, flags) Returns a valid_detail row stating if a geometry is valid or if not a reason and a location
  • ST_IsValidReason(geomA) Returns text stating if a geometry is valid, or a reason for invalidity

检测是否有效:

SELECT ST_IsValid(ST_GeometryFromText(
         'POLYGON((0 0, 0 1, 1 1, 2 1, 2 2, 1 2, 1 1, 1 0, 0 0))'
));

结果为:false

检测无效原因:

SELECT ST_IsValidReason(ST_GeometryFromText(
         'POLYGON((0 0, 0 1, 1 1, 2 1, 2 2, 1 2, 1 1, 1 0, 0 0))'
));

image-20230105172632405

可以看到(1,1)点自相交

检测纽约社区表的有效性:

SELECT name, ST_IsValidReason(geom)
FROM nyc_neighborhoods
WHERE NOT ST_IsValid(geom);

image-20230105173021776

2.3 修复无效几何图形

PostGIS提供了自动修复函数:

  • ST_MakeValid(input) Attempts to make an invalid geometry valid without losing vertices

尝试修复无效上面提到的无效图形:

SELECT ST_AsText(ST_MakeValid(ST_GeometryFromText(
         'POLYGON((0 0, 0 1, 1 1, 2 1, 2 2, 1 2, 1 1, 1 0, 0 0))'
)));

image-20230105173602749

可以看到PostGIS将这个无效的几何图形拆为了两个Polygon并合成了一个MultiPolygon

尝试修复纽约社区表中无效的图形:

SELECT name, ST_AsText(ST_MakeValid(geom))
FROM nyc_neighborhoods
WHERE NOT ST_IsValid(geom);

image-20230105174019486

使用ST_Buffer(geometry, 0.0)也有时也可达到修复的效果:

image-20230105174208895

自动修复函数有时并不能起作用,需要手动将无效的几何图形导入临时表,然后使用GIS软件进行修改:

-- Side table of invalids
CREATE TABLE nyc_neighborhoods_invalid AS
SELECT * FROM nyc_neighborhoods
WHERE NOT ST_IsValid(geom);
 
-- Remove them from the main table
DELETE FROM nyc_neighborhoods
WHERE NOT ST_IsValid(geom);

3. 参考资料

[1]23. Validity — Introduction to PostGIS

[2]PostGIS教程十五:几何图形的有效性 - 知乎 (zhihu.com)

[3]PostGIS 3.3.3dev Manual

[4]PostGIS Cheat Sheet

与PostGIS之几何有效性相似的内容: