PostGIS学习教程十五:几何图形的有效性

PostGIS学习教程十五:几何图形的有效性

在90%的情况下,“为什么我的查询给了我一个’TopologyException’错误"的问题的答案是"一个或多个输入的几何图形是无效的”,这就引出了这样一个问题:几何图形"无效"是什么意思?我们为什么要关注它?


文章目录

  • PostGIS学习教程十五:几何图形的有效性
  • 一、什么是有效性?
  • 二、检测有效性
  • 三、修复无效的图形
    • 3.1、ST_MakeValid函数
    • 3.2、ST_Buffer


一、什么是有效性?

对于多边形来说,有效性是最重要的,因为多边形定义了有界区域,需要很好的结构。线串非常简单,不会无效,点也不会无效。

多边形有效性的一些规则很明显,而另一些规则是任意的。

多边形的环必须闭合
内环必须位于外环的内部
环不能自相交(它们不能相互接触,也不能交叉)
除了在某个点接触,环不能与其他环接触
最后两条规则属于任意类别。定义多边形的其他规则也是自洽合理的,但是上面的规则是PostGIS所遵循的OGC SFSQL标准所定义的多边形有效性的规则。

规则之所以重要,是因为几何图形的计算依赖于输入的几何图形的结构。可以构建没有结构假设的算法,但这些程序往往非常慢,因为任何无结构程序的第一步都是分析输入并在其中构建结构。

这里有一个解释为什么几何图形的结构重要的例子。首先这个多边形是无效的:

POLYGON((0 0, 0 1, 2 1, 2 2, 1 2, 1 0, 0 0));

在此图中,你可以更清楚地看到无效的原因:
在这里插入图片描述
这个多边形的外环实际上是一个数字8的形状,中间有一个自交点(也就是这个多边形的环自相交了)。图形程序成功地渲染了多边形填充,使其在视觉上看起来是一个"区域":两个一个单位的正方形,因此多边形总面积为两个单位的面积。

让我们看看PostGIS数据库认为多边形的面积是多少:

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

在这里插入图片描述
这里发生了什么?计算面积的算法假设环不自相交。程序始终计算位于边界线的一侧的区域的面积。

然而,在我们的(表现不佳)的形似数字8的多边形中,对于其中一个部分,图形区域位于边界线的右侧,而对于另一个部分,图形区域在边界线的左侧。这将导致为每个部分计算的面积互相抵消(一个为1,另一个为-1),因此结果为"0面积"。

二、检测有效性

在前面的示例中,我们可以轻易发现一个多边形是无效的。然而我们如何在一个包含数百万个几何图形的表中检测无效?答案是使用ST_IsValid(geometry)函数:

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

在这里插入图片描述
现在我们知道这个图形是无效的,但是我们不知道为什么无效。我们可以使用ST_IsValidReason(geometry)函数来查找无效的原因:

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

在这里插入图片描述
请注意,除了原因(自相交),图形自相交的坐标(coordinate(1 1))也被返回了。

我们也可以使用ST_IsValid(geometry)函数来测试数据表:

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

在这里插入图片描述

三、修复无效的图形

首先,坏消息是:没有100%确定的方法来修复无效的几何图形。最坏的情况是使用ST_IsValid(geometry)函数识别它们,然后将单独它们移动到另一张表,导出该表,然后在外部(比如说桌面端GIS软件)修复它们。

下面是SQL的一个示例,它将无效的几何图形从原表转移到另一张表中。

CREATE TABLE nyc_neighborhoods_invalid AS
SELECT * FROM nyc_neighborhoods
WHERE NOT ST_IsValid(geom);
 
DELETE FROM nyc_neighborhoods
WHERE NOT ST_IsValid(geom);

在这里插入图片描述
在视觉上修复无效几何图形的一个好工具是OpenJump,它在Tools->QA->Validate Selected Layers.下包含一个验证程序。

现在好消息是:可以使用以下任何一种方法在数据库中修复很大一部分的缺陷:

