Chapter 9. 拓扑结构

Table of Contents

PostGIS拓扑类型和函数用于管理拓扑对象,例如面、边和节点。

Sandro Santilli在2011年PostGIS Day Paris会议上的演示提供了关于PostGIS拓扑和未来发展方向的很好概述。您可以查看他的幻灯片演示,链接如下:Topology with PostGIS 2.0 slide deck

Vincent Picavet 在 PostGIS 拓扑 PGConf EU 2012 中对拓扑是什么、如何使用以及支持它的各种 FOSS4G 工具提供了很好的概要和概述。

基于拓扑的 GIS 数据库的一个示例是美国人口普查拓扑集成地理编码和参考系统 (TIGER) 数据库。 如果您想尝试 PostGIS 拓扑并需要一些数据,请查看 Topology_Load_Tiger

The PostGIS topology module has existed for a long time but was not always part of the official documentation. Extensive cleanup removed deprecated functions, fixed known usability issues, documented the features and functions, added new functionality, and improved SQL-MM compliance.

该项目的详细信息可以在 PostGIS Topology Wiki 中找到

与该模块关联的所有函数和表都安装在称为拓扑架构中。

SQL/MM 标准中定义的函数以 ST_ 为前缀,而 PostGIS 特定的函数没有前缀。

Topology support is built by default and can be disabled by specifying the --without-topology configure option at build time as described in Chapter 2, PostGIS 安装

9.1. Topology Primitive Tables

The core primitives of any topology are stored in the edge_data, node, and face tables that live in the schema created by CreateTopology. Each row of edge_data represents an oriented edge: it records a directed curve from start_node to end_node together with the identifier of the face encountered on the left of that direction (left_face) and the face encountered on the right (right_face). The same geometric segment may therefore appear twice—once for each orientation—when it belongs to two faces.

The next_left_edge and next_right_edge columns complete this orientation information by encoding how to keep walking around a face. They store signed integers whose absolute value is the identifier of the next oriented edge and whose sign determines whether the stored orientation has to be followed as-is or reversed when traversing. Formally, the following rules hold for every edge e:

  • abs(next_left_edge) is the identifier of the edge reached by continuing around the face that lies to the left of e. If the value is positive the walk continues from the end node of e along the stored orientation of the referenced edge; if it is negative the referenced edge must be followed backwards so that the shared face remains on the walker’s left.

  • abs(next_right_edge) analogously follows the boundary of the face located on the right of e. A positive value means that the next edge is taken with its recorded orientation starting from the end node of e, whereas a negative value instructs to traverse the referenced edge in reverse, starting from its end node, so that the right-hand face is preserved.

  • A zero value indicates that the edge is dangling on the corresponding side (for example an isolated edge whose incident face is the universal face 0). The abs_next_left_edge and abs_next_right_edge columns exposed by the edge view are convenience projections of these absolute values.

This representation is a variant of a doubly connected edge list and is exploited by many topology routines. Functions such as GetRingEdges and ValidateTopology rely on it to reconstruct face boundaries and to diagnose inconsistencies—hence the “invalid next_left_edge” and “invalid next_right_edge” diagnostics reported during validation. Constructors like AddEdge initialise the next_* attributes with trivial self references, while editing routines including ST_AddEdgeModFace and ST_RemEdgeModFace update the links as edges are inserted or removed. Other bulk operations (for example Polygonize) may intentionally leave the fields unset, which is why the documentation flags their behaviour explicitly.

9.2. 拓扑类型

Abstract

本节列出了 PostGIS Topology 安装的 PostgreSQL 数据类型。 请注意,我们描述了这些的强制转换行为,这非常重要,尤其是在设计您自己的函数时。

9.3. 拓扑域

Abstract

本节列出了 PostGIS Topology 安装的 PostgreSQL 域。 域可以像对象类型一样用作函数或表列的返回对象。 域和类型之间的区别在于,域是绑定了检查约束的现有类型。

  • TopoElement — 一个由 2 个整数组成的数组,用于表示简单或分层拓扑几何的一个组件。
  • TopoElementArray — TopoElement 对象的数组。

