第10章 MySQL における空間情報の機能

目次

10.1. はじめに
10.2. OpenGIS ジオメトリモデル
10.2.1. ジオメトリクラス階層
10.2.2. Geometry クラス
10.2.3. クラス Point
10.2.4. Curve クラス
10.2.5. LineString クラス
10.2.6. Surface クラス
10.2.7. Polygon クラス
10.2.8. GeometryCollection クラス
10.2.9. MultiPoint クラス
10.2.10. MultiCurve クラス
10.2.11. MultiLineString クラス
10.2.12. MultiSurface クラス
10.2.13. MultiPolygon クラス
10.3. サポートされている空間データ形式
10.3.1. Well-Known Text(WKT)形式
10.3.2. Well-Known Binary(WKB)形式
10.4. 空間的に有効な MySQL データベースの作成
10.4.1. MySQL 空間データ型
10.4.2. 空間情報の値の作成
10.4.3. 空間情報カラムの作成
10.4.4. 空間情報カラムへのデータ入力
10.4.5. 空間データの取り込み
10.5. 空間情報の分析
10.5.1. ジオメトリの形式を変換する関数
10.5.2. Geometry プロパティ分析関数
10.5.3. 既存ジオメトリから新規ジオメトリを作成する関数
10.5.4. ジオメトリオブジェクト間の空間的関係をテストするための関数
10.5.5. 最小外接矩形(MBR)における関係
10.5.6. ジオメトリ間の空間関係をテストする関数
10.6. 空間分析の最適化
10.6.1. 空間インデックスの作成
10.6.2. 空間インデックスの使用
10.7. MySQL の適合性と互換性
10.7.1. まだ実装されていない GIS 機能

MySQL 4.1 では空間情報を扱う機能が導入され、地理的特性の生成、格納、分析が可能になっています。 地理情報は現在、MyISAM テーブルに対してのみ使用することができます。

この章で取り上げるトピックは以下のとおりです。

10.1. はじめに

MySQL は、Open GIS Consortium(OGC)の仕様に準拠した空間情報の機能を実装します。OGC は、合計 250 を超える団体からなる国際コンソーシアムです。加盟している企業、政府機関、大学では、公開可能な概念ソリューションを開発しており、それらのソリューションは、空間データを管理するあらゆるアプリケーションで使用できるものです。 OGC の Web サイトは http://www.opengis.org/ です。

