第 11 章 空間オブジェクトのプロパティを検査する(Begining Spatial with SQL Server 2008)

第 4 部 空間データの解析

 本書のこの部では,geography 型および geometry 型でデータをフィルターし解析できるメソッドを論ずる.それはアプリケーションにおいて空間データの力を開発するのに使うのに必要な主要な機能を提供してくれる.
 そのメソッドは3つのカテゴリに分類される.章ごとに一つ.第11章では個別の空間オブジェクトのプロパティについての情報を解析して返すメソッドを扱う.第12章では既存のオブジェクト間の組み合わせまたは修飾の間の新しいオブジェクトを定義するメソッドをカバーする.第13章ではオブジェクト間の関係をテストするメソッドを紹介する.例えば同一性,近接性,交差などである.

第 11 章 空間オブジェクトのプロパティを検査する

 空間データの個々のアイテムについて多くの異なる質問が湧いてきていると思う.それはどこにあるのか?それはどれくらい大きいのか?そのオブジェクトはどんな種類なのか?それはどこから始まりどこで終わるのか?その中心はどこに位置するのか?本章では,SQL Server が提供するメソッドをテストしてこれら全ておよびそれ以上の質問に答えようと思う.本章で論ずるすべてのテクニックを単一の geometry 型および geography 型のアイテムに適用するだけで,一般にはいかなるパラメータをも要しない.インスタンスのプロパティにアクセスするために必要な標準的な構文は故に次に示すようになる.

Instance.Property

ここで言う Instance は問い合わせたい情報に関連する列または変数の名前であり,Property は問題の特定の名前である.

 ある例では,アイテムに関する情報の特定の側面は厳密にはそのアイテムのプロパティではなく,メソッドの結果であることがあり,その場合の適切な構文はこうである.

Instance.Method()

付記 本章で扱う各メソッドから得られる結果を理解するのを助けるため,各メソッドはサンプルコードのリストと共に図示しよう.コードリストはメソッドの適用されるジオメトリを SELECT し,その結果はそのジオメトリが使われたときにメソッドにより返り,仮にそのメソッドの結果が geometry 型や geography 型のインスタンスで返すとしても,そのインスタンスの WKT 表現で返す.出力の WKT 表現を見せよう.しかし読者もまた SQL Server Management Studio の空間結果タブを使って各メソッドの結果を視覚化した結果を見ることができる.

 第4章で論じた静的メソッドのように,本章で論じるインスタンスのメソッドは Open Geospatial Consortium による定義に基づいている.そのようなメソッドのためにメソッド名は接頭辞文字列 “ST” を付加されている.例えば STX, STCentroid(), STLength などのように.これら多くの標準メソッドはジオメトリが特徴的な振る舞いを見せるのかどうか記述するために使われる.シンプルなのか,閉じているのか,空なのか?これらのいかなる問いへの答えも真理値であり,それは真か偽かのみであるという意味である.そのような場合,メソッド名は STIsXXX() というのが伝統であり,XXX とはプロパティやテストされる振る舞いである.そのメソッドの返り値は 0 か 1 のいずれかである.そのインスタンスが問題の振る舞いを示すならその反応は 1 (真)であり,そのインスタンスがメソッドによる特徴的な振る舞いを示さないなら結果は 0 (偽)である.

注意 本章で論ずるメソッドやプロパティの多くは geometry 型にも geography 型にも適用可能であるが,いくつかのメソッドは一つの型にのみ実装されている.紹介する各メソッドについて,いずれのデータ型がそれを実装しているのか,またそのデータ型のインスタンスでどう使われるのか伝えよう.

ジオメトリの種類の名前を返す

 geography 型や geometry 型のデータの単一のアイテムはいくつかの異なるジオメトリの種類の一つとして表現されることを思い出そう.つまり Point, LineString, Polygon およびこれら3つを含むコレクションである.いかなる空間データのアイテムも,その最も基本的なプロパティの一つは,それゆえ記述する特徴を表現するのに使われるジオメトリの種類である.そのアイテムの WKT や GML 表現の目視検査由来と明らかに見える一方で,WKB 表現や SQL Server 自身のバイナリ表現フォーマットと由来とははっきり見えない.STGeometryType() メソッドを使って,geography 型や geometry 型データのアイテムにより記述されたジオメトリの種類の文字記述を戻らせることができる.

サポートされるデータ型

 STGeometryType() メソッドは次のデータ型のインスタンスに使うことができる.

  • geometry 型
  • geography 型

使用法

 STGeometryType() はパラメータを必要とせず,geography 型や geometry 型のデータアイテムに対して次のように使うことができる.

Instance.STGeometryType()

 STGeometryType() メソッドの戻り値は nvarchar(4000) の文字列で,特定のインスタンスにより表現されたジオメトリの種類の名前を含む.

  • Point
  • LineString
  • Polygon
  • MultiPoint
  • MultiLineString
  • MultiPolygon
  • GeometryCollection

 STGeometryType() メソッドを示すため,次の例を考えてみる.geometry 型のデータを生成し,それは SRID 32614 (UTM Zone 14N) の MexicoCity を表現しており,STGeometryType() メソッドを使ってそのアイテムで表現されたジオメトリの種類を選択する.

DECLARE @MexicoCity geometry
SET @MexicoCity = geometry::STGeomFromText('Point(486321 2146238)', 32614)
SELECT
  @MexicoCity AS Shape,
  @MexicoCity.STGeometryType() AS GeometryType
Point

 Mexico City の位置を表現するため変数 @MexicoCity は Point ジオメトリを使うという結果を確認する.

ジオメトリにより占められる次元数を返す

 STGeometryType() のように,STDimension() メソッドは地物を表現するのに使うジオメトリの種類を記述する基本的な情報を提供するのに使われる.しかし,geography 型や geometry 型インスタンスにより表現されるジオメトリの種類を記述する文字列を返すというよりも,STDimension() はジオメトリの種類が占める次元数を表現する整数値を返す.第1章で論じたように,Point は 0 次元のジオメトリ,LineString は 1 次元を占め,Polygon は 2 次元を占める.

サポートされるデータ型

 STDimension() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STDimenstion() メソッドはいかなるパラメータも取らず,geography 型や geometry 型のアイテムに対して次のように使われる.

Instance.STDimension()

 STDimension() メソッドの結果は整数値であり Instance の占める次元数を次のように表現する.

  • Point や MultiPoint に対しては STDimension() は 0 を返す
  • LineString や MultiLineString に対しては STDimension() は 1 を返す
  • Polygon や MultiPolygon に対しては STDimension() は 2 を返す
  • 空のジオメトリはいかなる種類でも(つまり,ジオメトリがその定義において点を一つも含まない場合),-1 を返す
  • いくつか異なる種類のジオメトリを含む Geometry Collection に対しては,STDimension() はそのコレクションに含まれる要素の最大の次元数を返す

付記 同じ種類のジオメトリは単一要素でも多要素でも,同じ次元数を占める.

 STDimension() メソッドの使用法を次のコードで示す.ある LineString ジオメトリのインスタンスを生成し,その占める次元数をテストする.

DECLARE @LineString geometry
SET @LineString = geometry::STGeomFromText('LineString(-120 48, -122 47)', 0)
SELECT
  @LineString AS Shape,
  @LineString.STDimension() AS Dimension
1

ジオメトリが特定の種類か否かテストする

 InstanceOf() メソッドは,インスタンスにより特定されるジオメトリの種類を記述することで,機能的に STGeometryType() メソッドを補完する.STGeometryType() が記述的メソッドとして使われインスタンスにより表現されるジオメトリの種類名を返すのに対して,InstanceOf() メソッドは,あるインスタンスが与えられたジオメトリを表現するか否かをテストするのに使われる.そのインスタンスをテストするためのジオメトリの種類はパラメーターとしてテキスト文字列で InstanceOf() メソッドに提供しなければならない.

サポートされるデータ型

 InstanceOf() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 InstanceOf() メソッドを使うための構文は以下の通りである.

Instance.InstanceOf(geometry_type)

 geometry_type パラメータは nvarchar(4000) の文字列であり,特定のジオメトリの種類の例なのかどうかを定義することができる.例えば,仮に Instance が LineString ジオメトリならば Instance.InstanceOf(‘LineString’) は 1 を返すが,それ以外なら 0 を返す.

 InstanceOf() メソッドが 1 を返すのは Instance が geometry_type で特定されたジオメトリの種類と正確に一致した時か,あるいは Instance の任意の種類が geometry_type の下位互換である場合である.インスタンスのテストされる geometry_type の値は7つのインスタンス化できるオブジェクトの種類,ここでは STGeopmetryType() で返るの意味だが,の一つに限らず,それに加えて Curve, Surface, MultiCurve, MultiSurface ジオメトリの種類が LineSring, Polygons, MultiLineStrings, MultiPolygons にそれぞれ加わる.下位互換のすべての特異的ジオメトリの種類から,汎用のジオメトリの種類を特定することもできる.geometry_type のありうるすべての値のリストは以下の通りである.

  • Geometry
  • Point
  • MultiPoint
  • Curve
  • LineString
  • MultiCurve
  • MultiLineString
  • Surface
  • Polygon
  • MultiSurface
  • MultiPolygon
  • GeometryCollection

