空間データ型の概要

適用対象:SQL ServerAzure SQL DatabaseAzure SQL Managed Instance

空間データには 2 つの型があります。 geometry データ型は平面 (ユークリッド (平面地球)) データをサポートしています。 geometry データ型 (平面) は、Open Geospatial Consortium (OGC) Simple Features for SQL Specification version 1.1.0 および SQL MM (ISO 標準) の両方に準拠しています。 また、SQL Server では、geography データ型もサポートされています。このデータ型は、GPS の緯度経度座標などの楕円体 (球体地球) データを格納します。

ヒント

SQL Server 空間ツールは、SQL Server の空間型で使用するための、Microsoft によるオープンソースツールのコレクションです。 このプロジェクトでは、アプリケーションが使用できる再利用可能な関数のセットを提供します。 これらの関数には、データ変換ルーチン、新しい変換、集計などが含まれる場合があります。詳細については、GitHub の Microsoft/SQLServerSpatialTools を参照してください。

空間データ オブジェクト

geometrygeography の各データ型は、16 種類の空間データ オブジェクト (インスタンス型) をサポートしています。 ただし、"インスタンス化可能" なインスタンス型、つまりデータベース内でインスタンスを作成して使用することができる (インスタンス化できる) インスタンス型は、そのうちの 11 種類のみです。 これらのインスタンスによって、親データ型から特定のプロパティが派生されます。

次の図は geometry の階層を表しており、geometrygeography の各データ型はこれに基づいています。 geometrygeography のインスタンス化可能な型は青で示されています。

geom_hierarchy

geography データ型には、もう 1 つ FullGlobeというインスタンス化可能な型があります。 geometry 型および geography 型は、特定のインスタンスが適切な形式のインスタンスである限り、明示的に定義されていない場合でも、そのインスタンスを認識できます。 たとえば、STPointFromText() メソッドを使用して Point インスタンスを明示的に定義した場合、そのインスタンスは、メソッドの入力が適切な形式である限り、geometrygeography によって Pointとして認識されます。 STGeomFromText() メソッドを使用して同じインスタンスを定義した場合は、 geometry データ型と geography データ型の両方で Pointとして認識されます。

geometry 型および geography 型のサブタイプには、単純型とコレクション型があります。 STNumCurves() などのメソッドは、単純型でのみ機能します。

単純型:

コレクション型:

geometry と geography の各データ型の違い

多くの場合、2 つの空間データの型は同じように動作します。 データの格納方法と操作方法に重要な違いがいくつかあります。

接続エッジの定義方法

LineString 型と Polygon 型の定義データは頂点のみです。 geometry 型の 2 つの頂点間の接続エッジは直線です。 一方、geography 型の 2 つの頂点間の接続エッジは、2 つの頂点を結ぶ短い方の大楕円弧です。 大楕円は、楕円体とその中心を通る平面の交差部分です。 大楕円弧は、大楕円の円弧セグメントです。

円弧セグメントの定義方法

geometry 型の円弧セグメントは、XY デカルト座標平面上に定義されます (Z 値は無視されます)。 geography 型の円弧セグメントは、参照球の曲線セグメントによって定義されます。 参照球の平行線は、両方の円弧の点に一定の緯度角がある、2 つの補助的な円弧によって定義できます。

空間データ型の測定

平面 (平面地球) 座標系では、距離や面積の測定値は座標と同じ測定単位で表されます。 geometry データ型を使用した場合、(2, 2) と (5, 6) の間の距離は、使用されている単位に関係なく 5 単位になります。

楕円体 (球体地球) 座標系では、座標は緯度と経度で表されます。 ただし、長さと面積は、geography インスタンスの空間参照系識別子によっても異なりますが、通常はメートルと平方メートルで測定されます。 メートルは、 geography データ型の最も一般的な測定単位です。

空間データの方向

平面座標系では、ポリゴンのリングの方向は重要ではありません。 OGC Simple Features for SQL Specification では、リングの順序は定められておらず、SQL Server はリングの順序を強制しません。

楕円体座標系では、ポリゴンは方向がないと意味がなくなります (あいまいになります)。 たとえば、赤道の周りのリングが北半球を表すのか南半球を表すのかがわからなくなります。 geography データ型を使用して空間インスタンスを格納する場合は、リングの方向を指定し、インスタンスの位置を正確に示す必要があります。

楕円体座標系でのポリゴンの内部は、"左手の法則" によって定義されています。geography のポリゴンのリングに沿って歩いていると想像する場合、点が一覧表示されている順序に従って、左側の領域がポリゴンの内部として扱われ、右側の領域がポリゴンの外部として扱われます。

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 が返されます。

SQL Server の FullGlobe は、球全体を覆う特殊な多角形です。 領域はありますが、境界や頂点はありません。

geography データ型の外部および内部のリング

OGC Simple Features for SQL Specification では外部リングと内部リングが取り上げられていますが、SQL Server の geography データ型ではこの区別はほとんど意味を持ちません。ポリゴンのリングはすべて外部リングと見なすことができます。

OGC 仕様の詳細については、以下のドキュメントを参照してください。

円弧セグメント

円弧セグメントでは、 CircularStringCompoundCurveCurvePolygonの 3 つのインスタンス化可能な型を使用できます。 円弧セグメントは、2 次元平面内の 3 つの点によって定義されます。3 番目のポイントを最初のポイントと同じにすることはできません。 円弧セグメントの例をいくつか次に示します。

circular_arc_segments

最初の 2 つの例は、一般的な円弧セグメントを示しています。 3 つの点が 1 つの円周上にあることに注意してください。