1997 年、Open GIS Consortium は OpenGIS (R) Simple Features Specifications For SQL を公開しました。この文書では、SQL RDBMS を拡張して空間データをサポートするための概念的な手法がいくつか提案されています。この仕様は、Open GIS Web サイト(http://www.opengis.org/techno/implementation.htm)で入手可能であり、この章の補足情報が記載されています。

MySQL は、OGC により提案されているジオメトリタイプを有する SQL 環境のサブセットを実装します。 これは、ジオメトリタイプのセットにより拡張された SQL 環境のことです。ジオメトリ値を持つ SQL カラムは、ジオメトリタイプのカラムとして実装されます。仕様には、SQL ジオメトリタイプのセットと、ジオメトリ値の作成と分析に使用される、これらのタイプの各種関数について記述されています。

地理的特性とは、実世界において位置を持つ存在を指します。 地理的特性の例を以下に示します。

  • 実体。たとえば山、池、都市。

  • 空間。たとえば郵便番号エリア、熱帯地方。

  • 定義可能な場所。たとえば交差道路(2 つの通りが交差する地点)。

また、geospatial(地理空間) という用語が使用されている文書を探し、地理空間について詳しい情報を得ることもできます。

ジオメトリは、地理情報の機能を表す別の用語です。ジオメトリは本来、数学の一分野である幾何学を意味します。 もう 1 つの意味は地図作成法に由来し、地図の作成時に使用される地理的な特性を指します。

この章では、地理的特性地理空間特性地物ジオメトリをすべて同義語として使用しています。 使用頻度が最も高い用語はジオメトリです。

ここでは、ジオメトリ位置を持ち存在を表すポイントまたはポイントの集まりと定義します。

10.2. OpenGIS ジオメトリモデル

OGC のジオメトリタイプを有する SQL 環境で提案されているジオメトリタイプのセットは、OpenGIS ジオメトリモデルに基づきます。このモデルでは、各ジオメトリオブジェクトに以下の汎用特性があります。

  • 空間参照系(オブジェクトが定義される座標空間を示す)に関連付けられている。

  • ジオメトリクラスに属している。

10.2.1. ジオメトリクラス階層

ジオメトリクラスの階層は以下のとおりです。

  • Geometry(インスタンス化できない)

    • Point(インスタンス化できる)

    • Curve(インスタンスできない)

      • LineString(インスタンス化できる)

        • Line

        • LinearRing

    • Surface(インスタンス化できない)

      • Polygon(インスタンス化できる)

    • GeometryCollection(インスタンス化できる)

      • MultiPoint(インスタンス化できる)

      • MultiCurve(インスタンス化できない)

        • MultiPoint(インスタンス化できる)

      • MultiSurface(インスタンス化できない)

        • MultiPolygon(インスタンス化できる)

これらのクラスの一部は抽象クラス(インスタンス化できないクラス)です。つまり、これらのクラスのオブジェクトを作成することはできません。他のクラスはインスタンス化が可能であり、オブジェクトを作成することができます。 各クラスにはプロパティがあり、インスタンス化可能なクラスにはアサート(有効なクラスインスタンスを定義するルール)が含まれている場合があります。

Geometry は基本クラスです。これは抽象クラスです。 Geometry のインスタンス化可能サブクラスは、2 次元の座標空間に存在する 0 次元、1 次元、2 次元のジオメトリオブジェクトに制限されています。インスタンス化可能なジオメトリクラスはすべて、有効なインスタンスが位相的に閉じるように定義されています(すべての定義済みジオメトリには境界が含まれています)。

基本 Geometry クラスには、PointCurveSurfaceGeometryCollection のサブクラスがあります。

  • Point は 0 次元オブジェクトを表す。

  • Curve は 1 次元オブジェクトを表す。このクラスには、サブクラス LineString のほか、サブサブクラス Line および LinearRing が属している。

  • Surface は 2 次元オブジェクト用に設計されており、その下にサブクラス Polygon がある。

  • GeometryCollection には、0 次元、1 次元、2 次元のコレクションクラス、MultiPointMultiLineStringMultiPolygon が含まれている。これらのクラスは、それぞれPointLineStringPolygon のコレクションになっているジオメトリをモデル化するためのものである。 MultiCurveMultiSurface は、複数の CurveSurface を処理するコレクションインタフェースを汎用化する抽象スーパークラスとして導入されている。

GeometryCurveSurfaceMultiCurveMultiSurface は、インスタンス化できないクラスとして定義されます。 これらのクラスには、それぞれのサブクラス用メソッドの共通セットが定義されています。これらは拡張目的で含まれています。

PointLineStringPolygonGeometryCollectionMultiPointMultiLineStringMultiPolygon はインスタンス化が可能なクラスです。

10.2.2. Geometry クラス

Geometry は階層のルートクラスです。これはインスタンス化できないクラスですが、Geometry サブクラスから作成されたすべてのジオメトリの値に対して共通な多数のプロパティを含んでいます。 これらのプロパティを以下に示します。特定のサブクラスには固有のプロパティがありますが、それについては後述します。

ジオメトリのプロパティ

ジオメトリ値には以下のプロパティがあります。

  • タイプ。 各ジオメトリは、階層上のインスタンス化可能なクラスのいずれかに属す。

  • SRID(Spatial Reference Identifier = 空間参照識別子)。ジオメトリに関連付けられる空間参照系(ジオメトリオブジェクトが定義される座標空間を示す)が、この値で識別される。

  • 空間参照系における座標。倍精度(8 バイト)の数値で表現される。空白以外のジオメトリには、少なくとも 1 組(X,Y)の座標が含まれている。空白のジオメトリには座標が含まれない。

    座標は SRID に関連付けられている。 たとえば、異なった座標系では、両方のオブジェクトの座標が一致していてもオブジェクト間の距離が一致しないことがある。平面座標系での距離と地心座標系(地球表面上の座標)での距離は同じものではないからである。

  • 内部境界外部

    すべてのジオメトリは、空間のどこかの位置を占める。ジオメトリの外部とは、ジオメトリによって占有されていない空間のすべてを指す。ジオメトリの内部とは、ジオメトリによって占有されている空間を指す。境界は、ジオメトリの内部と外部の接触面である。

  • MBR(Minimum Bounding Rectangle = 最小外接矩形)または Envelope。 これは境界ジオメトリであり、最小と最大(X,Y)の座標で形成される。

    ((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
    
  • 単純であるか非単純であるかの性質。 いくつかのタイプ(LineStringMultiPointMultiLineString)のジオメトリ値は単純または非単純になる。単純か非単純かに関する判定は各タイプで決定。

  • 閉じている閉じていないかの性質。 いくつかのタイプ(LineStringMultiString)のジオメトリ値は、閉じている/閉じていないのいずれかになる。閉じているかどうかに関する独自の判定は各タイプで決定。

  • 空でないかの性質。 ジオメトリは、Point を持たない場合に空になる。 空白ジオメトリの外部、内部、境界は定義されない(つまり、NULL 値で表現される)。 空白ジオメトリは、常に単純で 0 の領域を持つように定義される。

  • 次元。ジオメトリは、?1、0、1、2 のいずれかの次元になる。

    • ?1 は、ジオメトリが空であることを示す。

    • 0 は、ジオメトリに長さと領域がないことを示す。

    • 1 は、ジオメトリの長さが 0 以外で領域が 0 であることを示す。

    • 2 は、ジオメトリの領域が 0 以外であることを示す。

    Point オブジェクトは 0 次元。LineString オブジェクトは 1 次元。Polygon オブジェクトは 2 次元。MultiPointMultiLineString、および MultiPolygon オブジェクトの次元は、それぞれの構成要素の次元と同じ。

10.2.3. クラス Point

Point は、座標空間における単一の場所を表すジオメトリです。

Point の例

  • 縮尺の大きい世界地図に多数の都市が含まれている場合、Point は各都市を表す。

  • 市内地図の場合、Point はバス停を表す。

Point のプロパティ

  • X 座標値。

  • Y 座標値。

  • Point は、0 次元のジオメトリとして定義される。

  • Point の境界は空のセット。

10.2.4. Curve クラス

Curve は 1 次元のジオメトリであり、通常は一連の Point によって表現されます。Curve の特定のサブクラスでは、Point 間の内挿が定義されます。Curve はインスタンス化できないクラスです。

Curve のプロパティ

  • 各 Point の座標。

  • Curve は、1 次元のジオメトリとして定義される。

  • Curve は、同じ Point を 2 回通過しない場合には単純になる。

  • Curve は、開始 Point が終了 Point と一致する場合に閉じている。

  • 閉じた Curve は空である。

  • 閉じていない Curve の境界は、2 つの終了 Point で構成される。

  • 単純で閉じている CurveLinearRing である。

10.2.5. LineString クラス

LineString は、Point 間が直線補間されている Curve です。

LineString の例

  • 世界地図の場合、LineString オブジェクトは河川を表す。

  • 市内地図の場合、LineString オブジェクトは通りを表す。

LineString のプロパティ

  • 連続したポイントのペアによって定義された LineString セグメントの座標。

  • LineString は、2 つの Point のみで構成される場合には Line

  • LineString は、閉じていて単純な場合には LinearRing

10.2.6. Surface クラス

Surface は 2 次元のジオメトリです。インスタンス化できないクラスであり、その下に属するインスタンス化可能なサブクラスは Polygon だけです。

Surface のプロパティ

  • Surface は 2 次元のジオメトリとして定義される。

  • OpenGIS 仕様では、単純な Surface は、単一の外部境界と 0 以上の内部境界に関連付けられている単一の ``区間'' のみで構成されるジオメトリとして定義されている。

  • 単純な Surface の境界は、外部境界および内部境界に対応する閉じた Curve のセット。

10.2.7. Polygon クラス

Polygon は、複数の辺を持つジオメトリを表す平面 Surface です。単一の外部境界および 0 以上の内部境界によって定義されます。内部境界はそれぞれ Polygon 内の穴を定義します。

Polygon の例

  • 地域地図の場合、Polygon オブジェクトは森林、地区その他を表す。

Polygon のアサート

  • Polygon の境界は、外部境界と内部境界を形成する LinearRing オブジェクト(単純で閉じている LineString オブジェクト)のセットで構成される。

  • 2 つの Ring が境界で交わることはない。Polygon の境界にある Ring が Point で交わることはある。ただし、その場合は接線として交わるのみ。

  • Polygon には、切断線、突起、陥没のいずれもあってはならない。

  • Polygon は、接続された Point のセットである。

  • 1 つ以上の穴がある Polygon の外部は接続されていない。 それぞれの穴は、外部の接続されたコンポーネントを示す。

上記のアサートでは、Polygon は単純なジオメトリです。これらのアサートにより、Polygon は単純なジオメトリになります。

10.2.8. GeometryCollection クラス

GeometryCollection は単一のジオメトリですが、任意クラスのジオメトリ(1 つ以上)のコレクションとなっています。

GeometryCollection に含まれる要素はすべて、同じ座標系に存在していなければなりません。 GeometryCollection では、他の制限を要素に課していません。ただし、以降で説明する GeometryCollection のサブクラスによってメンバーシップが制限されることがあります。制限は以下に基づきます。

  • 要素タイプ(たとえば MultiPoint には Point 要素のみ含まれる)

  • 次元

  • 要素間の空間的重なりの度合いに対する制限

10.2.9. MultiPoint クラス

MultiPoint は、Point 要素で構成されるジオメトリコレクションです。各ポイントは接続されておらず、順序付けられてもいません。

MultiPoint の例

  • 世界地図の場合、Multipoint は小さな群島を表す。

  • 市内地図の場合、Multipoint はチケット販売チェーン店を表す。

MultiPoint のプロパティ

  • MultiPoint は、0 次元のジオメトリとして定義される。

  • MultiPoint は、同じ(座標値が一致する) Point 値のペアがない場合には単純である。

  • MultiPoint の境界は空のセット。

10.2.10. MultiCurve クラス

MultiCurve は、Curve 要素で構成されるジオメトリコレクションです。MultiCurve はインスタンス化できないクラスです。

MultiCurve のプロパティ

  • MultiCurve は、1 次元のジオメトリとして定義される。

  • MultiCurve が単純であるのは、その要素がすべて単純で、あらゆる 2 要素の交点のみが 2 要素の境界上のポイントに存在する場合だけである。

  • MultiCurve を取得するには、次の ``mod 2 union rule''(別名は odd-even rule)を適用する。 すなわち、MultiCurve 要素で奇数の境界にある Point は、MultiCurve の境界にある。

  • MultiCurve は、すべての要素が閉じている場合に閉じている。

  • 閉じた MultiCurve は常に空である。

10.2.11. MultiLineString クラス

MultiLineString は、LineString 要素で構成される MultiCurve ジオメトリコレクションです。

MultiLineString の例

  • 地域地図の場合、MultiLineString は水系または幹線道路網を表す。

10.2.12. MultiSurface クラス

MultiSurface は、地表面要素で構成されるジオメトリコレクションです。 MultiSurface はインスタンス化できないクラスであり、その下に属するインスタンス化可能なサブクラスは MultiPolygon だけです。

MultiSurface のアサート

  • MultiSurface では、2 つの Surface の内部が交差することはない。

  • MultiSurface では、いずれか 2 つの要素の境界が有限の点数で交差することがある。

10.2.13. MultiPolygon クラス

MultiPolygon は、Polygon 要素で構成される MultiSurface オブジェクトです。

MultiPolygon の例

  • 地域地図の場合、MultiPolygon は湖沼系を表す。

MultiPolygon のアサート

  • MultiPolygon の要素になっている 2 つの Polygon 値の内部が交差することはない。

  • MultiPolygon の要素になっているいずれか 2 つの Polygon 値における境界も交差することはなく、有限ポイント数で接触することがあるだけである。 (前述したアサートにおいても、交差は禁止されている。)

  • MultiPolygon には、切断線、突起、陥没のいずれもあってはならない。MultiPolygon は、通常の閉じた Point セットである。

  • 1 つ以上の Polygon で構成される MultiPolygon の内部は接続されていない。MultiPolygon 内部の接続されたコンポーネントの数は、MultiPolygon における Polygon 値の数と一致する。

MultiPolygon のプロパティ

  • MultiPolygon は 2 次元のジオメトリとして定義される。

  • MultiPolygon の境界は、Polygon 要素の境界に対応する閉じた Curve(LineString 値)のセットである。

  • MultiPolygon の境界内の各 Curve は、単一の要素 Polygon の境界に当たる。

  • 要素 Polygon の境界の各 Curve は、MultiPolygon の境界に属す。

10.3. サポートされている空間データ形式

このセクションでは、クエリでジオメトリオブジェクトを表現するために使用される標準的な空間データ形式について説明します。 具体的には、以下のデータ形式が対象となります。

  • Well-Known Text(WKT)形式

  • Well-Known Binary(WKB)形式

MySQL でジオメトリ値が内部的に保存される形式は、WKT 形式でも WKB 形式でもありません。

10.3.1. Well-Known Text(WKT)形式

ジオメトリの Well-Known Text(WKT)表現は、ジオメトリデータを ASCII 形式で交換するためのものです。

ジオメトリオブジェクトの WKT の例

  • Point:

    POINT(15 20)
    

    注意: Point 座標はカンマなしで指定される。

  • Point が 4 つある LineString

    LINESTRING(0 0, 10 10, 20 25, 50 60)
    
  • 外部 Ring と内部 Ring が 1 つずつある Polygon

    POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
    
  • Point 値が 3 つある MultiPoint

    MULTIPOINT(0 0, 20 20, 60 60)
    
  • LineString 値が 2 つある MultiLineString

    MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
    
  • Polygon 値が 2 つある MultiPolygon

    MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
    
  • 2 つの Point 値と 1 つの LineString で構成される GeometryCollection

    GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
    

WKT 値を記述するための正式なプロダクションルールを指定する Backus-Naur 文法については、この章の冒頭で言及されている OGC 仕様書を参照してください。

10.3.2. Well-Known Binary(WKB)形式

ジオメトリック値の Well-Known Binary(WKB)表現は、OpenGIS 仕様によって定義されています。 また、ISO ``SQL/MM Part 3: Spatial'' 標準でも定義されています。

ジオメトリック WKB 情報を含む BLOB 値で表現されるバイナリストリームとしてジオメトリ値を交換するために、WKB を使用します。

1 バイトの符号なし整数、4 バイトの符号なし整数、8 バイトの倍精度数値(IEEE 754 形式)が WKB によって使用されます。1 バイトは 8 ビットです。

たとえば WKB 値が POINT(1 1) に対応する場合、この値は次の 21 バイトの連続(ここでは 2 桁の 16 進数で 1 バイト)で構成されます。

0101000000000000000000F03F000000000000F03F

上記の数値は以下の構成要素に分割できます。

Byte order : 01
WKB type   : 01000000
X          : 000000000000F03F
Y          : 000000000000F03F

構成要素の表現は以下のとおりです。

  • バイト順位は 0 または 1 であり、それぞれリトルエンディアンとビッグエンディアンによる格納を示す。リトルエンディアンとビッグエンディアンによるバイト順位は、それぞれネットワークデータ表現(NDR)と外部データ表現(XDR)としても知られている。

  • WKB タイプは、ジオメトリタイプを示すコードである。1 ? 7 の値はそれぞれ、PointLineStringPolygonMultiPointMultiLineStringMultiPolygonGeometryCollection を示す。

  • Point の値は X と Y の座標を含んでおり、それぞれ倍精度の値として表現される。

より複雑なジオメトリ値に対応する WKB 値は、より複雑なデータ構造で表現されます(詳細については OpenGIS 仕様を参照してください)。

10.4. 空間的に有効な MySQL データベースの作成

このセクションでは、MySQL で空間データを表現するために使用できるデータ型と、空間値の作成および検索に使用できる関数について説明します。

10.4.1. MySQL 空間データ型

MySQL には、OpenGIS ジオメトリモデルのクラス階層内のクラスに対応するデータ型のセットが用意されています。これらのデータ型には、単一ジオメトリ値を保持するものもあります。

  • GEOMETRY

  • POINT

  • LINESTRING

  • POLYGON

GEOMETRY は、単一値データ型のうちで最も汎用的であり、どのタイプのジオメトリ値でも格納できます。 他の単一値データ型では、特定かつ単一のジオメトリタイプに値が制限されます。

上記以外のデータ型では、値のコレクションが保持されます。

  • MULTIPOINT

  • MULTILINESTRING

  • MULTIPOLYGON

  • GEOMETRYCOLLECTION

GEOMETRYCOLLECTION では、あらゆるタイプのオブジェクトのコレクションを格納できます。他のコレクションタイプでは、コレクションメンバは特定のジオメトリタイプを持つものに制限されます。

10.4.2. 空間情報の値の作成

このセクションでは、Well-Known Text および Well-Known Binary 関数(OpenGIS 標準で定義)と MySQL 固有の関数を使用して空間情報の値を作成する方法について説明します。

10.4.2.1. WKT 関数によるジオメトリ値の作成

MySQL には、Well-Known Text 表現(およびオプションとして空間参照系 ID(SRID))を入力パラメータとして受け取り、対応するジオメトリを返す関数が多数用意されています。

GeomFromText() は、任意のジオメトリタイプの WKT を最初の引数として受け取ります。タイプ固有の作成関数も用意されており、これらは各ジオメトリタイプのジオメトリ値を生成するために使用されます。

  • GeomFromText(wkt[,srid]) , GeometryFromText(wkt[,srid])

    WKT 表現と SRID を使用して、任意のタイプのジオメトリ値を生成する。

  • PointFromText(wkt[,srid])

    WKT 表現と SRID を使用して、POINT 値を生成する。

  • LineFromText(wkt[,srid]) , LineStringFromText(wkt[,srid])

    WKT 表現と SRID を使用して、LINESTRING 値を生成する。

  • PolyFromText(wkt[,srid]) , PolygonFromText(wkt[,srid])

    WKT 表現と SRID を使用して、POLYGON 値を生成する。

  • MPointFromText(wkt[,srid]) , MultiPointFromText(wkt[,srid])

    WKT 表現と SRID を使用して、MULTIPOINT 値を生成する。

  • MLineFromText(wkt[,srid]) , MultiLineStringFromText(wkt[,srid])

    WKT 表現と SRID を使用して、MULTILINESTRING 値を生成する。

  • MPolyFromText(wkt[,srid]) , MultiPolygonFromText(wkt[,srid])

    WKT 表現と SRID を使用して、MULTIPOLYGON 値を生成する。

  • GeomCollFromText(wkt[,srid]) , GeometryCollectionFromText(wkt[,srid])

    WKT 表現と SRID を使用して、GEOMETRYCOLLECTION 値を生成する。

Ring または閉じた LineString 値のコレクションの WKT 表現に基づいて Polygon 値または MultiPolygon 値を生成するためのオプション関数についても、OpenGIS 仕様に記述されています。これらの値は交差できます。これらの関数は、MySQL にまだ実装されていません。

  • BdPolyFromText(wkt,srid)

    閉じた LineString 値から成る任意のコレクションが含まれている MultiLineString 値(WKT 形式)から Polygon 値を生成する。

  • BdMPolyFromText(wkt,srid)

    閉じた LineString 値から成る任意のコレクションが含まれている MultiLineString 値(WKT 形式)から MultiPolygon 値を生成する。

10.4.2.2. WKB 関数によるジオメトリ値の作成

Well-Known Binary 表現が含まれている BLOB(およびオプションとして空間参照系 ID(SRID))を入力パラメータとして受け取り、対応するジオメトリを返す関数が MySQL に多数用意されています。

GeomFromWKT() は、任意のジオメトリタイプの WKB を最初の引数として受け取ります。タイプ固有の作成関数も用意されており、これらは各ジオメトリタイプのジオメトリ値を生成するために使用されます。

  • GeomFromWKB(wkb[,srid]) , GeometryFromWKB(wkt[,srid])

    WKB 表現と SRID を使用して、任意のタイプのジオメトリ値を生成する。

  • PointFromWKB(wkb[,srid])

    WKB 表現と SRID を使用して、POINT 値を生成する。

  • LineFromWKB(wkb[,srid]) , LineStringFromWKB(wkb[,srid])

    WKB 表現と SRID を使用して、LINESTRING 値を生成する。

  • PolyFromWKB(wkb[,srid]) , PolygonFromWKB(wkb[,srid])

    WKB 表現と SRID を使用して、POLYGON 値を生成する。

  • MPointFromWKB(wkb[,srid]) , MultiPointFromWKB(wkb[,srid])

    WKB 表現と SRID を使用して、MULTIPOINT 値を生成する。

  • MLineFromWKB(wkb[,srid]) , MultiLineStringFromWKB(wkb[,srid])

    WKB 表現と SRID を使用して、MULTILINESTRING 値を生成する。

  • MPolyFromWKB(wkb[,srid]) , MultiPolygonFromWKB(wkb[,srid])

    WKB 表現と SRID を使用して、MULTIPOLYGON 値を生成する。

  • GeomCollFromWKB(wkb[,srid]) , GeometryCollectionFromWKB(wkt[,srid])

    WKB 表現と SRID を使用して、GEOMETRYCOLLECTION 値を生成する。

Ring または閉じた LineString 値のコレクションの WKB 表現に基づいて Polygon または MultiPolygon を生成するためのオプション関数についても、OpenGIS 仕様に記述されています。これらの値は交差できます。これらの関数は、MySQL にまだ実装されていません。

  • BdPolyFromWKB(wkb,srid)

    閉じた LineString 値から成る任意のコレクションが含まれている MultiLineString 値(WKB 形式)から Polygon 値を生成する。

  • BdMPolyFromWKB(wkb,srid)

    閉じた LineString 値から成る任意のコレクションが含まれている MultiLineString 値(WKB 形式)から MultiPolygon 値を生成する。

10.4.2.3. MySQL 固有の関数によるジオメトリ値の作成

注意: このセクションで取り上げる関数は、MySQL にまだ実装されていません。

ジオメトリ WKB 表現を作成する際に役立つ関数が MySQL に用意されています。このセクションで説明する関数は、OpenGIS 仕様に対する MySQL 拡張です。これらの関数の結果、SRID のないジオメトリ値の WKB 表現を含む BLOB 値が返されます。 これらの関数の結果は、GeomFromWKB() 関数ファミリに含まれるどの関数についても、最初の引数として代用できます。

  • Point(x,y)

    座標を使用して WKB Point を生成する。

  • MultiPoint(pt1,pt2,...)

    WKB Point 引数を使用して WKB MultiPoint 値を生成する。 いずれかの引数が WKBPoint でない場合、返り値は NULL になる。

  • LineString(pt1,pt2,...)

    WKB Point 引数から WKB LineString 値を生成する。いずれかの引数が WKB Point でない場合、返り値は NULL になる。Point 引数が 2 個に満たない場合、返り値は NULL になる。

  • MultiLineString(ls1,ls2,...)

    WKB LineString 引数を使用して WKB MultiLineString 値を生成する。いずれかの引数が LineString でない場合、返り値は NULL になる。

  • Polygon(ls1,ls2,...)

    WKB LineString 引数から WKB Polygon 値を生成する。いずれかの引数が LinearRing のWKB を表さない場合(閉じている単純な LineString でない場合)、返り値は NULL になる。

  • MultiPolygon(poly1,poly2,...)

    WKB Polygon 引数から WKB MultiPolygon 値を生成する。 いずれかの引数が WKB Polygon でない場合、返り値は NULL になる。

  • GeometryCollection(g1,g2,...)

    WKB GeometryCollection を生成する。いずれかの引数がジオメトリの WKB 表現として適切ではない場合、返り値は NULL になる。

10.4.3. 空間情報カラムの作成

ジオメトリタイプに対して空間情報カラムを作成する標準的な方法が MySQL に用意されています(たとえば CREATE TABLE または ALTER TABLE を使用)。 空間情報カラムは現在、MyISAM テーブルに対してのみサポートされています。

  • CREATE TABLE ステートメントを使用し、空間情報カラムのあるテーブルを作成する。

    mysql> CREATE TABLE geom (g GEOMETRY);
    Query OK, 0 rows affected (0.02 sec)
    
  • ALTER TABLE ステートメントを使用し、既存テーブルに空間情報カラムを追加したり、既存テーブルの空間情報カラムを破棄したりする。

    mysql> ALTER TABLE geom ADD pt POINT;
    Query OK, 0 rows affected (0.00 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    mysql> ALTER TABLE geom DROP pt;
    Query OK, 0 rows affected (0.00 sec)
    Records: 0  Duplicates: 0  Warnings: 0
    

10.4.4. 空間情報カラムへのデータ入力

作成した空間情報カラムには、空間データを入力することができます。

値は内部ジオメトリ形式で格納する必要がありますが、Well-Known Text(WKT)または Well-Known Binary(WKB)形式から内部ジオメトリ形式に変換することも可能です。WKT 値を内部ジオメトリ形式に変換してジオメトリ値をテーブルに挿入する方法を、以下の例に示します。

この変換は、INSERT ステートメントで直接実行することができます。

INSERT INTO geom VALUES (GeomFromText('POINT(1 1)'));

SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (GeomFromText(@g));

INSERT の前に変換が実行される場合もあります。

SET @g = GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@g);

以下の例では、より複雑なジオメトリをテーブルに挿入しています。

SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (GeomFromText(@g));

SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (GeomFromText(@g));

SET @g = 'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (GeomFromText(@g));

前述したいずれの例でも、GeomFromText() を使用してジオメトリ値を作成しています。タイプ固有の関数を使用することもできます。

SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (PointFromText(@g));

SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (LineStringFromText(@g));

SET @g = 'POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))';
INSERT INTO geom VALUES (PolygonFromText(@g));

SET @g = 'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (GeomCollFromText(@g));

注意: クライアントアプリケーションプログラムは、ジオメトリ値の WKB 表現を使用する場合、正しい形式の WKB をクエリでサーバに送信しなければなりません。この要件を満たすにはいくつかの方法があります。たとえば、以下のようにします。

  • POINT(1 1) 値を 16 進リテラル構文で挿入する。

    mysql> INSERT INTO geom VALUES
        -> (GeomFromWKB(0x0101000000000000000000F03F000000000000F03F));
    

  • ODBC アプリケーションは WKB 表現を送信し、それをプレースホルダにバインドすることができる(BLOB 型の引数を使用)。

    INSERT INTO geom VALUES (GeomFromWKB(?))
    

    他のプログラミングインタフェースでも、類似したプレースホルダ機構がサポートされている場合がある。

  • C プログラムでは、mysql_real_escape_string() を使用してバイナリ値をエスケープし、サーバに送信されるクエリ文字列に結果を取り込むことができる。 See 項11.1.3.44. 「mysql_real_escape_string()

10.4.5. 空間データの取り込み

テーブルに格納されたジオメトリ値は、内部形式に変換して取り込めます。この値は WKT または WKB 形式に変換することもできます。

10.4.5.1. 空間データの取り込み(内部形式を使用)

内部形式によるジオメトリ値の取り込みは、テーブル間の転送に有効です。

CREATE TABLE geom2 (g GEOMETRY) SELECT g FROM geom;

10.4.5.2. 空間データの取り込み(WKT 形式を使用)

AsText() 関数では、ジオメトリ値をテキストとして使用することができます。この関数は、ジオメトリを内部形式から WKT 文字列に変換します。

mysql> SELECT AsText(g) FROM geom;
+-------------------------+
| AsText(p1)              |
+-------------------------+
| POINT(1 1)              |
| LINESTRING(0 0,1 1,2 2) |
+-------------------------+

10.4.5.3. 空間データの取り込み(WKB 形式を使用)

AsBinary() 関数では、ジオメトリ値をバイナリとして使用することができます。 この関数は、ジオメトリを内部形式から BLOB(WKB 値を含む)に変換します。

SELECT AsBinary(g) FROM geom;

10.5. 空間情報の分析

空間情報カラムに値を入力した後は、クエリと分析を行うことができます。空間データに対して各種の操作を実行するための関数が MySQL に用意されています。これらの関数は、実行する操作に基づき 4 つの主要なカテゴリに分類されます。

  • 各種形式間でジオメトリを変換する関数

  • ジオメトリの質的または量的プロパティへのアクセスを提供する関数

  • 2 つのジオメトリの関係を記述する関数

  • 既存ジオメトリから新規ジオメトリを作成する関数

以下のような多くの状況で、空間情報の分析関数を使用することができます。

  • インタラクティブな SQL プログラム(mysqlMySQLCC など)。

  • MySQL クライアント API をサポートする言語で記述されたアプリケーションプログラム。

10.5.1. ジオメトリの形式を変換する関数

MySQL でサポートされている以下の関数では、WKT または WKB 形式と内部形式間でジオメトリ値を変換することができます。

  • GeomFromText(wkt[,srid])

    文字列値を WKT 表現から内部ジオメトリ形式へと変換し、結果を返す。 タイプ固有の関数も数多くサポートされている(PointFromText()LineFromText() など)。項10.4.2.1. 「WKT 関数によるジオメトリ値の作成」 参照。.

  • GeomFromWKB(wkb[,srid])

    バイナリ値を WKB 表現から内部ジオメトリ形式へと変換し、結果を返す。 タイプ固有の関数も数多くサポートされている(PointFromWKB()LineFromWKB() など)。項10.4.2.2. 「WKB 関数によるジオメトリ値の作成」 参照。

  • AsText(g)

    内部ジオメトリ形式の値を WKT 表現に変換し、結果文字列を返す。

    mysql> SET @g = 'LineString(1 1,2 2,3 3)';
    mysql> SELECT AsText(GeomFromText(@g));
    +--------------------------+
    | AsText(GeomFromText(@G)) |
    +--------------------------+
    | LINESTRING(1 1,2 2,3 3)  |
    +--------------------------+
    

  • AsBinary(g)

    内部ジオメトリ形式の値を WKB 表現に変換し、結果のバイナリ値を返す。

10.5.2. Geometry プロパティ分析関数

このグループに属す関数は、ジオメトリ値を引数として使用し、ジオメトリの質的または量的プロパティを返します。一部の関数では、引数のタイプが制限されています。そのような関数は、引数のジオメトリタイプが不正な場合に NULL を返します。たとえば、オブジェクトタイプが PolygonMultiPolygon のいずれでもない場合、Area()NULL を返します。

10.5.2.1. 汎用 Geometry プロパティ分析関数

このセクションに列挙されている関数には引数に対する制限はなく、どのタイプのジオメトリ値も受け入れられます。

  • GeometryType(g)

    ジオメトリインスタンス g がメンバになっているジオメトリタイプの名称を文字列として返す。 この名称は、インスタンス化可能な Geometry サブクラスの 1 つに対応する。

    mysql> SELECT GeometryType(GeomFromText('POINT(1 1)'));
    +------------------------------------------+
    | GeometryType(GeomFromText('POINT(1 1)')) |
    +------------------------------------------+
    | POINT                                    |
    +------------------------------------------+
    

  • Dimension(g)

    ジオメトリ値 g 固有の次元を返す。結果は ?1、0、1、2 のいずれか(これらの値の意味については 項10.2.2. 「Geometry クラス」 を参照)。

    mysql> SELECT Dimension(GeomFromText('LineString(1 1,2 2)'));
    +------------------------------------------------+
    | Dimension(GeomFromText('LineString(1 1,2 2)')) |
    +------------------------------------------------+
    |                                              1 |
    +------------------------------------------------+
    

  • SRID(g)

    ジオメトリ値 g の空間参照系 ID を示す整数を返す。

    mysql> SELECT SRID(GeomFromText('LineString(1 1,2 2)',101));
    +-----------------------------------------------+
    | SRID(GeomFromText('LineString(1 1,2 2)',101)) |
    +-----------------------------------------------+
    |                                           101 |
    +-----------------------------------------------+
    

  • Envelope(g)

    ジオメトリ値 g の最小外接矩形(MBR)を返す。 結果は Polygon 値として返す。

    mysql> SELECT AsText(Envelope(GeomFromText('LineString(1 1,2 2)')));
    +-------------------------------------------------------+
    | AsText(Envelope(GeomFromText('LineString(1 1,2 2)'))) |
    +-------------------------------------------------------+
    | POLYGON((1 1,2 1,2 2,1 2,1 1))                        |
    +-------------------------------------------------------+
    

    境界ボックスのコーナーポイントによって、Polygon が定義される。

    POLYGON((MINX MINY, MAXX MINY, MAXX MAXY, MINX MAXY, MINX MINY))
    

OpenGIS 仕様では以下の関数も定義していますが、これらは MySQL でまだ実装されていません。

  • Boundary(g)

    ジオメトリ値 g の組み合わせ境界の終わりとなるジオメトリを返す。

  • IsEmpty(g)

    ジオメトリ値 g が空白ジオメトリであれば 1、空白でなければ 0、引数が NULL であれば ?1 を返す。 ジオメトリが空の場合、空の Point セットを表す。

  • IsSimple(g)

    現在、この関数はプレースホルダとなっており、使用すべきではない。 実装された場合の機能については、以下のとおり。

    ジオメトリ値 g に不正な(自己交差や自己接触が起きている)ジオメトリ Point がない場合、1 を返す。IsSimple() は、引数が単純であれば 0、引数が NULL であれば ?1 を返す。

    インスタンス化可能な各ジオメトリクラスについては該当するセクションで説明したが、そこで、そのクラスのインスタンスが非単純と分類される場合の特定の条件について説明している。

10.5.2.2. Point プロパティ分析関数

Point はX 座標と Y 座標から構成されますが、これらは以下の関数を使用して取得できます。

  • X(p)

    Point p の X 座標値を倍精度の数値として返す。

    mysql> SELECT X(GeomFromText('Point(56.7 53.34)'));
    +--------------------------------------+
    | X(GeomFromText('Point(56.7 53.34)')) |
    +--------------------------------------+
    |                                 56.7 |
    +--------------------------------------+
    

  • Y(p)

    Point p の Y 座標値を倍精度の数値として返す。

    mysql> SELECT Y(GeomFromText('Point(56.7 53.34)'));
    +--------------------------------------+
    | Y(GeomFromText('Point(56.7 53.34)')) |
    +--------------------------------------+
    |                                53.34 |
    +--------------------------------------+
    

10.5.2.3. LineString プロパティ分析関数

LineStringPoint 値で構成されます。LineString に関し、その特定 Point を抽出するか、含まれている Point 数をカウントするか、その長さを取得することができます。

  • EndPoint(ls)

    LineStringls の終点となっている Point を返す。

    mysql> SELECT AsText(EndPoint(GeomFromText('LineString(1 1,2 2,3 3)')));
    +------------------------------------------------------------+
    | AsText(EndPoint(GeomFromText('LineString(1 1,2 2,3 3)')))  |
    +------------------------------------------------------------+
    | POINT(3 3)                                                 |
    +------------------------------------------------------------+
    

  • GLength(ls)

    関連する空間参照における LineStringls の長さを倍精度の数値として返す。

    mysql> SELECT GLength(GeomFromText('LineString(1 1,2 2,3 3)'));
    +--------------------------------------------------+
    | GLength(GeomFromText('LineString(1 1,2 2,3 3)')) |
    +--------------------------------------------------+
    |                                  2.8284271247462 |
    +--------------------------------------------------+
    

  • IsClosed(ls)

    LineStringls が閉じている(StartPoint() 値と EndPoint() 値が一致する)場合、1 を返す。 ls が閉じてなければ 0、NULL であれば ?1 を返す。

    mysql> SELECT IsClosed(GeomFromText('LineString(1 1,2 2,3 3)'));
    +---------------------------------------------------+
    | IsClosed(GeomFromText('LineString(1 1,2 2,3 3)')) |
    +---------------------------------------------------+
    |                                                 0 |
    +---------------------------------------------------+
    

  • NumPoints(ls)

    LineStringls における Point 数を返す。

    mysql> SELECT NumPoints(GeomFromText('LineString(1 1,2 2,3 3)'));
    +----------------------------------------------------+
    | NumPoints(GeomFromText('LineString(1 1,2 2,3 3)')) |
    +----------------------------------------------------+
    |                                                  3 |
    +----------------------------------------------------+
    

  • PointN(ls,n)

    LineStringls における n 番目の Point を返す。 Point 番号は 1 から始まる。

    mysql> SELECT AsText(PointN(GeomFromText('LineString(1 1,2 2,3 3)'),2));
    +-----------------------------------------------------------+
    | AsText(PointN(GeomFromText('LineString(1 1,2 2,3 3)'),2)) |
    +-----------------------------------------------------------+
    | POINT(2 2)                                                |
    +-----------------------------------------------------------+
    

  • StartPoint(ls)

    LineStringls の始点となっている Point を返す。

    mysql> SELECT AsText(StartPoint(GeomFromText('LineString(1 1,2 2,3 3)')));
    +-------------------------------------------------------------+
    | AsText(StartPoint(GeomFromText('LineString(1 1,2 2,3 3)'))) |
    +-------------------------------------------------------------+
    | POINT(1 1)                                                  |
    +-------------------------------------------------------------+
    

OpenGIS 仕様では以下の関数も定義していますが、これは MySQL でまだ実装されていません。

  • IsRing(ls)

    LineStringls が閉じており(StartPoint() 値と EndPoint() 値が一致)、かつ、単純である(同じ Point を 2 回以上通過しない)場合、1 を返す。 ls が Ring でなければ 0、NULL であれば ?1 を返す。

10.5.2.4. MultiLineString プロパティ分析関数

  • GLength(mls)

    MultiLineStringmls の長さを倍精度の数値として返す。mls の長さは、要素の長さを合計した値と一致する。

    mysql> SELECT GLength(GeomFromText('MultiLineString((1 1,2 2,3 3),(4 4,5 5))'));
    +-------------------------------------------------------------------+
    | GLength(GeomFromText('MultiLineString((1 1,2 2,3 3),(4 4,5 5))')) |
    +-------------------------------------------------------------------+
    |                                                   4.2426406871193 |
    +-------------------------------------------------------------------+
    

  • IsClosed(mls)

    MultiLineStringmls が閉じている(mls で各 LineString に対する StartPoint() 値と EndPoint() 値が一致する)場合、1 を返す。 mls が閉じていなければ 0、NULL であれば ?1 を返す。

    mysql> SELECT IsClosed(GeomFromText('MultiLineString((1 1,2 2,3 3),(4 4,5 5))'));
    +--------------------------------------------------------------------+
    | IsClosed(GeomFromText('MultiLineString((1 1,2 2,3 3),(4 4,5 5))')) |
    +--------------------------------------------------------------------+
    |                                                                  0 |
    +--------------------------------------------------------------------+
    

10.5.2.5. Polygon プロパティ分析関数

  • Area(poly)

    空間参照系での測定に基づいて、Polygonpoly の領域を倍精度の数値として返す。

    mysql> SELECT Area(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'));
    +----------------------------------------------------------------------------+
    | Area(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))')) |
    +----------------------------------------------------------------------------+
    |                                                                          8 |
    +----------------------------------------------------------------------------+
    

  • NumInteriorRings(poly)

    Polygonpoly における内部 Ring 数を返す。

    mysql> SELECT NumInteriorRings(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'));
    +----------------------------------------------------------------------------------------+
    | NumInteriorRings(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))')) |
    +----------------------------------------------------------------------------------------+
    |                                                                                      1 |
    +----------------------------------------------------------------------------------------+
    

  • ExteriorRing(poly)

    Polygonpoly の外部 Ring を LineString として返す。

    mysql> SELECT AsText(ExteriorRing(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))')));
    +--------------------------------------------------------------------------------------------+
    | AsText(ExteriorRing(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'))) |
    +--------------------------------------------------------------------------------------------+
    | LINESTRING(0 0,0 3,3 3,3 0,0 0)                                                            |
    +--------------------------------------------------------------------------------------------+
    

  • InteriorRingN(poly,n)

    Polygonpolyn 番目の内部 Ring を LineString として返す。 Ring 番号は 1 から始まる。

    mysql> SELECT AsText(InteriorRingN(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'),1));
    +-----------------------------------------------------------------------------------------------+
    | AsText(InteriorRingN(GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1))'),1)) |
    +-----------------------------------------------------------------------------------------------+
    | LINESTRING(1 1,1 2,2 2,2 1,1 1)                                                               |
    +-----------------------------------------------------------------------------------------------+
    

OpenGIS 仕様では以下の関数も定義していますが、これらは MySQL でまだ実装されていません。

  • Centroid(poly)

    Polygonpoly の数学的な重心を Point として返す。結果が Polygon 上に存在することは保証されない。

  • PointOnSurface(poly)

    Polygonpoly に存在することが保証される Point 値を返す。

10.5.2.6. MultiPolygon プロパティ分析関数

  • Area(mpoly)

    空間参照系での測定に基づいて、MultiPolygonmpoly の領域を倍精度の数値として返す。

    mysql> SELECT Area(GeomFromText('MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))'));
    +-----------------------------------------------------------------------------------+
    | Area(GeomFromText('MultiPolygon(((0 0,0 3,3 3,3 0,0 0),(1 1,1 2,2 2,2 1,1 1)))')) |
    +-----------------------------------------------------------------------------------+
    |                                                                                 8 |
    +-----------------------------------------------------------------------------------+
    

OpenGIS 仕様では以下の関数も定義していますが、これらは MySQL でまだ実装されていません。

  • Centroid(mpoly)

    MultiPolygonmpoly の数学的な重心を Point として返す。結果が MultiPolygon 上に存在することは保証されない。

  • PointOnSurface(mpoly)

    MultiPolygonmpoly 上に存在することが保証される Point 値を返す。

10.5.2.7. GeometryCollection プロパティ分析関数

  • NumGeometries(gc)

    GeometryCollectiongc におけるジオメトリ数を返す。

    mysql> SELECT NumGeometries(GeomFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'));
    +------------------------------------------------------------------------------------+
    | NumGeometries(GeomFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))')) |
    +------------------------------------------------------------------------------------+
    |                                                                                  2 |
    +------------------------------------------------------------------------------------+
    

  • GeometryN(gc,n)

    GeometryCollectiongc における n 番目のジオメトリを返す。ジオメトリ番号は 1 から始まる。

    mysql> SELECT AsText(GeometryN(GeomFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'),1));
    +------------------------------------------------------------------------------------------+
    | AsText(GeometryN(GeomFromText('GeometryCollection(Point(1 1),LineString(2 2, 3 3))'),1)) |
    +------------------------------------------------------------------------------------------+
    | POINT(1 1)                                                                               |
    +------------------------------------------------------------------------------------------+
    

10.5.3. 既存ジオメトリから新規ジオメトリを作成する関数

10.5.3.1. 新規ジオメトリを作成する関数

セクション 項10.5.2. 「Geometry プロパティ分析関数」 では、既存ジオメトリから新規ジオメトリを構築する関数をいくつか取り上げました。

  • Envelope(g)

  • StartPoint(ls)

  • EndPoint(ls)

  • PointN(ls,n)

  • ExteriorRing(poly)

  • InteriorRingN(poly,n)

  • GeometryN(gc,n)

10.5.3.2. 空間情報の演算子

OpenGIS では、ジオメトリを作成できるその他の関数が数多く提案されています。これらは、空間演算子を実装するように設計されています。

そのような関数は MySQL では実装されておらず、将来のリリースで実装される予定です。

  • Intersection(g1,g2)

    ジオメトリ値 g1 および g2 の Point セット交差を表すジオメトリを返す。

  • Union(g1,g2)

    ジオメトリ値 g1 および g2 の Point セット接合を表すジオメトリを返す。

  • Difference(g1,g2)

    ジオメトリ値 g1 および g2 の Point セット差異を表すジオメトリを返す。

  • SymDifference(g1,g2)

    ジオメトリ値 g1 および g2 の Point セット対称差異を表すジオメトリを返す。

  • Buffer(g,d)

    ジオメトリ値 g からの距離が d の距離以下になっているすべての Point を表すジオメトリを返す。

  • ConvexHull(g)

    ジオメトリ値 g の凸包を表すジオメトリを返す。

10.5.4. ジオメトリオブジェクト間の空間的関係をテストするための関数

これらのセクションで説明されている関数は、2 つのジオメトリを入力パラメータとして受け取り、ジオメトリ間の質的または量的な関係を返します。

10.5.5. 最小外接矩形(MBR)における関係

ジオメトリ g1 および g2 の最小外接矩形間の関係をテストできる関数が MySQL に用意されています。 たとえば、以下の関数があります。

  • MBRContains(g1,g2)

    1 または 0 を返すことにより、g1 の最小外接矩形に g2 の最小外接矩形が含まれているかどうかを示す。

    mysql> SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
    mysql> SET @g2 = GeomFromText('Point(1 1)');
    mysql> SELECT MBRContains(@g1,@g2), MBRContains(@g2,@g1);
    ----------------------+----------------------+
    | MBRContains(@g1,@g2) | MBRContains(@g2,@g1) |
    +----------------------+----------------------+
    |                    1 |                    0 |
    +----------------------+----------------------+
    

  • MBRWithin(g1,g2)

    1 または 0 を返すことにより、g1 の最小外接矩形が g2 の最小外接矩形に含まれているかどうかを示す。

    mysql> SET @g1 = GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))');
    mysql> SET @g2 = GeomFromText('Polygon((0 0,0 5,5 5,5 0,0 0))');
    mysql> SELECT MBRWithin(@g1,@g2), MBRWithin(@g2,@g1);
    +--------------------+--------------------+
    | MBRWithin(@g1,@g2) | MBRWithin(@g2,@g1) |
    +--------------------+--------------------+
    |                  1 |                  0 |
    +--------------------+--------------------+
    

  • MBRDisjoint(g1,g2)

    1 または 0 を返すことにより、ジオメトリ g1g2 の 2 つの最小外接矩形が分離している(交差していない)かどうかを示す。

  • MBREquals(g1,g2)

    1 または 0 を返すことにより、ジオメトリ g1g2 の 2 つの最小外接矩形が同じかどうかを示す。

  • MBRIntersects(g1,g2)

    1 または 0 を返すことにより、ジオメトリ g1g2 の 2 つの最小外接矩形が交差しているどうかを示す。

  • MBROverlaps(g1,g2)

    1 または 0 を返すことにより、ジオメトリ g1g2 の 2 つの最小外接矩形が重なっているかどうかを示す。

  • MBRTouches(g1,g2)

    1 または 0 を返すことにより、ジオメトリ g1g2 の 2 つの最小外接矩形が接触しているどうかを示す。

10.5.6. ジオメトリ間の空間関係をテストする関数

OpenGIS 仕様では以下の関数を定義していますが、これらは MySQL でまだ実装されていません。将来のリリースで実装される予定です。 実装されると、MBR ベースのサポートのみならず、空間分析の完全なサポートが提供されます。

これらの関数は、2 つのジオメトリ値 g1 および g2 で動作します。

  • Contains(g1,g2)

    1 または 0 を返すことにより、g1g2 が完全に含まれているかどうかを示す。

  • Crosses(g1,g2)

    g1g2 と空間的にクロスする場合、1 を返す。 g1Polygon または MultiPolygon であるか、あるいは g2Point または MultiPoint である場合、NULL を返す。 その他の場合は 0 を返す。

    空間的にクロスするという表現は、以下のプロパティを持つ 2 つの指定されたジオメトリの関係を示す。

    • 2 つのジオメトリは交差する。

    • 交差した部分が単一のジオメトリとなり、そのジオメトリの次元は指定された 2 つのジオメトリの最大次元よりも1 つ小さくなる。

    • 交差した部分は、指定された 2 つのジオメトリと等しくない。

  • Disjoint(g1,g2)

    1 または 0 を返すことにより、g1g2 が空間的に分離している(交差しない)かどうかを示す。

  • Equals(g1,g2)

    1 または 0 を返すことにより、g1g2 が空間的に等しいかどうかを示す。

  • Intersects(g1,g2)

    1 または 0 を返すことにより、g1g2 が空間的に交差するどうかを示す。

  • Overlaps(g1,g2)

    1 または 0 を返すことにより、g1g2 が空間的に重なるかどうかを示す。 空間的に重なるという用語が使用されるのは、2 つのジオメトリの交差部分が単一のジオメトリになり、そのジオメトリは指定された 2 つのジオメトリと次元が一致するが、どちらのジオメトリとも等しくない場合である。

  • Touches(g1,g2)

    1 または 0 を返すことにより、g1g2 が空間的に接触するどうかを示す。2 つのジオメトリが空間的に接触するのは、ジオメトリ内部は交差しないが、一方のジオメトリの境界が他方のジオメトリの境界または内部と交差する場合である。

  • Within(g1,g2)

    1 または 0 を返すことにより、g1g2 に空間的に含まれているかどうかを示す。

  • Distance(g1,g2)

    2 つのジオメトリにおける任意の 2 Point の最短距離を倍精度の数値として返す。

  • Related(g1,g2,pattern_matrix)

    1 または 0 を返すことにより、pattern_matrix によって指定された空間関係が g1g2 の間に存在するかどうかを示す。 引数が NULL である場合は ?1 を返す。 パターン行列は文字列である。パターン行列については、この関数が実装された時点でここに記載する。

10.6. 空間分析の最適化

すでに知られていることですが、非空間データベースでの検索操作はインデックスを使用して最適化できます。このことは、空間データベースについても当てはまります。 さまざまな多次元インデックス作成方法が考案されており、それらを活用すれば空間検索を最適化することができます。代表的な例を以下に示します。

  • 指定されたポイントが含まれているオブジェクトをすべて検索するポイントクエリ。

  • 指定された領域が含まれているオブジェクトをすべて検索する領域クエリ。

MySQL では、二次分割アルゴリズムを利用した R-Tree を使用して空間カラムにインデックスを付けます。空間インデックスは、ジオメトリの MBR を使用して作成されます。 多くのジオメトリに対しては、MBR はジオメトリを囲む最小矩形です。水平または垂直な LineString に対しては、MBR は LineString に縮退した矩形です。 Point に対しては、MBR は Point に縮退した矩形です。

10.6.1. 空間インデックスの作成

MySQL では空間インデックスを作成できます。作成時に使用する構文は、通常のインデックスを作成するための構文に似ていますが、SPATIAL キーワードで拡張されています。 現在インデックス付けされている空間カラムは、NOT NULL と宣言されなければなりません。空間インデックスを作成する方法を以下の例に示します。

  • CREATE TABLE を使用する場合。

    mysql> CREATE TABLE geom (g GEOMETRY NOT NULL, SPATIAL INDEX(g));
    
  • ALTER TABLE を使用する場合。

    mysql> ALTER TABLE geom ADD SPATIAL INDEX(g);
    
  • CREATE INDEX を使用する場合。

    mysql> CREATE SPATIAL INDEX sp_index ON geom (g);
    

空間インデックスを破棄するには、ALTER TABLE または DROP INDEX を使用します。

  • ALTER TABLE を使用する場合。

    mysql> ALTER TABLE geom DROP INDEX g;
    
  • DROP INDEX を使用する場合。

    mysql> DROP INDEX sp_index ON geom;
    

例: テーブル geom に 32,000 個を超えるジオメトリが格納されており、これらが GEOMETRY 型の g で保存されているとします。 このテーブルには AUTO_INCREMENT カラム fid もあり、このカラムにオブジェクト ID 値が保存されます。

mysql> SHOW FIELDS FROM geom;
+-------+----------+------+-----+---------+----------------+
| Field | Type     | Null | Key | Default | Extra          |
+-------+----------+------+-----+---------+----------------+
| fid   | int(11)  |      | PRI | NULL    | auto_increment |
| g     | geometry |      |     |         |                |
+-------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

mysql> SELECT COUNT(*) FROM geom;
+----------+
| count(*) |
+----------+
|    32376 |
+----------+
1 row in set (0.00 sec)

カラム g で空間インデックスを追加するには、以下のステートメントを使用します。

mysql> ALTER TABLE geom ADD SPATIAL INDEX(g);
Query OK, 32376 rows affected (4.05 sec)
Records: 32376  Duplicates: 0  Warnings: 0

10.6.2. 空間インデックスの使用

MBRContains()MBRWithin() などの関数を WHERE 句で使用するクエリの検索で空間インデックスを使用できるかどうかが、オプティマイザによって確認されます。 たとえば、指定された矩形に含まれているオブジェクトをすべて検索する必要があるとします。

mysql> SELECT fid,AsText(g) FROM geom WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-----+-----------------------------------------------------------------------------+
| fid | AsText(g)                                                                   |
+-----+-----------------------------------------------------------------------------+
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8)     |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4)     |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2)     |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823)     |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2)     |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2)   |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121)     |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113)           |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6)       |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2)   |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077)         |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4)   |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019)     |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8)   |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8)       |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134)         |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4)       |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001)     |
+-----+-----------------------------------------------------------------------------+
20 rows in set (0.00 sec)