付記 これらのジオメトリ間の関連を示す継承ツリーの解説は第3章を参照のこと.

 次の例は geometry 型の MultiPoint インスタンスを定義しており,InstanceOf() を使ってその例が Geometry Collection の種類の例か否かテストしている.

DECLARE @MultiPoint geometry
SET @MultiPoint = geometry::STGeomFromText('MULTIPOINT(0 0, 51 2, -3 10.5)', 0)
SELECT
  @MultiPoint AS Shape,
  @MultiPoint.InstanceOf('GEOMETRYCOLLECTION') AS InstanceOfGeomColl
1

付記 MultiPoint, MultiLineString, MultiPolygon ジオメトリはすべて同質の多要素ジオメトリで汎用の多要素 Geometry Collection の下位互換であることを思い出そう.InstanceOf() メソッドを使ってすべてこれらの種類が Geometry Collection の例であるかテストするなら,その結果は 1 (真)である.

STDimension(), STGeometryType(), InstanceOf() の結果を比較する

 Table 11-1 に示したのは様々な種類のジオメトリの STGeometryType(), STDimension(), InstanceOf() メソッドから得られた結果を比較したものである.STGeometryType() および STDimension() の列は,Geometry 列に示した種類のジオメトリのインスタンスを,各メソッドで呼んで得られた結果である.InstanceOf() の列は,そのジオメトリを呼んだときに 1 (真)の返る geometry_type の値を示している.

Table 11-1. STGeometry(), STDimension() および InstanceOf() メソッドの結果を比較する
Geometry STGeometryType() STDimenstion() InstanceOf()
Point Point 0 Geometry, Point
LineString LineString 1 Geometry, Curve, LineString
Polygon Polygon 2 Geometry, Surface, Polygon
MultiPoint MultiPoint 0 Geometry, GeometryCollection, MultiPoint
MultiLineString MultiLineString 1 Geometry, GeometryCollection, MultiCurve, MultiLineString
MultiPolygon MultiPolygon 2 Geometry, GeometryCollection, MultiSurface, MultiPolygon
GeometryCollection GeometryCollection -1, 0, 1, 2a Geometry, GeometryCollection
Empty Point Point -1 Geometry, Point
Empty LineString LineString -1 Geometry, Curve, LineString
Empty Polygon Polygon -1 Geometry, Surface, Polygon
a STDimension() メソッドをGeometryCollection インスタンスに使うとき,そのコレクションの任意の要素の最大次元数が返る.例えば,Point と LineString だけからなる GeometryCollection では STDimension() の結果は 1 となる.

付記 空のジオメトリとは点が一つも存在しないジオメトリのことである.

 Figure 11-1 にこれらのメソッドの適用結果を示す(略).

ジオメトリが単純であるか否かをテストする

 第1章に戻ると,異なるジオメトリが単純なジオメトリに分類されるために満たさなければならない基準を紹介した.本質的に,単純さのための要求とはジオメトリが自己交差しないことである.つまり,一回以上同じ点を含まないことである(ただし LineString の開始点と終了点を除く).いくつかの特徴的な例を次に示す.

  • Point オブジェクトは常に単純である.MultiPoint オブジェクトは単純だが,同じ Point を2回含まない限りにおいてである.
  • LineString と MultiLineString は点と点の間に引かれた経路が自身と交差しない限り単純である.
  • Polygon と MultiPolygon は常に単純である.

 STIsSimple() メソッドは geometry 型データのインスタンスに対して使われ,問題のジオメトリの種類にとって関連する基準に合致するか否か検査する.

サポートされるデータ型

 STIsSimple() メソッドは次のデータ型のインスタンスに使われる.

  • geometry 型

使用法

 STIsSimple() メソッドはパラメータを要せず,geometry 型のデータのインスタンス上で次のように呼び出される.

Instance.STIsSimple()

 そのインスタンスによって表現されるそのジオメトリが単純なら,STIsSimple() メソッドは値 1 を返す.そのジオメトリが単純さに要求される基準に達しないなら,メソッドは 0 を返す.Figure 11-2 に示したのは異なる種類のジオメトリ上で STIsSimple() メソッドを使ったときに得られた結果である(略).

 次の例は,New York CIty 中心を通るバンの配達路を表現した LineString ジオメトリを生成する.その LineString は6つの点を有しており,その点はバンが停車して配達を行う位置を示している(解説の目的のため,バンは各位置の間を最短の直線経路を取るものと仮定する).STIsSimple() メソッドは LineString ジオメトリが単純であるか否か検査するために使われる.

DECLARE @DeliveryRoute geometry
SET @DeliveryRoute = geometry::STLineFromText(
  'LINESTRING(586960 4512940, 586530 4512160, 585990 4512460,
  586325 4513096, 587402 4512517, 587480 4512661)', 32618)
SELECT
  @DeliveryRoute AS Shape,
  @DeliveryRoute.STIsSimple() AS IsSImple
0

 結果はその LineString ジオメトリ @DeliveryRoute が単純ではないことを教えてくれる.その旅の間,バンは以前通った経路を跨がなければならない.これは @DeliveryRoute で表現される経路が目的地間の最適な経路ではないことの指標である可能性がある.示すために,バンが同じ地点から出発して残りの地点を違う経路を辿ったと考えてみよう,次のように.

DECLARE @DeliveryRoute geometry
SET @DeliveryRoute = geometry::STLineFromText(
  'LINESTRING(586960 4512940, 587480 4512661, 587402 4512517,
  586325 4513096, 585990 4512460, 586530 4512160)', 32618)
SELECT
  @DeliveryRoute AS Shape,
  @DeliveryRoute.STIsSimple() AS IsSimple

 この場合,その LineSring は同じ6地点を結ぶが,自身を跨がない.このジオメトリに使われる STIsSimple() メソッドの結果はゆえに 1 である.

 経路を単純にすることで,バンが経路を再交差する必要性を省き,走行距離は 3.6 km から 3.3 km に減少した.これは後に本章で紹介する STLength() メソッドで確認できる.

ジオメトリが閉じているか否かをテストする

 あるジオメトリが閉じていることは次の規則で定義できる.

  • Point ジオメトリは閉じていない.
  • LineString は開始点と終了点が同じ場合に限り閉じている.
  • あらゆる Polygon は閉じている.
  • Geometry Collection は一つでも閉じていないジオメトリがあれば(Point や閉じていない LineString があれば),閉じていない.

 STClosed() メソッドは geometry 型のインスタンスがこれらの基準に合致しているか否か検査するのに使われる.Figure 11-3 は,異なる種類のジオメトリの例に使われた STIsClosed() メソッドの結果を示す(略).

サポートされるデータ型

 STIsClosed() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STIsClosed() メソッドはパラメータを要せず,次のように使われる.

Instance.STIsCloed()

 STIsClosed() メソッドはインスタンスが閉じているときに 1 を返し,閉じていない時には 0 を返す.

 Mount Snowdon (Yr Wyddfa, Welsh) の山頂はウェールズにある山で最も高く,高度は標高 3500 フィートを超える.次の例では多くの LineString を含む MultiLineString ジオメトリを生成し,それはその山頂周辺の等高線を表現する.一本の等高線は高さの等しい点を結んだ線であり,それで,経度と緯度の座標の記述に加えて,各 LineString の各点はみな LineString の表現する等高線の高さに等しい z 座標値を特定しており,標高フィートで測定されている.STIsClosed() メソッドは MultiLineString インスタンスが閉じているか否かを検査するために使われている.

DECLARE @Snowdon geometry
SET @Snowdon = geometry::STMLineFromText(
'MUTLILINESTRING(
 (-4.07668 53.06804 3445,  -4.07694 53.06832 3445,  -4.07681 53.06860 3445,
  -4.07668 53.06869 3445,  -4.07651 53.06860 3445,  -4.07625 53.06832 3445,
  -4.07661 53.06804 3445,  -4.07668 53.06804 3445),
 (-4.07668 53.06776 3412,  -4.07709 53.06795 3412,  -4.07717 53.06804 3412,
  -4.07730 53.06832 3412,  -4.07730 53.06860 3412,  -4.07709 53.06890 3412,
  -4.07668 53.06898 3412,  -4.07642 53.06890 3412,  -4.07597 53.06860 3412,
  -4.07582 53.06832 3412,  -4.07603 53.06804 3412,  -4.07625 53.06791 3412,
  -4.07668 53.06776 3412),
 (-4.07709 53.06768 3379,  -4.07728 53.06778 3379,  -4.07752 53.06804 3379,
  -4.07767 53.06832 3379,  -4.07773 53.06860 3379,  -4.07771 53.06890 3379,
  -4.07728 53.06918 3379,  -4.07657 53.06918 3379,  -4.07597 53.06890 3379,
  -4.07582 53.06879 3379,  -4.07541 53.06864 3379,  -4.07537 53.06860 3379,
  -4.07526 53.06832 3379,  -4.07556 53.06804 3379,  -4.07582 53.06795 3379,
  -4.07625 53.06772 3379,  -4.07668 53.06757 3379,  -4.07709 53.06768 3379))',
