20. 幾何構建函數¶
到目前為止,我們見識過的所有函數都將幾何「原樣」使用並傳回
物件的分析(ST_Length(geometry)、ST_Area(geometry))、
物件的序列化(ST_AsText(geometry)、ST_AsGML(geometry))、
物件的部分(ST_RingN(geometry,n))或
真/假測試(ST_Contains(geometry,geometry)、ST_Intersects(geometry,geometry))。
「幾何構建函數」將幾何作為輸入並輸出新的形狀。
20.1. ST_Centroid / ST_PointOnSurface¶
在組合空間查詢時,一個常見的需求是使用特徵的點表示取代多邊形特徵。這對於空間聯結很有幫助(如 多邊形/多邊形聯結 所述),因為使用 ST_Intersects(geometry,geometry) 函數對兩個多邊形圖層進行運算時,常常會導致重複計算:一個位在邊界的多邊形會與兩側的物件相交;使用點取代後,就會強制將其置於某一側,而不是兩側。
ST_Centroid(geometry) 會傳回一個點,該點大約落在輸入參數的質量中心。這個簡單的運算速度很快,但有時並非理想的選擇,因為傳回的點不一定會在特徵本身內部。如果輸入特徵具有凸度(想像字母「C」),傳回的質心可能不會在特徵的內部。
ST_PointOnSurface(geometry) 會傳回一個點,保證會位於輸入參數內部。這使得其更適合用於計算空間聯結的「代理點」。

-- Compare the location of centroid and point-on-surface for a concave geometry
SELECT ST_Intersects(geom, ST_Centroid(geom)) AS centroid_inside,
ST_Intersects(geom, ST_PointOnSurface(geom)) AS pos_inside
FROM (VALUES
('POLYGON ((30 0, 30 10, 10 10, 10 40, 30 40, 30 50, 0 50, 0 0, 0 0, 30 0))'::geometry)
) AS t(geom);
centroid_inside | pos_inside
-----------------+------------
f | t
20.2. ST_Buffer¶
緩衝區運算在 GIS 流程中很常見,PostGIS 中也有提供。 ST_Buffer(geometry,distance) 函數會接收緩衝區距離和幾何類型,並且輸出一個多邊形,其邊界與輸入幾何的距離為緩衝區距離。

例如,如果美國國家公園管理局想要實施保護自由女神像周圍的海洋交通,他們可能會在自由女神像周圍建立一個 500 公尺的緩衝區多邊形。自由女神像是我們 nyc_census_blocks
表中的一個普查區塊,所以我們可以輕鬆地將其萃取出來並建立緩衝區。
-- Make a new table with a Liberty Island 500m buffer zone
CREATE TABLE liberty_island_zone AS
SELECT ST_Buffer(geom,500)::geometry(Polygon,26918) AS geom
FROM nyc_census_blocks
WHERE blkid = '360610001001001';

ST_Buffer 函數也接受負距離,並在多邊形輸入中建立內接多邊形。對於線和點,您只會得到一項空回傳。

20.3. ST_Intersection¶
另一個經典 GIS 操作「疊加」透過計算兩個疊加多邊形的交集,建立新的覆蓋圖層。結果具有以下屬性:結果中任何一個多邊形都可透過合併結果中的多邊形建立。
ST_Intersection(geometry A, geometry B) 函數回傳兩個參數都共有的空間區域(或線,或點)。如果參數不相交,函數會回傳空白幾何圖形。
-- What is the area these two circles have in common?
-- Using ST_Buffer to make the circles!
SELECT ST_AsText(ST_Intersection(
ST_Buffer('POINT(0 0)', 2),
ST_Buffer('POINT(3 0)', 2)
));