このクエリがどのように実行されるかを、EXPLAIN を使用して確認します。

mysql> EXPLAIN SELECT fid,AsText(g) FROM geom WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
| id | select_type | table | type  | possible_keys | key  | key_len | ref  | rows | Extra       |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
|  1 | SIMPLE      | geom  | range | g             | g    |      32 | NULL |   50 | Using where |
+----+-------------+-------+-------+---------------+------+---------+------+------+-------------+
1 row in set (0.00 sec)

空間インデックスがないとどうなるかを確認します。

mysql> EXPLAIN SELECT fid,AsText(g) FROM g IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
| id | select_type | table | type | possible_keys | key  | key_len | ref  | rows  | Extra       |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
|  1 | SIMPLE      | geom  | ALL  | NULL          | NULL |    NULL | NULL | 32376 | Using where |
+----+-------------+-------+------+---------------+------+---------+------+-------+-------------+
1 row in set (0.00 sec)

上記のクエリを実行し、使用可能な空間キーを無視します。

mysql> SELECT fid,AsText(g) FROM geom IGNORE INDEX (g) WHERE
mysql> MBRContains(GeomFromText('Polygon((30000 15000,31000 15000,31000 16000,30000 16000,30000 15000))'),g);
+-----+-----------------------------------------------------------------------------+
| fid | AsText(g)                                                                   |
+-----+-----------------------------------------------------------------------------+
|   1 | LINESTRING(30250.4 15129.2,30248.8 15138.4,30238.2 15136.4,30240 15127.2)   |
|   2 | LINESTRING(30220.2 15122.8,30217.2 15137.8,30207.6 15136,30210.4 15121)     |
|   3 | LINESTRING(30179 15114.4,30176.6 15129.4,30167 15128,30169 15113)           |
|   4 | LINESTRING(30155.2 15121.4,30140.4 15118.6,30142 15109,30157 15111.6)       |
|   5 | LINESTRING(30192.4 15085,30177.6 15082.2,30179.2 15072.4,30194.2 15075.2)   |
|   6 | LINESTRING(30244 15087,30229 15086.2,30229.4 15076.4,30244.6 15077)         |
|   7 | LINESTRING(30200.6 15059.4,30185.6 15058.6,30186 15048.8,30201.2 15049.4)   |
|  10 | LINESTRING(30179.6 15017.8,30181 15002.8,30190.8 15003.6,30189.6 15019)     |
|  11 | LINESTRING(30154.2 15000.4,30168.6 15004.8,30166 15014.2,30151.2 15009.8)   |
|  13 | LINESTRING(30105 15065.8,30108.4 15050.8,30118 15053,30114.6 15067.8)       |
|  21 | LINESTRING(30350.4 15828.8,30350.6 15845,30333.8 15845,30333.8 15828.8)     |
|  22 | LINESTRING(30350.6 15871.4,30350.6 15887.8,30334 15887.8,30334 15871.4)     |
|  23 | LINESTRING(30350.6 15914.2,30350.6 15930.4,30334 15930.4,30334 15914.2)     |
|  24 | LINESTRING(30290.2 15823,30290.2 15839.4,30273.4 15839.4,30273.4 15823)     |
|  25 | LINESTRING(30291.4 15866.2,30291.6 15882.4,30274.8 15882.4,30274.8 15866.2) |
|  26 | LINESTRING(30291.6 15918.2,30291.6 15934.4,30275 15934.4,30275 15918.2)     |
| 154 | LINESTRING(30276.2 15143.8,30261.4 15141,30263 15131.4,30278 15134)         |
| 155 | LINESTRING(30269.8 15084,30269.4 15093.4,30258.6 15093,30259 15083.4)       |
| 157 | LINESTRING(30128.2 15011,30113.2 15010.2,30113.6 15000.4,30128.8 15001)     |
| 249 | LINESTRING(30337.8 15938.6,30337.8 15946.8,30320.4 15946.8,30320.4 15938.4) |
+-----+-----------------------------------------------------------------------------+
20 rows in set (0.46 sec)