9.4. 拓扑和拓扑几何管理

Abstract

本节列出了用于构建新拓扑模式、验证拓扑和管理 TopoGeometry 列的拓扑函数

  • AddTopoGeometryColumn — 将拓扑几何列添加到现有表中,将此新列注册为topology.layer 中的图层并返回新的layer_id。
  • RenameTopoGeometryColumn — 重命名拓扑几何列
  • DropTopology — 谨慎使用:删除拓扑模式并从topology.topology 表中删除其引用,并从geometry_columns 表中删除对该模式中表的引用。
  • RenameTopology — 重命名拓扑
  • DropTopoGeometryColumn — 从架构 schema_name 中名为 table_name 的表中删除拓扑几何列,并从 topology.layer 表中取消注册这些列。
  • FixCorruptTopoGeometryColumn — Fixes topogeometry corruption caused by upgrade to postgis_topology 3.6.0 and higher
  • Populate_Topology_Layer — 通过从拓扑表读取元数据,将缺失的条目添加到topology.layer表中。
  • TopologySummary — 获取拓扑名称并提供拓扑中对象类型的汇总总数。
  • ValidateTopology — 返回一组 validatetopology_returntype 对象,详细说明拓扑问题。
  • ValidateTopologyRelation — 返回有关无效拓扑关系记录的信息
  • ValidateTopologyPrecision — 返回拓扑中不精确的顶点。
  • MakeTopologyPrecise — 将拓扑顶点对齐到精度网格。
  • FindTopology — 通过不同的方式返回拓扑记录。
  • FindLayer — 通过不同的方式返回topology.layer记录。
  • TotalTopologySize — 指定拓扑占用的总磁盘空间,包括所有索引和TOAST数据。
  • UpgradeTopology — 将指定拓扑升级为支持大整数(int8)类型的拓扑 ID 和要素 ID。

9.5. 拓扑统计管理

Abstract

本节讨论拓扑构建期间数据库统计信息的管理。

向拓扑添加元素会触发许多数据库查询,以查找将被分割的现有边、添加节点并更新将与新线路连接的边。 因此,有关拓扑表中数据的统计信息是最新的非常有用。

PostGIS 拓扑数据的填充和编辑函数不会自动更新统计信息,因为在每次拓扑更改之后都更新统计信息会显得过于冗余,所以更新统计信息是调用者的责任。

[Note]

由 autovacuum 更新的统计信息对于在 autovacuum 过程完成之前启动的事务不可见,因此长时间运行的事务将需要自行运行 ANALYZE,以使用更新的统计信息。

9.6. 拓扑构造器

Abstract

本节介绍用于创建新拓扑的拓扑函数。

  • CreateTopology — 创建一个新的拓扑架构并将其注册到topology.topology 表中。
  • CopyTopology — 将拓扑(节点、边、面、层和拓扑几何)的副本复制到新模式中
  • ST_InitTopoGeo — 创建一个新的拓扑架构并将其注册到topology.topology 表中。
  • ST_CreateTopoGeo — 将几何图形集合添加到给定的空拓扑并返回详细说明成功的消息。
  • TopoGeo_AddPoint — 使用容差并可能分割现有边向现有拓扑添加点。
  • TopoGeo_AddLineString — 使用容差将线串添加到现有拓扑中,并在可能的情况下拆分边或面。
  • TopoGeo_AddPolygon — 使用公差并可能分割现有边/面将多边形添加到现有拓扑。 返回面标识符。
  • TopoGeo_LoadGeometry — 将几何图形加载到现有拓扑中,并在必要时执行捕捉和拆分操作。

9.7. 拓扑编辑器

Abstract

