分享方式:


Polygon

適用於:SQL ServerAzure SQL DatabaseAzure SQL 受控執行個體

Polygon 是儲存為一連串點的二維介面,這些點可定義一個外部週框環形以及零個或多個內部環形。

Polygon 執行個體

Polygon 執行個體可以從環形組成 (此環形至少有三個相異點)。 Polygon 執行個體也可以是空的。

Polygon 的外部和任何內部環形定義了它的界限。 此環形內的空間定義了 Polygon的內部。

下圖顯示 Polygon 執行個體的範例。

Examples of geometry Polygon instances

如本圖所示:

  1. 圖 1 是 Polygon 執行個體,其界限是由外部環形所定義。

  2. 圖 2 是 Polygon 執行個體,其界限是由一個外部環形和兩個內部環形所定義。 內部環形內的區域是 Polygon 執行個體外部的一部分。

  3. 圖 3 是有效的 Polygon 執行個體,因為它的內部環形會在單一正切點上相交。

已接受的執行個體

已接受的 Polygon 執行個體是指可儲存在 geometrygeography 變數中而不會擲回例外狀況的執行個體。 已接受的 Polygon 執行個體如下:

  • 空白的 Polygon 執行個體
  • 具有可接受之外環 (LineString) 以及零或多個可接受之內環 (LineStrings) 的 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 多邊形的環形、並遵循點所列出的順序行走,則左邊區域會視為多邊形的內部,右邊區域則為多邊形的外部。

逆時針方向

DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 0 0, 20 0, 20 20, 0 20))', 4326);
SELECT @square;

Visualization of 'left-hand rule' counter-clockwise orientation

順時針

DECLARE @square GEOGRAPHY;
SET @square = GEOGRAPHY::STPolyFromText('POLYGON((0 20, 20 20, 20 0, 0 0, 0 20))', 4326);
SELECT @square;

Visualization of 'left-hand rule' clockwise orientation

在 SQL Server 中,當相容性層級為 100 以下時,geography 資料類型就具有下列限制:

  • 每一個 geography 執行個體都必須納入單一半球。 大於半球的空間物件將無法儲存。

  • 當來自開放式地理空間協會 (Open Geospatial Consortium, OGC) 已知的文字 (Well-Known Text, WKT) 或已知的二進位 (Well-Known Binary, WKB) 表示法的任何 geography 執行個體產生大於半球的物件時,都會擲回 ArgumentException。

  • 需要兩個地理執行個體輸入的地理資料類型方法 (例如 STIntersection()、STUnion()、STDifference() 及 STSymDifference()),會在這些方法的結果不符合單一半球大小時,傳回 null。 如果輸出超過單一半球,STBuffer() 也會傳回 null。

方向可以利用 ReorientObject 擴充方法來反轉。

範例

範例 A。

下列範例會建立包含間距及 SRID 10 的簡單 geometryPolygon 執行個體。

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.

這是另一個將無效執行個體轉換成有效 geometry 執行個體的範例。 在下列範例中,我們已經使用三個完全相同的點來建立 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)。 如果給定的 PolygonPOLYGON((1 3, 1 5, 1 3, 1 3)) ,則 MakeValid() 就會傳回 LINESTRING(1 3, 1 5)

另請參閱

STArea (geometry 資料類型)
STExteriorRing (geometry 資料類型)
STNumInteriorRing (geometry 資料類型)
STInteriorRingN (geometry 資料類型)
STCentroid (geometry 資料類型)
STPointOnSurface (geometry 資料類型)
MultiPolygon
空間資料 (SQL Server)
STIsValid (geography 資料類型)
STIsValid (geometry 資料類型)