2015/04/01

R ポータブル版の準備と PostgreSQL への接続(2)

[R][PostgreSQL][PostGIS]
昨日セットアップした R ポータブル版を使い、同じくポータブル版の PostgreSQL / PostGIS サーバに接続するテストです。後者のセットアップは 2015/03/28 の記事を参照。実行環境はWindows 7 32bit のゲストユーザで、ポータブルアプリを入れた外部ディスクのみ使っています。

↓ R を起動し PostgreSQL に接続するためのパッケージ RPostgreSQL を追加します。


↓ パッケージ追加は普通にコマンド一行で完了。installed.packages() では次の起動時まで表示されません(環境変数が足りないかも)。一方 packageDescription() では確認できました。ロードすると R 本体が最新でないため警告が出ますが、今回のテストでは特に問題なし。

install.packages('RPostgreSQL')
rownames(installed.packages()) # 次の R 起動時にパッケージ表示
packageDescription('RPostgreSQL') # インストール直後でも表示
library(RPostgreSQL) # パッケージ呼び出し





↓ 次に(最初でもいいですが)ポータブル版 PostgreSQL 9.4 を起動します。コマンドプロンプトの psql は今回は使いません。



↓ パラメータを適宜入力して PostgreSQL へ接続し、エラーが出なければ成功です。ここでは 2015/03/28 の記事で作成した PostGIS データベースを指定。
con = dbConnect(PostgreSQL()
, host = 'localhost'
, port = 5432
, dbname = 'test_postgis215'
, user = 'postgres'
, password = *********
)


↓ クエリを発行すると、結果がデータフレームになります。
dbGetQuery(con, "
SELECT * FROM pg_tables WHERE schemaname = 'public'
")


これで接続テスト完了。インストール版と同様にあっけなく終わってしまったので、ついでに PostGIS ラスタで画像を作り R で受け取るテストをしました。昨年書いた記事(2014/11/04 : Base64 形式を経由して PostGIS ラスタ → R)と似ていますが、今回は地理データではなく幾何的な簡単な模様で、ローカルの PNG に保存する所まで。準備としてパッケージ base64 を追加します。

install.packages('base64')
library(base64)


PostGIS 2.2 日本語マニュアル : ST_AsRaster に、簡単な図形をジオメトリで作成 → ラスタに変換して色付け → PNG に出力するサンプルコードがあります。その応用で、ネギま!? 1000%BOX パッケージの模様にしました。前に R 単独で行ったもの(2015/03/11) の PostGIS 版。



↓ こんなクエリを R の文字列変数に入れます。クエリ内に二重引用符がなければ、クエリ全体を " で囲んでヒアドキュメント風に(改行やタブを自由に入れて)書けます。
sql = "
WITH a (stdnum, color) AS (
-- // color -> RGB
-- // http://kenpg2.seesaa.net/article/407308561.html
VALUES ('{0, 8, 13, 15}' :: int[], '#FF4500') -- // orangered
, ('{1, 3, 19, 30}' , '#FF69B4') -- // hotpink
, ('{2, 5, 6, 9}' , '#FFD700') -- // gold
, ('{4, 14, 27}' , '#228B22') -- // forestgreen
, ('{7, 11, 17}' , '#20B2AA') -- // lightseaGreen
, ('{10, 24, 26}' , '#708090') -- // slategray
, ('{12, 16, 29}' , '#9ACD32') -- // yellowgreen
, ('{18, 21, 25, 28, 31}' , '#9370DB') -- // mediumpurple
, ('{20, 22, 23}' , '#FF8C00') -- // darkorange
), b (stdnum, color) AS (
SELECT unnest(stdnum) + 5
, ARRAY[
concat('x', substring(color, 2, 2)) :: bit(8) :: int
, concat('x', substring(color, 4, 2)) :: bit(8) :: int
, concat('x', substring(color, 6, 2)) :: bit(8) :: int
-- // 上の三行で HEX 形式を RGB に変換
, (255 * 0.6) :: int -- // add alpha value
]
FROM a
)
SELECT encode(ST_AsPNG(ST_Union(ST_AsRaster(
ST_Buffer(ST_Point((stdnum - 1) % 6 + 1 -- // x
, 6 - floor((stdnum - 1) / 6) -- // y
), 0.45), 45, 45 -- // radius and pixel
, '{8BUI, 8BUI, 8BUI, 8BUI}' :: text[]
, color
, '{0, 0, 0, 0}' :: int[]))), 'base64')
FROM b ;
"


上のクエリは、PostGIS 側で作成した PNG を Base64 形式の文字列にエンコードして返します。それを一時ファイルに書き込み、base64 パッケージでデコード(復元)すれば ↓ 元の PNG の出来上がり。二枚目の画像はクエリ結果の先頭部分です。
b64 = dbGetQuery(con, sql)[1,1]
tmp = tempfile()
write(b64, tmp)
decode(tmp, '20150401_negima_box_1.png')



↓ できた PNG です。円の部分以外は透明なので、背景を自由に付けられます。



↓ 先ほどのクエリで、色の透明度を上げ(add alpha value を 0.4)円をぴったり隣り合わせにして(radius and pixel を 0.5, 50, 50)出力したもの。


実用性を聞かれると困りますが、何もデータがなくとも PostGIS ジオメトリとして模様を作り、ラスタで色を付けて遊べる例です。
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。