第 4 章 空間データオブジェクトを生成する (Beginning Spatial with SQL Server 2008)

第 2 部 空間データを追加する

 本書のこの部では空間データを SQL Server 2008 データベースに追加する様々な方法を説明する.第 4 章では,既知の座標からいかなるアイテムをも生成するのに使われる存在する静的メソッドのそれぞれを紹介する.第 5 章では,外部資源をかぶせてそれらの座標を派生させるのを助けるための技術を解説する.Microsoft の Virtual Earth Map Control を使う.第 6 章では,空間データの蓄積される他の一般的なデータフォーマットについて議論し,これらの蓄積されたデータを SQL Server 2008 にインポートする方法についての例を提供する.最後に,第 7 章で SQL Server を拡張してジオコーディング機能を提供する方法を示す.つまり,.NET 経由で Microsoft MapPoint Web Services にアクセスして自動的に住所から座標を取得することである.

 前章では,静的メソッドの概念について紹介し,geography 型および geometry 型のオブジェクトをインスタンス化する方法について説明した.本章では各データ型で利用できる異なる静的メソッドを検査し,空間データの新しいアイテムを生成するのに使われる方法について比較する.

注記 本章でのほとんどのコードサンプルは,@Point などのローカル変数を宣言し,その結果静的メソッドにより生成されたインスタンスを蓄積する.しかし,INSERT ステートメントを呼び出すことで静的メソッドの結果をテーブルの geometry 型および geography 型の列に挿入することもできる.

適切な静的メソッドを選択する

 geography 型および geometry 型は共に多くの異なる静的メソッドを提供し,空間データオブジェクトを生成する.特定の状況で適切なメソッドを使用するのは次に述べる因子による.

生成しようとするジオメトリの種類

 いくつかのメソッドは単に特定のジオメトリを生成するためだけに使われる.例えば,STLineFromWKB() メソッドおよび STLineFromText() メソッドは単に LineString ジオメトリインスタンスを生成するだけである.

このジオメトリの属性を記述する方法

 全てのメソッドはジオメトリの空間参照の提供を必要とし,三つの異なる標準フォーマットのうち一つを使う.つまり,Well-Known Text (WKT), Well-Known Binary (WKB) および Geometry Markup Language (GML) である.ジオメトリを記述するためにいずれのメソッドを選んだかにより,適切な表現フォーマットを使わなければならない.例えば,任意のジオメトリインスタンスを GML 表現から生成するには GeomFromGML() メソッドを使わなければならない.

geometry 型または geography 型で生成したいアイテムは一体何か

 geometry 型および geography 型共に,それら自身の各静的メソッドを実装している.静的メソッドはメソッド自身と同一のデータ型のオブジェクトのインスタンスを生成できるだけであるため,生成したいオブジェクトのデータ型によって適切なデータ型のメソッドを選択しなければならない.例えば,geometry 型の Point オブジェクトを WKT 表現から生成するには geometry::STPointFromText() メソッドを使うべきである.geography 型の Point オブジェクトを WKT 表現から生成するには代わりに同等の geography 型のメソッドである geography::STPointFromText メソッドを使うべきである.

 Table 4-1 に異なるジオメトリインスタンスを生成するのに使用されるメソッドを示す.これら全てのメソッドは geography 型にも geometry 型にも共に実装されている.

Table 4-1. 異なる表現から空間オブジェクトをインスタンス化するのにサポートされる方法
オブジェクトの種類 Well-Known Text Well-Known Binary Geography Markup Laguage
Point STPointFromText() STPointFromWKB() GeoFromGml()
LineString STLineFromText() STLineFromWKB() GeoFormGml()
Polygon STPolyFromText() STPolyFromWKB() GeoFromGml()
MultiPoint STMPointFromText() STMPointFromWKB() GeoFromGml()
MultiLineString STMLineFromText() STMLineFromWKB() GeoFromGml()
MultiPolygon STMPolyFromText() STMPolyFromWKB() GeoFromGml()
Geometry Collection STGeomCollFromText() STGeomCollFromWKB() GeoFromGml()
Any supported type STGeomFromText() Parse() STGeomFromWKB() GeoFromGml()

 空間オブジェクトを表現するのにいずれの言語を使うにせよ,また,いずれの型のオブジェクトを生成するにせよ,本章で議論する静的メソッドは全て同一の構文を共有する.この汎用構文は次に示す通りである.

datatype::method(geometryrepresentation, srid)

 この構文は次に示すとおり 4 つの構成要素からなる.

  • datatype は静的メソッドが geography 型か geometry 型のいずれに属するかを指定し,ゆえにメソッドにより生成されたインスタンスのデータ型を定義する.
  • method はジオメトリを生成するメソッド名である.これは必ず Table 4-1 に列挙したメソッドの一つでなければならない.
  • geometryrepresentation は生成すべきジオメトリの有効な表現である.この表現は選択されたメソッドにより生成された適切なフォーマットにおいて表現されなければならない.その表現とは(WKT および GML フォーマットの)文字列,あるいは問題のジオメトリを定義するのに必要な全情報を含んだバイナリーストリーム (WKB) である.
  • srid は空間参照系の識別子を表現した整数値であり,メソッドを通して geometryrepresentation パラメーター内で座標を定義するのに使われる.

 その中でジオメトリが表現される各フォーマットおよび,オブジェクトがそれらの表現から生成される各メソッドは,それぞれ利点と欠点を有する.しかし,geography 型データか geometry 型データか,いずれのメソッドを使ってアイテムを生成するかの決定は,生成の時点でのみ重要であり,アイテムの生成後は無関係になっていく.特定のメソッドを使って空間データのアイテムを生成してしまえば,そのデータのアイテムは,他の利用可能だったメソッドを使って生成されたものであっても,全く同一のものとなる.

レイトバインディング

 任意の静的メソッドにより指定された geography 型あるいは geometry 型オブジェクトへの参照は,実行中にのみ解決され,それはメソッドを呼び出すクエリが実行される時である.これはレイトバインディングとして知られている.レイトバインディングの一つの効果として,クエリが実行されるまでは SQLCLR はどんな種類のオブジェクトが静的メソッドにより生成されるかを知らない.結果として,SQL Server は表現を解析して有効なデータであるかチェックすることができない.例えば,次のクエリはいかなる解析エラーも発生させずに SQL Server Management Studio において正しくコンパイルされる.

SELECT  geometry::STGeomFromText('This is not a real geometry')

 しかし,実行の際に,メソッドに渡された表現が有効な WKT ではないため,このクエリは失敗する.有効な WKT とは,STGeomFromText() メソッドに必要な,という意味である.いかなる静的メソッドでも表現を指定して渡す時には注意されたい.というのは,これらのクエリを実行するまでエラーが表示されないかもしれないからである.

Well-Known Text からジオメトリを生成する

 Well-Known Text は Open Geospatial Consortium (OGC) により空間情報変換のために定義された標準フォーマットの一つである.それは簡素でテキストベースのフォーマットであり,簡単にテストし理解できる.既に WKT 表現として第 1 章で見たと思う.それは SQL Server 2008 がパラメーターを蓄積するために使い,sys.spatial_reference_systems テーブルの well_known_text 列内の測地空間参照系をサポートする.その文脈では,WKT は空間参照系の属性を記述するのに使われる.しかし,WKT はまた空間参照系内部で個別のジオメトリオブジェクトを表現するのに使うこともできる.例えば,次のコード行は WKT が座標 (12,20) および (30,44) 地点間の LineString を定義するのに使う方法を示す.

LINESTRING(12 20,30 44)

 WKT フォーマットの利点はいくつかある.

  • 簡素で構造化されたフォーマットであり,システム間での共有と保存が容易である.
  • テキストベースのため,WKT 表現で運ばれた情報を視覚で識別するのが容易である.

 しかし,WKT には次の欠点がある.

  • どのテキストベースの表現であれ,バイナリーメソッドで取得された確実な小数点の座標値を正確に記述することは不可能である.丸めエラーは不可避であり,無理にそうすると精度が失われる.
  • SQL Server は WKT 表現内のテキストを解析して同等の空間オブジェクトを生成しなければならないため,WKT からのオブジェクト生成は他の方法よりも遅くなる.

 可読性と相対的な簡潔性により,WKT フォーマットは他のユーザーと空間データを共有し図示するのに一般的に使われ,本書において最も使われるフォーマットである.SQL Server 2008 Books Online,  Microsoft SQL Server オンラインドキュメントで使われるフォーマットでもある.http://msdn.microsoft.com/en-us/library/ms130214.aspx

 SQL Server 2008 は WKT から基本的な種類のジオメトリの形態に特定の静的メソッドを実装する.Point, LineString および Polygon であるが,同種で多要素および異種の Geometry Collection オブジェクト型に対しても同様である.WKT からサポートされる種類のジオメトリオブジェクトを生成できる汎用のメソッドも存在する.さて,各メソッドの詳細を見てみよう.

WKT から Point を生成する

 デカルト座標系に由来する Point を表現する WKT 構文とは,投影座標系に由来するようなものであるが,次のようである.

POINT(x y)

 地理座標系で指定された Point のための同等の WKT 構文.

POINT(longitude latitude)

 それぞれのケースでは,POINT というキーワードを伴う表現は,その後にポイントの座標値にあたるところが続き,丸括弧に囲まれている.座標値はコンマではなく,スペースで区切られていることに注意されたい.

注意 日常言語では緯度と経度を参照するのは普通である(その順序で).しかし,一組の地理座標を WKT 内で定義する時には,経度座標が先で,緯度座標がその後になる.正しい順序で座標を指定するように注意しよう!

 WKT 表現から geography 型あるいは geometry 型の Point オブジェクトを生成するには,適切なデータ型の STPointFromText() メソッドを使うことができる.例えば,geography 型を使って Edinburgh を表現する Point オブジェクトを生成したいとする.座標が経度 -3.19 度の緯度 55.95 度,空間参照系に SRID 4326 で表現されているとする.次のクエリを SQL Server Management Studio で実行できる.

