mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
186 lines
7.6 KiB
Python
186 lines
7.6 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
"""
|
|
***************************************************************************
|
|
BatchAlgorithmDialog.py
|
|
---------------------
|
|
Date : August 2012
|
|
Copyright : (C) 2012 by Victor Olaya
|
|
Email : volayaf at gmail dot com
|
|
***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
***************************************************************************
|
|
"""
|
|
|
|
__author__ = 'Victor Olaya'
|
|
__date__ = 'August 2012'
|
|
__copyright__ = '(C) 2012, Victor Olaya'
|
|
|
|
# This will get replaced with a git SHA1 when you do a git archive
|
|
|
|
__revision__ = '$Format:%H$'
|
|
|
|
from pprint import pformat
|
|
import time
|
|
|
|
from qgis.PyQt.QtWidgets import QMessageBox
|
|
from qgis.PyQt.QtCore import Qt, QCoreApplication
|
|
|
|
from qgis.core import (QgsProcessingParameterDefinition,
|
|
QgsProcessingParameterRasterDestination,
|
|
QgsProcessingParameterVectorDestination,
|
|
QgsProcessingParameterFeatureSink,
|
|
QgsProcessingOutputLayerDefinition,
|
|
QgsProcessingOutputHtml,
|
|
QgsProcessingOutputNumber,
|
|
QgsProcessingOutputString,
|
|
QgsProject,
|
|
QgsProcessingMultiStepFeedback,
|
|
Qgis,
|
|
QgsScopedProxyProgressTask)
|
|
|
|
from qgis.gui import QgsProcessingAlgorithmDialogBase
|
|
from qgis.utils import OverrideCursor, iface
|
|
|
|
from processing.gui.BatchPanel import BatchPanel
|
|
from processing.gui.AlgorithmExecutor import execute
|
|
from processing.gui.Postprocessing import handleAlgorithmResults
|
|
|
|
from processing.core.ProcessingResults import resultsList
|
|
|
|
from processing.tools.system import getTempFilename
|
|
from processing.tools import dataobjects
|
|
|
|
import codecs
|
|
|
|
|
|
class BatchAlgorithmDialog(QgsProcessingAlgorithmDialogBase):
|
|
|
|
def __init__(self, alg, parent=None):
|
|
super().__init__(parent)
|
|
|
|
self.setAlgorithm(alg)
|
|
|
|
self.setWindowTitle(self.tr('Batch Processing - {0}').format(self.algorithm().displayName()))
|
|
self.setMainWidget(BatchPanel(self, self.algorithm()))
|
|
self.hideShortHelp()
|
|
|
|
def runAlgorithm(self):
|
|
alg_parameters = []
|
|
|
|
feedback = self.createFeedback()
|
|
|
|
load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
|
|
project = QgsProject.instance() if load_layers else None
|
|
|
|
for row in range(self.mainWidget().batchRowCount()):
|
|
parameters = self.mainWidget().parametersForRow(row, destinationProject=project, warnOnInvalid=True)
|
|
alg_parameters.append(parameters)
|
|
|
|
task = QgsScopedProxyProgressTask(self.tr('Batch Processing - {0}').format(self.algorithm().displayName()))
|
|
multi_feedback = QgsProcessingMultiStepFeedback(len(alg_parameters), feedback)
|
|
feedback.progressChanged.connect(task.setProgress)
|
|
|
|
with OverrideCursor(Qt.WaitCursor):
|
|
|
|
self.mainWidget().setEnabled(False)
|
|
self.cancelButton().setEnabled(True)
|
|
|
|
# Make sure the Log tab is visible before executing the algorithm
|
|
try:
|
|
self.showLog()
|
|
self.repaint()
|
|
except:
|
|
pass
|
|
|
|
start_time = time.time()
|
|
|
|
algorithm_results = []
|
|
for count, parameters in enumerate(alg_parameters):
|
|
if feedback.isCanceled():
|
|
break
|
|
self.setProgressText(
|
|
QCoreApplication.translate('BatchAlgorithmDialog', '\nProcessing algorithm {0}/{1}…').format(
|
|
count + 1, len(alg_parameters)))
|
|
self.setInfo(self.tr('<b>Algorithm {0} starting…</b>').format(self.algorithm().displayName()),
|
|
escapeHtml=False)
|
|
multi_feedback.setCurrentStep(count)
|
|
|
|
parameters = self.algorithm().preprocessParameters(parameters)
|
|
|
|
feedback.pushInfo(self.tr('Input parameters:'))
|
|
feedback.pushCommandInfo(pformat(parameters))
|
|
feedback.pushInfo('')
|
|
|
|
# important - we create a new context for each iteration
|
|
# this avoids holding onto resources and layers from earlier iterations,
|
|
# and allows batch processing of many more items then is possible
|
|
# if we hold on to these layers
|
|
context = dataobjects.createContext(feedback)
|
|
|
|
alg_start_time = time.time()
|
|
ret, results = execute(self.algorithm(), parameters, context, multi_feedback)
|
|
if ret:
|
|
self.setInfo(
|
|
QCoreApplication.translate('BatchAlgorithmDialog', 'Algorithm {0} correctly executed…').format(
|
|
self.algorithm().displayName()), escapeHtml=False)
|
|
feedback.pushInfo(
|
|
self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
|
|
feedback.pushInfo(self.tr('Results:'))
|
|
feedback.pushCommandInfo(pformat(results))
|
|
feedback.pushInfo('')
|
|
algorithm_results.append(results)
|
|
else:
|
|
break
|
|
|
|
handleAlgorithmResults(self.algorithm(), context, multi_feedback, False, parameters)
|
|
|
|
feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))
|
|
task = None
|
|
|
|
self.finish(algorithm_results)
|
|
self.cancelButton().setEnabled(False)
|
|
|
|
def finish(self, algorithm_results):
|
|
for count, results in enumerate(algorithm_results):
|
|
self.loadHTMLResults(results, count)
|
|
|
|
self.createSummaryTable(algorithm_results)
|
|
self.mainWidget().setEnabled(True)
|
|
self.resetGui()
|
|
|
|
def loadHTMLResults(self, results, num):
|
|
for out in self.algorithm().outputDefinitions():
|
|
if isinstance(out, QgsProcessingOutputHtml) and out.name() in results and results[out.name()]:
|
|
resultsList.addResult(icon=self.algorithm().icon(), name='{} [{}]'.format(out.description(), num),
|
|
result=results[out.name()])
|
|
|
|
def createSummaryTable(self, algorithm_results):
|
|
createTable = False
|
|
|
|
for out in self.algorithm().outputDefinitions():
|
|
if isinstance(out, (QgsProcessingOutputNumber, QgsProcessingOutputString)):
|
|
createTable = True
|
|
break
|
|
|
|
if not createTable:
|
|
return
|
|
|
|
outputFile = getTempFilename('html')
|
|
with codecs.open(outputFile, 'w', encoding='utf-8') as f:
|
|
for res in algorithm_results:
|
|
f.write('<hr>\n')
|
|
for out in self.algorithm().outputDefinitions():
|
|
if isinstance(out, (QgsProcessingOutputNumber, QgsProcessingOutputString)) and out.name() in res:
|
|
f.write('<p>{}: {}</p>\n'.format(out.description(), res[out.name()]))
|
|
f.write('<hr>\n')
|
|
|
|
resultsList.addResult(icon=self.algorithm().icon(),
|
|
name='{} [summary]'.format(self.algorithm().name()), timestamp=time.localtime(),
|
|
result=outputFile)
|