4326)
SELECT
  @Snowdon AS Shape,
  @Snowdon.STIsClosed() AS IsClosed

 MultiLineString 内部に含まれる各 LineString は開始点と同じ地点で終わるため,@Snowdon は閉じたジオメトリであり,STIsClosed() メソッドにより返る結果は次のようである.

1

チップス 標高や高度を記述するためのオプションの z 座標は geometry 型で使用できることを思い出そう.

LineString がリングであるか否かをテストする

 リングとは単純かつ閉じている LineString のことである.STIsRIng() メソッドは geometry 型インスタンスがリングの例であるか否かテストするための OGC 準拠のメソッドである.Figure 11- 4 は異なる LineString ジオメトリ上で使われたときの STIsRIng() メソッドの結果を示している(略).

サポートされるデータ型

 STIsRing() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STIsRing() メソッドの構文は次の通り.

Instance.STIsRing()

 LineString インスタンス上で使うとき,STIsRIng() はインスタンスがリングの基準を満たす場合に 1 を返し,インスタンスがリングでない場合は 0 を返す.LineString 以外はいかなる種類のジオメトリであれそのメソッドは NULL を返す.

チップス リングは閉じていてかつ単純な LineString であるため,STIsRing() = 1 は論理的に InstanceOf(‘LineString’) = 1 AND STIsClosed() = 1 AND STIsSimple() = 1 と等価である. 

 次の例はIndy 500 レースの本拠地である Indianapolis Motor Speedway の経路を表現する LineString ジオメトリを生成する.STIsRing() メソッドを使い,そのジオメトリがリングを生成するか検査する.

DECLARE @Speedway geometry
SET @Speedway = geometry::STLineFromText(
'LINESTRING(565900 4404737, 565875 4405861, 565800 4405987, 565670 4406055,
  565361 4406050, 565222 4405975, 565150 4405825, 565170 4404760, 565222 4404617,
  565361 4404521, 565700 4404524, 565834 4404603, 565900 4404737)', 32616)
SELECT
  @Speedway AS Shape,
  @Speedway.STIsRing() AS IsRIng
1

ジオメトリの Point の数を数える

 STNumPoints() メソッドは geometry 型および geography 型インスタンスの定義内に含まれる点の数を返す.ジオメトリ定義内に列挙されるすべての点が数えられる.仮にジオメトリ定義が同じ点を複数回含んでいるとしても,それは複数回数えられる.例えば,Polygon の定義において,各リニアなリングの開始点と終了点が同じであることを思い出そう.この点は重複しているため,Plolygon ジオメトリに対して使われると,STNumnPoints() の結果は常にシェイプの側面の数よりも多くなる.

 Figure 11-5 に様々な種類のジオメトリに対して使われたときの STNumPoints() メソッドの結果を示す(略).

サポートされるデータ型

 STNumPoints() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STNumPoints() メソッドはパラメータを取らず,geography 型および geometry 型データのアイテムに対して次のように使われる.

Instance.STNumPoints()

 そのメソッドの結果は整数値でありインスタンス内に含まれる点の数を表現する.

 Bermuda Triangle はそこを通る船舶や航空機が説明の付かない遭難を引き起こすことで有名な大西洋の一部地域である.その正確な位置は異なる情報源の間で揺れているが,一般的にはフロリダのマイアミ,プエルトリコのサンジュアン,そしてバミューダ島の内部に含まれる地域と定義されている.次の例ではこれらの点に基づいて Bermuda Triangle を表現した geography 型の Polygon を生成し,その結果のインスタンスに STNumPoints() メソッドを呼び出している.

DECLARE @BermudaTriangle geography
SET @BermudaTriangle = geography::STPolyFromText(
'POLYGON((-66.07 18.45, -64.78 32.3, -80.21 25.78, -66.07 18.45))',
4326)
SELECT
@BermudaTriangle AS Shape,
@BermudaTriangle.STNumPoints() AS NumPoints
4

注意 Bermuda Triangle のような三角形の Polygon の定義は4つの点を含んでいる.3つと考えるかもしれないが,そうではない!これは STNumPoints() メソッドが Polygon の開始点と終了点を2回数えるからである.

ジオメトリが空であるか否かをテストする

 空(から)のジオメトリとは一つも点を含まないジオメトリのことである.一つも点を含まないにも関わらず,空のジオメトリは名目上特定の種類に割り当てられている.例えば,空の Point ジオメトリや空の LineString ジオメトリなどである.

 なぜ空のジオメトリを生成するのか戸惑っているかもしれない.一つも点を持たないと定義された地物を表現するシェイプをなぜ生成するのか?これについては次のような一つの考え方がある.仮にジオメトリが地球上の(ゆえに,実装によって,その存在の)地物の位置を表現するのなら,空のジオメトリはそのような地物を欠いていることを記述することになる.空のジオメトリは”x はどこだ?”という問いに対する”地球上のどこにもない”という答えとして使われる可能性がある.

 例えば,STIntersection() メソッドは,2つのジオメトリインスタンス間の共有点の集合を表現するジオメトリを返すのに使われる.仮にそれらのインスタンスが共通の点を一つも持っていない場合(互いに交わっていない),STIntersection() メソッドの結果は空のジオメトリになるだろう.

付記 空のジオメトリは NULL とは異なる.geometry 列や geography 列が NULL とは結果が評価されないことを示唆する.空のジオメトリは結果が評価され,しかし地球上に地物が存在しないことを示唆する.

サポートされるデータ型

 STIsEmpty() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STIsEmpty() メソッドはパラメータを要せず,geometry 型でも geography 型でもそのインスタンス上で次のように使われる.

Instance.STIsEmpty()

 Instance で表現されるそのジオメトリが一つも点を含まない場合,ゆえに STIsEmpty() の結果は 1 になる.そうでないならその結果は 0 になる.

チップス STIsEmpty() = 1 は論理的に STNumPoints() = 0 と等価である.

 次の例は2本の平行な LineString ジオメトリである @LineString1 と @LineString2 を生成する.そして STIntersection() メソッドを使って2本の LineString の交差からジオメトリを生成し,その前に結果のジオメトリ上に STIsEmpty() メソッドを呼び出す.

DECLARE @LineString1 geometry
DECLARE @LineString2 geometry
SET @LineString1 = geometry::STLineFromText('LINESTRING(2 4, 10 6)', 0)
SET @LineString2 = geometry::STLineFromText('LINESTRING(0 2, 8 4)', 0)
SELECT
@LineString1.STUnion(@LineString2) AS Shape,
@LineString1.STIntersection(@LineString2).STIsEmpty() AS IsEmpty
1

 STIntersection() メソッドから生成されるジオメトリが空のジオメトリであり,一つの点も有さないことがわかる.言い換えると,@LineString1 と @LineString2 は互いにいかなる点も共通に持たない(なぜなら平行だから).

付記 この例では STUnion() メソッドを使い,両者の LineString ジオメトリを結合し(空間結果タブに表示される),STIntersection() メソッドは2つのジオメトリ間の交差を計算する.これらのメソッドはともに第12章で詳細を述べる.

直交座標値を返す

 geometry データ型においては点は直交座標の x および y, または投影空間参照系由来の東座標および北座標により定義されることを思い出そう.生成されるいかなる個別の座標値もそれを取得するためには,geometry 型の STX および STY プロパティを使うことができる.

 STX および STY プロパティは,STPointFromText() のような静的メソッドから直接インスタンス化された Point ジオメトリに適用でき,他のメソッド,例えば STPointN() や STCentroid() などの結果として返る点も同様である.これについては本章の後半で述べる.

付記 Point ジオメトリの座標値はメソッド経由というよりむしろそのオブジェクトのプロパティとしてアクセスされる.STX や STY を使って座標値を取得するとき,プロパティ名の後に丸括弧を含めるべきではない.

サポートされるデータ型

 STX および STY プロパティは次のデータ型の Point インスタンス上で使われる.

  • geometry 型

使用法

 STX および STY プロパティは geometry 型の Point インスタンスに次のように適用する.

Instance.STX
Instance.STY

 次の例は,UTM 投影(南半球 Zone 35)を使って南アフリカのヨハネスブルグを表現する投影座標から Point ジオメトリを生成する.そして STX および STY プロパティを使ってその Point の x 座標(東座標)および y 座標(北座標)を取得する.

