Polygon
Polygon 是儲存為一連串點的二維度介面,這些點可定義一個外部週框環形以及零或多個內部環形。
Polygon 執行個體
Polygon 執行個體可以從環形組成 (此環形至少有三個相異點)。Polygon 執行個體也可以是空的。
Polygon 的外部和任何內部環形定義了它的界限。此環形內的空間定義了 Polygon 的內部。
下圖顯示 Polygon 執行個體的範例。
如本圖所示:
圖 1 是 Polygon 執行個體,其界限是由外部環形所定義。
圖 2 是 Polygon 執行個體,其界限是由一個外部環形和兩個內部環形所定義。內部環形內的區域是 Polygon 執行個體外部的一部分。
圖 3 是有效的 Polygon 執行個體,因為它的內部環形會在單一正切點上相交。
接受的執行個體
接受的 Polygon 執行個體就是可儲存在 geometry 或 geography 變數中,而不會擲回例外狀況的執行個體。下面是 geometry 類型之接受的 Polygon 執行個體:
空的 Polygon 執行個體
具有一個可接受之外部環形以及零或多個可接受之內部環形的 Polygon 執行個體
下列準則是要讓環形成為可接受環形的必要準則。
系統必須接受 LineString 執行個體。
LineString 執行個體至少必須具有四個點,其中包括三個相異點。
LineString 執行個體的起點和終點必須具有相同的 X 和 Y 值。
[!附註]
系統會忽略 Z 和 M 值。
只有當屬於 geography 類型的 Polygon 執行個體有效時,系統才會接受此執行個體。如需詳細資訊,請參閱<Valid Geography Polygon Instances>。
下列範例顯示屬於 geometry 類型之接受的 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))';
如 @g4 所示,接受的 Polygon 執行個體可能不是有效的 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 執行個體的有效性取決於其變數類型。
Geometry 資料類型
若要讓屬於 geometry 類型的 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) )';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid(), @g5.STIsValid();
@g1 無效,因為內部環形與外部環形有兩個接觸點。@g2 無效,因為第二個內部環形位於第一個內部環形的內部。@g3 無效,因為這兩個內部環形在多個連續點上接觸。@g4 無效,因為這兩個內部環形的內部重疊。@g5 無效,因為第一個環形是內部環形,而第二個環形是外部環形。
Geography 資料類型
若要讓屬於 geography 類型的 Polygon 執行個體有效,它必須符合下列準則:
此執行個體必須符合所有必要的規則,才能成為屬於 geometry 類型之接受的 Polygon 執行個體。
此執行個體的內部已使用左側規則連接。
此執行個體可容納在半球中。
沒有任何環形自行交叉或與任何其他環形交叉。
所有環形都只能在零或有限的正切點數上彼此接觸或與任何其他環形接觸。
下列範例會擲回 Microsoft.SqlServer.Types.GLArgumentException,因為 Polygon 執行個體超過半球。
DECLARE @g geography = 'POLYGON((-122.358 47.653, 122.348 47.649, 122.348 47.658, 122.358 47.658, -122.358 47.653))';
下列範例顯示 geography 類型之有效的 Polygon 執行個體。
DECLARE @g geography = 'POLYGON((-122.358 47.653, -122.348 47.649, -122.348 47.658, -122.358 47.658, -122.358 47.653))';
範例
下列範例會建立包含一個洞及 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);
可輸入無效的執行個體,並將它轉換成有效的 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))');
在下列範例中,會使用 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)))