Polygon

適用対象: SQL Server Azure SQL データベース Azure SQL Managed Instance

Polygon は、1 つの外部境界リングと 0 個以上の内部リングを定義する一連の点として格納される 2 次元表面です。

Polygon インスタンス

Polygon インスタンスは、3 つ以上の異なる点を持つリングで形成されます。 Polygon インスタンスは空にすることもできます。

Polygon の外部および内部のリングは、その境界を定義します。 リング内の空間は Polygonの内部を定義します。

次の図は、 Polygon インスタンスの例です。

geometry Polygon インスタンスの例

この図は次のことを示しています。

  1. 図 1 は、外部リングによって境界が定義されている Polygon インスタンスです。

  2. 図 2 は、1 つの外部リングと 2 つの内部リングによって境界が定義されている Polygon インスタンスです。 内部リングの内側の領域は、 Polygon インスタンスの外部の一部です。

  3. 図 3 の Polygon インスタンスは、内部リングが 1 つの接点で交差しているため有効です。

許容されるインスタンス

許容される Polygon インスタンスとは、例外をスローすることなく geometry 変数または geography 変数に格納できるインスタンスです。 次に示す Polygon インスタンスは許容されます。

  • 空の Polygon インスタンス
  • 1 つの許容される外部境界リング (LineString) と 0 個以上の許容される内部リング (LineString) を持つ Polygon インスタンス

リング (LineString) が許容されるためには、次の条件を満たす必要があります。

  • LineString インスタンスが許容されていること。
  • LineString インスタンスに 4 つ以上の点があること。
  • 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 インスタンスが許容されるためには、4 つの点を持つリングのみが含まれている必要があることを示しています。

次の例では、 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))';  

外部リングの LineString インスタンスが十分な数の点を含んでいないため、@g1 は許容されません。 外部リングの LineString インスタンスの始点が終点と同じでないため、@g2 は許容されません。 次の例では、外部リングは許容されますが、内部リングが許容されません。 この場合も System.FormatExceptionがスローされます。

DECLARE @g geometry = 'POLYGON((-5 -5, -5 5, 5 5, 5 -5, -5 -5),(0 0, 3 0, 0 0))';  

有効なインスタンス

Polygon の内部リングは、1 つの接点で自身および他の内部リングと接することができますが、 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 2 つの内部リングが 1 つの点で接し、互いに交差していないため、有効です。 次の例は、無効な 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();  

内部リングが 2 か所で外部リングに接しているため、@g1 は無効です。 2 つ目の内部リングが 1 つ目の内部リングの内側にあるため、@g2 は無効です。 2 つの内部リングが連続する複数の点で接しているため、@g3 は無効です。 2 つの内部リングの内部が交差しているため、@g4 は無効です。 外部リングが 1 つ目のリングでないため、@g5 は無効です。 リングが 3 つ以上の異なる点を持たないため、@g6 は無効です。

空間データの方向

平面座標系では、ポリゴンのリングの方向は重要ではありません。 OGC Simple Features for SQL Specification では、リングの順序は定められておらず、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;

「左手ルール」の反時計回りの向きの視覚化

時計回り

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 インスタンスが 1 つの半球に収まる必要があります。 半球よりも大きい空間オブジェクトを格納することはできません。

  • Open Geospatial Consortium (OGC) の Well-Known Text (WKT) 表現または Well-Known Binary (WKB) 表現の geography インスタンスでは、半球より大きいオブジェクトが生成される場合に ArgumentExceptionがスローされます。

  • 2 つの geography インスタンスの入力を必要とする geography データ型のメソッド (STIntersection()、STUnion()、STDifference()、STSymDifference() など) では、メソッドの結果が 1 つの半球に収まらない場合に null が返されます。 STBuffer() でも、出力が 1 つの半球に収まらない場合に null が返されます。

ReorientObject 拡張メソッドを使用して方向を反転できます。

例 A.

次の例では、1 つのすき間を持つ単純な geometry Polygon インスタンスを作成しています。SRID は 10 です。

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。

無効なインスタンスを有効なジオメトリ インスタンスに変換する別の例を示します。 次の例では、まったく同じ 3 つの点を使用して Polygon インスタンスが作成されています。

DECLARE @g geometry  
SET @g = geometry::Parse('POLYGON((1 3, 1 3, 1 3, 1 3))');  
SET @g = @g.MakeValid();  
SELECT @g.ToString()  

上の例で返されるジオメトリ インスタンスは 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 データ型)