DECLARE @Johannesburg geometry
SET @Johannesburg = geometry::STGeomFromText('POINT(604931 7107923)', 32735)
SELECT
  @Johannesburg.STX AS X,
  @Johannesburg.STY AS Y
X       Y
604931  7107923

地理座標値を返す

 geography 型を使うとき,STX および STY プロパティと同等の機能は代わりに Lat および Long プロパティにより提供される.これらのプロパティは STX および STY と同様に正確に作用するが,Point の x 座標値および y 座標値に関するのと違って,それらは経度と緯度を取得する.

サポートされるデータ型

 Lat および Long プロパティは次のデータ型のインスタンス上で使われる.

  • geography 型

使用法

 Lat および Long プロパティは geography 型のインスタンスに次のように適用される.

Instance.Lat
Instance.Long

 各メソッドの結果は浮動小数点で示した関連する座標値である.

 次の例は,Sri Lanka の Colombo に該当する Well-Known BInary 表現から geography 型を使って Point を生成する.そして Long および Lat プロパティを使ってその Point の経度と緯度を取得する.

DECLARE @Colombo geography
SET @Colombo = geography::STGeomFromWKB(0x0101000000666666F65340B81E85EB51B81B40, 4326)
SELECT
  @Colombo.Long AS Longitude,
  @Colombo.Lat AS Latitude
Longitude  Latitude
79.85      6.93

拡張座標値を返す

 必須の x および y 座標(または経度と緯度)に加えて,ジオメトリ定義内で各点はオプションで z および m 座標をも含められることを思い出そう.z 座標は高度や標高を蓄積する.m 座標はその点に関する何らかの測定値であり,浮動小数点で表現される.これらの付加的な座標値を取得するために,z および M プロパティを Point インスタンス上で使うことができる.

サポートされるデータ型

 z および M プロパティは次のデータ型のインスタンス上で使うことができる.

  • geometry 型
  • geography 型

使用法

 m および z 座標プロパティは geometry 型や geography 型 Point インスタンス上で次にようにアクセスできる.

Instance.M
Instance.Z

 その結果は浮動小数点で表現した適切な z あるいは m 座標値である.座標値が定義できない場合,NULL が返る.

 連邦通信委員会は合衆国内の登録済みのアンテナ構造のデータベースを維持している.そのデータベースは様々なフィールドを維持しており,それにはアンテナの緯度や経度,地上からの全体の高さを含んでいる.そのデータベースはオンラインで検索できる.http://wireless2.fcc.gov/UlsApp/AsrSearch/asrRegistrationSearch.jsp

 次の例はそのようなアンテナの一つを表現した Point ジオメトリを生成する.北緯 39°49’54” 西経 89°38’52” に位置し,空間参照系 EPSG 4269 を使う.そのアンテナは地上高 34.7 m まで伸び,その点の z 座標で表現する.m 座標は値 1000131 が割り当てられており,それはこのアンテナに割り振られた参照ナンバーを表現している.そしてその例はいかにして z および m プロパティが使われその Point の該当する座標値が取得されるかを示している.

DECLARE @Antenna geography
SET @Antenna = geography::STPointFromText('POINT(-89.64778 39.83167 34.7 1000131)', 4269)
SELECT
  @Antenna.M AS M,
  @Antenna.Z AS Z
M        Z
1000131  34.7

ジオメトリから特定の Point を返す

 STPointN() メソッドはジオメトリの個別の点を特定し返すのに使われる.そのメソッドに提供されるパラメータ n に基づき,STPointN() メソッドはどんなジオメトリの定義でも,含まれる n 番目の点を返す.

 Figure 11-6 は異なる種類のジオメトリに使われたときの STPointN() メソッドの結果を示す(略).

付記 STPointN() メソッドを有効に使うには,ジオメトリの点が定義される順番を理解しなくてはならない.そのジオメトリがユーザーにより生成されたなら,そのインスタンスを生成した静的メソッドにもともと渡す表現の順に点は列挙されている.そのジオメトリが SQL Server 2008 により(他のメソッドの結果由来で)生成されたなら,点はまずインスタンス順に,そしてインスタンス内のリング順に,さらに各リング内の点の順である.

サポートされるデータ型

 STPointN() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STPointN() メソッドは整数のパラメータ n を提供しなくてはならない.それはジオメトリから返るべき点の序数である.その構文は次のとおりである.

Instance.STPointN(n)

 Instance.STPointN(n) は Instance で表現されるジオメトリの n 番目の点を返す.パラメータ n の有効な値の範囲は 1 (ジオメトリの最初の点)から STNumPoints() の値(ジオメトリの最終点)までである.そのメソッドの戻り値は geography 型または geometry 型の Point オブジェクトである.それはそのメソッドの呼ばれたインスタンスのデータ型に一致している.

 次の例は geography 型インスタンス LineString を生成し,ロンドンマラソンにおいてランナーが競走するルートを表現している.収縮した LineString 由来の個々の点はコースに渡るすべてのマイルに等間隔である.STPointN() メソッドは LineString 内の14番目の点を選択するのに使われ,それはレースのおよその中間点を表現している.

DECLARE @LondonMarathon geography
SET @LondonMarathon = geography::STLineFromText(
'LINESTRING(0.0112 51.04731, 0.0335 51.4749, 0.0527 51.4803, 0.0621 51.4906,
0.0448 51.4923, 0.0238 51.4870, 0.0021 51.4843, -0.0151 51.4814,
-0.0351 51.4861, -0.0460 51.4962, -0.0355 51.5011, -0.0509 51.5013,
-0.0704 51.4989, -0.0719 51.5084, -0.0493 51.5098, -0.0275 51.5093,
-0.0257 51.4963, -0.0134 51.4884, -0.0178 51.5003, -0.0195 51.5046,
-0.0087 51.5072, -0.0278 51.5112, -0.0472 51.5099, -0.0699 51.5084,
-0.0911 51.5105, -0.1138 51.5108, -0.1263 51.5010, -0.1376 51.5031)',
4326)
SELECT
@LondonMarathon AS Shape,
@LondonMarathon.STPointN(14) AS Point14,
@LondonMarathon.STPointN(14).STAsText() AS WKT
POINT(-0.0719 51.5084)

ジオメトリの開始点と終了点を見つける

 STStartPoint() および STEndPoint() は”ショートカット”メソッドであり,それぞれジオメトリの最初の点と最後の点の返る特別な場合に使った STPointN() と同じ結果を提供する.

  • STStartPoint() は STPointN(1) と等価である
  • STEndPoint() は STPointN(STNumPoints()) と等価である

サポートされるデータ型

 STStartPoint() および STEndPoint() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STStartPoint() および STEndPoint() メソッドはgeography 型や geometry 型のインスタンス上で次のように使われる.

Instance.STStartPoint()
Instance.STEndPoint()

 各メソッドの結果はgeography 型ないし geometry 型の Point オブジェクトであり,メソッドの呼ばれたインスタンスの型と一致する.

 1919 年 5 月,Albert Read 少佐の率いる5名の飛行士が大西洋横断飛行に成功した.Rockaway Naval 空港を出発し,Raed は彼の飛行機 NC-4 を Nova Scotia の Halifax まで操縦し,そしてアゾレス諸島の Horta 島に渡る前に Newgoundland の Trepassey 上空を通過した.アゾレス諸島から,クルーはポルトガルのリスボンに出発し,スペインに少し立ち寄り,最後にイングランドの Plymouth で旅を完了した.次の例は取られた経路のおよそを表現する LineString を生成し,STStartPoint() と STEndPoint() メソッドを使って旅の最初と最後の点を返す.

DECLARE @TransatLatinCrossing geography
SET @TransatlatinCrossing = geography::STLineFromText('
LINESTRING(
  -73.88 40.57, -63.57 44.65, -53.36 46.74, -28.63 38.54,
  28.24 38.42, -9.14 38.71, -8.22 43.49, -4.14 50.37)',
  4326
)
SELECT
  @TransatLatinCrossing AS Shape,
  @TransatLatinCrossing.STStartPoint().STAsText() AS StartPoint,
  @TransatLatinCrossing.STEndPoint().STAsText() AS EndPoint
StartPoint            EndPoint
POINT (-73.88 40.57)  POINT (-4.14 50.37)

geometry 型の Polygon の重心を求める

 polygon の重心は”重力の中心”と考えられている.その点では Plolygon に含まれる面積が等しく分布する.重心の位置はそのジオメトリの形状全体に基づく計算から数学的に由来する.SQL Server 2008 では,STCentroid() メソッドを使うと,いかなる geometry 型の Polygon の重心をも表現する Point インスタンスを返すことができる.

 Figure 11-7 はいくつかの geometry 型の Polygon の重心を示している(略).

注意 Polygon の重心は必ずしも Polygon 内部にある必要はない.Polygon が均等に分布する点であればよい.