DECLARE @Edinburgh geography
SET @Edinburgh = geography::STPointFromText('POINT(-3.19 55.95)', 4326)

 次のメッセージを受け取るに違いない.

Command(s) completed successfully.

 変数 @Edinburgh は今度はこのメソッドで生成された Point インスタンスを保持する.別の例を試してみよう.今度は,Glasgow を表現する Point を生成してみよう.座標は (258647,665289) で空間参照系は 27700 を使っている.このために,次のクエリを実行させてみる.

DECLARE @Glasgow geography
SET@Glasgow = geography::STPointFromText('POINT(258647 665289)', 27700)

 何てことだ!今回は次のエラーメッセージを受け取ることになる.

Msg 6522, Level 16, State 1, Line 2
A .NET Framework error occurred during execution of user-defined routine or aggregate "geography";
System.ArgumentException: 24204: The spatial reference identifier (SRID) is not valid. The specified SRID must match one of the supported SRIDs displayed in the sys.spatial_reference_systems catalog view.

 思い出してほしい.geography 型は地理座標を蓄積するためだけにしか使えず,測地空間参照系由来と認識されたものに限られるということを.しかし,ここで使用した geography 型の STPointFromText() メソッドは SRID 27700 に基づく座標を提供しており,それは投影座標系に基づく空間参照系なのである.

 これらの座標系に基づいた空間オブジェクトを生成するには,WKT 構文をまだ使えるが,代わりに geometry 型に所属する STPointFromText() メソッドを使わなければならない.次のように.

DECLARE @Glasgow geometry
SET @Glasgow = geometry::STPointFromText('POINT(258647 665289)', 27700)

 今度は geometry 型を使用したため,投影空間参照系から取得した平面データを蓄積するもので,その Point インスタンスは成功裏に変数 @Glasgow に割り当てられた.次のメッセージに示す.

Command(s) completed successfully.

注意 WKT は geometry 型あるいは geography 型のオブジェクトの単なるテキスト表現であることを思い出そう.単なる WKT 文字列を直接 geometry 型あるいは geography 型の列に挿入することはできない.

INSERT INTO GeographyColumn VALUES ('POINT(100 40)')

 代わりに,WKT 文字列をパラメーターとして静的メソッドに渡さなければならない.

STPointFromText()
Z 座標および M 座標

 地球上のある地点の位置を定義するには,たった二つの座標が必要とするだけであることを知っている.x と y (投影座標参照系においては),あるいは,緯度と経度(地理座標参照系)である.しかし,これら二つの座標に加えて,WKT における Point オブジェクトは付加的な z および m 座標によって定義されることもある.

  • z 座標はある地点の高度,あるいは高さを表現する.地球表面上の位置が水平基準を参照して測定されるように,その表面の上下の高度は垂直基準を使って測定される.ある地点の z 座標は基盤となる地形の上である海面上の高度を測定し,あるいは,使われる垂直基準を定義する参照楕円体からの高度を測定する.
  • m 座標はある地点の計測値 “measure” を蓄積する.この座標はある地点の任意の付加的な属性を表現するのに使われ,倍精度数で表現される.例えば,仮に空間属性を時間ベースのデータで記録したいなら,ある地点の m 値を使ってデータの取得された時刻を表現することができる.あるいは,仮にその地点が経路上に位置しているなら,その m 座標は経路に沿った距離を蓄積するのに使うことができる.

 z および m を含む WKT 表現における地点を表現するには,次の構文を使うこと.

POINT(x y z m)

 あるいは,地理座標を使うなら,次の構文を使うこと.

POINT(longitude latitude z m)

 SQL Server 2008 が WKT に基づいて提供する静的メソッドは,STPointFromText()のようなものだが,POINT 定義の一部として z および m 値の生成と蓄積をサポートする.しかし,これらの座標が計算の実行時に使われることはない.例えば,(0 0 0) および (3 4 12) に位置する地点間の距離を計算する際に,SQL Server 2008 は結果を 5 単位(x および y の次元の差分の合計の平方根)として計算する.13 ではない(x, y および z 次元での差分の合計の平方根).

WKT から LineString を生成する

 n 個の点を含む LineString の WKT 構文は次の通り.

LINESTRING(x1 y1, x2 y2, ..., xn yn)

 Point の WKT 構文のように,生成すべきジオメトリ,ここでは LineString のことだが,その種類を指定するキーワードの表現に,丸括弧のジオメトリ内の各点の座標が続く.ある一点を定義するその座標値はスペースで区切られ,Linestring 内の各点を表現するその座標の集合はコンマで区切られる.

 LinsString オブジェクトを作成する STLineFromText() メソッドの組み合わせで一つの LineString を表現するのに WKT 表現を使うこともできる.一つの単純な LineString ジオメトリを作ってみよう.それは2つの点をつないだもので Sydney Habour Bridge の両端を示している.この例では geography 型を使うことにしよう.そして始点と終点の座標を SRID 4326 と定義しよう.

DECLARE @SydneyHarbourBridge geography
SET @SydneyHarbourBridge = geography::STLineFromText(
'LINESTRING(
151.209 -33.855, 
151.212 -33.850
)',
 4326)

 今度はもっと複雑な LineString, 5つの点を結んだものに挑戦しよう.この例では,コードを変更している.Geometry テーブルの GeometryColumn と言う名の geometry 型の列にジオメトリを挿入する方法を例示している.

INSERT INTO Geometries (
NameColumn,
GeometryColumn
)
VALUES (
'Linestring connecting five points',
geometry::STLineFromText(
'LINESTRING(
53.4 -2.99, 
53.5 -3.15, 
53.47 -4.66, 
53.40 -5.11, 
53.34 -6.25
)',
0)
)

 この例では,さらなる点の座標を単純に WKT 表現に追加することにより,より長くより複雑な LineString を作る方法を示している.それぞれの点はコンマで区切られている.

WKT から Polygon を生成する

 Polygon の WKT 構文は,各リングに n 個の点を持つ z 個のリングからなり,下記のように記述する.

POLYGON(
(ax1 ay1, ax2 ay2, ..., axn ayn, ax1 ay1),
(bx1 by1, bx2 by2, ..., bxn byn, bx1 by1),
...
(zx1 zy1, ax2 ay2, ..., zxn zyn, zx1 zy1)
)

 先述した WKT の例全てに当てはまるように,その表現には丸括弧が含まれ,次の初期キーワード,この例では POLYGON に続く.これらの丸括弧内には,Polygon のリングの各座標が含まれており,それら自身の追加の括弧内に収まっている.一つの Polygon のリングは閉じた LineString であるから,各リングの WKT 構文は一つの LineString の定義に使う構文と全く同じである.一つの座標タプル内の独立した座標値はスペースで区切られ,座標の集合はコンマで区切られる.

 座標の最初の集合である (ax1 ay1, ax2 ay2, …, axn, ayn, ax1 ay1) は Polygon の外周を定義する点を記述している.外周リングの定義に続けて,Polygon を内部リングをいくつでも任意の数だけ定義できる.(bx1 by2, bx2 by2, … bxn byn, bx1 by1), (zx1 zy1, zx2 zy2, … zxn zyn, zx1 zy1) など.すべての内部リングの定義は外部リングと同じ構文に従い,丸括弧の内部に含まれ,前のリングからはコンマにより区切られる.次の点は重要である.つまり,各リングは必ず閉じていなければならない.つまり,各リング内部では,最初の座標タプルと最後の座標タプルは等しくなければならない.

付記 geometry 型を使う時には外部リングはひとつの Polygon 内部を含む周縁を定義する.一方,各内部リングはその Polygon を切り取る「穴」を定義する.geography 型を使う時には,外部リングと内部リングの間を区別することは重要ではない.すべてのリングは Polygon 内に含まれる空間の面を定義し,除かれる面を定義する.ゆえに,geography 型を使用する際には,WKT 表現内に並べる順番は重要ではない.

 仮に Polygon が一つしかリングを含まない場合でも,そのリングの点もそれら丸括弧の集合内に含まれなくてはならない.この例では,その点の座標は POLYGON キーワード定義の後の二重の丸括弧内に含まれているようにみえる.次のようである.

PLOLYGON((x1 y1, x2 y2, ..., xn yn, x1 y1))

注意 Polygon は閉じたリングで構成され,そのため各リングの最初の座標セットと最後の座標セットは同じでなくてはならない.

 WKT から geometry 型でも geography 型でも Polygon を生成する SQL Server のメソッドは STPolyFromText() と呼ばれる.このメソッドを使って,ある Polygon ジオメトリを生成する方法を提示しよう.合衆国防衛省ペンタゴンの建物を表現し,geography 型で SRID 4326 を使う.

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.870737733163644,
-77.05673217773439 38.87170668418343,
-77.0554769039154 38.871848684516294,
-77.05491900444031 38.87097997215688,
-77.05582022666931 38.8702866652523
)
)',
4326
)

 この Polygon の定義は2つのリングを含む.各リングは角が5つの五角形をしているにも関わらず,各リングにはその定義に6つの点が含まれている.それはジオメトリの最初と最後の点が二回記述されているからである.次の点に注目しよう,この例が geography 型を使用しているため,最初のリングの点は建物の外側の縁を定義していて反時計回りの順番であること,反対に二番目のリングの点はジオメトリから省略された中庭を囲んでいて時計回りの順番に定義されていることを(geography 型を用いる際のリングの順番の違いについてさらなる情報は第2章を参照のこと).