空間インデックスを使用しないと、このクエリの実行時間は 0.00 秒から 0.46 秒に増大します。

将来のリリースでは、空間インデックスを使用して他の関数も最適化されるようになります。 See 項10.5.4. 「ジオメトリオブジェクト間の空間的関係をテストするための関数」

10.7. MySQL の適合性と互換性

10.7.1. まだ実装されていない GIS 機能

  • 追加のメタデータビュー

    OpenGIS 仕様には、追加のメタデータビューがいくつか提案されている。 たとえば、システムビュー GEOMETRY_COLUMNS にはジオメトリカラムの説明があり、1 行がデータベース内の各ジオメトリカラムに対応している。

  • 空間情報カラムを追加/破棄するための関数

    OpenGIS では、特別な関数 AddGeometryColumn()DropGeometryColumn() を使用してカラムを追加または破棄できることになっている。MySQL では、カラムを追加または破棄するために ALTER TABLECREATE INDEXDROP INDEX ステートメントを代用する。

  • 空間参照系とその ID(SRID)関連

    • Length()Area() などの関数は平面座標系に対応している。

    • すべてのオブジェクトは現在、同じ平面座標系にあるものと考えられている。

  • LineString および MultiLineString 上の OpenGIS 関数 Length() は現在、MySQL では GLength() として呼び出されなければならない。

    この関数と既存の SQL 関数 Length()(文字列値を計算)が競合するのが問題であり、この関数が文字コンテキストと空間コンテキストのどちらで呼び出されたのか区別できないことがある。何らかの方法でこの問題を解決するか、別の関数名を決定する必要がある。


This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.

アダルトレンタルサーバー