20.4. ST_Union¶
在前一個範例中,我們相交幾何圖形,創造一個包含兩個輸入的新幾何圖形。ST_Union 函數則反向運作;它需要輸入而且會移除常見線。有兩種形式的 ST_Union 函數
ST_Union(geometry, geometry):雙引數版本,需要輸入兩個幾何圖形並回傳合併的聯集。例如,當您在前一個區塊中將交集替換成聯集,我們前一個區塊的兩個圓形範例如下所示。
-- What is the total area these two circles cover? -- Using ST_Buffer to make the circles! SELECT ST_AsText(ST_Union( ST_Buffer('POINT(0 0)', 2), ST_Buffer('POINT(3 0)', 2) ));
ST_Union([geometry]):集合版本,需要輸入一組幾何圖形並回傳整個群組的合併幾何圖形。集合 ST_Union 可搭配
GROUP BY
SQL 陳述式使用,以建立基礎幾何圖形的小心合併子集。它的功能非常強大。
以 ST_Union 集合為例,考慮我們的 nyc_census_blocks
表格。人口普查地理是以小心構築的方式,以便可以從較小地理建立較大地理。因此,我們可以透過合併形成每個區劃的區塊來建立人口普查區劃地圖(就像我們稍後在 建立人口普查區地圖 中會做的那樣)。或者,我們可以透過合併縣中所有的區塊來建立縣地圖。
要執行合併,請注意唯一鍵 blkid
實際上包括較高級別地理資訊。以下是我們先前用過的自由島的關鍵部分
360610001001001 = 36 061 000100 1 001
36 = State of New York
061 = New York County (Manhattan)
000100 = Census Tract
1 = Census Block Group
001 = Census Block
因此,我們可以透過合併其 blkid
中前 5 個數字相同的,所有的幾何圖形資料,建立縣地圖。請耐心等待,這是運算成本很高的步驟,可能會花費一、兩分鐘。
-- Create a nyc_census_counties table by merging census blocks
CREATE TABLE nyc_census_counties AS
SELECT
ST_Union(geom)::Geometry(MultiPolygon,26918) AS geom,
SubStr(blkid,1,5) AS countyid
FROM nyc_census_blocks
GROUP BY countyid;

面積測試可以確認,我們的聯集運算沒有遺失任何幾何圖形。首先,我們計算個別人口普查區塊的面積,並對這些面積進行分組求和,依據人口普查縣 ID 分組。
SELECT SubStr(blkid,1,5) AS countyid, Sum(ST_Area(geom)) AS area
FROM nyc_census_blocks
GROUP BY countyid
ORDER BY countyid;
countyid | area
----------+------------------
36005 | 110196022.906506
36047 | 181927497.678368
36061 | 59091860.6261323
36081 | 283194473.613692
36085 | 150758328.111199
接著,從 county 表格中計算每一個新的行政區多邊形的面積
SELECT countyid, ST_Area(geom) AS area
FROM nyc_census_counties
ORDER BY countyid;
countyid | area
----------+------------------
36005 | 110196022.906507
36047 | 181927497.678367
36061 | 59091860.6261324
36081 | 283194473.593646
36085 | 150758328.111199
相同答案!我們已從人口普查區塊資料中成功建立紐約市行政區表格。
20.5. 函數列表¶
ST_Centroid(geometry):傳回一個代表輸入幾何之質心的點幾何。
ST_PointOnSurface(geometry):傳回保證位於輸入幾何內部的點幾何。
ST_Buffer(geometry, distance):針對幾何:傳回一個幾何,代表所有距離此幾何的點小於或等於 distance。計算為此幾何之空間參考系統。針對地理:使用平面轉換包裝器。
ST_Intersection(geometry A, geometry B):傳回一個幾何,代表 geomA 與 geomB 的共有部分。地理實作會進行幾何轉換來執行交集,然後再轉換回 WGS84。
ST_Union():傳回一個幾何,代表幾何的點集聯集。
ST_AsText(text):傳回幾何/地理的 Well-Known Text (WKT) 表示,但不含 SRID 元資料。
substring(string [from int] [for int]):PostgreSQL 字串函式,用於萃取符合 SQL 正規表示式的子字串。
sum(expression):PostgreSQL 聚集函式,傳回一組記錄中記錄的總和。