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) 會傳回一個點,保證會位於輸入參數內部。這使得其更適合用於計算空間聯結的「代理點」。

_images/centroid.jpg
-- 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) 函數會接收緩衝區距離和幾何類型,並且輸出一個多邊形,其邊界與輸入幾何的距離為緩衝區距離。

_images/st_buffer.png

例如,如果美國國家公園管理局想要實施保護自由女神像周圍的海洋交通,他們可能會在自由女神像周圍建立一個 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';
_images/liberty_positive.jpg

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

_images/liberty_negative.jpg

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)
));
_images/intersection.jpg

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)
    ));
    
    _images/union.jpg
  • 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;
_images/union_counties.png

面積測試可以確認,我們的聯集運算沒有遺失任何幾何圖形。首先,我們計算個別人口普查區塊的面積,並對這些面積進行分組求和,依據人口普查縣 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 聚集函式,傳回一組記錄中記錄的總和。