ST_MakeValid函数
ST_Buffer函数

3.1、ST_MakeValid函数

ST_MakeValid函数尝试在不对输入几何图形进行更改的情况下修复缺陷。不会删除或移动任何顶点,只需重新排列对象的结构即可。对于清晰但无效的数据来说,这个函数非常适用,对于杂乱无章且无效的数据来说,这个函数可能并不适用。

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

在这里插入图片描述
ST_MakeValid函数成功地将几何图形"8"转换为表示相同面积的multi-polygon。

3.2、ST_Buffer

使用缓冲区技巧清理时,可以利用缓冲区的生成方式来达到修复几何图形的目的:缓冲区几何图形是全新的几何图形,由关于原始图形的偏移线构建。如果不偏移原始线(零),则新几何图形在结构上将与原始几何图形相同,但由于它是使用OGC拓扑规则构建的,因此它将是有效的。

例如,这里有一个典型的无效现象——“香蕉多边形” —— 一个环,它包围着一个区域,但弯曲着接触自己,留下一个"孔洞(hole)",实际上并不是一个孔洞(违背了上面所说的环不能自相交的规则)。

POLYGON((0 0, 2 0, 1 1, 2 2, 3 1, 2 0, 4 0, 4 4, 0 4, 0 0))

在这里插入图片描述
在多边形上计算零偏移缓冲区将返回有效的OGC多边形,该多边形由在一点接触的外环和内环组成。

SELECT ST_AsText(
         ST_Buffer(
           ST_GeometryFromText('POLYGON((0 0, 2 0, 1 1, 2 2, 3 1, 2 0, 4 0, 4 4, 0 4, 0 0))'),
           0.0
         )
);

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/272502.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

JAVA复习三——CH5 Java Collection 、CH6 MultiThread

CH5 Java Collection(集合) 5.1 Java集合框架(位于java.util包中) 图一 集合框架图 从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集…

pytest分布式执行插件 pytest-xdist 的高级用法

想要使用多个CPU核心来进行测试,可以使用 -n 参数( 或者 --numprocesses) (使用8个核心来跑测试用例) 1 pytest -n 8 使用 -n auto 参数可以利用电脑的所有核心来跑测试用例 测试时使用的算法可以根据--dist命令参数定制: --dist load(默认选项)&…

手拉手Springboot整合JWT

环境介绍 技术栈 springbootmybatis-plusmysqljava-jwt 软件 版本 mysql 8 IDEA IntelliJ IDEA 2022.2.1 JDK 1.8 Spring Boot 2.7.13 mybatis-plus 3.5.3.2 Json Web令牌简称JWT Token是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。…

【多省市译协盖章】2023年第九届中西部外语翻译大赛

“由中西部翻译协会共同体指导发起,各省市译协共建学术指导委员会,2023年第九届中西部外语翻译大赛由中西部翻译协会共同体秘书处(武汉公仪网络科技有限公司)承办。” (证书样图) 证书盖章单位&#xff1…

文件重命名:特殊符号影响你找文件吗?来看看这个解决方法

在日常生活和工作中,电脑已经成为必不可少的工具,而文件管理也是一项重要的任务。有时候遇到文件重命名的问题,例如当文件名中包含特殊符号时,这可能会给工作带来很大的困扰。当尝试寻找一个文件时,却发现因为文件名中…

Linux的账号及权限管理

一.管理用户账号 1.1 用户账户的分类 1.1.1 用户账号的分类 超级用户:(拥有至高无上的权利) root用户是Linux操作系统中默认的超级用户账号,对本主机拥有最高的权限,系统中超级用户是唯一的。普通用户: …

c++学习笔记(6)-类型转换

1、概念 C类型转换是将一种数据类型转换为另一种数据类型的过程。 2、分类 C中的类型转换可以从3个角度来划分: 根据类型转换是由程序员显式指定,还是由编译器自动完成,分为显式类型转换和隐式类型转换;根据参与类型转换的变量…

