2010年7月17日土曜日

Spatialiteのデータ保存形式

Spatialiteという、SQLiteをベースに
拡張したOpenGISベースの便利なDBシステムがあります。

SQLiteなのでお手軽!とおもいきや
SQLを直たたきで位置情報を取ったりすることはできなくて
PostGIS同様関数でgeometry情報を格納しています。

spatialiteの持つテーブルは

CREATE TABLE spatial_ref_sys (
srid INTEGER NOT NULL PRIMARY KEY,
auth_name VARCHAR(256) NOT NULL,
auth_srid INTEGER NOT NULL,
ref_sys_name VARCHAR(256),
proj4text VARCHAR(2048) NOT NULL
)
CREATE TABLE geometry_columns (
f_table_name VARCHAR(256) NOT NULL,
f_geometry_column VARCHAR(256) NOT NULL,
type VARCHAR(30) NOT NULL,
coord_dimension INTEGER NOT NULL,
srid INTEGER,
spatial_index_enabled INTEGER NOT NULL
)

の二つで、地物をを地図に追加すると
地図のtableにalter tableで追加、、、ってそういう使い方ですか。

試しにspatialiteのページから
テストDBをDLして中をのぞいてみる。

sqlite> .tables
HighWays Towns geometry_columns
Regions geom_cols_ref_sys spatial_ref_sys

geometry_columns、spatial_ref_sysは
spatialiteがinitするときに作成しています。

geom_cols_ref_sysはVIEWなので割愛します。

これにHighWaysとTownsとRegionsの三つのデータが入っている感じなのですが
この中身は
INSERT INTO "Towns" VALUES(4847,'Druento',8235,1,0,0,X'0001787F000048E17A14BCAF17413D0AD733BE11534148E17A14BCAF17413D0AD733BE1153417C0100000048E17A14BCAF17413D0AD733BE115341FE');


こんな感じになっていて読めません。
スキーマではTownsは
CREATE TABLE Towns (
PK_UID INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT,
Peoples INTEGER,
LocalCounc INTEGER,
County INTEGER,
Region INTEGER,
"Geometry" POINT
);

という構造です。
POINTはspatilaiteの持つ形式で
0 - 7   X coordinate   a double value corresponding to the X coordinate for this POINT
8 - 15 Y coordinate a double value corresponding to the Y coordinate for this POINT

という構造のBLOBをALTERTABLEで追加しています。

もうすこし言うと、
TownsというのはPOINT構造体の配列をBLOBに格納した物で、
DBの機能や最適化はガン無視しています。

私もどちらかというと力技でプログラムを書いてきた方なので
言いたいことは痛いほどわかります。
たとえばLineのデータを持つときに
一点一点ポイントを

CREATE TABLE point(
point_id integer NOT NULL,
line_id integer,
x integer,
y integer
);

CREATE TABLE linestring(
line_id integer NOT NULL,
number_of_points integer
);


などとするよりも、
(簡便のためlinestring以外のケースなどは省略しています)
データをバイナリで持って、処理する側で解析も変更もやったほうが
便利なこともあるでしょう。
まとまったデータでのパフォーマンスも制御しやすくなります。

そしてこの、バイナリを数値やテキストとして扱えるようにした
OpenGISのインターフェースがついたのがspatialiteです。

地図DBの内容を使うだけの立場を取る限りは
内部構造がどうであろうと自分が望む形式で取り出せればそれで問題ないでしょう。
しかしさしあたって、
DBはDBでものすごいがんばって最適化やら効率化をいろいろしてるのに
BLOBだと殆どのDBではそういう恩恵が受けられないこと、
データ部分だけ交換ができないこと
がもったいないと思う点でしょうか。
何より、一般的なDBでの開発経験はほぼまったく生かせません。
もったいない。。

せっかく叩く側のI/Fがきちんと決まってるので
データベースとモデル化をちゃんと分離したら
システムの可搬性もスケーラビリティも選択の余地も
ぐっとあがると思うのですが、何故この状態なのか、実はそうでもないのか
もうすこし探ってみる必要がありそうです。

0 件のコメント:

コメントを投稿