本节介绍用于添加、移动、删除和分割边、面和节点的拓扑函数。 所有这些函数都是由 ISO SQL/MM 定义的。

  • ST_AddIsoNode — 将一个孤立的节点添加到拓扑结构中的一个面,并返回新节点的节点ID。如果"face"为空(null),仍然会创建节点。
  • ST_AddIsoEdge — 将由几何 alinestring 定义的孤立边添加到连接两个现有孤立节点anodeanothernode的拓扑,并返回新边的边id。
  • ST_AddEdgeNewFaces — 添加新边,如果这样做会分割一个面,请删除原始面并用两个新面替换它。
  • ST_AddEdgeModFace — 添加新边,如果这样做会分割面,则修改原始面并添加新面。
  • ST_RemEdgeNewFace — 删除一条边,如果删除的边将两个面分开,则删除原始面并用新面替换它们。
  • ST_RemEdgeModFace — 删除一条边,如果该边将两个面分开,则删除一个面并修改另一个面以覆盖两个面的空间。
  • ST_ChangeEdgeGeom — 改变边的形状而不影响拓扑结构。
  • ST_ModEdgeSplit — 通过沿现有边创建新节点、修改原始边并添加新边来分割边。
  • ST_ModEdgeHeal — 通过删除连接两条边的节点、修改第一条边并删除第二条边来修复两条边。 返回已删除节点的 id。
  • ST_NewEdgeHeal — 通过删除连接两条边的节点、删除两条边并用方向与提供的第一条边相同的边替换它们来修复两条边。
  • ST_MoveIsoNode — 在拓扑结构中将一个孤立节点从一个点移动到另一个点。如果新的apoint几何对象已存在作为一个节点,则会抛出错误。返回移动的描述。
  • ST_NewEdgesSplit — 通过沿现有边创建新节点、删除原始边并用两条新边替换它来分割边。 返回创建的连接新边的新节点的 id。
  • ST_RemoveIsoNode — 删除孤立节点并返回操作描述。 如果节点不是孤立的(是边的开始或结束),则会引发异常。
  • ST_RemoveIsoEdge — 删除孤立的边并返回操作的描述。 如果边缘未被隔离,则会引发异常。

9.8. 拓扑访问器

9.9. 拓扑处理

Abstract

本节介绍以非标准方式处理拓扑的函数。

  • Polygonize — 查找并注册由拓扑边定义的所有面。
  • AddNode — 将点节点添加到指定拓扑模式的节点表中,并返回新节点的nodeid。 如果点已经作为节点存在,则返回现有的nodeid。
  • AddEdge — 使用指定的线串几何将线串边添加到边表,并将关联的起点和终点添加到指定拓扑方案的点节点表,并返回新(或现有)边的edgeid。
  • AddFace — 将面基元注册到拓扑并获取其标识符。
  • ST_Simplify — 使用 Douglas-Peucker 算法返回给定 TopoGeometry 的“简化”几何版本。
  • RemoveUnusedPrimitives — 删除定义现有 TopoGeometry 对象不需要的拓扑基元。

9.10. 拓扑几何构造函数

Abstract

本节介绍用于创建新拓扑几何的拓扑函数。

  • CreateTopoGeom — 从拓扑元素数组创建一个新的拓扑几何对象 - tg_type: 1:[多]点, 2:[多]线, 3:[多]多边形, 4:集合
  • toTopoGeom — 将简单几何图形转换为拓扑几何图形。
  • TopoElementArray_Agg — 返回一组 element_id、类型数组 (topoelements) 的 topoelementarray
  • TopoElement — 将拓扑几何转换为拓扑元素。

9.11. 拓扑几何编辑器

Abstract

本节介绍用于编辑现有拓扑几何的拓扑函数。

9.12. 拓扑几何访问器

  • GetTopoGeomElementArray — 返回一个topoelementarray(包含拓扑元素的数组),其中包含给定TopoGeometry的拓扑元素和类型(原始元素)。
  • GetTopoGeomElements — 返回一组 topoelement 对象,其中包含给定 TopoGeometry(原始元素)的拓扑 element_id、element_type。
  • ST_SRID — 返回拓扑几何的空间参考标识符。

