QGIS プロセッシング Scriptsで一括処理したい その2
若干捕捉
QGIS プロセッシング Scriptsで一括処理したい その1 - waigani's diaryの続きを少々。
multiple vector
入力にfolderを指定しているのですが、本当はファイルを複数指定したいところです。
##input=multiple vector
という指定方法もあるのですが、これだとQGISに読み込み済みのレイヤしか対象に出来なかったりします。
processing.getObject()
前回の記事とは関係ないのですが、processingの仕様もバージョンによって少し変わっています。ファイル名を受け取りレイヤインスタンスを返してくれたメソッドが、以前のバージョンですと、
processing.getobject()
と書いていたところが、QGIS 2.4では
processing.getObject()
となっていたりします。ご注意ください。
複数のベクトルファイルを1つにする
QGISのメニューに【ベクタ】→【データマネジメントツール】→【複数のシェープファイルを1つに結合する】という機能があります。processingで対応するのは'qgis:mergevectorlayers'になるようです。ただしprocessingで実行すると、2つのファイルを指定して1つにする機能になっているようです。
複数のベクトルファイルを指定して1つにマージする機能が、processingのアルゴリズムの中になさそうなので、自作してみましょう。
入力は、
- 基準とするベクトルファイル指定
- マージするベクトルファイルの入っているフォルダを指定
- 出力ファイル名指定
とします。
処理の内容としては、
- 基準のベクトルファイルを出力ベクトルファイルにコピー
- 入力先フォルダから拡張子.shpのファイル名を取得
- 基準のベクトルファイルと違う図形タイプのファイルは対象外
- 基準のベクトルファイルと違う属性定義(名称と型だけ確認している)のファイルは対象外
- 対象のファイルについては、出力ベクトルファイルに図形をコピー
としています。
##[My Scripts]=group ##source=vector ##target_folder=folder ##output_file=output vector from processing.core.VectorWriter import VectorWriter from processing.core.ProcessingLog import ProcessingLog import os import glob def isSameFields(f1, f2) : if f1.count() != f2.count() : return False for i in range(0, f1.count()) : if f1.at(i).name() != f2.at(i).name() : return False if f1.at(i).type() != f2.at(i).type() : return False ProcessingLog().addToLog(ProcessingLog.LOG_INFO, "source vector file :" + source) ProcessingLog().addToLog(ProcessingLog.LOG_INFO, "target folder :" + target_folder) ProcessingLog().addToLog(ProcessingLog.LOG_INFO, "output vector file :" + output_file) sourceLayer = processing.getObject(source) provider = sourceLayer.dataProvider() writer = VectorWriter(output_file, provider.encoding(), provider.fields(), provider.geometryType(), sourceLayer.crs()) features = sourceLayer.getFeatures() for feature in features: writer.addFeature(feature) files = glob.glob(os.path.join(target_folder, r'*.shp')) for file in files: if os.path.normpath(file) == os.path.normpath(sourceLayer.source()) : continue layer = processing.getObject(file) if provider.geometryType () != layer.dataProvider().geometryType () : ProcessingLog().addToLog(ProcessingLog.LOG_INFO, "different geometry type :" + file) continue if isSameFields(provider.fields(), layer.dataProvider().fields()) : ProcessingLog().addToLog(ProcessingLog.LOG_INFO, "different fields :" + file) continue features = layer.getFeatures() for feature in features: writer.addFeature(feature) del writer
適当な名前にして、
ユーザのホームディレクトリ\.qgis2\processing\scripts
に置いておきます。qgisを再起動して、プロセッシングツールボックスから追加されたスクリプトを探して実行しましょう。
出力ベクトルファイルに対して、同一のスクリプト内もしくはモデラーで繋げて処理を行うことで、
- ファイルをマージ
- マージしたファイルに対して解析処理
の流れを作ってあげることが出来ます。