我是靠谱客的博主 热情朋友,最近开发中收集的这篇文章主要介绍cocos creator计算图形面积_PostGIS教程十五:几何图形的有效性,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

5e923ee88f1c5a8402a258390dfac8d0.png

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

一、什么是有效性?

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

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

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

最后两条规则属于任意类别。定义多边形的其他规则也是自洽合理的,但是上面的规则是PostGIS所遵循的OGC SFSQL标准所定义的多边形有效性的规则。

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

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

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

在此图中,你可以更清楚地看到无效的原因:

0bc212b2922e221eddd3f0d1af85c418.png

这个多边形的外环实际上是一个数字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))'
));

f3a7787cb286e91a5be2ab22871cd14c.png

94cbf3c00ad406574e58a16ad557ee02.png

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

然而,在我们的(表现不佳)的形似数字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))'
));

f79d2e87d094c5e0353f0c3575eea667.png

309a142ebdda4d47e5586bb8ba3556fb.png

现在我们知道这个图形是无效的,但是我们不知道为什么无效。我们可以使用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))'
));

1db9cb15e24643b8b515c127b5b71e07.png

539d67e69c8d2c7f964b334685e039f2.png

请注意,除了原因(自相交),图形自相交的坐标(coordinate(1 1))也被返回了。

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

-- Find all the invalid polygons and what their problem is
SELECT name, boroname, ST_IsValidReason(geom)
FROM nyc_neighborhoods
WHERE NOT ST_IsValid(geom);

5c4a58aa81bc7b3cc8dd20b0bbede22d.png

d6eb4a90d72157afbb3f46a0d678e80b.png

三、修复无效的图形

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

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

-- 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);

8cbf615be57d59213cb5b4337034d8b9.png

在视觉上修复无效几何图形的一个好工具是OpenJump(http://openjump.org),它在Tools->QA->Validate Selected Layers.下包含一个验证程序。

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

  • ST_MakeValid函数
  • ST_Buffer函数

3.1、ST_MakeValid函数

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

-- Fix the invalid figure-8 polygon
SELECT ST_AsText(ST_MakeValid(
         'POLYGON((0 0, 0 1, 1 1, 2 1, 2 2, 1 2, 1 1, 1 0, 0 0))'
));

ea90447d548ff42aeec88ac1fcea492f.png

83333a67533158cbd94ec8697816de32.png

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))

e399dbe477a41b22cf410de4ad941ac6.png

在多边形上计算零偏移缓冲区将返回有效的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
         )
);

6eac7c9bd1e2e94c5d62525c64531acc.png

7da0f4d5e0d5ce5f5c2bdfcaeca63f6f.png

最后

以上就是热情朋友为你收集整理的cocos creator计算图形面积_PostGIS教程十五:几何图形的有效性的全部内容,希望文章能够帮你解决cocos creator计算图形面积_PostGIS教程十五:几何图形的有效性所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部