サポートされるデータ型

 STCentroid() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STCentroid() メソッドはパラメータを要せず,geometry 型の Polygon または MultiPolygon インスタンス上で次のように使われる.

Instance.STCentroid()

 STCentroid() メソッドの結果は Point ジオメトリであり,呼ばれたインスタンスと同じ SRID を使って宣言される.STCentroid() は Polygon または MultiPolygon ジオメトリにしか使えないことは明記しておく必要がある.仮に Point や LineString オブジェクトに使うと,このメソッドは NULL を返す.

 次の例は Colorado 州を表現する Polygon ジオメトリを生成し,STCentroid() メソッドを使ってその Polygon の重心を定義している.

DECLARE @Colorado geometry
SET @Colorado = geometry::STGeomFromText('POLYGON((-102.0423 36.9931, -102.0518
41.0025, -109.0501 41.0006, -109.0452 36.9990, -102.0423 36.9931))', 4326)
SELECT
@Colorado.STCentroid() AS Centroid,
@Colorado.STCentroid().STAsText() AS WKT
POINT (-105.54621375420314 38.99851021101813)

 これは州の中心にある Elevenmile Canyon 貯水池から数マイル北の位置を表現している.

geography 型のインスタンスの中心を求める

 STCentroid() メソッドは geography 型には適用できない.しかし,似たような機能は EnvelopeCenter() メソッドにより提供されている.EnvelopeCenter() は,地球の中心からジオメトリ内の各点への位置を記述する位置ベクトルを平均し,その結果の位置をプロットする Point ジオメトリを返す.これはいかなる種類でもジオメトリの中心位置の非常に単純な近似である.Polygon インスタンス上でしか使えない geometry 型の STCentroid() メソッドとは対照的に,EnvelopeCenter() メソッドは geography 型ならどんな種類のジオメトリに対しても使うことができる.

付記 EnvelopeCenter() メソッドの結果はジオメトリ内の各一意の点の平均に基づいている.仮に geography 型のインスタンス内に同じ点が2回定義されている場合,リングの開始点と終了点のような場合だが,この点は計算においては1回だけ含まれる.

 Figure 11-8 は,点 P1, P2, P3 および P4 で定義された geography 型の Polygon から計算された EnvelopeCenter() のメソッドの結果を示している.地球の中心から各点の位置を記述した位置ベクトルは平均されて(点 P1 については Polygon リングの開始点と終了点を表現しており,一度だけ含まれる),そのメソッドは結果の位置に位置する点を返す(略).

サポートされるデータ型

 EnvelopeCenter() メソッドは次のデータ型のインスタンス上で使われる.

  • geography 型

使用法

 EnvelopeCenter() メソッドはいかなる種類でも geomgraphy 型のインスタンス上なら次のように使うことができる.

Instance.EnvepopeCenter()

 このメソッドの結果はgeography 型の Point オブジェクトであり,提供された元のインスタンスと同じ空間参照系を使って定義される.

 次の例は Utah 州を表すgeography 型の Polygon を生成し,EnvelopeCenter() メソッドを使って Polygon の中心にある点を返す.

DECLARE @Utah geography
SET @Utah = geography::STPolyFromText(
  'POLYGON((-109 37, -109 41, -111 41, -111 42, -114 42, -114 37, -109 37))', 4326)
SELECT
  @Utah AS Shape,
  @Utah.EnvelopeCenter() AS EnvelopeCenter,
  @Utah.EnvelopeCenter().STAsText() AS WKT
POINT (111.33053985766453 40.018634026864916)

 Figure 11-9 はその州の形状全体の Polygon 表現に関連したこの点を示しており,メルカトル投影を使って投影している.EnvelopeCenter() から得られたこの点は,座標値の最大値と最小値の平均から得られた幾何学的中心からは少し北東にずれている.これはこの Polygon の定義が,この州の北東部において凹んだ角を定義する点が,他の3つの角より大きな密度を有している事実に由来している.これにより EnvelopeCenter() で計算された平均ベクトルは北東に加重されることになる(略).

注意 EnvelopeCenter() は geography 型のインスタンスの中心点の近似を計算するだけである.

ジオメトリから任意の点を返す

 STPointOnSurface() メソッドは geometry 型のいかなる種類のジオメトリに対しても使われ,そのジオメトリ内部にある任意の点を返す.STPointOfSurface() メソッドの結果はそのメソッドが呼ばれたジオメトリの種類に依存する.

  • LineString や MultiLineString なら,その結果は LineString 上にある Point である.
  • Polygon なら,その結果は外部リング内の Point である(内部リング内の点は含まれない).
  • Point なら,その結果はその Point 自身であり,MultiPoint の場合は,MultiPoint Collection 内部に含まれるいずれか一つの Point である.

 ”なぜジオメトリから一つの,任意の点がほしいのか?”そう戸惑うかもしれない.”確かに,Polygon ジオメトリの形状全体を表現する Point ジオメトリを得たいなら,例えば,STCentroid() メソッドを代わりに使ったほうが良くなるのではないか?その形状内の一点が返るのだから”この疑問に対する答えはこうである.STCentroid() メソッドはジオメトリの重心を定義するのに使われるが,結果の Point はそのジオメトリそのものの内部には必ずしも含まれているわけではない.対照的に,STPointOnSurface() メソッドの結果は常に,そのメソッドが呼ばれたジオメトリ内部にあることが保証された一点である,ということである.

サポートされるデータ型

 STPointOnSurface() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STPointOnSurface() メソッドは geometry 型のインスタンス上でのみ次のように使われる.

Instance.STPointOnSurface()

 次の例は Polygon ジオメトリを生成し,STPointOnSurface() メソッドを使って Polygon 内部に含まれる任意の点を返す.

DECLARE @Polygon geometry
SET @Polygon = geometry::STGeomFromText('POLYGON((10 2, 10 4, 5 4, 5 2, 10 2))', 0)
SELECT
  @Polygon AS Shape,
  @Polygon.STPointOnSurface() AS PoinOnSurface,
  @Polygon.STPointOnSurface().STAsText() AS WKT
POINT (8.3333333333333339 3.3333333333333335)

付記 STPointOnSurface() メソッドは任意の点を返すが,ランダムな点ではない.先述した例を何度か実行するなら,各状況で同じ結果を受け取るだろう.

ジオメトリの長さを計測する

 STLength() はジオメトリの長さを返す.LineString に使うとき,これは点を結んだ線分の長さの合計を与える.Polygon に使うとき,これはpolygon の定義されたリングすべての長さを表現する.Polygon が一つのリングを含む場合,STLength() はゆえに Polygon の外周の長さを返す.MultiLineString のような多要素型に用いた場合,STLength() メソッドはインスタンス内の,または Geometry Collection 内部のすべてのインスタンスのすべての長さの合計を返す.Figure 11-10 は異なる種類のジオメトリに STLength() メソッドを使った結果を示す(略).

サポートされるデータ型

 STLength() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STLength() メソッドは geometry 型または geography 型のいかなる種類のインスタンス上でも次のように使うことができる.

Instance.STLength()

 結果は浮動小数点の値で,問題にしているジオメトリの長さを表現している.geography 型のインスタンスにとって,その結果は sys.spatial_reference_system テーブルの unit_of_measure 列の単位で記述されることになり,それはその座標が記述された SRID に対応している.geometry 型のインスタンスにとっては,その結果はそのジオメトリ自体の座標と同じ計測単位で記述されることになる.

 The Royal Mile はエディンバラ城とホリールード宮殿を結ぶ直線道路であり,エディンバラで最も古い道路の一つである.次の例は the Royal Mile を表現する LineString を生成し,STLength() メソッドを使ってその長さを定義する.

DECLARE @RoyalMile geography;
SET @RoyalMile = geography::STLineFromText(
  'LINESTRING(-3.20001 55.94821, -3.17227 55.9528)', 4326)
SELECT
  @RoyalMile AS Shape,
  @RoyalMile.STLength() AS Length
1806.77067641223

 @RoyalMile LineString の座標は EPSG 4326 空間参照系を使って定義されているため,その結果はその系の計測単位であるメートルで記述される.

 1824 年以前,1807 メートルの結果は the Royal Mile の長さを測定したのと同様,Scottish mile の定義であった.これは今日使われるマイル,それは約 1609 メートルに等しいが,よりも長い.

ジオメトリに含まれる面積を計算する

 STArea() メソッドは計算に使われ,オブジェクトにより占められる面積を返す.0 次元または 1 次元のオブジェクトに使われた場合(Point や LineString など),そのメソッドは 0 を返す.

 geography 型に使われたとき,STArea() メソッドの結果は geography 型インスタンスの空間参照型により定義された計測単位の2乗で返る.例えば,SRID 4326 で特定された geography 型のオブジェクトに対して使うとき,STArea() で返る結果は平方メートルで表現されるが,SRID 4157 を使うときは,その計測単位は平方フィートである.geomatry 型のオブジェクトに対して使うとき,その計測単位は提供された座標の単位の2乗である.Figure 11-11 に異なる種類のジオメトリに STArea() メソッドを使ったときの結果を示す(略).