WKT から MultiPoint を生成する

 MultiPoint は一つのオブジェクト内にいくつかの Point ジオメトリを収めたコレクションである.MultiPoint オブジェクトを WKT で表現するには,最初に MULTIPOINT 要素名を宣言し,続けてコンマで区切られた,インスタンス内に含まれる各ジオメトリの座標タプルのリストが続く.単一要素の Point オブジェクトで表現されるのと同じ作法である(つまり,コレクション内の各 Point の独立した座標値は x y z m の順に続けて記述するか,longitude latitude z m の順にスペースで区切って記述する).

 例えば,次の MultiPoint オブジェクトの WKT 表現は3つの Point を含んでいる.

MULTIPOINT(21 2, 12 2, 30 40)

 WKT 表現における各点は2つから4つの座標値を含むため(オプションの z 座標と m 座標が定義されているかに依存する),各座標タプルを区切るためにコンマデリミタは正確に置かなければならない.先述した例と比べると次のコードは同じ座標値を使っているが2つの Point ジオメトリを含む MultiPoint インスタンスを生成しており,それぞれの点は x, y および z 座標を有している.

MULTIPOINT(21 2 12, 2 30 40)

 MultiPoint ジオメトリの WKT 表現は,新しい MultiPoint オブジェクトをインスタンス化するための STMPointFromText() メソッドで提供することができる.例えば,次のコードは STMPointFromText() メソッドを使って3つの Point を含む MultiPoint ジオメトリを生成するのを示しており,3つの Point は Giza にある Khafre, Khufu, Menkaure のピラミッドを表現しており,SRID 32636 を使って定義している.

DECLARE @Pyramids geometry
SET @Pyramids = geometry::STMPointFromText(
'MULTIPOINT(319640 3317580, 319980 3317940, 319400 3317200)',
32636
)

WKT から MultiLIneString を生成する

 MultiLineString ジオメトリの WKT 表現は各 LineString ジオメトリのコンマ区切りリストが形成される.しかし,LineString ジオメトリのWKT 構文がすでに各点の間にコンマデリミタを含んでいるため,MultiLineString コレクション内部に含まれる各 LineString は丸括弧で囲まなければならず,それにより MultiLineString 内にある他の LineString 要素から特定の LineString 内の点を区別することができる.

 次の例が示すように,MultiLineString インスタンスの構文は2つの LineString 要素を含んでおり,最初のは3つの Point を含み,二番目のは2つの Point を含んでいる.

MULTILINESTRING((10 20, 3 4, 43 42),(44 10, 20 40))

 この表現からSRID 20539 に基づいて geometry 型の MultiLineString のインスタンスを生成するには,STMLineFromText() メソッドを使うことができる.次のようである.

DECLARE @MultiLineString geometry
SET @MultiLineString = geometry::STMLineFromText(
'MULTILINESTRING((10 20, 3 4, 43 42),(44 10, 20 40))',
20539
)

WKT から MultiPolygon を生成する

 MultiPolygon インスタンスの WKT 表現は MULTIPOLYGON キーワードの宣言から始まる.MultiLineString でみたように,multiPolygon 内部の各 Polygon 要素は丸括弧の集合を付加して収められており,コンマで区切る.次の MultiPolygon 要素の WKT 表現は2つの Polygon を含んでおり,それぞれが外部リングのみを持つ.

MULTIPOLYGON(((10 20, 30 40, 44 50, 10 20)),((5 0, 20 40, 30 34, 5 0)))

 MultiPolygon インスタンを WKT から生成するメソッドは STMPolyFromText() である.これは先述した表現で SIRD 0 を用いて使われる.次のようである.

DECLARE @MultiPolygon geometry
SET @MultiPolygon = geometry::STMPolyFromText(
'MULTIPOLYGON(((10 20, 30 40, 44 50, 10 20)), ((5 0, 20 40, 30 34, 5 0)))',
0
)

注意 2つの Polygon を含む MultiPolygon と2つのリングを含む単一の Polygon とを混同してはいけない.一つの MultiPolygon, 例えば MULTIPOLYGON(((10 20, 30 40, 44 50, 10 20)), ((35 36, 37 37, 38 34, 35 36))) は空間の2つの異なる面を定義する.一方で 2つのリングを含む単一の Polygon, 例えば POLYGON((10 20, 30 40, 44 50, 10 20), (35 36, 37 37, 38 34, 35 36)) は,二番目に定義された面に含まれる点が除外された空間の単一の面を定義している.

WKT から Gemetry Collection を生成する

 Geometry Collection は多要素のオブジェクトであり,同質の多要素の型の MultiPoint や MultiLineString, MultiPolygon とは異なり,複数の異なる型のジオメトリが単一のオブジェクト内に存在する.

 Geometry Collection の WKT を形成するにはGEOMETRYCOLLECTION キーワードを使い,コレクション内に含まれるそれぞれ個別のオブジェクトをコンマで区切った WKT 表現が続く.この表現から Geometry Collection のインスタンスを生成する関連するメソッドは STGeomCollFromText() である.このメソッドの使い方を示すために,次のコードは新しい Geometry Collection を生成し,一つの Polygon と一つの Point オブジェクトを含む SRID 0 と geometry 型を使う.

DECALRE @GeometryCollection geometry
SET @GeometryCollection = geometry::STGeomCollFromText(
'GEOMETRYCOLLECTION(
POLYGON((5 5, 10 5, 10 10, 5 5)),
POINT(10 10))',
0
)

付記 多要素型の MultiPoint, MultiLineString, MultiPolygon はみな特定のジオメトリ型であり,汎用の Geometry Collection クラスに由来する.

WKT から任意の種類のジオメトリを生成する

 これまで論じてきた各々のメソッドは,WKT からある特定の型のジオメトリオブジェクトだけを生成することができる.例えば STPointFromText() は Point オブジェクトをインスタンス化し,STPolyFromText() は Polygon オブジェクトをインスタンス化する.これらのジオメトリ特異的なメソッドに加えて,SQL Server 2008 は2つの一般化されたメソッドを提供し,それは任意のオブジェクトを整然とした WKT から生成することができる.これらのメソッドは STGeomFromText() および Parse() である.両メソッドはgeometry 型にも geography 型にも使うことができる.

 STGeomFromText() は OGC の標準規格に準拠したメソッドであり,WKT からいかなる種類の空間オブジェクトをも生成することができる.それで,次の例のように,ジオメトリ特異的なメソッドである STPointFromText() および STLineFromText() の代わりに,

DECLARE @myTable TABLE (GeographyColumn geography)
INSERT INTO @myTable (Geography) VALUES
(geography::STPointFromText('POINT(-122.34 47.65)', 4326))
INSERT INTO @myTable (Geography) VALUES
(geography::STLineFromText('LINESTRING(32.51 -23.34, 33.98 -12.10)', 4326))

代わりに STGeomFromText() メソッドを両方のケースで使うことができる.次のように.

DECLARE @myTable TABLE (Geographycolumn geography)
INSERT INTO @myTable (GeographyColumn) VALUES
(geography::STGeomFromText('POINT(-122.34 47.65,)', 4326))
INSERT INTO @myTable (Geographycolumn) VALUES
(geography::STGeomFromText('POINT(LINESTRING(32.51 -23.34, 33.98 -12.10))', 4326))

 同じ STGeomFromText() メソッドをいかなる種類の有効なオブジェクトをも WKT から生成するのに使うことができるため,なぜ更に特異的な STPointFromText() や STLineFromText() を使う代わりに,単純に STGeomFromText() メソッドをすべての場面で使わないのかと不思議に思うかもしれない.

 この質問に対する答えはこうである.つまり,オブジェクト特異的メソッドは,そのメソッドで生成されるオブジェクトの型のための有効なデータを表現していることを確保するために WKT をパースする一方で,STGeomFromText() は提供される入力をそれほど厳密に検証できないのである.それゆえにSTGeomFromText() メソッドを使うと出来損ないや不正確な型のオブジェクトを生成してしまう危険性がある.ある種類のジオメトリを作ろうとしていることが分かっているなら,型特異的なメソッドを使って特定のジオメトリオブジェクトをデザインするほうが良い.しかし,状況によっては STGeomFromText() のほうが有利な場合もある.例えば同じ関数を再利用して多くの異なる型のジオメトリを生成するような場合であるとか,あるいはどんな種類のジオメトリが生成されるのに有利なのか分かっていない場合である.

付記 汎用メソッドは STGeomFromText() と呼ばれるにも関わらず,それはgeometry 型にも geography 型にも使われる.

 OGC 準拠の STGeomFromText() メソッドに加えて,geometry 型および geography 型もまた Parse() メソッドを提供する.Parse() メソッドは正確に STGeomFromText() メソッドと同じ方法で操作する.geometry 型に関しては,Parse() は SRID を 0 と決めつける.geography 型に関しては,Parse() は SRID 4326 を使う.これは GPS 衛星測位装置および多くの他の一般的なアプリケーションで使われる空間参照系のための EPSG コードである.使用するそのデータ型のための空間参照系を使って定義されたオブジェクトを生成するなら,SRID を省略して代わりに Parse() メソッドを使うほうが便利だと分かるだろう.次のようである.

DECLARE @LineString geography
SET @LineString = geography::Parse('LINESTRING(120 50, 128 52)')

 このコードは東経 120°北緯50°と東経128°北緯52°の地点間の LineString を定義しており,空間参照系 EPSG 4326 を使って定義されている.

既存のジオメトリを WKT として表現する

 WKT は空間のオブジェクトの表現であることを思い出そう.それはテキストの文字列で先述したメソッドのいくつかのパラメーターで提供され,SQL Server 内に空間オブジェクトのインスタンスを生成するためのものである.しかし,geometry 型でも geography 型でも列や変数に実際に蓄積される値とは異なる.

 WKT に基づく静的メソッドを使うときは,例えば STGeomFromText() メソッドの場合,SQL Server 2008 はその同じ情報を表現するバイナリオブジェクトを生成するために提供されたその WKT 表現をパースする.そのメソッドによって返り,geometry 型ないし geography 型のアイテムとして蓄積されるのはバイナリオブジェクトである.

 例えば,次のクエリを走らせてみると,

