11. 空間關係¶
到目前為止,我們僅使用測量 (ST_Area、ST_Length)、序列化 (ST_GeomFromText) 或反序列化 (ST_AsGML) 幾何圖形的空間函數。這些函數的共通點是,它們一次只針對一個幾何圖形運作。
空間資料庫強大之處,在於它們不僅儲存幾何圖形,還能比較幾何圖形之間的關係。
「哪些腳踏車架最靠近公園?」或「地鐵線和街道的交叉點在哪裡?」等問題,只能透過比較表示腳踏車架、街道和地鐵線的幾何圖形才能解答。
OGC 標準定義了用於比較幾何圖形的下列方法集。
11.1. ST_Equals¶
ST_Equals(geometry A, geometry B) 測試兩個幾何圖形的空間相等性。

ST_Equals 會傳回 TRUE,當兩個相同類型的幾何圖形具有相同的 X,Y 座標值,亦即,如果第二個形狀等於(相同)第一個形狀。
首先,我們從 nyc_subway_stations
表格中擷取一個點的表示。我們只取 'Broad St' 的項目。
SELECT name, geom
FROM nyc_subway_stations
WHERE name = 'Broad St';
name | geom
----------+---------------------------------------------------
Broad St | 0101000020266900000EEBD4CF27CF2141BC17D69516315141
接著,將幾何圖形表示塞回 ST_Equals 測試中
SELECT name
FROM nyc_subway_stations
WHERE ST_Equals(
geom,
'0101000020266900000EEBD4CF27CF2141BC17D69516315141');
Broad St
注意
這個點的表示並不好讀 (0101000020266900000EEBD4CF27CF2141BC17D69516315141
),但它準確表示座標值。對於相等性等測試而言,使用精確座標是必要的。
11.2. ST_Intersects、ST_Disjoint、ST_Crosses 和 ST_Overlaps¶
ST_Intersects、ST_Crosses 和 ST_Overlaps 測試幾何圖形的內部是否相交。

ST_Intersects(geometry A, geometry B) 如果這兩個形狀有任何空間共用,即其邊界或內部相交,則會傳回 t (TRUE)。

ST_Intersects 的相反詞為 ST_Disjoint(geometry A , geometry B)。如果兩個幾何不相交,它們不會互交,反之亦然。事實上,測試「不相交」通常比測試「相離」更有效率,這是因為相交測試可以根據空間索引,而相離測試則不行。

對於多點/多邊形、多點/線串、線串/線串、線串/多邊形、以及線串/多多邊形比較,ST_Crosses(geometry A, geometry B) 如果交集的結果為維度低於兩個原始幾何最大維度一級的幾何,而且交集集合是兩個原始幾何的內部,則會傳回 t (真值)。

ST_Overlaps(geometry A, geometry B) 比較兩個維度相同的幾何,而且如果其交集集合的結果為與兩個原始幾何維度不同,但卻為相同維度的幾何,則會傳回 TRUE。
讓我們使用 ST_Intersects 函數,來針對 Broad Street 地鐵站找出鄰近地區
SELECT name, ST_AsText(geom)
FROM nyc_subway_stations
WHERE name = 'Broad St';
POINT(583571 4506714)
SELECT name, boroname
FROM nyc_neighborhoods
WHERE ST_Intersects(geom, ST_GeomFromText('POINT(583571 4506714)',26918));
name | boroname
--------------------+-----------
Financial District | Manhattan
11.3. ST_Touches¶
ST_Touches 測試兩個幾何是否在它們的邊界處相切,但在它們的內部不相交

ST_Touches(geometry A, geometry B) 如果任一個幾何邊界相交,或如果只有一個幾何內部與另一個的邊界相交,則會傳回 TRUE。
11.4. ST_Within 和 ST_Contains¶
ST_Within 和 ST_Contains 測試一個幾何是否完全在另一個內部。

ST_Within(geometry A , geometry B) 如果第一個幾何完全在第二個幾何內,則會傳回 TRUE。ST_Within 測試與 ST_Contains 結果完全相反。
ST_Contains(geometry A, geometry B) 如果第二個幾何完全包含在第一個幾何內,則會傳回 TRUE。
11.5. ST_Distance 和 ST_DWithin¶
一個 GIS 中極常見的問題就是「找出距離這其他東西 X 距離內的所有事物」。
ST_Distance(geometry A, geometry B) 計算兩個幾何之間的最短距離並傳回一個浮動數值。這可以用來回報物件之間的距離。
SELECT ST_Distance(
ST_GeometryFromText('POINT(0 5)'),
ST_GeometryFromText('LINESTRING(-2 2, 2 2)'));
3
若要測試兩個物件是否在彼此距離內,ST_DWithin 函數提供一個索引加速的真/假測試。這可以回答像「有多少棵樹在道路的 500 公尺緩衝區內?」的問題。你不需要計算實際的緩衝區,你只要測試距離關係即可。

再次使用我們的 Broad Street 地鐵站,我們可以找到地鐵站附近(在 10 公尺內)的街道
SELECT name
FROM nyc_streets
WHERE ST_DWithin(
geom,
ST_GeomFromText('POINT(583571 4506714)',26918),
10
);
name
--------------
Wall St
Broad St
Nassau St
而我們可以在地圖中驗證答案。Broad St. 車站實際位於 Wall、Broad 和 Nassau 街的交叉口。

11.6. 函數清單¶
ST_Contains(geometry A, geometry B):若且唯若 B 的所有點不在 A 的外部,且 B 內部至少一點位於 A 的內部中,則回傳 true。
ST_Crosses(geometry A, geometry B):若提供的幾何圖形中,有一些(但不是全部)內部點共用,則回傳 TRUE。
ST_Disjoint(geometry A , geometry B):若幾何圖形「沒有空間相交」 - 它們並不共用任何空間 - 則回傳 TRUE。
ST_Distance(geometry A, geometry B):以投射單位,回傳兩個幾何圖形在 2 維笛卡爾座標系統中最小距離(根據空間參考)。
ST_DWithin(geometry A, geometry B, radius):若幾何圖形彼此的距離在特定距離範圍(半徑)內,則回傳 true。
ST_Equals(geometry A, geometry B):若兩個幾何圖形表示相同的幾何圖形時,則回傳 true。方向性將予忽略。
ST_Intersects(geometry A, geometry B):若幾何圖形/地理空間資料「有空間相交」 - (共享任何部分的空間),則回傳 TRUE;若沒有空間相交(它們不相交),則回傳 FALSE。
ST_Overlaps(geometry A, geometry B):若幾何圖形共用空間、維度相同,但彼此並不完全包圍,則回傳 TRUE。
ST_Touches(geometry A, geometry B):若幾何圖形至少有一個點是共用的,但內部沒有相交,則回傳 TRUE。
ST_Within(geometry A , geometry B):若幾何圖形 A 完全在幾何圖形 B 內,則回傳 true。