サポートされるデータ型

 STArea() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STArea() メソッドは geography 型や geometry 型のいかなるジオメトリにも次のように呼び出せる.

Instance.STArea()

 STArea() の結果は最低でも1個の Polygon ジオメトリを含まない限り,いかなるジオメトリに対しても 0 となる.

 次の例は geometry 型の Polygon を生成し,それは UTM Zonre 31N 投影 (EPSG 32631) を使って南フランスの土地の一画を表現している.その一画には関連するコストがあり,それを変数 @Cost で表現している.ジオメトリに適用した STArea() メソッドの結果で総コストを除算することで,土地の1平方メートルあたりのコストをひねり出すことができる.

DECLARE @Cost money = 80000
DECLARE @Plot geometry
SET @Plot = geometry::STPolyFromText(
  'POLYGON((633000 4913260, 633000 4913447, 632628 4913447, 632642 4913260, 633000 4913260))',
  32631)
SELECT
  @Plot AS Shape,
  @Cost / @Plot.STArea() AS PerUnitAreaCost
1.1720753058384

ジオメトリの SRID を設定・取得する

 geography 型や geometry 型のいずれから生成したいかなる種類のジオメトリでもすべてのインスタンスは関連する空間参照識別子を有している.それは座標の得られたシステムを定義し,地球上の位置を一意に識別することを可能とする.STSrid プロパティはいかなるオブジェクトの SRID をも返し,設定することができる.

サポートされるデータ型

 STSrid プロパティは次のデータ型のインスタンス上で使うことができる.

  • geometry 型
  • geography 型

使用法

 STSrid プロパティはgeometry 型および geography 型の両者に対して次のように使われる.

Instance.STSrid

 STSrid では一般的ではないが,たいていの空間プロパティはリードオンリーだが,オブジェクトの SRID を設定することができる.

 座標の定義されていない,空間参照系の記述されていない,未知のソースから投影座標を記述した空間データをいくつかインポートしたいと仮定しよう.投影座標は平面を操作するため,まずそのデータを SRID 0 を使って geometry 型の列に次のようにインポートすることができる.

CREATE TABLE #Imported_Data (
  Location geometry
)
INSERT INTO #Imported_Data VALUES
(geometry::STGeomFromText('LINESTRING(122 74, 123 72)', 0))
(geometry::STGeomFromText('LINESTRING(140 65, 132 63)', 0))
SELECT
  Location.STAsText(),
  Location.STSrid
FROM #Imported_Data
LINESTRING (122 74, 123 72)  0
LINESTRING(140 65, 132 63)  0

 今度は,挿入されたデータ,EPSG 32731 参照系に基づく投影座標に関するデータを発見すると仮定しよう.ゆえにこれを反映するためにあなたのデータすべてを更新したい.これを行うため,STSrid プロパティの値を UPDATE ステートメントを使って次のように設定できる.

UPDATE #Imported_Data
  SET Location.STSrid = 32731
SELECT
  Location.STAsText(),
  Location.STSrid
FROM #Imported_Data
LINESTRING (122 74, 123 72)  32731
LINESTRING (140 65, 132 63)  32731

付記 指定している異なる SRID はジオメトリの座標値をそのシステムに再投影しない.それはただ,それらの座標が定義されたシステムの記述を提供するのみである.

Polygon ジオメトリの外部リングを単離する

 先述したように,Polygon はいくつかの内部リングを含む場合がある.それは”穴”と定義され,主要な Polygon ジオメトリを切り取る空間の面積のことである.ときに,しかし,その内部に定義されるいかなる内部リングも無視して Polygon の外部リングだけを返すことが有益であることもある.STExteriorRing() メソッドはこの場合に使われる.それは LineString オブジェクトを返し,Polygon 形状の外部周縁を表現している.Figure 11-12 に geometry 型の Polygon インスタンスに対して STExteriorRIng() メソッドを使ったときの結果を示す(略).

サポートされるデータ型

 STExteriorRing() メソッドは次のデータ型のインスタンスに使われる.

  • geometry 型

使用法

 STExteriorRing() メソッドは geometry 型の Polygon に対して次のように使われる.

Instance.STExterorRing()

 STExteriorRing() メソッドの結果はLineString ジオメトリであり,メソッドの呼ばれたそのインスタンスと同じ SRID を使って定義される.

 次の例は大文字の A の形をした geometry 型の Polygon を生成する.STExteriorRing() メソッドはその Polygon の外周を返す.

DECLARE @A geometry
SET @A = geometry::STPolyFromText(
'POLYGON((0 0, 4 0, 6 5, 14 5, 16 0, 20 0, 13 20, 7 20, 0 0),
(7 8, 13 8, 10 16, 7 8))',
0)
SELECT
@A AS Shape,
@A.STExteriorRing() AS ExteriorRing,
@A.STExteriorRing().STAsText() AS WKT
LINESTRING (0 0, 4 0, 6 5, 14 5, 16 0, 20 0, 13 20, 7 20, 0 0)

付記 STExteriorRing() メソッドは外周リングの LineString ジオメトリを返す.そのリング内部の面を囲む Polygon ではない.Polygon 内部の内部リングにより生成された,単に”穴を埋めた”ものではない.

ジオメトリの内部リングを数える

 STNumInteriorRing() メソッドは,Polygon ジオメトリ内部に定義された内部リングの総数を表現する整数値を返す.仮に Polygon が内部リングを一つも持たない場合,そのメソッドの結果は 0 である.Figure 11-14 に2つの異なる MultiPolygon インスタンス上で STNumInteriorRing() メソッドを使った結果を示す(略).

サポートされるデータ型

 STNumInteriorRing() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STNumInteriorRing() メソッドはパラメータを要せず,geometry 型のインスタンスに対して次のように使われる.

Instance.STNumInteriorRIng()

 結果は整数値であり,ゼロに等しいかそれより大きく,Polygon ジオメトリ内の内部リングの数を表現している.

 次の例は Polygon を生成し,STNumInteriorRing() メソッドを使ってその Polygon 内部に含まれる内部リングの数を確認している.

DECLARE @Polygon geometry
SET @Polygon = geometry::STPolyFromText('
  POLYGON(
    (0 0, 20 0, 20 10, 0 10, 0 0),
    (3 1, 3 8, 2 8, 3 1),
    (14 2, 18 6, 12 4, 14 2))',
  0)
SELECT
  @Polygon AS Shape,
  @Polygon.STNumInteriorRing() AS NumInteriorRing
2

Polygon から内部リングを単離する

 STInteriorRingN() メソッドは n 番目の内部リングを Polygon から単離する.Polygon のそのリングは閉じた LineString であるため,そのメソッドの結果も常に単純で閉じた LineString である.Figure 11-15 に異なる Polygon ジオメトリ上で STInteriorRingN() メソッドを使った結果生成した LineString を示す(略).

サポートされるデータ型

 STInteriorRingN() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STInteriorRing() メソッドの構文は,geometry 型の Polygon 上で使われ,次のようである.

Instance.STInteriorRIngN(n)

 これは LineString を返し,Instance の n 番目のリングを表現している.n の有効な値の範囲は 1 (最初の内部リング)から STNumInteriorRing() の結果(最後の内部リング)までである.

 次の例は大文字の A の形に geometry 型の Polygon を生成する.ついでSTInteriorRIngN() メソッドを使って最初の(かつ唯一の)内部リングをジオメトリから単離する.