DECLARE @Point geography
SET @Point = geography::STGeomFromText('POINT(-122.34 47.65)', 4326)
SELECT @Point

その結果は ‘Point(-122.34 47.65) と言う文字列ではなく,次のようなバイナリ値が代わりに返ってくる.

0xE6100000010C3333333333D34740F6285C2955EC0

 WKT フォーマットにおける空間データの既存のアイテムを表現するために,SQL Server 2008 は3つの方法を提供している.STAsText(), AsTextZM(), ToString() である.Table 4-2 に各3つのメソッドの概要を示してあり,それぞれ次のセクションで探索することにしよう.

Table 4-2. 空間データのインスタンスを WKT 表現で取得する方法
方法 説明
STAsText() 任意の種類のジオメトリインスタンスを WKT フォーマットで表現する OGC 標準のメソッドである.結果の出力としてジオメトリ内部の各ポイントは2つの座標(x/y または緯度・経度)のみで表現される.
AsTextZM() このメソッドはジオメトリの各ポイントは4つまでの座標値(x/y または緯度・経度,(定義されていれば)z および m)と共にジオメトリの WKT 表現を取得する.
ToString() このメソッドは .NET 内のオブジェクトの全ての型に実装され継承される.geometry 型および geography 型のインスタンスを使う時,このメソッドは,AsTextZM() のように,定義されていれば z 座標値および m 座標値を含んだ WKT 表現を返す.

付記 STAsText(), ToString() および AsTextZM() メソッドによって返る WKT 表現にはジオメトリの各点の座標値は含まれるが,それらの得られる空間参照系の SRID は含まれていない.この情報は代わりに STSrid() プロパティを使って取得できる.これについては第11章で詳しく論じる.

STAsText() メソッド

 STAsText() は OGC 準拠のメソッドでありデータのアイテムのWKT 文字列表現を返す.注意しておくが,WKT からデータを生成するのに使う静的メソッドと違って,STAsText() は既存の特定のオブジェクトのインスタンス上で動作する.STAsText() を使ってテーブルのジオメトリ列にあるすべての行の WKT 表現を取得するには,その構文は次のとおりである.

SELECT
GeometryColumn.STAsText()

 STAsText() はただ,インスタンスの点を定義するその x および y (あるいは経度および緯度)座標を返すのみである.このメソッドは z または m 座標値が含まれているかもしれない点に対して使われるにも関わらず,それらは出力されない.次の例を考えてみよう.

DECLARE @Point geometry
SET @Point = geometry::STPointFromText('POINT(30 20 10 5)', 0)
SELECT @Point.STAsText()

 結果は次のようである.

POINT (30 20)
ToString() メソッド

 WKT 表現に z および m 座標値が含まれるオブジェクトを必要とするなら,ToString() 拡張メソッドが使える.その構文は次のとおりである.

DECLARE @Point geometry
SET @Point = geometry::STPointFromText('POINT(30 20 10 5)', 0)
SELECT @Point.ToSDtring()

 これは次の結果をもたらす.

POINT (30 20 10 5)

付記 この ToString() メソッドは .NET 基本オブジェクトクラスにより定義されており,そこから全てのオブジェクトの特異的なクラスが由来する.geometry 型と geography 型を継承・実行するとき,このメソッドはそのオブジェクトの対応する WKT 表現を返す.

AsTextZM() メソッド

 AsTextZM() メソッドは ToString() メソッドの代替であり,オブジェクトの WKT 表現を返し,拡張座標値の z および m を含んでいる.次のように使う.

DECLARE @Point geometry
SET @geometry = geometry::STPointFromText('30 20 10 5', 0)
SELECT @Point.AsTextZM()

 結果は次の通り.

POINT (30 20 10 5)

チップス どんな静的メソッドをつかって生成したデータでも,geometry 型および geography 型の列でも変数でも STAsText(), ToString() および AsTextZM() メソッドを使って WKT 表現を得ることができる.

Well-Known Binary からジオメトリを生成する

 WKB 表現とは,WKT 表現と似ているが,OGC により定義された空間データを表現する標準的手段である.テキストベースの WKT 表現とは対照的に,WKB 表現は geometry 型および geography 型オブジェクトをバイナリフォーマット内の連続したバイトストリームとして表現する.すべての WKB 表現は,表現しているジオメトリの種類を定義するヘッダーセクションから始まり,それはバイトオーダーである(バイトオーダーについては次のサイドバー”ビッグエンディアン対リトルエンディアン”参照のこと).ジオメトリの種類に依存して,そのヘッダーは付加情報を記述する可能性がある.例えば多要素インスタンス内部に含まれるジオメトリの数であったり,Polygon ジオメトリ内に含まれるリングの数であったりなど.ヘッダーの次の情報は,ジオメトリ内の各点の座標を表す 8 バイト値のストリームの WKB 表現のリストである.次のコードはある Point ジオメトリの WKB 表現を示す.

0x0000000001401C00000000000040300E000A000000

 見たように,WKB フォーマットはその姉妹フォーマットである WKT と比較して全く理解しやすくない.しかし,WKB フォーマットにはいくつかの利点がある.

  • WKB からオブジェクトを生成するのはテキストベースの GML や WKT フォーマットから静的メソッドを使用して生成するのと比較して,速い.WKB 内の各 x および y (または経度および緯度)座標値は 8 バイトのバイナリバウンダリーで蓄積されており,それは SQL Server 自身の内部ストレージ表現と同じである.WKB 静的メソッドはゆえに WKB から関連するインスタンスを処理し生成することができ,一方で GML や WKT ではまずテキスト表現全体をパーサーが読まなくてはならない.
  • バイナリフォーマットであるがゆえに,WKB は浮動小数点精度で二項演算から計算した座標値を保持しており,テキストベースフォーマットに由来する丸めエラーがない.

 しかし,WKB にもまた次のような顕著な欠点がある.

  • バイナリ値は人間の読者には簡単に理解できない.ゆえに,WKT や GML 相当の表現ではテストで簡単に見つかったエラーの検出が,WKB 表現では難しくなる.

 WKB が最も似つかわしいのは,異なるコンピュータシステム間で空間データをやり取りするような状況である.というのは,このフォーマットでは速さと精度が良く,人の可読性の欠如は大したことはないからである.

 WKT フォーマットだけではなく,SQL Server 2008 は WKB 表現から各種のジオメトリオブジェクトを生成する特異的メソッドを提供しており,他にも汎用メソッドとして STGeomFromWKB() があり,WKB からいかなる種類のオブジェクトをも生成できる.各メソッドを順番に見ていこう.

ビッグエンディアン対リトルエンディアン

 1 バイトのバイナリデータが蓄積できるのは 256 の異なる値のうちの一つである.16進法での記法では,これらの値は 0x00 (0) から 0xFF (255) の範囲内にある.正確な位置情報を記述するために,WKB フォーマットにおける各座標値は浮動小数点として表現し,8 バイトのデータとして蓄積する.このようにマルチバイトで蓄積するいかなるシステムにおいても,ここの独立したバイナリ値を表現するのに異なる手法が存在する.

  • リトルエンディアンバイナリデータは最下位バイト,あるいは最小バイトを最小有効アドレスに蓄積する.つまり,リトルエンドが最初に来る.リトルエンディアンバイトオーダーはネットワークデータ表現として知られる(NDR).
  • ビッグエンディアンバイナリデータは最上位バイトを最小有効アドレスに蓄積する.つまり,最初にビッグエンドに蓄積する.ビッグエンディアンバイトオーダーは外部データ表現として知られる (XDR).

 WKB 表現は,あらゆるバイナリデータのように,これらのフォーマットのいずれかで蓄積される.例えば,次の2つのバイナリストリームはともに WKB 表現として有効であり,同じジオメトリのインスタンスを正確に表現している.それぞれビッグエンディアン,リトルエンディアンである.

0x00 00000001 401C000000000000 4030000000000000
0x01 01000000 0000000000001C40 0000000000003040

 各バイトは 16 進数の文字列を表現しており,リトルエンディアンの値 0x1234 はビッグエンディアンの値 0x3412 と等しい.0x4321 ではない.どちらのバイナリ順が使われているかを知るために,WKB ストリーム表現内のデータの最初のバイトがシングルバイトオーダーマーカーを表現している(BOM).

  • 最初のバイトが 0 (0x00) なら,残りのバイトがビッグエンディアンバイトオーダーで表現されることを示している.
  • 最初のバイトが 1 (0x01) なら,残ったバイトがリトルエンディアンバイトオーダーで表現されていることを示す.

 バイトオーダーのマーカー自身は1バイトであるため,どのシステムが使われるかには影響しない.

 T-SQL バイナリ関数は一般にビッグエンディアンバイトオーダーを使う.しかし,STAsBinary() メソッドはバイナリデータをリトルエンディアン順で表現する.ゆえに,STGeomFromWKB() メソッドを使ってビッグエンディアン WKB からオブジェクトを生成した時には,そしてそのオブジェクトの WKB 表現を取得するために STAsBinary() メソッドを使った時には,リトルエンディアン WKB バイナリで生成した同じオブジェクトとは異なる結果が得られる.

WKB から Point を生成する

 Point オブジェクトの WKB 表現は 21 バイトのバイナリデータストリームである.その要素には次のようなものが含まれている.

[ByteOrder][Type][X][Y]

 最初の要素である [ByteOrder] は 1 バイトの値で WKB ストリームの残りのバイトがビッグエンディアン (0x00) バイトオーダーなのかリトルエンディアン (0x01) バイトオーダーなのかを示している.[Type] は 4 バイトの符号なし整数で,ジオメトリの種類を示している.Point オブジェクトにはこれは常に 1 が割り振られており,最初のバイトに特異的な関連バイトオーダーを使って表現されている.つまり,ビッグエンディアンなら 0x00000001 でありリトルエンディアンなら 0x01000000 である.[X] および [Y] はともに 8 バイトの浮動小数点値であり,点の x 座標および y 座標,または点が地理座標系由来なら経度および緯度を示している.

