OceanBaseデータベースは、クエリ内の幾何オブジェクトを表すために2種類の標準的な空間データ形式をサポートしています。
Well-Known Text Format(WKT)
Well-Known Binary Format(WKB)
WKT
WKTは、EBNF(Extended Backus-Naur Form)に基づいて定義されています。WKTはデータ形式として使用することもできます(本記事ではWKT-Dataと呼びます)、またGISにおいてSRSの定義にも使用されます(本記事ではWKT-SRSと略称します)。
Point
Pointはカンマで区切りません。フォーマット例は以下のとおりです:
POINT(15 20)
次の例では、ST_X()関数を使用してPointオブジェクトからX座標を抽出します。最初の例では、Point()関数を直接使用してオブジェクトを生成します。2番目の例では、ST_GeomFromText()関数を使用してWKT表現をPointに変換します。
obclient> SELECT ST_X(Point(15, 20));
+---------------------+
| ST_X(Point(15, 20)) |
+---------------------+
| 15 |
+---------------------+
1 row in set
obclient> SELECT ST_X(ST_GeomFromText('POINT(15 20)'));
+---------------------------------------+
| ST_X(ST_GeomFromText('POINT(15 20)')) |
+---------------------------------------+
| 15 |
+---------------------------------------+
1 row in set
Line
Lineは複数の点で構成され、点と点の間はカンマで区切られます。フォーマット例は以下のとおりです:
LINESTRING(0 0, 10 10, 20 25, 50 60)
Polygon
Polygonは、少なくとも1つの外部リング(閉じた線)と複数の内部リング(閉じた線、0個でも可)で構成されます。フォーマット例は以下のとおりです:
POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
MultiPoint
MultiPointは複数の点で構成され、線と似ていますが、意味は異なります。複数の点が接続されて線を形成し、複数の点が離散的に配置されるとMultiPointになります。フォーマット例は以下のとおりです:
MULTIPOINT(0 0, 20 20, 60 60)
関数ST_MPointFromText()およびST_GeoFromText()では、MultiPoint内の点を括弧で囲むことも可能です。フォーマット例は以下のとおりです:
ST_MPointFromText('MULTIPOINT (1 1, 2 2, 3 3)')
ST_MPointFromText('MULTIPOINT ((1 1), (2 2), (3 3))')
MultiLineString
MultiLineStringは複数の線の集合です。フォーマット例は以下のとおりです:
MULTILINESTRING((10 10, 20 20), (15 15, 30 15))
MultiPolygon
MultiPolygonは複数のポリゴンの集合です。フォーマット例は以下のとおりです:
MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0)),((5 5,7 5,7 7,5 7, 5 5)))
GeometryCollection
GeometryCollectionは、さまざまな基本型および集合型の集合である可能性があります。
GEOMETRYCOLLECTION(POINT(10 10), POINT(30 30), LINESTRING(15 15, 20 20))
WKB
WKBはOpenGIS規格に基づいて開発されており、7種類のタイプ(Point、Linestring、Polygon、Multipoint、Multilinestring、Multipolygon、Geometrycollection)とそれぞれの形式定義をサポートしています。
Point
POINT(1 -1) を例にとると、フォーマットの定義は以下の表のとおりです。
| コンポーネント名 | 仕様 | タイプ | 値 |
|---|---|---|---|
| Byte order | 1バイト | unsigned int | 01 |
| WKB type | 4バイト | unsigned int | 01000000 |
| X coordinate | 8バイト | double-precision | 000000000000F03F |
| Y coordinate | 8バイト | double-precision | 000000000000F0BF |
Linestring
LINESTRING(1 -1, -1 1) を例にとると、フォーマットの定義は以下の表のとおりです。Num points は2以上である必要があります。
| コンポーネント名 | 仕様 | タイプ | 値 |
|---|---|---|---|
| Byte order | 1バイト | unsigned int | 01 |
| WKB type | 4バイト | unsigned int | 02000000 |
| Num points | 4バイト | unsigned int | 02000000 |
| X coordinate | 8バイト | double-precision | 000000000000F03F |
| Y coordinate | 8バイト | double-precision | 000000000000F0BF |
| X coordinate | 8バイト | double-precision | 000000000000F0BF |
| Y coordinate | 8バイト | double-precision | 000000000000F03F |
Polygon
| コンポーネント名 | 仕様 | タイプ | 値 |
|---|---|---|---|
| Byte order | 1バイト | unsigned int | 01 |
| WKB type | 4バイト | unsigned int | 03000000 |
| Num rings | 4バイト | unsigned int | 1以上 |
| repeat ring | - | - | - |
MultiPoint
| コンポーネント名 | 仕様 | タイプ | 値 |
|---|---|---|---|
| Byte order | 1バイト | unsigned int | 01 |
| WKB type | 4バイト | unsigned int | 04000000 |
| Num points | 4バイト | unsigned int | Num pointsは1以上である必要があります。 |
| repeat POINT | - | - | - |
MultilineString
| コンポーネント名 | 仕様 | タイプ | 値 |
|---|---|---|---|
| Byte order | 1バイト | unsigned int | 01 |
| WKB type | 4バイト | unsigned int | 05000000 |
| Num linestrings | 4バイト | unsigned int | 1以上 |
| repeat LINESTRING | - | - | - |
MultiPolygon
| コンポーネント名 | 仕様 | タイプ | 値 |
|---|---|---|---|
| Byte order | 1バイト | unsigned int | 01 |
| WKB type | 4バイト | unsigned int | 06000000 |
| Num polygons | 4バイト | unsigned int | 1以上 |
| repeat POLYGON | - | - | - |
GeometryCollection
| コンポーネント名 | 仕様 | タイプ | 値 |
|---|---|---|---|
| Byte order | 1バイト | unsigned int | 01 |
| WKB type | 4バイト | unsigned int | 07000000 |
| Num wkbs | 4バイト | unsigned int | - |
| repeat WKB | - | - | - |
説明:
- GeometryCollectionのみが空であることが許され、これは0個の要素が格納されていることを意味します。他の型は空にすることができません。
LENGTH()関数がGISオブジェクトに適用される場合、返されるのは格納されているバイナリデータの長さです。
obclient [test]> SET @g = ST_GeomFromText('POINT(1 -1)');
Query OK, 0 rows affected
obclient [test]> SELECT LENGTH(@g);
+------------+
| LENGTH(@g) |
+------------+
| 25 |
+------------+
1 row in set
obclient [test]> SELECT HEX(@g);
+----------------------------------------------------+
| HEX(@g) |
+----------------------------------------------------+
| 000000000101000000000000000000F03F000000000000F0BF |
+----------------------------------------------------+
1 row in set
構文と幾何学的正当性
構文の正当性
構文が正当であるためには、以下の条件を満たす必要があります:
- Linestringは少なくとも2つの点を含む必要があります。
- Polygonは少なくとも1つの輪郭を含む必要があります。
- Polygonは閉じた形状である必要があります(先頭の2つの点は同じである)。
- Polygonの輪郭は少なくとも4つの点を含む必要があります(最小の多角形は三角形であり、最初の点と最後の点は同じである)。
- GeometryCollection以外の集合型は空ではない必要があります。
幾何学的正当性
幾何学的に正当であるためには、以下の条件を満たす必要があります:
- Polygonは自分自身と交差してはなりません。
- Polygonの外側の輪郭は内側の輪郭より外側にある必要があります。
- Multipolygonsには重複する多角形が存在してはなりません。
ST_IsValid()関数を使用すると、幾何オブジェクトの幾何学的正当性を明示的にチェックできます。
GISの例
挿入例
//変換関数とWKTはSQL文内に記述する
INSERT INTO geom VALUES (ST_GeomFromText('POINT(1 1)'));
//WKTをパラメータに指定する
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (ST_GeomFromText(@g));
//変換式を直接パラメータに指定する
SET @g = ST_GeomFromText('POINT(1 1)');
INSERT INTO geom VALUES (@g);
//統一された変換関数を使用する
SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (ST_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 (ST_GeomFromText(@g));
SET @g ='GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (ST_GeomFromText(@g));
//型に基づく変換関数を使用する
SET @g = 'POINT(1 1)';
INSERT INTO geom VALUES (ST_PointFromText(@g));
SET @g = 'LINESTRING(0 0,1 1,2 2)';
INSERT INTO geom VALUES (ST_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 (ST_PolygonFromText(@g));
SET @g =
'GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))';
INSERT INTO geom VALUES (ST_GeomCollFromText(@g));
//WKBに基づいて直接挿入することもできる
INSERT INTO geom VALUES(ST_GeomFromWKB(X'0101000000000000000000F03F000000000000F03F'));
クエリ例
//クエリしてWKTに変換して出力する
SELECT ST_AsText(g) FROM geom;
//クエリしてWKBに変換して出力する
SELECT ST_AsBinary(g) FROM geom;