智能优化算法应用:基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于减法平均算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.减法平均算法4.实验参数设定5.算法结果6.…

测试用例要如何写

​ 📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:欢迎加入我们一起学习!📢资源分享:耗时200小时精选的「软件测试…

IDEA基本设置

本博客适用于纯新手小白,或者刚下载IDEA想要优化开发添加配置的读者。 基础设置 不区分大小写代码补全 打开 IntelliJ IDEA。转到 “File”(文件) > “Settings”(设置)(Windows/Linux)或 “…

swagger1.2 apiPost工具测试接口没有问题,换成swagger 接口调测时报错 Required request body is missing

把 请求方法由get换成post GetMapping换成 PostMapping 原因apiPost自动把请求json参数封装到请求体里了, 但swagger没有封装,通过networker可以看到载荷里并没有任何东西

(C++)DS哈希查找—二次探测再散列(附思路和详细注释)

Description 定义哈希函数为H(key) key%11。输入表长(大于、等于11),输入关键字集合,用二次探测再散列构建哈希表,并查找给定关键字。 Input 测试数据组数 1≤�≤50. 每组测试数据格式如下&#xff1a…

面试题:Zabbix 和 Prometheus 到底怎么选?

文章目录 前言历史简介PrometheusZabbix 架构对比PrometheusZabbix 综合对比总结 前言 新公司要上监控,面试提到了 Prometheus 是公司需要的监控解决方案,我当然是选择跟风了。 之前主要做的是 Zabbix,既然公司需要 Prometheus,…

【如何破坏单例模式(详解)】

✅如何破坏单例模式 💡典型解析✅拓展知识仓✅反射破坏单例✅反序列化破坏单例✅ObjectlnputStream ✅总结✅如何避免单例被破坏✅ 避免反射破坏单例✅ 避免反序列化破坏单例 💡典型解析 单例模式主要是通过把一个类的构造方法私有化,来避免重…

鸿蒙系统的分布式技术:重塑智能终端的未来

华为鸿蒙系统自发布以来,凭借其创新的分布式技术,改变了我们对智能终端的认知和使用方式。鸿蒙系统的分布式技术是一种全新的设计理念,它将不同设备、不同应用场景视为一个整体,通过共享、协同和无缝连接,为用户带来前…

android setText不生效问题

1.直接说解决方案: 在代码没问题的情况下,将你的TextView的Id改一下,然后再重启编译器即可(注意,不修改TextView的ID,单独重启是没有作用的!) 2.出现问题的过程: 产品新增一个需求&#xff0c…

SpringBoot整合JWT+Spring Security+Redis实现登录拦截(一)登录认证

一、JWT简介 JWT 全称 JSON Web Token,JWT 主要用于用户登录鉴权,当用户登录之后,返回给前端一个Token,之后用户利用Token进行信息交互。 除了JWT认证之外,比较传统的还有Session认证,如何选择可以查看之前…

MAGVIT: Masked Generative Video Transformer

Paper name MAGVIT: Masked Generative Video Transformer Paper Reading Note Paper URL: https://arxiv.org/abs/2212.05199 Project URL: https://magvit.cs.cmu.edu/ Code URL: https://github.com/google-research/magvit TL;DR 2023 年 CMU、google 等发表 CVPR20…

[Python工程化之路] 搭建Python开发环境 包管理环境以及Linter

个人博客:Sekyoro的博客小屋 个人网站:Proanimer的个人网站 在工程化上,Python相比于Java,C#这类语言还是差了不少,不过整个生态还是不错的. 项目结构 一般有两种,一种称为flat另一种为src. ├── sample │ ├── AUTHORS.rst │ ├── docs | | ├── conf.py │ │ └…

深入Apache Commons Config:管理和使用配置文件

第1章:引言 咱们都知道,在软件开发中,管理配置文件是一件既重要又让人头疼的事。想象一下,咱们的应用程序有一堆设置需要调整,比如数据库的连接信息、应用的端口号,或者是一些功能的开关。如果这些信息硬编…