付記 WKT フォーマットにもあったように,点の WKB 表現は地理座標系においては経度を先に記述し次に緯度を記述する.しかし WKT と違い,追加的な z および m 座標値を WKB において各点に定義することはできない.

WKB Point 表現を生成する

 SQL Server が WKB から Point オブジェクトを生成するために提供する静的メソッドを示すため,我々はサンプルとして WKB Point ジオメトリを生成する必要がある.これをするために,まず変数を宣言し,その WKB ストリームを含む各要素の値を表現する.

DECLARE @ByteOrder bit
DECLARE @Type int
DECLARE @longitude float
DECLARE @latitude float

 我々の WKB 表現を形作るために,我々はT-SQL の CAST 関数を使って各要素をバイナリフォーマットに変換する必要がある.この関数の結果は,すべてのネイティブ SQL Server 関数のように,ビッグエンディアンバイトオーダーを使う.我々の WKB 表現は CAST 関数の結果ビッグエンディアンに基づいていなければならないため,我々はBOMの値を 0 と設定してビッグエンディアンオーター順になるようにしなければならない.

SET @ByteOrder = 0

 WKB バイナリフォーマットにおける次の要素は表現されるジオメトリの種類を定義することである.この例では,我々は Point ジオメトリを記述しており,それは WKB ではジオメトリタイプ 1 と記述する.

SET @Type = 1

 我々は次のコード値に基づいて点を生成しよう.それはEPSG 4326 の空間参照系を用いたポーランドのワルシャワの近似値を表現している.

SET @longitude = 21.01
SET @latitude = 52.23

 それぞれの要素を定義したところで,我々は CAST 関数を使ってそれらを関連する長さのバイナリ値に変換し,それらを単一のバイナリストリームに結合しよう.それらを @WKB と言う名の変数 varbinary(max) に格納しよう.次のコードで示す.

DECLARE @WKB varbinary(max)
SET @WKB = 
CAST(@ByteOrder AS binary(1))
+ CAST(@Type AS binary(4))
+ CAST(@longitude AS binary(8))
+ CAST(@latitude AS binary(8))

 変数 @WKB は今や我々の点を示す有効な WKB 表現を保持している.それがどのように見えるか調べるため,次のクエリを実行する.

SELECT @WKB

 結果は次のようである.

0x00000000014035028F5C28F5C3404A1D70A3D70A3D

 注意しなければいけないのは,我々はまだジオメトリオブジェクトを生成したわけではない.先述したのは WKB 表現に過ぎない.それは入力として受け付けられる WKB の静的メソッドの一つに伴ってジオメトリオブジェクトを生成するために使われただけである.

付記 実際には,今見せたような T-SQL を用いて WKB 表現を組み立てることはまれである.外部資源からの WKB フォーマット内に存在する情報のほうがもっと重要であろう.今見せた手順はWKB フォーマットの構造を示すために最初に使った.

STPointFromWKB() メソッドを使う

 今や我々は Point の WKB 表現を有しており,STPointFromWKB() メソッドを使って geometry 型なり geography 型なりのインスタンスを生成することができる.SRID 0 を使い,geometry 型の Point を生成するため,先のセクションで生成した変数に基づいて,次の構文を使ってみよう.

DECLARE @Warsaw geography
SET @Warsaw = geography::STPointFromText(@WKB, 4326)

 そうだ!@Warsaw 変数は今や提供したパラメータに基づいた geometry 型の Point インスタンスを保持している.これがコード全体である.

/*Declare variables to hold each element of the WKB */
DECLARE @ByteOrder bit
DECLARE @Type int
DECLARE @longitude float
DECLARE @latitude float

/* Set the byte order marker to indicate big-endian byte order */
SET @ByteOrder = 0

/* Geometry Type 1 denotes for a point */
SET @Type = 1

/* Set the values of each coordinate for the point */
SET @longitude = 21.01
SET @latitude = 52.23

/* Declare a new binary variable to hold the WKB */
DECLARE @WKB varbinary(max)

/* Append each of the elements together and store them in @WKB */
SET @WKB =
CAST(@ByteOrder AS binary(1))
+ CAST(@Type AS binary(1))
+ CAST(@longitude AS binary(8))
+ CAST(@latitude AS binary(8))

/* Declare a new variable to hold the resulting geometry instance */
DECLARE @Warsaw geography

/* Parse the WKB representation created to the STPointFromWKB() method */
SET @WKB = geography::STPointFromWKB(@WKB, 4326)

 点が正確に生成されたか調べるため,STAsText() メソッドを使って新しい Point ジオメトリの WKT 表現を取得してみる.

SELECT @Warsaw.STAsText()

 結果は次のとおりである.

POINT (21.01 52.23)

付記 WKT とは違い,座標値の点 z, m を拡張して WKB 表現を使うことはできない.各 WKB の点は正確に座標値を定義しており,それは x および y 座標または経度および緯度である.

WKB から LineString を生成する

 n 個の点を含む LineString オブジェクトの WKB 表現は次のバイトストリームのようである.

[ByteOrder][Type][NumPoints][X1][Y1][X2][Y2]...[Xn][Yn]

 Point の WKB 表現で見たように,最初のバイト [ByteOrder] はデータがリトルエンディアンかビッグエンディアンかを宣言する.次の 4 バイト [Type] は生成するジオメトリの種類を示し,LineString は常に 2 で表現する.

 ジオメトリの種類の宣言に続く付加的な 4 バイト [NumPoints] はLineString 内の点の数を記述する.WKB 構造には WKT で使ったようなコンマのようなデリミタやカッコが存在しないため,その表現が必要になる.SQL Server が何個の座標がストリームに存在するのか知るため,またいつ表現の最後に到達したのか知るためである.LineString の点の個数の直後には 8 バイトの浮動小数点の値のペアが続き,それはそれら各点の座標値を示している.

 これらの情報に基づいて,我々は次のコードで LineString の WKB 表現を組み立てよう.

/* Declare the parameters needed to build a WKB representation of a LineString */
DECLARE @ByteOrder bit
DECLARE @Type int
DECLARE @NumPoints int
DECLARE @x1 float
DECLARE @y1 float
DECLARE @x2 float
DECLARE @y2 float

/* We are using CAST to convert the parameters to big-endian byte order */
SET @ByteOrder = 0

/* LineStrings are denoted as geometry type 2 */
SET @Type = 2

/* This LineString will contain two points */
SET @NumPoints = 2

/* St the x and y coordinate values of each point */
SET @x1 = 16
SET @y1 = 7
SET @x2 = 23
SET @y2 = 10

/* Declare a new binary parameter to hold the full WKB */
DECLARE @WKB varbinary(max)

/* Append the components together to build the Well-Known Binary representation */
SET @WKB =
CAST(@ByteOrder AS binary(1))
+ CAST(@Type AS binary(4))
+ CAST(@NumPoints AS binary(4))
+ CAST(@x1 AS binary(8))
+ CAST(@y1 AS binary(8))
+ CAST(@x2 AS binary(8))
+ CAST(@y2 AS binary(8))

 @WKB は今次の値を保持している(省略).

 我々はこの表現から STLineFromWKB() メソッドを使って geometry 型ないし geography 型の LineString ジオメトリを生成することができる.この例では,我々は SRID 0 を使って meimetry 型に帰属するこのメソッドを使おう.

DECLARE @LineString geometry
SET @LineString = geometry::STLineFormWKB(@WKB, 0)

 その線が正確に生成されたか調べるため,再び WKT 表現を我々の新しい LineString に STAsText() メソッドを使ってみよう.

SELECT @LineString.STAsText()

 結果は次のとおりである.

LINESTRING (16 7, 23 10)

WKB から Polygon を生成する

 2つのリングを有する Polygon ジオメトリの WKB 表現は次のとおりである.

[ByteOrder][Type][NumRings][NumPoints][X1][Y1]...[Xn][Yn][NumPoints][X1][Y1]...[Xn][Yn]

 この表現内に含まれる要素は次のリストのとおりである.

  • 他の WKB 表現で見たように,ストリームは 1 バイトの指標で始まり,残りのバイトのバイトオーダーを示す[ByteOrder].
  • [Type] は 4 バイトの符号なしの整数でありジオメトリの種類を示す.WKB においてすべての Polygon のための [Type] の値は 3 である.
  • 続く 4 バイトの整数値は [NumRings] であり,Polygon 内のリングの総数を示す.この値は外周リング,およびジオメトリで定義されるすべての内部リングを数える.
  • 各リングの定義に続き,外周リングで始まる.各リングは閉じた LineString であるため,各 Polygon は WKB においては個々の LineString と同じフォーマットに従う.つまり最初の 4 バイトは [NumPoints] でリングの点の個数を記述し,続いて各点の x および y 座標または経度および緯度が続く.
  • Polygon に含まれるすべての内部リングは外部リングに続いて順番にリストされる.

 この構文を示すため,次のコードを考えてみる.一つの外部リング内に一つの内部リングを含む Polygon の WKB 表現を組み立てる.

/* Declare all the elements required */
DECLARE @ByteOrder bit
DECLARE @Type int
DECLARE @NumRings int
DECLARE @Ext_NumPoints int
DECLARE @Ext_x1 float, @Ext_y1 float
DECLARE @Ext_x2 float, @Ext_y2 float
DECLARE @Ext_x3 float, @Ext_y3 float
DECLARE @Ext_x4 float, @Ext_y4 float
DECLARE @Int_NumPoints int
DECLARE @Int_x1 float, @Int_y1 float
DECLARE @Int_x2 float, @Int_y2 float
DECLARE @Int_x3 float, @Int_y3 float

