32. 拓樸基本類型

在閱讀本文檔之前,請至少查看以下文件之一:

入門研討會:PostGIS 拓樸研討會.

手冊:PostGIS 拓樸.

ISO 拓樸:OGC-SFS 幾何.

在此研討會中,我們將檢視拓樸的一些基本原理、基礎知識和定義。此研討會的目的不是教導如何直接使用它們,而是讓您理解它,以便能夠輕鬆地使用它。

32.1. 類型

_images/basic_types.png

基本的拓樸操作基於三種基本類型。

  • 節點 (Node):2D 點,所有物件由此開始或結束

  • 邊 (Edge):以節點為起點和終點,具有方向的線字串

  • 面 (Face):封閉的線字串集合,構成多邊形

節點、邊和面的集合必須遵守一些規則才能有效。請查看 ISO 拓樸文件,其中對這些條件有非常好的摘要。遵循所有規則的拓樸就是有效的拓樸。

請注意,到目前為止,PostGIS 會在內部儲存所有這些資訊,每種類型都有其唯一的 ID,我們可以利用它透過可用的函數來編輯和更改它們。例如,使用 ST_RemEdgeNewFace 可以刪除邊並建立新的面。

但是,還缺少一個環節:我們要如何指定例如面具有特定屬性?PostGIS 實作了幾個概念來執行此操作,例如圖層 (Layers)、拓樸幾何 (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:邊的幾何。