33. 拓扑和几何表示

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

拥有包含所有图元的拓扑很有用,但为了使其更实用,我们需要一种在表中表示这些元素的方法。与我们拥有空间表类似,我们也可以拥有拓扑表。

33.1. 几何表示简介

如果你已经遵循任何使用拓扑表示几何图形的示例,你可能会记得这一点,当我们从几何表填充拓扑表时,我们使用 TopoGeometries 而不是 Geometries,并且在某种程度上,每个 TopoGeometry 能够表示拓扑中包含的一个或多个图元。

_images/geomtable2topotable.png

重点是我们如何从 TopoGeometry 访问实际图元,数据的结构如何,所以首先让我们看看最全局的定义

_images/topology_main_concept.png

TopoGeometry 可以表示一组图元或其他 TopoGeometries,为了创建 TopoGeometry,你需要一个图层。

图层是最大的盒子,它们存储 TopoGeometries,TopoGeometries 也存储 TopoElements,最后一个表示图元或其他 TopoGeometries。

只是用两种方式写

  • 图层包含

    • TopoGeometries,其中它们都具有相同的 TopoElement 类型,每个都包含

      • TopoElements,其中每个都可以表示一个

        • 其他图层的 TopoGeometry

        • 几何图形集合

        • 来自拓扑的图元

          • 节点

TopoGeometries 以键的形式公开,它们在图层内部具有唯一的键,但也会存储其图层键,这使得 Postgis 可以将其存储在任意列中,并且始终能够找到其 TopoElements,以及它们代表的内容。

你需要一个将在其中构造 TopoGeometry 的图层,之后你无需记住它属于哪个图层。

这个概念是用户使用的概念,从现在开始,我们将解释深入的技术细节。

附注,Postgis 拓扑在内部有一些关于键的技巧,有助于优化很多部分,但同时也有很多冗余信息,如果你在两个或多个地方找到相同的信息,请不要感到惊讶。

33.2. 特征

TopoElements 可以表示 TopoGeometry 和图元,考虑一下 TopoGeometry,如果将它们存储在 TopoElement 中,它们仍然包含其他 TopoElements,如果我们沿着它的路径,我们最终将始终到达拓扑的图元。

特征将表示几何图形集的类型,如果你使用 TopoGeometries 或图元,这并不重要,最终图层可以直接或间接地包含以下任何集合

    1. 节点

    1. 几何图形集合

数字很重要,在任何请求特征类型的函数中,你可以使用数字或名称作为字符串来指定它。

33.3. 分层图层、子项和父项

我稍后会介绍这个概念,但为了更好、更深入地解释这个概念,你会发现这是必要的。

_images/hierarchy1.png

图像的第一个方面是使用图元构建的表,图层 1 将具有 TopoGeometries,其中其 TopoElements 仅引用拓扑的图元。

我们将图层 1 和图元之间的关系定义为

  • 图层 1 是图元的父项

  • 图元是图层 1 的子项

父项和子项之间的关系是关于大小的,子项很小,当我们有一组子项时,我们会构建一个父项,一个更大的组。

图层 2 将图层 1 作为子项,这意味着该图层中的每个 TopoGeometry 都可以引用图层 1 的一个或多个 TopoGeometries。

这也意味着你不能选择图层 1 的一半 TopoGeometry,选择它的一半意味着你需要引用 TopoGeometry 的 TopoElement 之一,在这种情况下,它属于图元(其子项),如果你真的需要这样做,那么请使用图层 1 的子项(图元)构建图层 2。

每个图层只能有一个子图层,这意味着子项和父项共享相同的拓扑模式。

你将注意到层次结构的某些方面可能会发生变化,以支持类似半个 TopoGeometry 或混合图层之类的东西,但目前尚未实现。

33.4. 图层

为了存储 TopoGeometries,我们需要一个图层,因此,当我们创建 TopoGeometrie 的列时,我们也会创建一个图层,这就是为什么我们使用特殊函数来为此创建列的原因。

创建 TopoGeometry 列

图层和 TopoGeometry 列具有特殊关系,它们是链接的,但它们不是相同的。

图层有很多信息,我们必须提供这些信息才能知道我们想要哪种类型的图层。

图层在每个拓扑中都有一个唯一标识符,此标识符称为 layer_id。

  • 图层键:由 [topology_id, layer_id] 组成的复合键

  • 表路由:模式名称、表名称和列名称,以了解其链接位置。

  • 特征类型:图层将包含的特征类型。

  • 级别:此值从 0 开始,如果使用另一个图层构建此图层,它将加 1,因此我们知道我们距离图元有多少层,如果该值为 0,则表示该图层是使用图元而不是 TopoGeometries 构建的。

  • child_id:如果该图层不是使用图元构建的,而是使用另一个图层作为基础,我们需要此图层的图层标识符 (layer_id),我们不需要 topology_id,因为我们已经从父项中知道了它。