9.13. 拓扑几何输出

  • AsGML — 返回拓扑几何的 GML 表示形式。
  • AsTopoJSON — 返回拓扑几何的 TopoJSON 表示形式。

9.14. 拓扑空间关系

Abstract

本节列出了用于检查拓扑几何和拓扑基元之间关系的拓扑函数

  • Equals — 如果两个拓扑几何由相同的拓扑基元组成,则返回 true。
  • Intersects — 如果两个拓扑几何中的任何一对图元相交,则返回 true。

9.15. 导入和导出拓扑

创建拓扑以及关联的拓扑层后,您可能希望将它们导出为基于文件的格式以进行备份或传输到另一个数据库中。

使用 PostgreSQL 的标准转储/恢复工具是有问题的,因为拓扑由一组表(基元为 4 个,层为任意数量)和元数据表中的记录(topology.topology 和 topology.layer)组成。 此外,拓扑标识符在数据库中并不是唯一的,因此在恢复拓扑时需要更改拓扑参数。

为了简化拓扑的导出/恢复,提供了一对可执行文件:pgtopo_exportpgtopo_import。 用法示例:

pgtopo_export dev_db topo1 | pgtopo_import topo1 | psql staging_db

9.15.1. 使用拓扑导出器

pgtopo_export 脚本采用数据库和拓扑的名称,并输出转储文件,该文件可用于将拓扑(和关联的层)导入到新数据库中。

默认情况下,pgtopo_export 将转储文件写入标准输出,以便可以将其通过管道传输到 pgtopo_import 或重定向到文件(拒绝写入终端)。 您可以选择使用 -f 命令行开关指定输出文件名。

默认情况下,pgtopo_export 包含针对给定拓扑定义的所有层的转储。 这可能是比您需要的更多的数据,或者可能不起作用(如果您的图层表具有复杂的依赖关系),在这种情况下,您可以使用 --skip-layers 开关请求跳过图层并单独处理这些图层。

调用 pgtopo_export时使用 --help(或缩写的 -h)指令将始终打印简短的用法说明字符串。

转储文件格式是 pgtopo_export 目录的压缩 tar 存档,其中至少包含一个带有格式版本信息的 pgtopo_dump_version 文件。 从版本 1 开始,该目录包含制表符分隔的 CSV 文件,其中包含拓扑基元表的数据(节点、边、面、关系)、与其关联的拓扑和层记录以及(除非给出 --skip-layers)自定义 -format PostgreSQL 转储表报告为给定拓扑的层。

9.15.2. 使用拓扑导入器

pgtopo_import 脚本采用 pgtopo_export 格式的拓扑转储和要创建的拓扑的名称,并输出重建拓扑和关联层的 SQL 脚本。

生成的 SQL 文件将包含以下语句:创建具有给定名称的拓扑、在其中加载原始数据、通过将所有 TopoGeometry 值正确链接到其正确的拓扑来恢复和注册所有拓扑层。

默认情况下,pgtopo_import 从标准输入读取转储,以便它可以与管道中的 pgtopo_export 结合使用。 您可以选择使用 -f 命令行开关指定输入文件名。

默认情况下,pgtopo_import 在输出 SQL 文件中包含用于恢复转储中找到的所有层的代码。

如果您的目标数据库已经具有与转储中的表同名的表,这可能是不需要的或不起作用的。 在这种情况下,您可以使用 --skip-layers 命令请求跳过层并单独(或稍后)处理这些层。

可以使用 --only-layers 命令生成仅加载层并将层链接到命名拓扑的 SQL。 这对于在解决命名冲突后加载图层或将图层链接到不同的拓扑(例如起始拓扑的空间简化版本)非常有用。

如果目标拓扑已存在,并且你希望在创建前将其删除,可以传递 --drop-topology 参数(自 PostGIS 3.6.0 起支持)。