32. 拓扑基本类型

在阅读本文档之前,至少请查看以下文档之一:

入门研讨会:PostGIS 拓扑研讨会.

手册:PostGIS 拓扑.

ISO 拓扑:OGC-SFS 几何.

在本研讨会中,我们将检查拓扑的一些基本原理、基础知识和定义。这不是直接使用它们的方式,而是为了理解它,以便能够轻松地使用它。

32.1. 类型

_images/basic_types.png

基本拓扑使用三种基本类型。

  • 节点:2D 点,所有内容在此处开始或结束

  • 边:一条具有方向的线串,它在一个节点上开始并在一个节点上结束

  • 面:一组封闭的线串,构成一个多边形

一组节点、边和面要有效,需要满足一些规则,请查看 ISO 拓扑文档,其中对这些条件进行了很好的总结,遵循所有规则的拓扑是有效的拓扑。

值得注意的是,到目前为止,Postgis 会在内部保存所有这些信息,每种类型都有其唯一的 ID,我们可以使用可用的函数来编辑和更改它们,例如,使用 ST_RemEdgeNewFace 您可以删除一条边并创建一个新面。

但仍然缺少一块,例如,我们如何说一个面具有特定的属性?Postgis 实现了几个概念来做到这一点,例如图层、TopoGeometry、TopoElement。

32.2. 通用面

可能会直观地认为只存在由边构成的面,但有一个例外,所有面之外的空白空间也是一个面!

空白空间称为通用面,当拓扑为空时,所有空间都是通用面,当我们添加线串时,它是这个面的边,然后当我们制作多边形时,就像在面中打了一个洞,并将其偷走以分配给一个面。

这个面是无限的,没有任何边界。

_images/boros_universal_face.png

通用面的 ID 为 0。

32.3. 边的解释

为了正确表示拓扑及其形式,有一些定义用于构建存储所有内容的表,边是其中较复杂的定义之一。

关于边的所有信息都存储在自定义拓扑模式中的 edge_data 表中,我们需要在边中包含哪些信息?基本上是它的节点和面信息,边是连接两者的基元。

这些线串被称为边,因为它们是面的边。

32.3.1. 边方向、左和右

拓扑中的边具有定义的右侧视角和视图,当我们看到它们时必须以下面的方式进行:

_images/edge_perspective.png

当我们想从边的角度来看时,总是从结束节点到开始边,始终向前看边。

_images/edge_left_right.png

边具有左侧和右侧属性,正如我们所见,它们是使用边的视角定义的,从开始节点到结束节点查看线串,总会有一个明确定义的左侧和右侧。

因此向前看边,您始终具有左侧和右侧。

这有助于关联哪些面在边的每一侧

_images/face_directions.png

检查图像上的边,虽然几乎所有的边都从下到上和从左到右,但有一条橙色的边方向相反,因此它的左侧和右侧相对于其他边交换了,但是如果您向前看边,则右侧和左侧是正确的。

继续看橙色的边,虽然它的右侧有一个由边构建的多边形,但左侧是通用面。

当我们要分析任何边时,我们需要从边的角度来看它,总是向前看边,永远不要向后看!

所有下一个边是什么?向前看,我们从开始节点到结束节点,所有在边的结束节点开始或结束的边!

32.4. 边数据

edge_data 表包含与边相关的信息,从我们现在所知道的,我们可以解释以下列:

  • edge_id:边的唯一 ID

  • start_node:与边的起始点相同的节点的 ID

  • end_node:与边的结束点相同的节点的 ID

  • left_face:边左侧的面的 ID

  • right_face:边右侧的面的 ID

  • geom:边的几何形状

32.4.1. 绝对下一个边 & 下一个边

表 edge_data 有列 abs_next_left_edge 和 abs_next_right_edge,此时如何解释它有点棘手。

到目前为止,我们主要看到边本身的属性以及边两侧的内容,下一个边属性是不同的,不要只问关于边本身,而是问哪个是构建右侧或左侧面上的下一个边。

right_edge 和 left_edge 的逻辑非常相似,因此我们将首先深入研究左侧,然后再展示右侧。

我们将使用以下拓扑作为示例

_images/next_edge_base.png

32.4.1.1.

让我们以边 5 为例,这条边的左侧是面 2,向前看,构建面 2 的下一个边是哪一个?

这是边 6。

_images/next_left_edge_perspective.png

这里非常重要的是我们跟随线的视角,取决于边的方向,就像顺时针或逆时针查看面一样。

有了这些信息,我们得到 abs_next_left_edge,它将是 6。

next_left_edge 几乎与 abs_next_left_edge 相同,除了它可以是负数,这取决于我们看到边的视角。

如果我们遵循边的视角,我们将有两个方向,下一个边的方向,以及下一个边上的视角方向。

我们将在每种情况下使用下一个符号:

  • 视角方向和下一个边方向相反:“-”

  • 视角方向和下一个边方向相同:无,保持值为正数

视角和边 6 的方向相同,next_left_edge 将为 6。

  • abs_next_left_edge: 6

  • next_left_edge: 6

32.4.1.3. 孤立边案例

有一个可能会让人困惑的案例,上面的所有规则都以相同的方式遵循,但最好看一看。

_images/next_edge_one_edge.png

当我们有一条没有与其他边连接的边时,我们首先可以认识到的是,左侧的面与右侧的面相同,在本例中是面 0,通用面。

如果我们遵循过去的逻辑,左侧是面 0,构建面 0 的下一个边是哪一个?实际上,有一条边,它就是它自己,并且它也像以前一样具有视角。

_images/next_edge_one_edge_left.png

如果我们检查视角方向,我们会发现它与相同的边但是方向相反,这意味着边 1 及其下一个边(边 1)的方向相反。

  • edge_id: 1

  • abs_next_left_edge: 1

  • next_left_edge: -1(当我们向前看孤立的边时,它将始终为负数)

对于下一个右侧边也是如此,下一个边将是它自身,唯一改变的是视角

_images/next_edge_one_edge_right.png

当我们向后看任何孤立的边时,视角将始终与边的方向相同,因此

  • edge_id: 1

  • abs_next_right_edge: 1

  • next_right_edge: -1(当我们向后看孤立的边时,它将始终为正数)

32.4.2. edge_data 的完整列

我们已经检查了 edge_data 表的所有列

  • edge_id:边的唯一 ID。

  • start_node:与边的起始点相同的节点的 ID。

  • end_node:与边的结束点相同的节点的 ID。

  • left_face:边左侧的面的 ID。

  • abs_next_left_edge:构建左侧面的下一个边。

  • next_left_edge:abs_next_left_edge,如果右侧面在下一个左侧边的右侧,则为负号。

  • right_face:边右侧的面的 ID。

  • abs_next_right_edge:构建右侧面的下一个边。

  • next_right_edge:abs_next_right_edge,如果左侧面在下一个右侧边的右侧,则为负号。

  • geom:边的几何形状。