/* Set the values */
SET @ByteOrder = 0
SET @Type = 3
SET @NumRings = 2
-- Exterior Ring
SET @Ext_NumPoints = 5
SET @Ext_x1 = -4
SET @Ext_y1 = -5
SET @Ext_x2 = -4
SET @Ext_y2 = 10
SET @Ext_x3 = 12
SET @Ext_y3 = 10
SET @Ext_x4 = 12
SET @Ext_y4 = -5
-- Interior Ring
SET @Int_NumPoints = 4
SET @Int_x1 = 3
SET @Int_y1 = 1
SET @Int_x2 = 3
SET @Int_y2 = 5
SET @Int_x3 = 7
SET @Int_y3 = 3

/* Build the WKB representation */
DECLARE @WKB varbinary(max)
SET @WKB =
CAST()
+ CAST()
+ CAST()
-- Exteroir Ring
+ CAST(@Ext_x1 AS binary(8)) + CAST(@Ext_y1 AS binary(8)) 
+ CAST(@Ext_x2 AS binary(8)) + CAST(@Ext_y3 AS binary(8)) 
+ CAST(@Ext_x3 AS binary(8)) + CAST(@Ext_y3 AS binary(8)) 
+ CAST(@Ext_x4 AS binary(8)) + CAST(@Ext_y4 AS binary(8)) 
+ CAST(@Ext_x1 AS binary(8)) + CAST(@Ext_y1 AS binary(8)) 
-- Interior Ring
+ CAST(@Int_x1 AS binary(8)) + CAST(@Int_y1 AS binary(8))  
+ CAST(@Int_x2 AS binary(8)) + CAST(@Int_y2 AS binary(8)) 
+ CAST(@Int_x3 AS binary(8)) + CAST(@Int_y3 AS binary(8)) 
+ CAST(@Int_x1 AS binary(8)) + CAST(@Int_y1 AS binary(8)) 

 我々は今や,我々の WKB 表現に関連する STPolyFromWKB() メソッドを使うことができる.次のようである.

DECLARE @polygon geometry
SET @Polygon = beometry::STPolyFromWKB(@WKB, 0)
SELECT @Polygon.STAsText()

 結果は次のとおりである.

POLYGON ((-4 -5, -4 10, 12 10, 12 -5, -4 -5), (3 1, 3 5, 7 3, 3 1))

WKB から Multielement Geometry を生成する

 多要素のジオメトリの種類の WKB 表現は,MultiPoint, MultiLineString, MultiPolygon および Geometry Collection であるが,すべて同じ構造のフォームであり次のとおりである.

[ByteOrder][Type][NumGeometries]<Geometry1><Geometry2>…<GeometryN>

 各々のケースにおいて,バイナリストリームの要素は次のとおりである.

  • [ByteOrder] は1バイトの指標であり,多要素インスタンスを記述する値の残りがリトルエンディアンかビッグエンディアンかのバイトオーダーであることを示す.注意すべき点として,これは多要素インスタンス自身に関連する特異的な値にのみ適用される.つまり [Type] と [NumGeometries] である.多要素インスタンスに含まれるそれぞれの独立したジオメトリは,どのバイトの特異的要素に蓄積されるかで順番を特定されなくてはならない.
  • [Type] は4バイトの符号なし整数であり,多要素ジオメトリの種類を記述する指標である.4 は MultiPoint を示す.5 は MultiLineString を示す.6 は MultiPolygon を示す.7 は Geomtry Collection を示す.
  • [NumGeometries] は 4 バイトの符号なし整数であり,各多要素インスタンスに含まれる個々のジオメトリの個数を表現する.
  • <Geometry1>…<GeometryN>は多要素インスタンスに含まれる個々のジオメトリのフルフォームの WKB 表現であり,単一のジオメトリを定義したとしても同じルールが適用される.これはすべての個々の要素が,その種類のジオメトリの WKB 定義で要求されるすべての要素を明確に宣言しなくてはならないことを示しており,それには個々の座標値だけではなく,ジオメトリの種類とバイトオーダーが含まれる.

注意 仮に一種類の多要素を定義したなら,<Geometry1>…<GeometryN>の値はすべて対応する単数型の個別のジオメトリのインスタンスを表現しなくてはならない.例えば,MultiLineString要素に含まれる要素は全て有効な LineString ジオメトリの表現でなくてはならない.

 次の WKB 表現の例はGeometry Collection を示しており,一つの Point と一つの LineString を示す(省略).

 Table 4-3 にこの表現を分解した各要素を掲載する.

Table 4-3. WKB 多要素ジオメトリ表現例の内部に含まれる要素
説明
0x 16進表記を使って表現されるバイナリ値を示す
00 続く値がビッグエンディアンのバイト順で表現される
00000007 このジオメトリは16 進数の geometry collection であり,7 型と記述される.
00000002 これらはこのコレクション内に含まれる2つのジオメトリである.
00 最初の要素のバイトがビッグエンディアンのバイト順で表現される.
00000001 最初の要素は Point ジオメトリを表現する.
404433333333 この Point オブジェクトの x 座標値.
C002888A47ECEFE9B この Point オブジェクトの y 座標値.
01 2番目の要素はリトルエンディアンのバイト順で表現される.
02000000 2番めの要素は LineString を表現する.
02000000 この LineString は2つの point を含む.
9BFEEC478A8802C0 LineString 内の最初の point の x 座標値.
333333333333440 LineString 内の最初の point の y 座標値.
6666666666F65340 LineString 内の2番目の point の x 座標値.
B81E85EB51B81B40 LineString 内の2番目の point の y 座標値.

 多要素 WKB 表現からの多要素ジオメトリをインスタンス化するため,次のように適切な型特異的メソッドを使うことができる.

  • WKB から MultiPoint ジオメトリを生成するために STMPointFromWKB() を使う
  • WKB から MultiLineString ジオメトリを生成するために STMLineFromWKB() を使う
  • WKB から MultiPolygon ジオメトリを生成するために STMPolyFromWKB() を使う
  • WKB から Geometry Collection を生成するために STGeomCollFromWKB() を使う

 先の例で見たように,WKB は Geometry Collection を,STGeomCollFromWKB() メソッドを使って次のように表現する.

SELECT geometry::STGeomCollFromWKB(
..., 0)

WKB から任意の種類のジオメトリを生成する

 WKT 同様に,SQL Server 2008 はgeometry 型および geography 型のための汎用的なメソッドを提供しており,それらのメソッドはいかなる種類のジオメトリオブジェクトをも整った WKB から生成することができる.この汎用的なメソッドは STGeomFromWKB() であり,このセクションで言及したすべての型特異的なメソッドの代わりに使うことができる.

既存のジオメトリを WKB として表現する

 SQL Server 2008 は空間データをバイナリデータストリームとして蓄積するにも関わらず,それは WKB バイナリデータフォーマットと同じではない.結果として,WKB 表現からの geometry 型または geography 型データのアイテムの値を直接セットすることはできない.代わりに適切な静的メソッドの一つにそれらの表現を通過させなくてはならない.同様に,空間データを蓄積するために SQL Server が使う内部のバイナリデータを直接選択したい時には,それらの地物の WKB 表現と同じという訳にはいかない.この理由の一つとして,SQL Server は内部のバイナリフォーマットに空間参照系に関連する詳細な付加情報を有しており,元の WKB 表現にはそれが存在しないことが挙げられる.

 geometry 型または geography 型のオブジェクトの WKB 表現を取得するため,STAsBinary() メソッドを代わりに使う必要がある.

SELECT geometry::STPointFromText('Point(10.572 2.245)', 0).STAsBinary()

 これはジオメトリの WKB 表現を返し,リトルエンディアンバイナリフォーマットを表現する(省略).

 この例の1ステージを更に取得するため,次のコードは WKT 表現から STGeomFromText() を使って Point ジオメトリを生成し,STGeomFromWKB() メソッドに関連する STAsBinary() メソッドの結果2番目の Point を生成する前に,STAsBinary() を使ってWKB 表現を返すことを示す.

DECLARE
@WKT varchar(255) = 'POINT(52 8)'
@WKB varbinary(max),
@SRID int = 0,
@Geometry1 geometry,
@Geometry2 geometry

SET @Geometry1 = geometry::STGeomFromText(@WKT, @SRID)
SET @WKB = @Geometry1.STAsBinary()
SET @Geometry2 = geometry::STGeomFromWKB(@WKB, @SRID)

SELECT
@Geometry1.STAsText(),
@Geometry2.STAsText()

 結果は両メソッドで生成されたジオメトリが同じであることを示す.

POINT (52 8)  POINT (52 8)

チップス リトルエンディアンであれビッグエンディアンであれ WKB 表現からジオメトリが生成されるにもかかわらず,STAsBinary() メソッドで返るジオメトリの表現は常にリトルエンディアンバイトオーダーである.

Geography Markup Language からジオメトリを生成する

 Geography Markup Language は XML ベースの空間情報を代表する言語である.GML 表現を使って表現されたとき,ジオメトリの各プロパティはドキュメント構造内の特異的要素タグ内に含まれる.これにより GML は明確かつ高度に構造化されたフォーマットとなる.次のコードは一つの点の GML 表現の例を示す.

<Point xmlns=”http://www.opengis.net/gml”>
<pos>10 30</pos>
</Point>

 GML フォーマットには次のような利点がある.

  • GML はテキストベースであり,それを使って表現された情報を人間が検査し理解することが比較的容易である.
  • すべての XML ベースのフォーマットのように,GML は明確で高度に構造化された階層ドキュメントフォーマットを有している.これにより,関連する GML ドキュメントを調べることで複雑な空間オブジェクトの構造を理解するのが容易になる.
  • GML はとても冗長であり,特異的要素内部に明確にすべての値を記述している.

 しかし,GML にもまた次のような欠点がある.

  • 非常に冗長である!GML と WKT はどちらもテキストベースフォーマットであるにも関わらず,オブジェクトの GML 表現は同等の WKT 表現よりも大いに多くのスペースを占める.これは関連する要素タグ内部にすべての値を蓄積するからである.
  • GML は WKT 同様テキストベースであるため,バイナリの浮動小数点座標値を表現するとき,丸めにより精度に問題がある.

 XML ベースの環境においては GML は空間情報を表現するのに普通に使われる.これはインターネットでつながった空間データを含み,これについては第8章で論じる.