DECLARE @A geometry
SET @A = geometry::STPolyFromText('
  POLYGON((0 0, 4 0, 6 5, 14 5, 16 0, 20 0, 13 20, 7 20, 0 0),
    (7 8, 13 8, 10 16, 7 8))', 0)
SELECT
  @A AS Shape,
  @A.STInteriorRingN(1) AS InteriorRing,
  @A.STInteriorRingN(1).STAsText() AS WKT
LINESTRING (7 8, 13 8, 10 16, 7 8)

geography 型の Polygon 内のリングを数える

 geography 型を使うときは,地球の球体モデル上の位置を定義しており,Polygon のリングを感覚的に”内部”や”外部”のカテゴリに割り当てることはできない.すべてのリングは空間を2つの領域に分割する.それはPolygon 内部に含まれる領域と,そこから除外される領域とである.この理由で,geography 型は STNumInteriorRing()  メソッドを実装しておらず,別のメソッドである NumRIngs() を実装している.NumRings() メソッドはgeography 型の Polygon インスタンス内のリングの総数を数え,それらが”内部”なのか”外部”なのかは区別しない.Figure 11-17 に2つの異なる geography 型の Polygon 上で NumRings() メソッドを使った結果を示す(略).

サポートされるデータ型

 NumRings() メソッドは次のデータ型のインスタンス上で使われる.

  • geography 型

使用法

 NumRings() メソッドは geography 型の Polygon 上で次のように使われる.

Instance.NumRings()

 結果は整数値で Polygon に定義されたリングの総数を表現している.

 次の例は2つのリングを含む geography 型の Polygon を生成し,合衆国国防省 Pentagon の建物を表現している.ついで NumRings() メソッドを使い,そのインスタンス内のリングの数を数えている.

DECLARE @Pentagon geography
SET @Pentagon = geography::STPolyFromText(
  'POLYGON(
    (-77.0532238483429 38.870863029297695,
     -77.05468297004701 38.87304314667469,
     -77.05788016319276 38.872800914712734,
     -77.05849170684814 38.870219840133124,
     -77.05556273460388 38.8690670969385,
     -77.0532238483429 38.870863029297695),
    (-77.05582022666931 38.8702866652523,
     -77.0569360256195 38.870337733163644,
     -77.05673217773439 38.87170668418343,
     -77.0554769039154 38.871848684516294,
     -77.05491900444031 38.87097997215688,
     -77.05582022666931 38.8702866652523)
  )', 4326)
SELECT
  @Pentagon AS Shape,
  @Pentagon.NumRings() AS NumRings
2

geography 型の Polygon から一つのリングを単離する

 geography 型で STNumInteriorRing() ではなく NumRings() メソッドが実装されているように,Polygon からいかなる与えられたリングをも単離するそれ自身のメソッドが定義されており,”内部”や”外部”の分類を持たない.geography 型の Polygon からいかなるリングをも単離するそのメソッドは RingN() である.Figure 11-18 にgeography 型の Polygon に RingN() メソッドを使った結果を示す(略).

サポートされるデータ型

 RingN() メソッドは次のデータ型のインスタンス上で使われる.

  • geography 型

使用法

 RingN() メソッドはパラメータ n を提供されなければならず,geography 型のインスタンスから返るリングを次のように特定するものである.

Instance.RingN(n)

 n の値は整数値でなくてはならず,その範囲は 1 からそのインスタンスに含まれるリングの総数までである(それは NumRings() メソッドを使って定義される).そのメソッドの結果は geography 型の LineString であり,Instance のSRID を使って定義される.

 次のコードは2つのリングを持つ geography 型の Polygon を生成し,合衆国国防省 Pentagon の建物を表現している.ついで RingN() メソッドを使い,その定義から最初のリングを単離し,結果の WKT 表現を返している.

DECLARE @Pentagon geography
SET @Pentagon = geography::STPolyFromText(
  'POLYGON(
    (-77.0532238483429 38.870863029297695,
     -77.05468297004701 38.87304314667469,
     -77.05788016319276 38.872800914712734,
     -77.05849170684814 38.870219840133124,
     -77.05556273460388 38.8690670969385,
     -77.0532238483429 38.870863029297695),
    (-77.05582022666931 38.8702866652523,
     -77.0569360256195 38.870337733163644,
     -77.05673217773439 38.87170668418343,
     -77.0554769039154 38.871848684516294,
     -77.05491900444031 38.87097997215688,
     -77.05582022666931 38.8702866652523)
  )', 4326)
SELECT
  @Pentagon AS Shape,
  @Pentagon.RingN(1) AS Ring1,
  @Pentagon.RingN(1).STAsText() AS WKT
LINESTRING (-77.0532238483429 38.870863029297695,
     -77.05468297004701 38.87304314667469,
     -77.05788016319276 38.872800914712734,
     -77.05849170684814 38.870219840133124,
     -77.05556273460388 38.8690670969385,
     -77.0532238483429 38.870863029297695)

ジオメトリの境界を識別する

 STBoundary() メソッドは geometry 型インスタンスの境界を表現するジオメトリを返す.空間データにおいて,境界という言葉は,あなたが考えているようにジオメトリの外周を意味するのではなく,問題にしているジオメトリの種類に依存する特異的な定義を有している.

  • Point および LineString インスタンスは境界を持たない.
  • LineString および MultiLineString はジオメトリの開始点と終了点から形成される境界を有するが,何度も発生するいかなる点も除去する.
  • Polygon の境界は LineString から形成され,各々のリングを表現する.

 Figure 11-19 に様々な異なる種類のジオメトリに STBoundary() メソッドを使った結果を示す(略).

チップス 内部リングのない Polygon に対して使うと,STBoundary() により生成されるジオメトリは STExteriorRing() メソッドと全く同じになる.しかし,STExteriorRing() が定義された順に点群を返すのと違い,STBoundary() は最小座標値から開始する点群を返す.

サポートされるデータ型

 STBoundary() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STBoundary() メソッドはいかなるパラメータも取らず,geometry 型のインスタンス上で次のように呼び出される.

Instance.STBoundary()

 STBoundary() メソッドの戻り値により表現されるジオメトリの種類は,呼び出したインスタンスのジオメトリの種類に依存する.

 次の例は大文字の A の形に polygon インスタンスを生成し,ついでSTBoundary() メソッドを使ってその Polygon の境界を識別する.

DECLARE @A geometry
SET @A = geometry::STPolyFromText('
  POLYGON((0 0, 4 0, 6 5, 14 5, 16 0, 20 0, 13 20, 7 20, 0 0),
    (7 8, 13 8, 10 16, 7 8))', 0)
SELECT
  @A AS Shape,
  @A.STBoundary() AS Boundary,
  @A.STBoundary().STAsText() AS WKT
MULTILINESTRING((7 8, 8 10, 16 7, 7 8), (0 0, 4 0, 6 5, 14 5, 16 0, 20 0, 13 20, 7 20, 0 0))

ジオメトリの境界ボックスを計算する

 ジオメトリのエンベロープは最小の軸方向の長方形で,ジオメトリのすべての部分を包含するものである.それは境界ボックスとも呼ばれる.仮に MinX, MaxX, MinY および MaxY がジオメトリ内に含まれるすべての点の x 座標と y 座標の最小値と最大値であるなら,その境界ボックスは次の WKT 表現で定義される Polygon である.

POLYGON ((MinX, MinY), (MaxX, MinY), (MaxX, MaxY), (MinX, MaxY), (MInX, MinY))

 STEnvelope() メソッドはいかなる種類の geometry 型インスタンスでもその境界ボックスを返す.Figure 11-21 に様々な geometry 型インスタンスに対して STEnvelope() メソッドを使って生成した境界ボックスを示す(略).

付記 仮に Point インスタンスに対して STEnvelope() メソッドを使うと,SQL Server はその点周囲の最小面積の Polygon を生成する.例えば,POINT (30 20) という Point 周囲の STEnvelope() の結果は POLYGON ((29.999999 19.999999, 30.000001 19.99999, 30.000001 20.000001, 29.99999 20.000001, 29.99999 19.999999)) である.

サポートされるデータ型

 STEnvelope() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型

使用法

 STEnvelope() メソッドはいかなるパラメータも要せず,geometry 型のいかなる種類のインスタンス上でも次のように使われる.

Instance.STEnvelope

 STEnvelope() メソッドの結果は常に Polygon であり,呼び出されたその geometry 型インスタンスと同じ SRID を使って定義される.

 次のコードは大文字 A の形に Polygon ジオメトリを生成し,ついでその Polygon 周囲に STEnvelope() メソッドを使って境界ボックスを生成する.

DECLARE @A geometry
SET @A = geometry::STPolyFromText('
  POLYGON((0 0, 4 0, 6 5, 14 5, 16 0, 20 0, 13 20, 7 20, 0 0),
  (7 8, 13 8, 10 16, 7 8))', 0)
SELECT
@A AS Shape,
@A.STEnvelope() AS Envelope,
@A.STEnvelope().STAsText() AS WKT
PLYGON ((0 0, 4 0, 6 5, 14 5, 16 0, 20 0, 13 20, 7 20, 0 0))

geography 型のオブジェクトの包囲角を計算する

 STEnvelope() メソッドは geography 型のオブジェクトには提供されていない.軸に沿った直線の単純な長方形の境界ボックスは,地球の楕円形モデルには適用できないからである.しかし,SQL Server は geography 型インスタンスの範囲を記述する代わりのメソッドを提供しており,それは EnvelopeCenter() メソッドと EnvelopeAngle() メソッドである.

 筆者はすでに EnvelopeCenter() メソッドについて本章の最初の方で紹介した.それは geography 型インスタンス内のすべての点群のベクトル平均から計算された Point オブジェクトを返すのに使われ,いかなる種類のジオメトリでもその中心を近似するのに使われる.EnvelopeAngle() メソッドは,EnvelopeCenter() メソッドで得られた点と,ジオメトリ内で EnvelopeCenter() の点から最も遠い点との間の角度を返す.その戻り値は geography 型インスタンスが地球の中心点まで広がった点にまで及ぶ計測である.figure 11-23 にEnvelopeCenter() の計算されたメソッドを示す(略).

サポートされるデータ型

 EnvelopeAngle() メソッドは次のデータ型のインスタンス上で使われる.

  • geography 型

使用法

 EnvelopeAngle() メソッドはいかなるパラメータも取らず,geography 型のインスタンス上で次のように使われる.

Instance.EnvelopeAngle()

 EnvelopeAngle() メソッドの結果は浮動小数点数であり,弧度法で測定した角度を表現している.このメソッドで返りうる最大値は 90 であり,それより大きな角度は Polygon の占める単一の半球よりも大きなところに点が含まれるという理由による.geography 型の制約の一つである.

 次の例は geography 型の Polygon @NorthernHemisphere を生成し,北半球を表現している.@NorthernHemisphere は赤道上に位置する点群の外部リング内に含まれる面として定義され,それは北緯 0.1° にある.例ではついで EnvelopeAngle() メソッドを使い,@NorthernHemisphere Polygon 内の任意の点とエンベロープの中心点との間の最大の角度を計算している.

DECLARE @NorthernHemisphere geography
SET @NorthernHemisphere = geography::STGeomFromText('POLYGON((0 0.1, 90 0.1, 180 0.1, -90 0.1, 0 0.1))', 4326)
SELECT
  @NorthernHemisphere AS SHape,
  @NorthernHemisphere.EnvelopeAngle() AS EnvelopeAngle

 エンベロープの中心点が北極点であること,その Polygon が赤道上にまで広がっていることから,その結果は 90° 近くに見える.

89.90000000000014

チップス EnvelopeAngle() の結果が 90 を超えることは決してない.関連する geography 型インスタンスは単一の半球を超えられないからである.

Geometry Collection の要素数を数える

 STNumGeometries() メソッドは本章の最初で紹介した STNumPoints() メソッドと多くの点で同様に動作する.ジオメトリ内の点の数を数える代わりに,STNumGeometries() は geometry 型または geography 型インスタンス内部に含まれるジオメトリの数を記述する整数値を返す.Geometry Collection に対して使われたとき,その結果はコレクション内部の要素数となる.単一要素のインスタンスに対して使われた場合,Point, LineString または Polygon の場合だが,STNumGeometries() の結果は 1 になる.いかなる種類でも空のインスタンスに使われた場合,結果は 0 になる.Figure 11-24 に様々な種類のインスタンスに STNumGeometries() メソッドを使ったときの結果を示す(略).

サポートされるデータ型

 STNumGeometries() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STNumGeometries() メソッドはいかなるパラメータも取らず,geometry 型および geography 型インスタンス上で次のように呼び出される.

Instance.STNumGeometries()

 次の例において,(2つの Point からなる)MultiPoint 要素,一つの LineStirng, 一つの Polygon を含む Geometry Collection が生成される.STNumGeometries() メソッドを使ってコレクション内の要素の総数を数えている.

DECLARE @Collection geometry
SET @Collection = geometry::STGeomFromText('
  GEOMETRYCOLLECTION(
    MULTIPOINT((32 2), (23 12)),
    LINESTRING(30 2, 31 5),
    POLYGON((20 2, 23 2.5, 21 3, 20 2)))', 0)
SELECT
  @Collection AS Shape,
  @Collection.STNumGeometries() AS NumGeometries
3

 MultiPoint ジオメトリが2つの Point ジオメトリを含んでいるにも関わらず,コレクション全体の STNumGeometries() の結果は 3 である.これは MultiPoint ジオメトリが Geometry Collection においては唯一つの要素として数えられるからである.STNumGeometries() は単一の要素のジオメトリ(Point, LineString および Polygon),多要素ジオメトリ(MultiPoint, MultiLineString および MultiPolygon)および空のジオメトリはコレクションに含まれるいかなる種類であっても単一のアイテムとして数える.

Geometry Collection から個別のジオメトリを取得する

 STGeometryN() メソッドは Geometry Collection から n 番目のジオメトリを返す.それは汎用の Geometry Collection でもコレクションの特異的なサブタイプ(MultiPoint, MultiLineString あるいは MultiPolygon)の一つでもどちらでも使われる.Figure 11-25 に STGeometryN() メソッドを使ってジオメトリの範囲から個別の要素を単離するところを示す(略).

付記 単一要素のジオメトリには STGeometryN(1) を使うことができる.その場合メソッドの結果はそのジオメトリ自体である.

サポートされるデータ型

 STGeometryN() メソッドは次のデータ型のインスタンス上で使われる.

  • geometry 型
  • geography 型

使用法

 STGeometryN() メソッドは一つのパラメータ n を提供されなければならない.使い方の構文は次の通り.

Instance.STGeometryN(n)

 ここで n は,コレクション由来の取得したいジオメトリの序数である. n の値の範囲は 1 から Geometry Collection 内の要素の総数までである(STNumGeometries() で取得できる).

 次の例はダラス・フォートワース国際空港にある7本の滑走路を表現する MultiLineString を生成し,その数は全世界で最大である.ついで STGeometryN() メソッドを使って一本の滑走路を示す一つの LineString を単離して返す.

DECLARE @DFRunways geography
SET @DFRunways = geography::STMLineFromText(
  'MULTILINESTRING(
    (-97.0214781 32.9125542, -97.0008442 32.8949814),
    (-97.0831328 32.9095756, -97.0632761 32.8902694),
    (-97.0259706 32.9157078, -97.0261717 32.8788783),
    (-97.0097789 32.8983206, -97.0099086 32.8749594),
    (-97.0298833 32.9157222, -97.0300811 32.8788939),
    (-97.0507357 32.9157992, -97.0509261 32.8789717),
    (-97.0546419 32.9258147, -97.0548336 32.8789861))', 4326)
SELECT
  @DFRunways AS Shape,
  @DFRunways.STGeometryN(3) AS Geometry3,
  @DFRunways.STGeometryN(3).STAsText() AS WKT
LINESTRING (-97.0259706 32.9157078, -97.0261717 32.8788783)

要約

 Table 11-2 に本章で紹介したすべてのメソッドとプロパティを示し,そのメソッドのサポートするデータ型もともに掲載する.

Table 11-2. 各データ型によりサポートされる空間オブジェクトのプロパティを返すメソッド
メソッド 記述 geometry 型 geography 型
ジオメトリを記述する
STGeometryType() ジオメトリの種類の名前を返す(例 Point, LineString)
InstanceOf() インスタンスが特定のジオメトリの種類であるか否か検査する
STDimension() インスタンスの占める次元数を返す
STIsSimple() インスタンスが単純か否か判定する  
STIsClosed() インスタンスが閉じているか否か判定する  
STIsRIng() インスタンスがリングであるか否か判定する  
STNumPoints() インスタンスの点の数を返す
STIsEmpty() ジオメトリが空であるか否か判定する
Point の座標値を返す
STX geometry 型の Point インスタンスの x 座標を返す  
STY geometry 型の Point インスタンスの y 座標を返す  
Lat geography 型の Point インスタンスの緯度を返す  
Long geography 型の Point インスタンスの経度を返す  
M Point インスタンスの m(計測)座標を返す
Z Point インスタンスの z(標高)座標を返す
ジオメトリから個別の Point を返す
STPointN() インスタンスの定義内の n 番目の点を返す
STStartPoint() インスタンスの定義内の最初の点を返す
STEndPoint() インスタンスの定義内の最後の点を返す
STCentroid() Polygon インスタンスの幾何学的中心を返す  
EnvelopeCenter() geography 型インスタンスのエンベロープの中心を返す  
STPointOnSurface() インスタンスの内部由来の任意の点を返す  
STLength() インスタンス内のすべての線の長さを返す
STArea() インスタンスに含まれる面積を返す
STSrid インスタンスの定義された空間参照系の SRID を取得または設定する
Polygon のリングを操作する
STExteriorRing() Polygon インスタンスの外部リングを返す  
STNumInteriorRing() Polygon インスタンスの内部リングの数を返す  
STInteriorRingN() Polygon インスタンスの特定の内部リングを返す  
NumRIngs() geography 型の Polygon インスタンスのリングの数を返す  
RingN() geography 型の Polygon インスタンスから特定のリングを返す  
ジオメトリの範囲を記述する
STBoundary() インスタンスの境界を返す  
STEnvelope() geometry 型インスタンスのエンベロープ(境界ボックス)を返す  
STEnvelopeAngle() geography 型インスタンスと多くの外れている点との中心間の角度を返す  
多要素ジオメトリを操作する
STNumGeometries() インスタンス内のジオメトリの数を返す
STGeometryN() 多要素ジオメトリから特定のジオメトリを返す

 これらのメソッドのマイクロソフトリファレンスは,Microsoft SQL Server 2008 Books Online で参照可能である.

“第 11 章 空間オブジェクトのプロパティを検査する(Begining Spatial with SQL Server 2008)” への1件の返信

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください