9. 幾何圖形¶
9.1. 簡介¶
在之前的 單元 中,我們載入各種資料。在開始玩我們的資料之前,讓我們來看看一些更簡單的範例。回到 pgAdmin,再次選取nyc 資料庫,並開啟 SQL 查詢工具。將此 SQL 範例程式碼貼到 pgAdmin SQL 編輯器視窗中(移除預設文字),然後執行。
CREATE TABLE geometries (name varchar, geom geometry);
INSERT INTO geometries VALUES
('Point', 'POINT(0 0)'),
('Linestring', 'LINESTRING(0 0, 1 1, 2 1, 2 2)'),
('Polygon', 'POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))'),
('PolygonWithHole', 'POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))'),
('Collection', 'GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))');
SELECT name, ST_AsText(geom) FROM geometries;

上面的範例建立一個資料表 (geometries),並插入五個幾何圖形:一個點、一個線、一個多邊形、一個帶洞的多邊形,以及一個集合。最後,插入的列會被選取並顯示在「輸出」窗格中。
9.2. 後設資料表¶
配合 SFSQL(SQL 簡易特徵)規格,PostGIS 提供兩個資料表來追蹤和回報給定資料庫中的幾何圖形類型。
第一個資料表
spatial_ref_sys
定義資料庫已知的空間參照系統,稍後將更詳細地說明。第二個資料表(事實上,是一個視圖)
geometry_columns
提供所有「特徵」(定義為具有幾何屬性的物件)的清單,以及這些特徵的基本詳細資料。

讓我們看看在我們的資料庫中的 geometry_columns
資料表。和以前一樣把這個指令貼到查詢工具中
SELECT * FROM geometry_columns;

f_table_catalog
、f_table_schema
和f_table_name
提供包含給定幾何圖形的特徵資料表的完全限定名稱。由於 PostgreSQL 不使用目錄,f_table_catalog
通常會是空的。f_geometry_column
是包含幾何圖形的資料表的資料行名稱 - 對於具有多個幾何圖形資料行的特徵資料表,將會有一筆記錄。coord_dimension
和srid
分別定義幾何的維度(2、3 或 4 維度)和空間參考系統識別碼,指向spatial_ref_sys
表格。type
欄位定義幾何類型,如下所述。截至目前,我們已看過點狀和線段類型。
藉由查詢該表格,GIS 用戶端和程式庫可以確定在擷取資料時應期待什麼,而且可以在不需要檢查各個幾何的情況下執行任何必要的投影、處理或繪製。
注意事項
您的某些
nyc
表格是否有 26918 以外的srid
?這很容易可藉由更新表格來修復。
ALTER TABLE nyc_neighborhoods
ALTER COLUMN geom
TYPE Geometry(MultiPolygon, 26918)
USING ST_SetSRID(geom, 26918);
9.3. 表示真實世界物件¶
用於 SQL(SFSQL)的簡單特徵,PostGIS 開發的原始指導標準,定義如何表示真實世界的物件。藉由採用連續形狀並在固定解析度進行數位化,我們可以獲得物件的通用手冊表述。SFSQL 只處理 2 維表述。PostGIS 已將其擴充,以包含 3 維和 4 維表述;較新的 SQL 多媒體第 3 號(SQL/MM)規格已正式定義自己的表述。
我們的範例表格包含不同幾何類型的組合。我們可以使用讀取幾何資料的函式來收集各個物件的一般資訊。
ST_GeometryType(geometry) 傳回幾何類型
ST_NDims(geometry) 傳回幾何的維度數目
ST_SRID(geometry) 傳回幾何的空間參考識別號碼
SELECT name, ST_GeometryType(geom), ST_NDims(geom), ST_SRID(geom)
FROM geometries;
name | st_geometrytype | st_ndims | st_srid
-----------------+-----------------------+----------+---------
Point | ST_Point | 2 | 0
Polygon | ST_Polygon | 2 | 0
PolygonWithHole | ST_Polygon | 2 | 0
Collection | ST_GeometryCollection | 2 | 0
Linestring | ST_LineString | 2 | 0
9.3.1. 點¶

空間點表示地球上單一位置。該點由單一座標(包括 2、3 或 4 個維度)表示。點用於表示物件,當精確的細節(例如形狀和大小)在目標比例尺上不重要時。例如,地圖上的城市可以描述為點,而單一州的地圖則可以將城市表示為多邊形。
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Point';
POINT(0 0)
以下是針對點執行的特定空間函式
ST_X(geometry) 傳回 X 座標
ST_Y(geometry) 傳回 Y 座標
因此,我們可以讀取點座標,如下所示
SELECT ST_X(geom), ST_Y(geom)
FROM geometries
WHERE name = 'Point';
紐約地鐵站 (nyc_subway_stations
) 資料表是表示為點的資料集。下列 SQL 查詢會傳回與一個點相關的幾何 (在 ST_AsText 欄位中)。
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
LIMIT 1;
9.3.2. 線串¶