チップス SQL Server に実装された GML メソッド群はスケールダウンされた GML 3.1.1 スキーマに基づいている.SQL Server に使われているスキーマを http://schemas.microsoft.com/sqlserver/profiles/gml/ で見ることができるだろう.またはフルの GML 標準を OGC ウェブサイトで見つけることができるだろう.http://www.opengeospatial.org/standards.gml にある.

GML ドキュメントの構造

 いかなる GML 表現もその親要素は,表現しているジオメトリの種類を定義する.すべての GML 表現は次のタグのペア内部に含まれていなければならない.

  • <Point>…</Point>
  • <LineString>…</LineString>
  • <Polygon>…</Polygon>
  • <MultiPoint>…</MultiPoint>
  • <MultiCurve>…</MultiCurve>
  • <MultiSurface>…</MultiSurface>
  • <MultiGeometry>…</MultiGeometry>

 これらの要素タグ名は GML を使う異なるジオメトリを宣言するのに使われ,WKT においてジオメトリを定義するのに使うキーワードに名前が似ている.しかし,いくつか異なる点も存在する.

  • MultiLineString および MultiPolygon ジオメトリは WKT においては直接宣言されるのに対して,GML においてはそれぞれ MultiCurve および MultiSurface 要素の子要素として定義される.
  • WKT において Geometry Collection として知られる複数で異種のジオメトリを含む要素は,GML においては MultiGeometry 要素と呼ばれる.

 ジオメトリの構成要素のすべてのプロパティはトップレベルの親要素内部に含まれる子要素内で指定され,それを表現するジオメトリのプロパティを記述した特異的なタグ内部に囲まれている.各ジオメトリの GML 表現内に含まれる特定の要素はこのセクションの後で更に詳細に述べよう.

GML 名前空間の宣言

 XML 要素を定義するいかなるタグでも xml 属性を含み,それは要素名の名前空間に関連している.いかなる XML ドキュメントにおいても使われる要素の名前は与えられた名前空間内部では一意であり,だから <Point xmls=”http://opengis.net/gml”> は <Point xmls=”http://www.someothernamespace.com”> とは異なり,ただの <Point> は名前空間とはなんの関係もない.これにより異なる XML ドキュメントが異なる場面で適切な名前空間で資格を得ることで,同じ要素名を使うことが許されている.

 GML 表現に含まれるすべての要素は GML 名前空間に属していなければならない.これにより全てのGML 表現は,適切な GML 要素を,他の XML 名前空間由来の同名の要素から一意に識別することが確保される.

 GML 表現のすべての要素が正確な名前空間に関連することを確保するために,トップレベルの親要素に GML 名前空間の宣言を置くべきである.この名前空間はそれらのジオメトリ表現内部にネストされた各子要素に継承される.SQL Server 内部で使うためにジオメトリの GML 表現を定義する時には,ゆえに常に xmls 属性を,GML 名前空間である http://opengis.net/gml を参照する Uniform Resource Identifier (URI) をセットする値とともに,適切な親要素の開始タグ内部に含めるべきである.

 LineString を例に使うと,ゆえに GML 表現は次のタグで始まり,終わるべきである.

<LineString xmlns=”http://www.opengis.net/gml”>…</LineString>

 名前空間の宣言を削除すると,整った XML であっても有効な GML ジオメトリを定義できなくなる.このような表現を GeomFromGml() メソッドに関連して使おうとしているなら,次の例のようなエラー受け取るだろう.

DECLARE @Point geography
SET @Point = geography::GeomFromGML('
<Point>
<pos>10 30</pos>
</Point>',
4326)
System.FormatException: 24129: The given XML instance is not valid because its top-level tag was Point. The top-level element of the input Geographic Markup Language (GML) must be one of Point, LineString, Polygon MultiPoint, MultiGeometry, MultiCurve, or MultiSurface.

 このエラーメッセージのテキストはむしろ困惑させるようにみえる.トップレベルのタグが Point であるゆえに我々の GML 表現が無効であると記述している.代わりに,Point で始まる有効な要素の可能性のあるリストを手厚く提供している…

 このエラーの原因は,GeomFromCml() メソッドを通した XML インスタンスのトップレベルのタグは,その GML 名前空間由来で,リストされた要素名の一つでなければならないからである.名前空間を親要素タグ内で宣言することは,表現を有効にする.次の例のように.

DECLARE @Point geography
SET @Point = geography::GeomFromGML('
<Point xmls="http://www.opengis.net/gml">
<pos>10 30</pos>
</Point>',
4326)
Command(s) completed successfully.

GML からジオメトリオブジェクトをインスタンス化するメソッド

 WKT や WKB フォーマットとは異なり,SQL Server 2008 はGML 由来の特異的ジオメトリを生成するために異なるメソッドを提供してはいない.あらゆるジオメトリオブジェクトは,それが Point であれ LineString であれ Polygon であれ多要素のジオメトリであれ,単一の汎用メソッド GeomFromGml() を通して生成する.このメソッドで生成されたオブジェクトの種類は提供された GML 表現の構造と内容により定義される.

 GeomFromGml() メソッドは両方の空間データ型に実装されており,それを使って geography 型でも geometry 型でも適切な構文であれば地物を生成できる.次のように.

geometry::GeomFromGML('GML representation', srid)

あるいは

geography::GeomFromGML('GML representaion', srid)

 GML 標準自身は OGC により策定されたにも関わらず,GML からジオメトリオブジェクトをインスタンス化するためのサポートは SQL 仕様のための OGC Simple Features の一部ではない.結果として,GML からジオメトリオブジェクトを生成するこの GeomFromGml() 静的メソッドは拡張 SQL Server メソッドであり,接頭辞の文字列 “ST” がつかない.

 あらゆる種類のジオメトリが今見たように 同じ構文の GeomFromGml() メソッドを使って生成されるため,次の例で見るように個々のケースでこのメソッドを繰り返したくない.代わりに,各種のジオメトリの GML 表現との関連をお見せするに留める.

付記 名前にミスリードされないように.GML は Geography Markup Language の略であるが,GeomFromGml() は geography 型でも geometry 型でもいずれのデータ型でも GML 表現からオブジェクトを生成できる.

GML から Point を生成する

 Point の GML 表現は次の例の通り.

<Point xmlns=”http://www.opengis.net/gml”>
<pos>40.4 -2.31667</pos>
</Point>

 この例は Point ジオメトリを定義しており,座標 (40.4, -2.31667) に位置する.この GML 表現の特徴は次のとおりである.

  • 表現全体は <Point> 開始タグと </Point> 終了タグの間に含まれ,GML 名前空間を用いて宣言される.
  • この親要素内部に,点の位置を定義する座標は <pos> および </pos> タグ内部に含まれる.
  • 座標値自体はスペースで区切られ,直交座標においては x-y の順に,地理座標系では緯度-経度の順に列記する.
  • WKT におけるのと違って,GML における点の <pos> 要素は正確に2つの座標,つまり x および y または緯度と経度を含まなければならない.GML は z や m 座標をサポートしない.

注意 GML は地理座標を緯度-経度の順に表現する.WKT や WKB フォーマットとは逆順である.

 GML 表現を使って Point ジオメトリを生成するために,我々は geometry 型や geography 型の GeomFromGml() 静的メソッドを使う.次のようである.

DECLARE @gml xml;
SET @gml = '
<Point xmlns="http://www.opengis.net/gml">
<pos>40.4 -2.31667</pos>
</Point>
';
DECLARE @Point geometry;
SET @Point = geometry::GeomFromGML(@gml, 4326)

 変数 @Point は今や geomtry 型の Point オブジェクトを保持しており,我々が GeomFromGml() メソッドで提供したパラメータに基づいている.x 座標は 40.4 で y 座標は -2.31667 であり,SRID 4326 に基づく.この例で思い出していただきたいのは,geometry 型は平面の地面データを蓄積しているにも関わらず,正距円筒図法での y および x を直接地図にマップした緯度と経度の値を用いれば,地理座標系に基づく位置を定義することもできるということである.

 このオブジェクトが正確に生成されたかテストするため,この Point の WKT 表現を選択し,STAsText() メソッドを使ってみよう.

SELECT @Point.STAsText()

 結果は次のようになる.

POINT (40.4 -2.31667)

 緯度と経度の地理座標を使う空間参照系 EPSGL4326 に基づく点を定義したため,おそらく geometry 型を使うよりも geography 型を使うほうがより適切だろう.このため,我々は代わりに geography 型の GeomFromGml() メソッドを使うことができる.次の通り.

DECLARE @gml xml;
SET @gml = '
<Point xmlns="http://www.opengis.net/gml">
  <pos>40.4 -2.31667</pos>
</Point>
';
DECALRE @Point geography;
SET @Point = geography::GeomFromGML(@gml, 4326)
SELECT @Point.STAsText()

 結果は次のとおりである.

POINT (-2.31667 40.4)

 座標の順番が逆転しているのに気がついただろうか.最初の例では,直交座標を x-y 順の geometry 型の GeomFromGml() メソッドに通した.すると STAsText() を使って表現した結果と同じ順であった.しかし,二番目の例では geography 型に必要な地理座標を記述したのに,GeomFromGml() は緯度-経度の順でその座標を受け取り,STAsText() は結果を経度-緯度として通訳した.

 最初の例での「非投影」geometry 型の Point と等しい Point を生成するため,つまり経度が x にマップされ緯度が y にマップされるように,我々は座標を取り替えて GeomFromGml() に通す必要がある.次のように.