33.5. 关系表

最后,你可能正在寻找的部分是,Postgis 拓扑如何从 TopoGeometry 到它们包含的内容。

关系表函数是父项和子项之间的桥梁。

此表可以在以下位置找到:my_topology.relation

33.5.1. 我们现在知道的键和标识符

我将使用“标识符”这个词作为特定上下文中唯一的键。例如,每个图层都有一个数字作为标识符 (layer_id),它在其拓扑上下文中是唯一的,但不足以在数据库中找到图层。

虽然标识符在上下文中有效,但键将是寻址元素的完整方法,例如,任何图层的键都是两个值 [topology_id, layer_id]。

_images/topo_keys.png

该图像很好地总结了每个键的组成方式。

33.5.1.1. 键上的隐式标识符

Postgis 在使用图层和 TopoGeometries 时在某种程度上使用隐式逻辑,这是因为它们有一个上下文,你无需存储完整的键即可知道它。

为了显示一个示例

TopoGeometry 由以下项组成

  • topology_id

  • layer_id

  • topogeometry_id

正如我们之前所说,关系表存储在拓扑模式中。此表将包含 TopoGeometry 与 TopoElements 的关系,为了在此上下文中进行引用,我们需要 topology_id 吗?

我们可以跳过它!当我们离开拓扑模式时,我们需要该 ID 来查找它,但是当我们在其中时,我们可以查看模式名称,并在表 topology.topology 中找到其 ID,该表具有所有拓扑 ID 和名称。

33.5.2. TopoGeometry

TopoGeometry 是一个复合键,其中包含以下元素

  • topology_id:TopoGeometry 键的 topology_id

  • layer_id:TopoGeometry 键的 layer_id

  • id:TopoGeometry 键的 topogeometry_id

  • type:作为数字的特征类型

33.5.3. 基本关系表结构

每个模式拓扑都可以有自己的关系表,它将在你创建第一个 TopoGeometry 时创建,该表存储在拓扑中,如 custom_topology.relation

表的每一行都称为“组件”,例如关系的组件。

该组件保存两件事的配对,一个 TopoGeometry 键和一个 TopoElement,请记住,每个 TopoElement 只能表示一个图元或 TopoGeometry,因此为了让 TopoGeometry 能够表示多个图元或 TopoGeometry,该表存储具有相同 TopoGeometry 键和不同 TopoElements 的多行,这样,仅在表中进行筛选,我们就可以获取任何 TopoGeometry 的所有 TopoElements。

_images/components.png

33.5.4. 查找 TopoGeometry 的组件

查找属于 TopoGeometry 的组件有点棘手,因为这里将使用隐式键。

一个组件具有以下元素

  • TopoGeometry 键

    • topogeom_id:来自 TopoGeometry 键的 topogeometry_id

    • layer_id:来自 TopoGeometry 键的 layer_id

  • TopoElement

    • element_id

    • element_type

我们可以注意到 TopoGeometry 键不完整,这是因为关系表已经属于拓扑,因此无需再次存储拓扑标识符。

为了从 TopoGeometry 到达组件,我们需要查找 TopoGeometry.topology_id,并在 topology.topology.id 中搜索,并检索拓扑名称,有了它,我们可以在其各自的模式中找到关系表。

_images/topogeo2components.png

33.5.5. 读取 TopoElements

分解 TopoGeometry 的最后一部分是能够解释 TopoElements,这比其他键更复杂,因为它的含义可能会根据保存它的图层而变化。

正如我们所讨论的,图层可以将图元或 TopoGeometries 作为子项。

我们需要知道的第一件事是它正在使用哪些子项,为此,我们需要使用 TopoGeometry Key.layer_idtopology.layer.id 上查找,并获取 `topology.layer.child_id`

所以这些情况取决于 child_id

  • 如果为 NULL

    • element_id:图元标识符

    • element_type:特征编号,查看特征以了解要查看哪个图元表。

  • 如果不为 NULL

    • element_id:来自 TopoGeometry 键的 topogeometry_id

    • element_type:来自 TopoGeometry 键的 layer_id

第一种情况很简单,只需查看它们各自的 Primitive 表,并使用标识符来确定是哪个图元。

第二种情况使用 TopoElement 构建一个新的 TopoGeometry Key,如前所述,topology_id 是隐式的,因此 Key 是完整的。要查找新元素,请再次查看关系表,但使用新的 Key。

_images/read_topoelement.png