線串是位置之間的一條路徑。它採取兩個或更多點的有序系列的形式。道路和河流通常表示為線串。如果線串在同一點開始和結束,則稱為封閉線串。如果它沒有交叉或觸及它自己 (除了在它封閉時在它的端點處),則稱為單純線串。一個線串可以同時是封閉和單純線串。
紐約的街道網路 (nyc_streets
) 在工作坊中已於先前時候載入。此資料集包含名稱和類型等詳細資料。一個真實世界的街道可能包含許多線串,每個線串都表示一段具有不同屬性的道路。
下列 SQL 查詢會傳回與一個線串相關的幾何 (在 ST_AsText 欄位中)。
SELECT ST_AsText(geom)
FROM geometries
WHERE name = 'Linestring';
LINESTRING(0 0, 1 1, 2 1, 2 2)
以下是處理線串的一些特定空間函數
ST_Length(geometry) 傳回線串的長度
ST_StartPoint(geometry) 傳回第一組坐標作為點
ST_EndPoint(geometry) 傳回最後一組坐標作為點
ST_NPoints(geometry) 傳回線串中的坐標數目
因此,我們的線串的長度為
SELECT ST_Length(geom)
FROM geometries
WHERE name = 'Linestring';
3.41421356237309
9.3.3. 多邊形¶

多邊形是區域的表示。多邊形的外界線以環形表示。此環形是符合上述定義的封閉且單純線串。多邊形內部的洞也以環形表示。
多邊形用於表示其大小和形狀很重要的物件。當比例夠高可以看到其面積時,城市界線、公園、建築物足跡或水體通常都以多邊形表示。道路和河流有時也可以表示為多邊形。
下列 SQL 查詢會傳回與一個多邊形相關的幾何 (在 ST_AsText 欄位中)。
SELECT ST_AsText(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
注意事項
我們在 WHERE
子句中使用 LIKE
算符執行字串比對作業,而不是使用等於 =
符號。**你可能習慣於將「*」符號用作模式比對的「glob」,但在 SQL 中使用「%``」符號**,並與 LIKE
算符一起使用來告訴系統執行 glob 比對。
POLYGON((0 0, 1 0, 1 1, 0 1, 0 0))
POLYGON((0 0, 10 0, 10 10, 0 10, 0 0),(1 1, 1 2, 2 2, 2 1, 1 1))
第一個多邊形只有一個環。第二個有一個內部「洞」。大多數圖形系統都包含一個「多邊形」的概念,但 GIS 系統比較特殊,允許多邊形明確地有洞。

以下是與多邊形搭配使用的一些特定空間功能
ST_Area(geometry) 傳回多邊形的面積
ST_NRings(geometry) 傳回環的數量(通常為 1,如果有洞則更多)
ST_ExteriorRing(geometry) 傳回外環,做為線條
ST_InteriorRingN(geometry,n) 傳回指定內環,做為線條
ST_Perimeter(geometry) 傳回所有環的長度
我們可以使用面積函數計算多邊形的面積
SELECT name, ST_Area(geom)
FROM geometries
WHERE name LIKE 'Polygon%';
Polygon 1
PolygonWithHole 99
請注意,有洞的多邊形的面積是外殼(10x10 方形)的面積減去洞(1x1 方形)的面積。
9.3.4. 集合¶
有四種集合類型,可將多個簡單的幾何圖形分組成集合。
多點,點的集合
多線條字串,線條字串的集合
多邊形,多邊形的集合
幾何集合,任何幾何圖形(包括其他集合)的異質集合
集合是另一個在 GIS 軟體中出現的觀念,而不是在一般圖形軟體中。它們可用於直接將真實世界的物件建模為空間物件。例如,要如何建模一個被通行權分離的地段?做為多邊形,通行權兩側各有一部分。

我們的範例集合包含一個多邊形和一個點
SELECT name, ST_AsText(geom)
FROM geometries
WHERE name = 'Collection';
GEOMETRYCOLLECTION(POINT(2 0),POLYGON((0 0, 1 0, 1 1, 0 1, 0 0)))

以下是與集合搭配使用的一些特定空間功能
ST_NumGeometries(geometry) 傳回集合中區段的數量
ST_GeometryN(geometry,n) 傳回指定的區段
ST_Area(geometry) 傳回所有多邊形區段的總面積
ST_Length(geometry) 傳回所有線性區段的總長度
9.4. 幾何輸入和輸出¶
在資料庫中,幾何圖形會儲存在磁碟上的格式,而該格式只能由 PostGIS 程式使用。為了讓外部程式插入和擷取有用的幾何圖形,它們需要轉換成其他應用程式可以理解的格式。很幸運地,PostGIS 支援以大量的格式傳遞和使用幾何圖形
知名文字 (WKT)
ST_GeomFromText(text, srid) 傳回
geometry
ST_AsText(geometry) 傳回
text
ST_AsEWKT(geometry) 傳回
text
已知二進位格式 (WKB)
ST_GeomFromWKB(bytea) 傳回
geometry
ST_AsBinary(geometry) 傳回
bytea
ST_AsEWKB(geometry) 傳回
bytea
地理標記語言 (GML)
ST_GeomFromGML(text) 傳回
geometry
ST_AsGML(geometry) 傳回
text
Keyhole 標記語言 (KML)
ST_GeomFromKML(text) 傳回
geometry
ST_AsKML(geometry) 傳回
text
-
ST_AsGeoJSON(geometry) 傳回
text
可擴充向量圖形 (SVG)
ST_AsSVG(geometry) 回傳
text
建構函數最常見的用途是將幾何圖形文字表示轉換為內部表示。
請注意,除了帶有幾何表示的文字參數之外,我們還有一個提供幾何 SRID 的數字參數。
下列 SQL 查詢顯示 WKB 表示的一個範例 (呼叫 encode() 是將二進位輸出轉換為 ASCII 形式以進行列印的要求)
SELECT encode(
ST_AsBinary(ST_GeometryFromText('LINESTRING(0 0,1 0)')),
'hex');
01020000000200000000000000000000000000000000000000000000000000f03f0000000000000000
在本次工作坊中,我們將繼續使用 WKT,以確保您可以觀看並瞭解我們正在瀏覽的幾何圖形。然而,多數實際程序 (例如瀏覽地理資訊系統應用程式中的資料、將資料傳輸到網路服務或遙遠處理資料),WKB 都是首選格式。
由於 WKT 和 WKB 是在 SFSQL 規範中定義的,因此它們並未處理 3 或 4 維幾何圖形。對於這些情況,PostGIS 定義了擴展已知文字 (EWKT) 和擴展已知二進位格式 (EWKB) 格式。這些格式提供 WKT 和 WKB 相同的格式功能,並增加了次元。
這是一個 WKT 中 3D 線字串的範例
SELECT ST_AsText(ST_GeometryFromText('LINESTRING(0 0 0,1 0 0,1 1 2)'));
LINESTRING Z (0 0 0,1 0 0,1 1 2)
請注意該文字表示法會變更!這是因為 PostGIS 的文字輸入程式在消耗時很寬鬆。它會使用
十六進位編碼的 EWKB、
延伸的 Well-Known 文字,以及
ISO 標準的 Well-Known 文字。
在輸出方面,ST_AsText 函式比較保守,而且只會發出 ISO 標準的 Well-Known 文字。
除了 ST_GeometryFromText 函式外,還有許多其他的方法可以透過 Well-Known 文字或類似的格式化輸入來建立形狀
-- Using ST_GeomFromText with the SRID parameter
SELECT ST_GeomFromText('POINT(2 2)',4326);
-- Using ST_GeomFromText without the SRID parameter
SELECT ST_SetSRID(ST_GeomFromText('POINT(2 2)'),4326);
-- Using a ST_Make* function
SELECT ST_SetSRID(ST_MakePoint(2, 2), 4326);
-- Using PostgreSQL casting syntax and ISO WKT
SELECT ST_SetSRID('POINT(2 2)'::geometry, 4326);
-- Using PostgreSQL casting syntax and extended WKT
SELECT 'SRID=4326;POINT(2 2)'::geometry;
除了一般格式 (WKT、WKB、GML、KML、JSON、SVG) 的發送器外,PostGIS 也有四種格式 (WKT、WKB、GML、KML) 的接收器。大部分應用程式使用 WKT 或 WKB 形狀建立函式,但其他功能也能使用。這是一個使用 GML 並輸出 JSON 的範例
SELECT ST_AsGeoJSON(ST_GeomFromGML('<gml:Point><gml:coordinates>1,1</gml:coordinates></gml:Point>'));

9.5. 將文字轉型¶
我們到目前為止看到的 WKT 字串都是「文字」類型,並且我們一直使用 PostGIS 函式 (例如 ST_GeomFromText()) 將其轉換為「形狀」類型。
PostgreSQL 包含一個簡短形式的語法,可將資料從一種類型轉換為另一種類型,亦即轉型語法 oldata::newtype。例如,此 SQL 會將一個雙精度浮點數值轉換為文字字串。
SELECT 0.9::text;
更不重要的部份是,這個 SQL 會將一個 WKT 字串轉換成一個形狀
SELECT 'POINT(0 0)'::geometry;
使用轉型來建立形狀請注意一件事:除非您指定 SRID,否則您將會得到一個具有未知 SRID 的形狀。您可以使用「延伸」的 Well-Known 文字格式指定 SRID,該格式在前面包含了一個 SRID 區塊
SELECT 'SRID=4326;POINT(0 0)'::geometry;
在處理 WKT 及 geometry 和 geography 欄位時,使用轉型符號是很常見的 (請參閱 Geography)。
9.6. 函式清單¶
ST_Area:傳回曲面的面積,如果它是一個多邊形或多重多邊形。對於「geometry」類型,面積以 SRID 單位為單位。對於「geography」類型,面積以平方公尺為單位。
ST_AsText:傳回幾何/地理資料的 Well-Known Text (WKT) 表示法,不含 SRID 元資料。
ST_AsBinary:傳回幾何/地理資料的 Well-Known Binary (WKB) 表示法,不含 SRID 元資料。
ST_EndPoint:傳回 LINESTRING 幾何資料的最後一點作為 POINT。
ST_AsEWKB:傳回幾何資料的 Well-Known Binary (WKB) 表示法,包含 SRID 元資料。
ST_AsEWKT:傳回幾何圖形的已知文字 (WKT) 表示,具有 SRID 元資料。
ST_AsGeoJSON:傳回幾何圖形作為 GeoJSON 元素。
ST_AsGML:傳回幾何圖形作為 GML 版本 2 或 3 元素。
ST_AsKML:傳回幾何圖形作為 KML 元素。有數種衍生變形。預設版本為 2,預設精確度為 15。
ST_AsSVG:根據幾何圖形或地理物件,傳回 SVG 路徑資料中的幾何圖形。
ST_ExteriorRing:傳回一條線串,代表多邊形幾何圖形的外部環。如果幾何圖形不是多邊形,則傳回 NULL。無法用於多重多邊形。
ST_GeometryN:如果幾何圖形是 GEOMETRYCOLLECTION、多點、多線串、多曲線或多重多邊形,則傳回第 N 個基於 1 的幾何圖形。否則,傳回 NULL。
ST_GeomFromGML:輸入幾何圖形的 GML 表示,並輸出 PostGIS 幾何圖形物件。
ST_GeomFromKML:輸入幾何圖形的 KML 表示,並輸出 PostGIS 幾何圖形物件
ST_GeomFromText:根據已知文字表示 (WKT) 傳回指定的 ST_Geometry 值。
ST_GeomFromWKB:根據已知二進位幾何圖形表示 (WKB) 建立幾何圖形實例,以及選用的 SRID。
ST_GeometryType:傳回 ST_Geometry 值的幾何圖形類型。
ST_InteriorRingN:傳回多邊形幾何圖形的第 N 個內部線串環。如果幾何圖形不是多邊形,或給定 N 超過範圍,則傳回 NULL。
ST_Length:如果線串或多線串為 2d,則傳回幾何圖形的 2d 長度。幾何圖形會以空間參考單位表示,而地理則會以公尺表示(預設球體)
ST_NDims:傳回幾何圖形的座標維度,表示為小整數。值為:2、3 或 4。
ST_NPoints:傳回幾何圖形中的點(頂點)數量。
ST_NRings:如果幾何圖形是多邊形或多重多邊形,則傳回環的數量。
ST_NumGeometries:如果幾何圖形是 GEOMETRYCOLLECTION(或 MULTI*),傳回幾何圖形數量,否則傳回 NULL。
ST_Perimeter:傳回 ST_Surface 或 ST_MultiSurface 值邊界的長度測量。(多邊形、多重多邊形)
ST_SRID:傳回 ST_Geometry 的空間參考識別碼,如 spatial_ref_sys 表格中定義。
ST_StartPoint:將 LINESTRING 幾何的第一個點傳回為點 (POINT)。
ST_X:傳回點的 X 座標,或如果無法取得,則傳回 NULL。輸入必須是點。
ST_Y:傳回點的 Y 座標,或如果無法取得,則傳回 NULL。輸入必須是點。