GRASS シェルスクリプト小技集

GRASSの使い方の一つとして、シェルスクリプトでコマンドを組み合わせて自動的に処理を行うという使い方があるかと思います。
その際の小技を集めてみました。


ベクタレイヤーのフィールドの有無と型を調べるには

スクリプトで使用対象となるベクタレイヤーに指定したフィールドがあるかどうか、なおかつそれが指定した型かどうかを調べるには以下のようにします。

# 「class」というフィールドを検索
FIELD=`db.describe -c table="vector_layer" | grep -Gi "class"`
if [ -z $FIELD ]; then
  # 見つからなかった場合のエラー処理
fi

# 整数型かどうかを調べる
if [ -z `echo $FIELD | grep -Gi "integer"` ]; then
  # 整数型ではなかった場合のエラー処理
fi

r.patchで多くの画像を一括合成するには

プレフィックスが同じ画像を一括して合成したい場合は以下のようにします。

r.patch --o input=`g.mlist type=rast pattern="パターン" separator=comma` output="出力レイヤー名"

パターンには「img_*」のようにメタキャラクタを指定します。


GRASSにログインしているかどうかを調べるには

当然ながらGRASSのコマンドはGRASS環境下でないと使えません。
GRASSにログインしているかどうかを調べるには以下のようにします。

if [ -z "$GISBASE" ] ; then
    echo "ERROR: You must be in GRASS GIS to run this program." 1>&2
    exit 1
fi

GRASS的にエラーメッセージを表示するには

シェルスクリプトでメッセージを表示するにはechoprintを使いますが、
GRASSにはg.messageというコマンドがあり、これを使うとそれっぽいです。
エラーメッセージを出力するには以下のようにします。

g.message -e "メッセージ"

-eオプションを付けると出力に「ERROR:」文字が付加されます。
スクリプトを終了するわけではないので、エラー時にスクリプトを終了したい場合はexit 1を記述する必要があります。


レイヤーを一括消去するには

複数のレイヤーをワイルドカード等を指定して一括消去するにはg.mremoveコマンドを使用します。

g.mremove -f rast="パターン"

パターンにはg.mlistコマンドと同様に「img_*」のようにメタキャラクタを指定します。
-fオプションを付けないと実際には消去されずに、消去されうるレイヤーのリストが出力されます。
不安な場合は一度-fオプションを付けずに実行して確認するとよいでしょう。


レイヤーの有無を調べるには

スクリプトを実装する場合は処理対象となるレイヤーがあるかどうかを調べる場面が多いと思われます。
その場合は以下のようにします。

eval `g.findfile element=vector file=レイヤー名`
if [ -z $file ]; then
  存在しない場合の処理
fi

g.findfileコマンドはfileパラメータで与えたレイヤーの情報を以下のように出力します。

name='test'
mapset='test'
fullname='test@test'
file='C:UsersyamateDocumentsGIS_DataBase/JGD09/test/vector/test'

evalコマンドによってこの出力結果をコマンドとして評価するため、環境変数$fileに文字列が入っていればレイヤーが存在するということになります。

なお、ラスタレイヤーの有無を調べる場合はelementパラメータにはCELLを指定します。


ベクタレイヤーの種別を調べるには

GRASSのベクタレイヤーは複数の種別の要素を持つことができるので種別を調べるコマンドというものはありません。
しかし、例えばShapeファイルをインポートした直後のレイヤーであれば種別があるはずです。
そこでそのような場合はv.info -tコマンドで種別を調べることができます。

v.info -tコマンドはレイヤーある要素の数を種別ごとに出力します。

出力例
nodes=17237
points=0
lines=0
boundaries=16587
centroids=6141
areas=6141
islands=650
faces=0
kernels=0
primitives=22728
map3d=0

evalコマンドで各値が環境変数として記録されるので、種別を調べるときには以下のようにして要素数を手がかりにします。

eval `v.info -t map=対象レイヤー`
if [ $areas -ne 0 ]; then
	echo "layer is POLYGON."
elif [ $lines -ne 0 ]; then
	echo "layer is LINESTRING."
else
	echo "layer is POINT."
fi

ラスタレイヤーに指定したカテゴリがあるかどうかを調べるには

主題図ラスタレイヤーに指定したカテゴリのセルがあるかどうかを調べる方法はいくつかありますが、以下のようにすると一応できます(少々回りくどい気がしますが、、)。

if [ -z `r.describe -1 -n map=レイヤー名 2>/dev/null | grep -w カテゴリの数値` ]; then
  存在しない場合の処理
fi

続く、、

アーカイブ