GISの一般的な要件は、処理ツールを多数のファイルに適用するか、1つのファイルの多数のフィーチャのプロセスを別のファイルに適用することです。
これらの演算の多くは、計算結果がループ内の他の演算に影響を与えないという点で、恥ずかしいほど並行しています。それだけでなく、多くの場合、入力ファイルはそれぞれ異なります。
典型的な例は、シェイプファイルを、ポリゴンを含むファイルに対してクリップします。
これは、QGISのPythonスクリプトでこれを達成するための(テスト済みの)古典的な手続き型の方法です。(テストファイルを処理する時間を半分にしたよりも、実際のファイルへの一時メモリファイルの出力をfyi)
import processing
import os
input_file="/path/to/input_file.shp"
clip_polygons_file="/path/to/polygon_file.shp"
output_folder="/tmp/test/"
input_layer = QgsVectorLayer(input_file, "input file", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(input_layer)
tile_layer = QgsVectorLayer(clip_polygons_file, "clip_polys", "ogr")
QgsMapLayerRegistry.instance().addMapLayer(tile_layer)
tile_layer_dp=input_layer.dataProvider()
EPSG_code=int(tile_layer_dp.crs().authid().split(":")[1])
tile_no=0
clipping_polygons = tile_layer.getFeatures()
for clipping_polygon in clipping_polygons:
print "Tile no: "+str(tile_no)
tile_no+=1
geom = clipping_polygon.geometry()
clip_layer=QgsVectorLayer("Polygon?crs=epsg:"+str(EPSG_code)+\
"&field=id:integer&index=yes","clip_polygon", "memory")
clip_layer_dp = clip_layer.dataProvider()
clip_layer.startEditing()
clip_layer_feature = QgsFeature()
clip_layer_feature.setGeometry(geom)
(res, outFeats) = clip_layer_dp.addFeatures([clip_layer_feature])
clip_layer.commitChanges()
clip_file = os.path.join(output_folder,"tile_"+str(tile_no)+".shp")
write_error = QgsVectorFileWriter.writeAsVectorFormat(clip_layer, \
clip_file, "system", \
QgsCoordinateReferenceSystem(EPSG_code), "ESRI Shapefile")
QgsMapLayerRegistry.instance().addMapLayer(clip_layer)
output_file = os.path.join(output_folder,str(tile_no)+".shp")
processing.runalg("qgis:clip", input_file, clip_file, output_file)
QgsMapLayerRegistry.instance().removeMapLayer(clip_layer.id())
入力ファイルが2GBで、ポリゴンクリッピングファイルに400以上のポリゴンが含まれていることを除いて、これは問題ありません。結果として生じるプロセスは、クアッドコアマシンで1週間以上かかります。その間、3つのコアはアイドル状態にあります。
私の頭の中にある解決策は、プロセスをスクリプトファイルにエクスポートし、たとえばgnu parallelを使用して非同期で実行することです。ただし、QGIS pythonにネイティブなものを使用するのではなく、QGISからOS固有のソリューションにドロップする必要があるのは残念に思えます。だから私の質問は:
Python QGIS内で、恥ずかしいほどに並列な地理的操作をネイティブに並列化できますか?
そうでない場合、おそらく誰かがすでにこの種の作業を非同期シェルスクリプトに送信するコードを持っていますか?