適用於:SQL Server
Azure SQL 資料庫
Azure SQL 受控執行個體
Microsoft Fabric 中的 SQL 分析端點
Microsoft Fabric 中的倉儲
Microsoft Fabric 中的 SQL 資料庫
Polygon 是以一系列點儲存的二維曲面,這些點定義了一個外部邊界環以及零個或多個內部環。
多邊形實例
Polygon 執行個體可由至少具有三個相異點的一個環構成。 Polygon 執行個體也可以是空的。
Polygon 的外部和任何內部環形定義了它的界限。 此環形內的空間定義了 Polygon的內部。
下圖顯示 Polygon 執行個體的範例。
如本圖所示:
圖 1 是一個 Polygon 實例,其邊界由外環所定義。
圖 2 是一個 Polygon 實例,其邊界由一個外環和兩個內環所定義。 位於內部環內的區域屬於 Polygon 執行個體外部的一部分。
圖 3 是有效的 Polygon 執行個體,因為它的內部環形會在單一正切點上相交。
已接受的執行個體
已接受的 Polygon 執行個體是指可儲存在 geometry 或 geography 變數中而不會擲回例外狀況的執行個體。 以下是可接受的 Polygon 執行個體:
- 空白的 Polygon 執行個體
- 具有可接受的外環(LineString)以及零個或多個可接受的內環(LineString)的 Polygon 執行個體。
環(LineString)若要被視為可接受,必須符合下列條件。
- 系統必須接受 LineString 執行個體。
- LineString 執行個體至少必須具有四個點。
- LineString 執行個體的開始和結束點必須相同。
下列範例顯示可接受的 Polygon 執行個體。
DECLARE @g1 geometry = 'POLYGON EMPTY';
DECLARE @g2 geometry = 'POLYGON((1 1, 3 3, 3 1, 1 1))';
DECLARE @g3 geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 3 3, 0 3, 0 0))';
DECLARE @g4 geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(3 0, 6 0, 6 3, 3 3, 3 0))';
DECLARE @g5 geometry = 'POLYGON((1 1, 1 1, 1 1, 1 1))';
如 @g4 和 @g5 所示,已接受的 Polygon 實例可能不是有效的 Polygon 實例。
@g5 也顯示,Polygon 執行個體只需包含一個由任意四個點構成的環,即可被接受。
下列範例會擲回 System.FormatException,因為系統不接受 Polygon 執行個體。
DECLARE @g1 geometry = 'POLYGON((1 1, 3 3, 1 1))';
DECLARE @g2 geometry = 'POLYGON((1 1, 3 3, 3 1, 1 5))';
@g1 不被接受,因為外環的 LineString 實例未包含足夠數量的點。 不接受 @g2,因為外部環形 LineString 執行個體的起點與終點不相同。 下列範例具有可接受的外部環形,但是內部環形不是可接受的環形。 這也會擲出 System.FormatException。
DECLARE @g geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 0 0))';
有效的執行個體
Polygon 的內環可在單一相切點與自身及彼此接觸,但如果 Polygon 的內環互相交叉,則此實例無效。
下列範例顯示有效的 Polygon 執行個體。
DECLARE @g1 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20))';
DECLARE @g2 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0))';
DECLARE @g3 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 0 10, -5 -10, -10 0))';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid();
@g3 是有效的,因為這兩個內部環僅在一個點接觸,且不會彼此交叉。 下列範例顯示無效的 Polygon 執行個體。
DECLARE @g1 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (20 0, 0 10, 0 -20, 20 0))';
DECLARE @g2 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (5 0, 1 5, 1 -5, 5 0))';
DECLARE @g3 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 0 10, 0 -10, -10 0))';
DECLARE @g4 geometry = 'POLYGON((-20 -20, -20 20, 20 20, 20 -20, -20 -20), (10 0, 0 10, 0 -10, 10 0), (-10 0, 1 5, 0 -10, -10 0))';
DECLARE @g5 geometry = 'POLYGON((10 0, 0 10, 0 -10, 10 0), (-20 -20, -20 20, 20 20, 20 -20, -20 -20) )';
DECLARE @g6 geometry = 'POLYGON((1 1, 1 1, 1 1, 1 1))';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid(), @g5.STIsValid(), @g6.STIsValid();
@g1 不是有效的,因為內環在兩處與外環接觸。
@g2 無效,因為第二個內部環形位於第一個內部環形的內部。
@g3 是無效的,因為兩個內環在多個連續點相互接觸。
@g4 無效,因為兩個內環的內部彼此重疊。
@g5 無效,因為外環不是第一個環。
@g6 無效,因為環形並未包含至少三個不同的點。
空間資料的方向
在平面系統中,多邊形的環形方向不是重要因素。 OGC 的 SQL 簡單特徵規格並未指示環形順序,且 SQL Server 並未強制使用環形順序。
在橢圓體系統中,多邊形如果沒有方向的話,將沒有任何意義或模稜兩可。 例如,包圍赤道的環形是要描述北半球還是南半球? 如果我們使用 geography 資料類型來儲存空間執行個體,就必須指定此環形的方向,並正確描述此執行個體的位置。
在橢球體系統中,多邊形的內部是由「左手定則」所定義:如果您想像自己沿著 geography Polygon 的環、依照點列出的順序前進,則左側區域會被視為 Polygon 的內部,而右側區域則被視為 Polygon 的外部。
Counter-clockwise
DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 0 0, 20 0, 20 20, 0 20))', 4326);
SELECT @square;
Clockwise
DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 20 20, 20 0, 0 0, 0 20))', 4326);
SELECT @square;
當 SQL Server 中的相容性層級為 100 或更低時, geography 數據類型有下列限制:
每個 geography 執行個體都必須位於同一個半球內。 大於半球大小的空間物件無法儲存。
當來自開放式地理空間協會 (Open Geospatial Consortium, OGC) 已知的文字 (Well-Known Text, WKT) 或已知的二進位 (Well-Known Binary, WKB) 表示法的任何 geography 執行個體產生大於半球的物件時,都會擲回 ArgumentException。
需要輸入兩個 geography 執行個體的 geography 資料類型方法(例如
STIntersection()、STUnion()、STDifference()和STSymDifference()),如果這些方法的結果無法落在單一半球內,則會傳回 null。STBuffer()也會在輸出超過單一半球時傳回 null。
可利用 ReorientObject (geography 資料類型) 擴充方法來反轉方向。
Examples
範例 A。
下列範例會建立包含間距及 SRID 10 的簡單 geometry Polygon 執行個體。
DECLARE @g geometry;
SET @g = geometry::STPolyFromText(
'POLYGON((0 0, 0 3, 3 3, 3 0, 0 0), (1 1, 1 2, 2 1, 1 1))',
10);
範例 B.
無效的實例可以輸入並轉換成有效的 geometry 實例。 在下列 Polygon 的範例中,內環與外環重疊,因此該實例無效。
DECLARE @g geometry;
SET @g = geometry::Parse(
'POLYGON((1 0, 0 1, 1 2, 2 1, 1 0), (2 0, 1 1, 2 2, 3 1, 2 0))'
);
範例 C。
在下列範例中,會使用 MakeValid()讓無效的執行個體變成有效。
SET @g = @g.MakeValid();
SELECT @g.ToString();
從上一個範例傳回的 geometry 執行個體是 MultiPolygon。
MULTIPOLYGON (((2 0, 3 1, 2 2, 1.5 1.5, 2 1, 1.5 0.5, 2 0)),
((1 0, 1.5 0.5, 1 1, 1.5 1.5, 1 2, 0 1, 1 0)))
範例 D.
這是另一個將無效執行個體轉換為有效幾何執行個體的範例。 在下列範例中,我們已經使用三個完全相同的點來建立 Polygon 執行個體:
DECLARE @g geometry
SET @g = geometry::Parse('POLYGON((1 3, 1 3, 1 3, 1 3))');
SET @g = @g.MakeValid();
SELECT @g.ToString()
先前傳回的 geometry 實體是 Point(1 3)。 如果給定的 Polygon 為 POLYGON((1 3, 1 5, 1 3, 1 3)) ,則 MakeValid() 就會傳回 LINESTRING(1 3, 1 5)。