SpatiaLiteでジオメトリ型のカラムを作ったり、そこへデータを入れたり取得したりする方法をすぐ忘れるので、備忘録的に書いておきます。
環境として、Windows 10(64 bit)を前提として説明します。
SpatiaLiteとは何か
SQLiteで地理空間情報を扱えるようにしたものがSpatiaLiteです。また、その拡張モジュールをmod_spatialiteと呼びます。
PostgreSQLにおけるPostGISと同じような位置づけです。
spatialite_guiの利用
Windows 10ではGUIで利用できるspatialite_guiがあるので、それを利用します。
ダウンロード
The Gaia-SINS federated projects home-pageの下の方に、Windows向けバイナリのダウンロードへのリンクがあるので、"current stable version" をクリックしましょう。
ファイル一覧が出てくるので、 "spatialite_gui-4.3.0a-win-amd64.7z" をクリックしてダウンロードします。
最新の安定バージョンの公開日が2015年9月7日...最近は活発な更新が行われていないようですね。
ダウンロードした7zファイルは、7-Zipで解凍できます。
解凍すると "spatialite_gui.exe" という1ファイルだけが出てくるので、これをダブルクリックすれば起動します。
初回は新しいDBファイルを作成します。ツールバーの左から3つ目のアイコン "Creating a New (empty) SQLite DB" をクリックします。
表示されたファイルダイアログで、適当な名前をつけてファイルを保存しましょう。
2度目からは、一番左のアイコン "Connecting an exsiting SQLite DB" で、作成済みのファイルを開けばOKです。
ジオメトリ型カラムの作成
SpatiaLiteで気をつけなければらないのは、ジオメトリ型のカラムの扱いです。
例えば、3次元のPOLYGONを格納するカラムを持つテーブルを作成したいとしましょう。PostGISでは、以下のようにCREATE TABLE
文一つで解決です。
-- PostGISではOK。SpatiaLiteではNG
CREATE TABLE polygons (
name TEXT,
geom GEOMETRY(POLYGONZ, 4326)
);
(ここで4326はSRIDで、Google MapやGoogle Earthで使われているWGS84の座標系を示す番号です)
SpatiaLiteでは、上記のような書き方はできません。
ジオメトリ型のカラムはCREATE TABLE
をしたあとに、AddGeometryColumn
という関数で追加する必要があります。
-- SpatiaLiteではこの書き方をする。
CREATE TABLE polygons (
name TEXT
);
SELECT AddGeometryColumn(
'polygons', -- カラムを追加するテーブルの名前
'geom', -- 追加するカラムの名前
4326, -- SRID
'POLYGONZ', -- ジオメトリの型を指定
'XYZ', -- ジオメトリの次元を指定
1 -- 1にするとNOT NULL制約をつける。0だとつけない
);
上記SQLを画面右上のSQL入力欄にコピペして、右端の "Execute SQL Statement" ボタンをクリックすると、SQLが実行されます。
画面右下の結果セット表示欄に "1" が表示されれば正常完了です。
画面左側のツリーの "User Data" を右クリックして "refresh" すると、polygonsテーブルが追加されています。ノードを開いて、geomカラムに地球アイコンがついていることを確認しましょう。
WKTでのジオメトリ表現
WKTはWell-known textの略で、地図上で幾何学オブジェクト(点とか直線とか多角形とか)を表現するためのマークアップ言語です(Wikipediaの記事)。
例えば、x = 0
、y = 1
の二次元の点は以下のように表せます。
POINT (0 1)
3次元だと数字の並びが一つ増えます。幾何学の型にも "Z" が付きます。
(x, y, z) = (1, 2, 3)
の点は以下のように表します。
POINT Z (1 2 3)
多角形はPOLYGON
です。2次元空間において、左下隅が原点にくる辺の長さ1の正方形は以下のように表せます。
POLYGON ((0 0, 1 0, 1 1, 0 1, 0 0))
(x, y) = (0, 0)
を始点として、反時計回りに頂点座標を順に記述します。
POLYGON
の注意点として、始点と終点(今回は原点(0 0)
)を一致させる必要があります。
最後の(0 0)
を記述しないと、 "unclosed" とみなされます。
インサート
ジオメトリ型カラムに値を挿入するときは、WKT表現のテキストをバイナリのジオメトリデータに変換する関数GeomFromText
を利用します。
GeomFromText(<WKT文字列>, <SRID>)
例えば、以下のSQLはGooGle Earthのkmlの例にあるように、ペンタゴンを囲む五角形のポリゴン(高さ30mにある)を挿入します。
-- pentagon!
INSERT INTO polygons(name, geom)
VALUES
(
'pentagon',
GeomFromText(
'POLYGON Z ((' ||
'-77.0578845766096000 38.8725325989282000 30.0000000000000000, ' ||
'-77.0546597375670000 38.8729101628170000 30.0000000000000000, ' ||
'-77.0531553685479000 38.8705326779438000 30.0000000000000000, ' ||
'-77.0555262249351000 38.8687578012560000 30.0000000000000000, ' ||
'-77.0584405629039000 38.8699620650694000 30.0000000000000000, ' ||
'-77.0578845766096000 38.8725325989282000 30.0000000000000000))', -- WKT
4326 -- SRID
)
);
取得
ジオメトリ型のカラムをそのまま指定すると、バイナリデータのまま出力されるので人間が読めません。
-- geomカラムは人間に読めない
SELECT name, geom FROM polygons;
このとき、spatialite_guiではgeomカラムの値は "BLOB sz=196 GEOMETRY" みたいな表記になります。
そこで、人間がとりあえずこの値を見たいときは、このバイナリデータをWKTに変換する関数AsText
を使います。
SELECT AsText(geom) FROM polygons;
-- 出力
-- POLYGON Z((-77.057885 38.872533 30, -77.05466 38.87291 30, -77.053155 38.870533 30, -77.055526 38.868758 30, -77.058441 38.869962 30, -77.057885 38.872533 30))
KML出力
テーブルに格納したジオメトリをkmlで出力するには、AsKml
関数を使います。
SELECT
AsKml(
name, -- name
name, -- description
geom, -- geometry
16 -- precision
) AS kml
FROM test_geom;
こうして得られたkml表現は、適当なファイルへコピーペーストして.kmlファイルとして保存すると、Google Earth Proのようなソフトに読み込んで表示させることができます。