Share via


Polygon

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

Polygon 例項

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

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

下圖顯示 Polygon 例項的範例。

幾何 Polygon 執行個體的範例

如本圖所示:

  1. 圖 1 是 Polygon 例項,其界限是由外部環形所定義。

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

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

接受的例項

接受的 Polygon 例項是可以儲存在 geometry 或 geography 變數中而不會擲回例外狀況的例項。下列為 geometry 類型接受的 Polygon 例項:

  • 空的 Polygon 例項。

  • 具有可接受外部環形及零個或多個可接受內部環形的 Polygon 例項。

如果要讓環形為可接受的狀態,則需要下列準則。

  • 必須已接受 LineString 例項。

  • LineString 例項必須至少有四個點包含三個相異點。

  • LineString 例項的起點和結束點必須擁有相同的 X 和 Y 值。

    [!附註]

    Z 和 M 值會遭到忽略。

只有當此例項有效時,才會接受 geography 類型的 Polygon 例項。如需有關 geography 類型之有效 Polygon 例項的詳細資訊,請參閱<BkmkValidGeographyPolygons>。

下列範例會顯示接受的 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 的內部環形可以在單一正切點上接觸其本身及彼此接觸,但是如果 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))';
SELECT @g1.STIsValid(), @g2.STIsValid(), @g3.STIsValid(), @g4.STIsValid();

@g1 無效,因為內部環形在兩個地方接觸外部環形。@g2 無效,因為第二個內部環形位於第一個內部環形的內部。@g3 無效,因為兩個內部環形在多個連續點接觸。@g4 無效,因為兩個內部環形的內部重疊。

Geometry 資料類型

geometry 類型的 Polygon 例項必須符合以下準則,才會有效:

  1. 第一個環形是外部環形。

  2. 所有內部環形都在外部環形內。

  3. 沒有任何內部環形位於另一個內部環形內。

  4. 沒有任何環形會與自己或另一個環形相交。

  5. 沒有兩個環形可以共用相同的邊緣。

  6. 內部環形的內部不能與另一個內部環形的內部重疊。

  7. 所有環形只能在零個或有限正切點數上觸及其自身或另一個環形。

  8. 連接 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 例項必須符合以下準則,才會有效:

  1. 此例項必須符合所有必要的規則,才會是 geometry 類型的接受 Polygon 例項。

  2. 此例項的內部是使用左手規則連接。

  3. 此例項可以納入半球範圍內。

  4. 沒有任何環形會與自己或其他任何環形相交。

  5. 所有環形只能在零個或有限正切點數上觸及其自身或其他任何環形。

下列範例會擲回 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)))