-
-
Notifications
You must be signed in to change notification settings - Fork 3k
/
AlgorithmExecutor.py
141 lines (131 loc) · 5.98 KB
/
AlgorithmExecutor.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# -*- coding: utf-8 -*-
"""
***************************************************************************
AlgorithmExecutor.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. *
* *
***************************************************************************
"""
from processing.core.SilentProgress import SilentProgress
from processing.core.ProcessingLog import ProcessingLog
__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 PyQt4.QtGui import *
from PyQt4.QtCore import *
from qgis.core import *
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
from processing.tools import dataobjects
from processing.tools.system import *
from processing.tools.vector import *
from processing.gui.Postprocessing import Postprocessing
import sys
class AlgorithmExecutor(QThread):
percentageChanged = pyqtSignal(int)
textChanged = pyqtSignal(str)
error = pyqtSignal(str)
internalError = pyqtSignal(BaseException)
iterated = pyqtSignal(int)
infoSet = pyqtSignal(str)
commandSet = pyqtSignal(str)
debugInfoSet = pyqtSignal(str)
consoleInfoSet = pyqtSignal(str)
algExecuted = pyqtSignal()
#started & finished inherited from QThread
def __init__(self, alg, iterParam = None, parent = None):
QThread.__init__(self, parent)
self.algorithm = alg
self.parameterToIterate = iterParam
class Progress:
def __init__(self, algex):
self.algorithmExecutor = algex
def setText(self, text):
self.algorithmExecutor.textChanged.emit(text)
def setPercentage(self, p):
self.algorithmExecutor.percentageChanged.emit(p)
def setInfo(self, info):
self.algorithmExecutor.infoSet.emit(info)
def setCommand(self, cmd):
self.algorithmExecutor.commandSet.emit(cmd)
def setDebugInfo(self, info):
self.algorithmExecutor.debugInfoSet.emit(info)
def setConsoleInfo(self, info):
self.algorithmExecutor.consoleInfoSet.emit(info)
self.progress = Progress(self)
if self.parameterToIterate:
self.run = self.runalgIterating
#generate all single-feature layers
settings = QSettings()
systemEncoding = settings.value( "/UI/encoding", "System" )
layerfile = alg.getParameterValue(self.parameterToIterate)
layer = dataobjects.getObjectFromUri(layerfile, False)
provider = layer.dataProvider()
features = features(layer)
self.filelist = []
for feat in features:
output = getTempFilename("shp")
self.filelist.append(output)
writer = QgsVectorFileWriter(output, systemEncoding,provider.fields(), provider.geometryType(), layer.crs() )
writer.addFeature(feat)
del writer
else:
self.run = self.runalg
self.internalError.connect(self.raiseInternalError)
def raiseInternalError(self, error):
raise error
def runalg(self):
try:
self.algorithm.execute(self.progress)
if not self.parameterToIterate:
self.algExecuted.emit()
except GeoAlgorithmExecutionException, e :
self.error.emit(e.msg)
ProcessingLog.addToLog(sys.exc_info()[0], ProcessingLog.LOG_ERROR)
#=======================================================================
# except BaseException, e:
# self.error.emit(str(e))
#=======================================================================
# catch *all* errors, because QGIS tries to handle them in the GUI, which is fatal, this
# being a separate thread.
except:
msg = "Error executing " + str(self.alg.name) + "\nSee log for more information"
ProcessingLog.addToLog(sys.exc_info()[0], ProcessingLog.LOG_ERROR)
print msg
self.error.emit(msg)
def runalgIterating(self):
try:
outputs = {}
#store output values to use them later as basenames for all outputs
for out in self.algorithm.outputs:
outputs[out.name] = out.value
i = 1
for f in self.filelist:
self.algorithm.setParameterValue(self.parameterToIterate, f)
for out in self.algorithm.outputs:
filename = outputs[out.name]
if filename:
filename = filename[:filename.rfind(".")] + "_" + str(i) + filename[filename.rfind("."):]
out.value = filename
self.progress.setText("Executing iteration " + str(i) + "/" + str(len(self.filelist)) + "...")
self.progress.setPercentage((i * 100) / len(self.filelist))
self.runalg()
Postprocessing.handleAlgorithmResults(self.algorithm, SilentProgress().progress, False)
self.iterated.emit(i)
i += 1
self.algExecuted.emit()
except BaseException, e:
self.error.emit(str(e))
print "Error iterating " + str(e)
except:
print "Error iterating " + str(self)