Загальна вимога в ГІС - застосувати інструмент обробки до ряду файлів або застосувати процес для ряду функцій одного файлу до іншого файлу.
Значна частина цих операцій бентежно паралельна тим, що результати обчислень жодним чином не впливають на будь-яку іншу операцію в циклі. Мало того, але часто вхідні файли є різними.
Класичний випадок - це створення файлів із формами файлів, що містять багатокутники, для вирізання їх.
Ось (перевірений) класичний процедурний метод для досягнення цього в сценарії python для QGIS. (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())
Це було б добре, за винятком того, що мій вхідний файл становить 2 Гб, а відсічний файл багатокутника містить 400+ полігонів. Отриманий процес займає більше тижня на моїй чотирьохядерній машині. Увесь час три ядра просто працюють.
У мене в голові рішення - експортувати процес у файли сценаріїв і запускати їх асинхронно, наприклад, паралельно з gnu. Однак видається прикро відмовитись від QGIS у специфічному для ОС рішенні, а не використовувати щось рідне для QGIS python. Отже, моє питання:
Чи можу я зніяковіло паралельно встановити паралельні географічні операції всередині python QGIS?
Якщо ні, то, можливо, у когось вже є код, щоб відправити таку роботу в асинхронні сценарії оболонки?