<Point xmlns=”http://www.opengis.net/gml”>
<pos>-2.31667 40.4</pos>
</Point>

 geography 型の GeomFromGml() メソッドを提供された時には,WKT で表現すると,結果は次のようになる.

POINT (40.4 -2.31667)

GML から LineString を生成する

 GML において単一の Point を定義するとき,先述した例で述べたように,<pos> 要素内に含まれる座標値を特定する.単独の LineString を生成するときや,定義内に一点以より多くを要する他のジオメトリを生成するときには,代わりに <poslist> 要素を使う.GML においてはすべての点は正確に2つの座標を持つため,各点の間に付加的なデリミタは不要である.<poslist> 内部では,LineString 内の各点の座標値はスペースで区切られ,各座標ペア間のコンマは必要としない.

 次のコード例は点 (-6, 4) と点 (3, -5) を結ぶ LineString インスタンスの GML 表現を示している.

<LineString xmlns=”http://www.opengis.net/xml”>
<posList>-6 4 3 -5</posList>
</LineString>

 この GML から生成された LineString のWKT 表現は次の通りである.

LINESTRING (-6 4, 3 -5)

注意 WKT フォーマットと異なり,GML 表現では点を区切るコンマは存在しない.

GML から Polygon を生成する

 LineString の定義で見たように,Polygon のリングを定義する各点の座標値はスペースで区切られたリストで表現され,<poslist> 要素内部に含まれる.閉じた LineString の表現を含む点のリストと区別するため,一つの Polygon リングを定義する各 <poslist> 要素は <LinearRIng>…</LinearRing> タグでネストされる.

 すべての GML Polygon 表現は一つの <LinearRIng> 要素を Polygon 定義の <exterior> 要素内部に含まなければならず,それはそのポリゴンの外周縁を形作る点を定義する.GML は,Polygon 親要素の <interior> 要素内に付加的な一つないしそれ以上の <LinearRing> 要素を識別するかもしれない.それはポリゴンの内部リングを定義する.

 次のコード例は3つのリングを含む Polygon の GML 表現を示す.一つは外部リング,2つはPolygon の形を切り抜く内部リングである.

<Polygon xmlns=”http://www.opengis.net/gml”>
<exterior>
<LinearRing>
<posList>0 0 100 0 100 100 0 100 0 0</posList>
</LinearRing>
</exterior>
<interior>
<LinearRing>
<posList>10 10 20 10 20 20 10 20 10 10</posList>
</LinearRing>
</interior>
<interior>
<LinearRing>
<posList>75 10 80 10 80 20 75 20 75 10</posList>
</LinearRing>
</interior>
</Polygon>

GML から MultiPoint を生成する

 GML において MultiPoint を定義する親要素は <MultiPoint> タグを使って定義される.MultiPoint ジオメトリ内に含まれる個々の Point ジオメトリは順番に定義され,個別の Point として正確に同じ構文を使い,<pointMembers> と呼ばれる子要素の内部にネストされる.

 次の例は2つの Point ジオメトリを含む MultiPoint インスタンスの GML 表現を示す.

<MultiPoint xmlns=”http://www.opengis.net/gml”>
<pointMembers>
<Point>
<pos>2 3</pos>
</Point>
<Point>
<pos>4 10</pos>
</Point>
</PointMembers>
</MultiPoint>

GML から MultiLIneString を生成する

 GML において一つ以上の LineString ジオメトリを含むインスタンスを記述するとき,親要素は実際には MultiLineString よりも LultiCurve である.第3章で我々が geometry 型と geography 型で階層木の継承を調べたことを想起するかもしれない.MultiLineString オブジェクトは別種のオブジェクト,MultiCurve と呼ばれるものに由来することを階層木は示した.MultiCurve は任意のジオメトリのための汎用的なオブジェクト型であり,異なる一連の点群間の経路の多くを生成するもので,一方で MultiLineString は MultiCurve の特殊な例であり,そこではそれらの経路は点の間で線形補間により計算される.MultiCurve オブジェクトを直接生成することはできないが,GML 表現は次の事実を描写する.つまりMultiLineString は MultiCurve の下位互換である.MultiCurve 内部に含まれるすべての LineString 要素はそれらが個々のジオメトリであった場合と同じフォーマットで表現され,<curveMembers> と呼ばれる MultiCurve の子要素内で順番に列挙される.

 次のコード例は2つの LineString を含む MultiLineString の GML 表現を示す.

<MultiCurve xmlns=”http://www.opengis.net/gml”>
<curveMembers>
<LineString>
<poslist>2 3 4 10</poslist>
</LineString>
<LineString>
<poslist>4 10 15 40</poslist>
</LineString>
</curveMembers>
</MultiCurve>

GML から MultiPolygon を生成する

 複数の Polygon 要素を含む GML 要素は MultiSurface と呼ばれる.MultiSurface 内部では,各ジオメトリのメンバーの定義は <surfaceMembers> と呼ばれる要素に含まれる.

 次の例では2つの Polygon ジオメトリを有し,それぞれが一つのファイブリングを有する MultiPolygon インスタンスの GML 表現を列挙している.

<MultiSurface xmlns=”http://www.opengis.net/gml”>
<surfaceMembers>
<Polygon>
<exterior>
<LinearRing>
<posList>2 3 5 3 6 8 2 7 2 3</posList>
</LinearRing>
</exterior>
</Polygon>
<Polygon>
<exterior>
<LinearRing>
<psoList>10 20 20 20 20 30 10 30 10 20</posList>
</LinearRing>
</exterior>
</Polygon>
</surfaceMembers>
</MultiSurface>

GML から Gemetry Collection を生成する

 GML で表現される Geometry Collection の親要素は MultiGeometry と呼ばれる.その構成要素はそれゆえ開始タグ <MultiGeomtery> と終了タグ </MultiGeometry> の内部に含まれる.他で見たように,特異的,多要素インスタンス,MultiAGeometry 内に含まれる個々の独立したジオメトリは,<geometryMembers> と呼ばれるこのインスタンス内の付加的な要素内部にネストされる.

 次の例は一つの Point ジオメトリと一つの LineString ジオメトリを含む Geometry Collection の GML 表現を示す.

<MultiGeomtery xmlns=”http://www.opengis.net/gml”>
<geometryMembers>
<Point>
<pos>15 10</pos>
</Point>
<LineString>
<posList>4 10 2 3</posList>
</LineString>
</geometryMembers>
</MultiGeometry>

 他の GML ジオメトリ表現で見たように, geometry 型でも geography 型でもそれらを GeomFromGml() メソッドに通すことで,この表現に基づいてジオメトリのインスタンスをインスタンス化することができる.

既存のジオメトリを GML として表現する

 WKT や WKB フォーマットでみたように,SQL Server もまた既存の geometry 型や geography 型の GML でのオブジェクトを表現するのに使うメソッド,AsGml() を提供している.このメソッドの使用を説明するため,次のコードは WKT から LineString ジオメトリを生成する方法を説明し,ついでそのジオメトリの GML 表現を AsGml() を使って取得する方法を示している.

DECLARE @LineString geometry
SET @LineString = geometry::STLineFromText('LINESTRING(0 0, 12 10, 15 4)', 0)
SELECT @LineString.AsGml()

 結果は次の通り.

<LineString xmlns=”http://www.opengis.net/gml”>
<posList>0 0 12 10 15 4</posList>
</LineString>
POINT() を使ってPOINTS を生成する

 geometry 型でも geography 型でもPoint オブジェクトを生成したいだけなら,それらの点を表現する特異的な言語を使用するまでもない.それらは3つの数値パラメータを使って十分に記述できる.x (または経度),y (または緯度),そして SRID である.この例では,そのオブジェクトを表現するために本章で説明してきた専用言語メソッドを使う必要はない.代わりに Point() メソッドを使う.

 Point() メソッドは3つの引数を取る.緯度(または x),経度(または y)および SRID であるが,geometry 型でも geography 型でも Point オブジェクトを生成する.このメソッドを説明するため,次のコードを考えてみる.

SELECT
geography::Point(41, -87, 4269)

 この例では geography 型の緯度 41 度経度 -87 度の Point を SRID 4269 を使って生成する.

要約

 本章では geography 型と geometry 型のデータをインスタンス化して使うための静的メソッドそれぞれを紹介した.多くのメソッドが使用でき,3つの異なる標準フォーマットに基づいており,空間情報を表現できる.Well-Known Text (WKT), Well_Known Binary (WKB) および Geography Markup Language (GML) である.

  • それぞれの静的メソッドはぴったり2つのパラメーターを必要とする.空間参照系に使用される SRID と,WKT, WKB あるいは GML フォーマットを使用して表現するジオメトリ表現である.
  • WKT, WKB および GML 表現にはそれぞれ長所と欠点がある.一般的に言えば,WKT は理解するには最もシンプルで,WKB が最も速く,そして GML が最も構造化されている.
  • 空間データのアイテムを WKT または WKB から生成する時には,各ジオメトリの種類(Point, LineString, Polygon および multielement 型)に応じた特異的なメソッドが存在する.汎用のメソッドとして STGeomFromText() および STGeomFromWKB() などである.対照的に, GML から生成されたデータのアイテムはすべて同じ GeomFromGML() メソッドを使う.
  • Point ジオメトリを生成するには Point() メソッドを使用できるが,それに必要なのは2つの座標値とその座標を関連づける SRID だけである.
  • これらの各々の表現からオブジェクトを生成するために使われる静的メソッドに加えて,SQL Server はオブジェクトを WKT, WKB および GML フォーマットで表現するのに使うためのインスタンスメソッドも提供している.この機能は STAsText(), STAsBinary() および AsGML() メソッドで提供される.

“第 4 章 空間データオブジェクトを生成する (Beginning Spatial with SQL Server 2008)” への1件の返信

コメントを残す

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

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