他の 2 つの例は、直線セグメントを円弧セグメントとして定義できる方法を示しています。 2 つの点のみによって定義できる通常の直線セグメントとは異なり、円弧セグメントを定義するには 3 つの点が必要です。

円弧セグメント タイプで動作する方法では、直線セグメントを使用して円弧を近似します。円弧の近似に使用される線分の数は、円弧の長さと曲率によって異なります。Z 値は、円弧セグメントの種類ごとに格納できますが、計算には使用されません。

注意

Z 値が円弧セグメントに指定されている場合、円弧セグメントが入力として許容されるようにするには、円弧セグメント内のすべての点で Z 値が同じである必要があります。 たとえば、 CIRCULARSTRING(0 0 1, 2 2 1, 4 0 1) は許容されますが、 CIRCULARSTRING(0 0 1, 2 2 2, 4 0 1) は許容されません。

LineString と CircularString の比較

この例は、LineString インスタンスと CircularString インスタンスの両方を使用して同一の二等辺三角形を格納する方法を示しています。

DECLARE @g1 geometry;
DECLARE @g2 geometry;
SET @g1 = geometry::STGeomFromText('LINESTRING(1 1, 5 1, 3 5, 1 1)', 0);
SET @g2 = geometry::STGeomFromText('CIRCULARSTRING(1 1, 3 1, 5 1, 4 3, 3 5, 2 3, 1 1)', 0);
IF @g1.STIsValid() = 1 AND @g2.STIsValid() = 1
  BEGIN
      SELECT @g1.ToString(), @g2.ToString()
      SELECT @g1.STLength() AS [LS Length], @g2.STLength() AS [CS Length]
  END

CircularString インスタンスは、三角形を定義するために 7 つの点が必要であることに注意してください。 LineString インスタンスは、三角形を定義するために 4 つの点のみが必要です。 その理由は、 CircularString インスタンスは直線セグメントではなく円弧セグメントを格納するためです。 CircularString インスタンスに格納されている三角形の辺は ABC、CDE、および EFA です。 LineString インスタンスに格納されている三角形の辺は、AC、CE、および EA です。

次に例を示します。

SET @g1 = geometry::STGeomFromText('LINESTRING(0 0, 2 2, 4 0)', 0);
SET @g2 = geometry::STGeomFromText('CIRCULARSTRING(0 0, 2 2, 4 0)', 0);
SELECT @g1.STLength() AS [LS Length], @g2.STLength() AS [CS Length];

結果セットは次のようになります。

LS Length    CS Length
5.65685...   6.28318...

CircularString インスタンスでは LineString インスタンスよりも少ない点を使用して、さらに高い精度で曲面境界を格納します。 CircularString インスタンスは、たとえば特定の点から半径 20 マイルの検索を行う際など、円形境界を格納する場合に便利です。 LineString インスタンスは、四角い都市区画のような直線的な境界を格納する場合に適しています。

LineString と CompoundCurve の比較

次のコード例は、 LineString インスタンスと CompoundCurve インスタンスを使用して同じ図を格納する方法を示します。

SET @g = geometry::Parse('LINESTRING(2 2, 4 2, 4 4, 2 4, 2 2)');
SET @g = geometry::Parse('COMPOUNDCURVE((2 2, 4 2), (4 2, 4 4), (4 4, 2 4), (2 4, 2 2))');
SET @g = geometry::Parse('COMPOUNDCURVE((2 2, 4 2, 4 4, 2 4, 2 2))');

上の例では、 LineString インスタンスまたは CompoundCurve インスタンスで図を格納できます。 次の例では、 CompoundCurve を使用して円のスライスを格納します。

SET @g = geometry::Parse('COMPOUNDCURVE(CIRCULARSTRING(2 2, 1 3, 0 2),(0 2, 1 0, 2 2))');  

CompoundCurve インスタンスは円弧セグメント (2 2, 1 3, 0 2) を直接格納できますが、LineString インスタンスでは曲線をいくつかの小さな直線セグメントに変換する必要があります。

CircularString と CompoundCurve の比較

次のコード例は、 CircularString インスタンスに円のスライスを格納する方法を示します。

DECLARE @g geometry;
SET @g = geometry::Parse('CIRCULARSTRING( 0 0, 1 2.1082, 3 6.3246, 0 7, -3 6.3246, -1 2.1082, 0 0)');
SELECT @g.ToString(), @g.STLength();

CircularString インスタンスを使用して円のスライスを格納するには、各直線セグメントで 3 つの点を使用する必要があります。 中間点が不明な場合は、中間点を計算するか、次のスニペットで示すように直線セグメントの端点を二重にする必要があります。

SET @g = geometry::Parse('CIRCULARSTRING( 0 0, 3 6.3246, 3 6.3246, 0 7, -3 6.3246, 0 0, 0 0)');

CompoundCurve インスタンスは LineString コンポーネントおよび CircularString コンポーネントを許可して、認識される必要がある点が、円のスライスの直線セグメントの 2 点だけになるようにします。 このコード例は、 CompoundCurve を使用して同じ図を格納する方法を示します。

DECLARE @g geometry;
SET @g = geometry::Parse('COMPOUNDCURVE(CIRCULARSTRING( 3 6.3246, 0 7, -3 6.3246), (-3 6.3246, 0 0, 3 6.3246))');
SELECT @g.ToString(), @g.STLength();

Polygon と CurvePolygon の比較

CurvePolygon インスタンスは、外部リングと内部リングを定義するときに CircularString インスタンスと CompoundCurve インスタンスを使用できます。 Polygon インスタンスはできません。

関連項目