def initializeSettings(self): '''this is the place where you should add config parameters using the ProcessingConfig class. This method is called when a provider is added to the processing framework. By default it just adds a setting to activate or deactivate algorithms from the provider''' ProcessingConfig.settingIcons[self.getDescription()] = self.getIcon() name = "ACTIVATE_" + self.getName().upper().replace(" ", "_") ProcessingConfig.addSetting(Setting(self.getDescription(), name, "Activate", self.activate))
def unload(self): """Setting should be removed here, so they do not appear anymore when the plugin is unloaded. """ AlgorithmProvider.unload(self) ProcessingConfig.removeSetting( Basis_nl_algorithm_provider.INPUT_FOLDER)
def load(self): ProcessingConfig.settingIcons[self.name()] = self.icon() ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_GDAL', self.tr('Activate'), True)) ProcessingConfig.readSettings() self.refreshAlgorithms() return True
def runAlgorithm(self): ''' Execute geo-operation GeoAlgorithm Processing based ''' self.dlg.openChartDialogButton.setEnabled(False) algorithm = self.GeoprocessingAlgorithms[self.dlg.getGeoprocessingTypeData()](self.dlg.getOutputType()) self.dlg.algorithm = algorithm algorithm.provider = QGISAlgorithmProvider() algorithm.setParameterValue('ORIGIN',self.dlg.getComboboxData('originLayerSelect')) algorithm.setParameterValue('TARGET',self.dlg.getComboboxData('targetLayerSelect')) algorithm.setParameterValue('FIELDSORIGIN',self.dlg.getSelectedFields('tableViewOriginLayerFields')) algorithm.setParameterValue('FIELDSTARGET',self.dlg.getSelectedFields('tableViewTargetLayerFields')) algorithm.setParameterValue('EXPRESSIONSORIGIN',self.dlg.getSelectedFieldsNameWithExpression('tableViewOriginLayerFields')) algorithm.setParameterValue('EXPRESSIONSTARGET',self.dlg.getSelectedFieldsNameWithExpression('tableViewTargetLayerFields')) ProcessingConfig.setSettingValue(ProcessingConfig.USE_FILENAME_AS_LAYER_NAME,True) if self.dlg.getOutputType() == 'Shape File': outputFile = self.dlg.outputShapeFile.text() elif self.dlg.getOutputType() == 'Spatialite': outputFile = self.dlg.outputSpatialite.text() else: outputFile = self.dlg.getPostgisOutputValues() algorithm.setOutputValue('OUTPUT',outputFile) algorithm.execute(self.dlg) self.dlg.reslayer = handleAlgorithmResults(algorithm,self.dlg) #QObject.connect(self.dlg.reslayer[0], SIGNAL('layerDeleted()'),self.dlg.clearReslayer) ProcessingConfig.setSettingValue(ProcessingConfig.USE_FILENAME_AS_LAYER_NAME,False) self.dlg.openChartDialogButton.setEnabled(True)
def addToLog(msgtype, msg): try: # It seems that this fails sometimes depending on the msg # added. To avoid it stopping the normal functioning of the # algorithm, we catch all errors, assuming that is better # to miss some log info than breaking the algorithm. if msgtype == ProcessingLog.LOG_ALGORITHM: line = msgtype + '|' + datetime.datetime.now().strftime( ProcessingLog.DATE_FORMAT) + '|' \ + msg + '\n' with codecs.open(ProcessingLog.logFilename(), 'a', encoding='utf-8') as logfile: logfile.write(line) algname = msg[len('Processing.runalg("'):] algname = algname[:algname.index('"')] if algname not in ProcessingLog.recentAlgs: ProcessingLog.recentAlgs.append(algname) recentAlgsString = ';'.join(ProcessingLog.recentAlgs[-6:]) ProcessingConfig.setSettingValue( ProcessingConfig.RECENT_ALGORITHMS, recentAlgsString) else: if isinstance(msg, list): msg = '\n'.join([m for m in msg]) msgtypes = {ProcessingLog.LOG_ERROR: QgsMessageLog.CRITICAL, ProcessingLog.LOG_INFO: QgsMessageLog.INFO, ProcessingLog.LOG_WARNING: QgsMessageLog.WARNING, } QgsMessageLog.logMessage(msg, ProcessingLog.tr("Processing"), msgtypes[msgtype]) except: pass
def grassPath(): if not isWindows() and not isMac(): return '' folder = ProcessingConfig.getSetting(GrassUtils.GRASS_FOLDER) or '' if not os.path.exists(folder): folder = None if folder is None: if isWindows(): if "OSGEO4W_ROOT" in os.environ: testfolder = os.path.join(str(os.environ['OSGEO4W_ROOT']), "apps") else: testfolder = str(QgsApplication.prefixPath()) testfolder = os.path.join(testfolder, 'grass') if os.path.isdir(testfolder): for subfolder in os.listdir(testfolder): if subfolder.startswith('grass-6'): folder = os.path.join(testfolder, subfolder) break else: folder = os.path.join(QgsApplication.prefixPath(), 'grass') if not os.path.isdir(folder): folder = '/Applications/GRASS-6.4.app/Contents/MacOS' if folder: ProcessingConfig.setSettingValue(GrassUtils.GRASS_FOLDER, folder) return folder or ''
def __init__(self, layer, request): self.layer = layer self.selection = False if ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)\ and layer.selectedFeatureCount() > 0: self.iter = layer.selectedFeaturesIterator(request) self.selection = True else: self.iter = layer.getFeatures(request) invalidFeaturesMethod = ProcessingConfig.getSetting(ProcessingConfig.FILTER_INVALID_GEOMETRIES) def filterFeature(f, ignoreInvalid): geom = f.geometry() if geom is None: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Feature with NULL geometry found.')) elif not geom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or more input features have invalid geometry.')) if ignoreInvalid: return False else: raise GeoAlgorithmExecutionException(self.tr('Features with invalid geometries found. Please fix these geometries or specify the "Ignore invalid input features" flag')) return True if invalidFeaturesMethod == self.IGNORE: self.iter = filter(lambda x: filterFeature(x, True), self.iter) elif invalidFeaturesMethod == self.RAISE_EXCEPTION: self.iter = filter(lambda x: filterFeature(x, False), self.iter)
def unload(self): """Setting should be removed here, so they do not appear anymore when the plugin is unloaded. """ AlgorithmProvider.unload(self) ProcessingConfig.removeSetting( MultiClipProvider.MY_DUMMY_SETTING)
def initializeSettings(self): AlgorithmProvider.initializeSettings(self) ProcessingConfig.addSetting(Setting('AniMove', self.FIELD_SEPARATOR, 'CSV field separator', ',')) ProcessingConfig.addSetting(Setting('AniMove', self.DECIMAL_SEPARATOR, 'CSV decimal separator', '.'))
def unload(self): """ Unloads the provider. Any tear-down steps required by the provider should be implemented here. """ ProcessingConfig.removeSetting('VISIBILITY_ANALYSIS_ACTIVATED')
def addToLog(msgtype, msg): try: # It seems that this fails sometimes depending on the msg # added. To avoid it stopping the normal functioning of the # algorithm, we catch all errors, assuming that is better # to miss some log info that breaking the algorithm. if isinstance(msg, list): a = '|'.join(m.strip('\n') for m in msg) text = a else: text = msg.replace('\n', '|') line = msgtype + '|' + datetime.datetime.now().strftime( ProcessingLog.DATE_FORMAT).decode('utf-8') + '|' \ + text + '\n' logfile = codecs.open(ProcessingLog.logFilename(), 'a', encoding='utf-8') logfile.write(line) logfile.close() if msgtype == ProcessingLog.LOG_ALGORITHM: algname = text[len('Processing.runalg("'):] algname = algname[:algname.index('"')] if algname not in ProcessingLog.recentAlgs: ProcessingLog.recentAlgs.append(algname) recentAlgsString = ';'.join(ProcessingLog.recentAlgs[-6:]) ProcessingConfig.setSettingValue( ProcessingConfig.RECENT_ALGORITHMS, recentAlgsString) except: pass
def initializeSettings(self): AlgorithmProvider.initializeSettings(self) ProcessingConfig.addSetting(Setting( self.getDescription(), GdalUtils.GDAL_HELP_PATH, self.tr('Location of GDAL docs'), GdalUtils.gdalHelpPath()))
def writeRaw(self, fileName, hrLayer, studyLayer, areas): sepField = ProcessingConfig.getSetting('FIELD_SEPARATOR') sepNumber = ProcessingConfig.getSetting('DECIMAL_SEPARATOR') with open(fileName, 'w') as f: f.write('QGIS Random Home Range summary\n') f.write('Frame layer%s%s\n' % (sepField, studyLayer.name())) f.write('Home ranges layer%s%s\n' % (sepField, hrLayer.name())) f.write('Number of the home ranges%s%s\n' % (sepField, studyLayer.featureCount())) f.write('Number of iterations%s%s\n\n' % (sepField, len(self.overlaps) - 1)) f.write('Note: The first column contains the home range area\n\n') for i in range(len(self.overlaps)): if i == 0: f.write('Observed data:\n') else: f.write('Iteration %s:\n' % i) for j in range(len(self.overlaps[i])): text = str(areas[j]) + sepField for k in range(len(self.overlaps[i]) - len(self.overlaps[i][j])): text += sepField for k in range(len(self.overlaps[i][j])): val = self.overlaps[i][j][k] text += str(val).replace('.', sepNumber) + sepField text = text[:len(text) - 1] + '\n' f.write(text) f.write('\n')
def unload(self): ProcessingConfig.removeSetting('ACTIVATE_GRASS7') if isWindows() or isMac(): ProcessingConfig.removeSetting(Grass7Utils.GRASS_FOLDER) ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS) ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE) ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_PATH)
def unload(self): """Setting should be removed here, so they do not appear anymore when the plugin is unloaded. """ AlgorithmProvider.unload(self) ProcessingConfig.removeSetting( DifferentialPrivacyUtils.DIFFERENTIAL_EPSILON)
def sagaPath(): folder = ProcessingConfig.getSetting(SAGA_FOLDER) if folder is None or folder == '': folder = findSagaFolder() if folder is not None: ProcessingConfig.setSettingValue(SAGA_FOLDER, folder) return folder or ''
def initialize(): # Add the basic providers Processing.addProvider(QGISAlgorithmProvider()) Processing.addProvider(ModelerOnlyAlgorithmProvider()) Processing.addProvider(GdalOgrAlgorithmProvider()) Processing.addProvider(LidarToolsAlgorithmProvider()) Processing.addProvider(OTBAlgorithmProvider()) Processing.addProvider(RAlgorithmProvider()) Processing.addProvider(SagaAlgorithmProvider()) Processing.addProvider(GrassAlgorithmProvider()) Processing.addProvider(Grass7AlgorithmProvider()) Processing.addProvider(ScriptAlgorithmProvider()) Processing.addProvider(TauDEMAlgorithmProvider()) Processing.addProvider(Processing.modeler) Processing.modeler.initializeSettings() # And initialize AlgorithmDecorator.loadClassification() ProcessingLog.startLogging() ProcessingConfig.initialize() ProcessingConfig.readSettings() RenderingStyles.loadStyles() Processing.loadFromProviders() # Inform registered listeners that all providers' algorithms have been loaded Processing.fireAlgsListHasChanged()
def testGrass(self): '''Test GRASS is installed QGIS-89 (2)''' folder = ProcessingConfig.getSetting(GrassUtils.GRASS_FOLDER) ProcessingConfig.removeSetting(GrassUtils.GRASS_FOLDER) msg = GrassUtils.checkGrassIsInstalled() self.assertIsNone(msg) ProcessingConfig.setSettingValue(GrassUtils.GRASS_FOLDER, folder)
def unload(self): """Setting should be removed here, so they do not appear anymore when the plugin is unloaded. """ ProcessingConfig.removeSetting('ACTIVATE_EXAMPLE') ProcessingConfig.removeSetting( ExampleAlgorithmProvider.MY_DUMMY_SETTING)
def unload(self): """Setting should be removed here, so they do not appear anymore when the plugin is unloaded. """ AlgorithmProvider.unload(self) ProcessingConfig.removeSetting( ScipyPointClusteringUtils.POINT_LIMIT )
def unload(self): AlgorithmProvider.unload(self) if isWindows() or isMac(): ProcessingConfig.removeSetting(GrassUtils.GRASS_FOLDER) ProcessingConfig.removeSetting(GrassUtils.GRASS_WIN_SHELL) ProcessingConfig.removeSetting(GrassUtils.GRASS_LOG_COMMANDS) ProcessingConfig.removeSetting(GrassUtils.GRASS_LOG_CONSOLE) ProcessingConfig.removeSetting(GrassUtils.GRASS_HELP_PATH)
def unload(self): """ Setting should be removed here, so they do not appear anymore when the plugin is unloaded. """ AlgorithmProvider.unload(self) ProcessingConfig.removeSetting( GISCloudUtils.GISCloud_character)
def initializeMenus(): for provider in Processing.providers: for alg in provider.algs: d = defaultMenuEntries.get(alg.commandLineName(), "") setting = Setting("Menus", "MENU_" + alg.commandLineName(), alg.name, d) ProcessingConfig.addSetting(setting) ProcessingConfig.readSettings()
def initializeSettings(self): AlgorithmProvider.initializeSettings(self) ProcessingConfig.addSetting(Setting(self.getDescription(), LAStoolsUtils.LASTOOLS_FOLDER, 'LAStools folder', LAStoolsUtils.LAStoolsPath())) ProcessingConfig.addSetting(Setting(self.getDescription(), FusionUtils.FUSION_FOLDER, 'Fusion folder', FusionUtils.FusionPath()))
def unload(self): """Setting should be removed here, so they do not appear anymore when the plugin is unloaded. """ AlgorithmProvider.unload(self) ProcessingConfig.removeSetting( PolygonsParallelToLineProvider.MY_SETTING)
def setUp(self): ProcessingConfig.setSettingValue(ProcessingConfig.USE_THREADS, self.threaded) print print bcolors.INFO, self.msg, bcolors.ENDC, print "Parameters: ", self.alg.parameters, print "Outputs: ", [out for out in self.alg.outputs if not out.hidden], self.args = list(self.gen_test_parameters(self.alg, True)) print ' => ', self.args, bcolors.WARNING,
def handleAlgorithmResults(alg, context, feedback=None, showResults=True): wrongLayers = [] if feedback is None: feedback = QgsProcessingFeedback() feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers')) i = 0 for l, details in context.layersToLoadOnCompletion().items(): if feedback.isCanceled(): return False if len(context.layersToLoadOnCompletion()) > 2: # only show progress feedback if we're loading a bunch of layers feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion()))) try: layer = QgsProcessingUtils.mapLayerFromString(l, context, typeHint=details.layerTypeHint) if layer is not None: set_layer_name(layer, details) style = None if details.outputName: style = RenderingStyles.getStyle(alg.id(), details.outputName) if style is None: if layer.type() == QgsMapLayer.RasterLayer: style = ProcessingConfig.getSetting(ProcessingConfig.RASTER_STYLE) else: if layer.geometryType() == QgsWkbTypes.PointGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POINT_STYLE) elif layer.geometryType() == QgsWkbTypes.LineGeometry: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_LINE_STYLE) else: style = ProcessingConfig.getSetting(ProcessingConfig.VECTOR_POLYGON_STYLE) if style: layer.loadNamedStyle(style) details.project.addMapLayer(context.temporaryLayerStore().takeMapLayer(layer)) if details.postProcessor(): details.postProcessor().postProcessLayer(layer, context, feedback) else: wrongLayers.append(str(l)) except Exception: QgsMessageLog.logMessage(QCoreApplication.translate('Postprocessing', "Error loading result layer:") + "\n" + traceback.format_exc(), 'Processing', Qgis.Critical) wrongLayers.append(str(l)) i += 1 feedback.setProgress(100) if wrongLayers: msg = QCoreApplication.translate('Postprocessing', "The following layers were not correctly generated.") msg += "<ul>" + "".join(["<li>%s</li>" % lay for lay in wrongLayers]) + "</ul>" msg += QCoreApplication.translate('Postprocessing', "You can check the 'Log Messages Panel' in QGIS main window to find more information about the execution of the algorithm.") feedback.reportError(msg) return len(wrongLayers) == 0
def unload(self): '''Setting should be removed here, so they do not appear anymore when the plugin is unloaded''' AlgorithmProvider.unload(self) ProcessingConfig.removeSetting(qsdm_settings.JAVA_EXEC) ProcessingConfig.removeSetting(qsdm_settings.MAXENT) ProcessingConfig.removeSetting(qsdm_settings.MEM) ProcessingConfig.removeSetting(qsdm_settings.WORK_DIR) ProcessingConfig.removeSetting(qsdm_settings.TEMP)
def unload(self): ProcessingConfig.removeSetting('ACTIVATE_R') ProcessingConfig.removeSetting(RUtils.RSCRIPTS_FOLDER) if isWindows(): ProcessingConfig.removeSetting(RUtils.R_FOLDER) ProcessingConfig.removeSetting(RUtils.R_LIBS_USER) ProcessingConfig.removeSetting(RUtils.R_USE64) ProviderActions.deregisterProviderActions(self) ProviderContextMenuActions.deregisterProviderContextMenuActions(self.contextMenuActions)
def unload(self): """Do here anything that you want to be done when the provider is removed from the list of available ones. This method is called when you remove the provider from Processing. Removal of config setting should be done here. """ name = 'ACTIVATE_' + self.getName().upper().replace(' ', '_') ProcessingConfig.removeSetting(name)
class AlgorithmExecutionDialog(QtGui.QDialog): class InvalidParameterValue(Exception): def __init__(self, param, widget): (self.parameter, self.widget) = (param, widget) def __init__(self, alg, mainWidget): QtGui.QDialog.__init__( self, None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) self.executed = False self.mainWidget = mainWidget self.alg = alg self.resize(650, 450) self.buttonBox = QtGui.QDialogButtonBox() self.buttonBox.setOrientation(QtCore.Qt.Horizontal) self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Close) self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).setEnabled(False) self.runButton = QtGui.QPushButton() self.runButton.setText('Run') self.buttonBox.addButton(self.runButton, QtGui.QDialogButtonBox.ActionRole) self.runButton.clicked.connect(self.accept) self.setWindowTitle(self.alg.name) self.progressLabel = QtGui.QLabel() self.progress = QtGui.QProgressBar() self.progress.setMinimum(0) self.progress.setMaximum(100) self.progress.setValue(0) self.verticalLayout = QtGui.QVBoxLayout(self) self.verticalLayout.setSpacing(6) self.verticalLayout.setMargin(9) self.tabWidget = QtGui.QTabWidget() self.tabWidget.setMinimumWidth(300) self.tabWidget.addTab(self.mainWidget, 'Parameters') self.verticalLayout.addWidget(self.tabWidget) self.logText = QTextEdit() self.logText.readOnly = True self.tabWidget.addTab(self.logText, 'Log') self.webView = QtWebKit.QWebView() cssUrl = QtCore.QUrl( os.path.join(os.path.dirname(__file__), 'help', 'help.css')) self.webView.settings().setUserStyleSheetUrl(cssUrl) html = None url = None try: isText, help = self.alg.help() if help is not None: if isText: html = help else: url = QtCore.QUrl(help) else: html = '<h2>Sorry, no help is available for this \ algorithm.</h2>' except WrongHelpFileException, e: html = e.args[0] try: if html: self.webView.setHtml(html) elif url: print url self.webView.load(url) except: self.webView.setHtml('<h2>Could not open help file :-( </h2>') self.tabWidget.addTab(self.webView, 'Help') self.verticalLayout.addWidget(self.progressLabel) self.verticalLayout.addWidget(self.progress) self.verticalLayout.addWidget(self.buttonBox) self.setLayout(self.verticalLayout) self.buttonBox.rejected.connect(self.close) self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).clicked.connect( self.cancel) self.showDebug = ProcessingConfig.getSetting( ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
def unload(self): ProcessingConfig.removeSetting('ACTIVATE_GDAL')
def modelsFolders(): folder = ProcessingConfig.getSetting(ModelerUtils.MODELS_FOLDER) if folder is not None: return folder.split(';') else: return [ModelerUtils.defaultModelsFolder()]
def RScriptsFolders(): folder = ProcessingConfig.getSetting(RUtils.RSCRIPTS_FOLDER) if folder is not None: return folder.split(';') else: return [RUtils.defaultRScriptsFolder()]
def accept(self): super(AlgorithmDialog, self)._saveGeometry() feedback = self.createFeedback() context = dataobjects.createContext(feedback) checkCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_CRS) try: parameters = self.getParamValues() if checkCRS and not self.alg.validateInputCrs(parameters, context): reply = QMessageBox.question( self, self.tr("Unmatching CRS's"), self.tr('Layers do not all use the same CRS. This can ' 'cause unexpected results.\nDo you want to ' 'continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return checkExtentCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_EXTENT_CRS) # TODO if False and checkExtentCRS and self.checkExtentCRS(): reply = QMessageBox.question( self, self.tr("Extent CRS"), self. tr('Extent parameters must use the same CRS as the input layers.\n' 'Your input layers do not have the same extent as the project, ' 'so the extent might be in a wrong CRS if you have selected it from the canvas.\n' 'Do you want to continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return ok, msg = self.alg.checkParameterValues(parameters, context) if msg: QMessageBox.warning(self, self.tr('Unable to execute algorithm'), msg) return self.btnRun.setEnabled(False) self.btnClose.setEnabled(False) buttons = self.mainWidget.iterateButtons self.iterateParam = None for i in range(len(list(buttons.values()))): button = list(buttons.values())[i] if button.isChecked(): self.iterateParam = list(buttons.keys())[i] break self.progressBar.setMaximum(0) self.lblProgress.setText(self.tr('Processing algorithm...')) # Make sure the Log tab is visible before executing the algorithm try: self.tabWidget.setCurrentIndex(1) self.repaint() except: pass self.setInfo( self.tr('<b>Algorithm \'{0}\' starting...</b>').format( self.alg.displayName()), escape_html=False) feedback.pushInfo(self.tr('Input parameters:')) display_params = [] for k, v in parameters.items(): display_params.append("'" + k + "' : " + self.alg.parameterDefinition( k).valueAsPythonString(v, context)) feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }') feedback.pushInfo('') start_time = time.time() if self.iterateParam: self.buttonCancel.setEnabled( self.alg.flags() & QgsProcessingAlgorithm.FlagCanCancel) if executeIterating(self.alg, parameters, self.iterateParam, context, feedback): feedback.pushInfo( self.tr( 'Execution completed in {0:0.2f} seconds'.format( time.time() - start_time))) self.buttonCancel.setEnabled(False) self.finish(True, parameters, context, feedback) else: self.buttonCancel.setEnabled(False) self.resetGUI() else: command = self.alg.asPythonCommand(parameters, context) if command: ProcessingLog.addToLog(command) self.buttonCancel.setEnabled( self.alg.flags() & QgsProcessingAlgorithm.FlagCanCancel) def on_complete(ok, results): if ok: feedback.pushInfo( self.tr('Execution completed in {0:0.2f} seconds'. format(time.time() - start_time))) feedback.pushInfo(self.tr('Results:')) feedback.pushCommandInfo(pformat(results)) else: feedback.reportError( self.tr('Execution failed after {0:0.2f} seconds'. format(time.time() - start_time))) feedback.pushInfo('') self.buttonCancel.setEnabled(False) self.finish(ok, results, context, feedback) task = QgsProcessingAlgRunnerTask(self.alg, parameters, context, feedback) task.executed.connect(on_complete) QgsApplication.taskManager().addTask(task) except AlgorithmDialogBase.InvalidParameterValue as e: try: self.buttonBox.accepted.connect( lambda e=e: e.widget.setPalette(QPalette())) palette = e.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) e.widget.setPalette(palette) except: pass self.bar.clearWidgets() self.bar.pushMessage( "", self.tr("Wrong or missing parameter value: {0}").format( e.parameter.description()), level=QgsMessageBar.WARNING, duration=5)
def fillTreeUsingCategories(self): providersToExclude = ['model', 'script'] self.algorithmTree.clear() text = unicode(self.searchBox.text()) groups = {} for providerName in Processing.algs.keys(): provider = Processing.algs[providerName] name = 'ACTIVATE_' + providerName.upper().replace(' ', '_') if not ProcessingConfig.getSetting(name): continue if providerName in providersToExclude \ or len(Providers.providers[providerName].actions) != 0: continue algs = provider.values() # add algorithms for alg in algs: if not alg.showInToolbox: continue (altgroup, altsubgroup, altname) = \ AlgorithmDecorator.getGroupsAndName(alg) if altgroup is None: continue if text == '' or text.lower() in altname.lower(): if altgroup not in groups: groups[altgroup] = {} group = groups[altgroup] if altsubgroup not in group: groups[altgroup][altsubgroup] = [] subgroup = groups[altgroup][altsubgroup] subgroup.append(alg) if len(groups) > 0: mainItem = QTreeWidgetItem() mainItem.setText(0, 'Geoalgorithms') mainItem.setIcon(0, GeoAlgorithm.getDefaultIcon()) mainItem.setToolTip(0, mainItem.text(0)) for (groupname, group) in groups.items(): groupItem = QTreeWidgetItem() groupItem.setText(0, groupname) groupItem.setIcon(0, GeoAlgorithm.getDefaultIcon()) groupItem.setToolTip(0, groupItem.text(0)) mainItem.addChild(groupItem) for (subgroupname, subgroup) in group.items(): subgroupItem = QTreeWidgetItem() subgroupItem.setText(0, subgroupname) subgroupItem.setIcon(0, GeoAlgorithm.getDefaultIcon()) subgroupItem.setToolTip(0, subgroupItem.text(0)) groupItem.addChild(subgroupItem) for alg in subgroup: algItem = TreeAlgorithmItem(alg) subgroupItem.addChild(algItem) self.algorithmTree.addTopLevelItem(mainItem) for providerName in Processing.algs.keys(): groups = {} provider = Processing.algs[providerName] name = 'ACTIVATE_' + providerName.upper().replace(' ', '_') if not ProcessingConfig.getSetting(name): continue if providerName not in providersToExclude: continue algs = provider.values() # add algorithms for alg in algs: if not alg.showInToolbox: continue if text == '' or text.lower() in alg.name.lower(): if alg.group in groups: groupItem = groups[alg.group] else: groupItem = QTreeWidgetItem() groupItem.setText(0, alg.group) groupItem.setToolTip(0, alg.group) groups[alg.group] = groupItem algItem = TreeAlgorithmItem(alg) groupItem.addChild(algItem) actions = Processing.actions[providerName] for action in actions: if text == '' or text.lower() in action.name.lower(): if action.group in groups: groupItem = groups[action.group] else: groupItem = QTreeWidgetItem() groupItem.setText(0, action.group) groups[action.group] = groupItem algItem = TreeActionItem(action) groupItem.addChild(algItem) if len(groups) > 0: providerItem = QTreeWidgetItem() providerItem.setText( 0, Processing.getProviderFromName( providerName).getDescription()) providerItem.setIcon( 0, Processing.getProviderFromName(providerName).getIcon()) providerItem.setToolTip(0, providerItem.text(0)) for groupItem in groups.values(): providerItem.addChild(groupItem) self.algorithmTree.addTopLevelItem(providerItem) if text != '': self.algorithmTree.expandAll()
def __init__(self, model=None): super().__init__(None) self.setAttribute(Qt.WA_DeleteOnClose) self.setupUi(self) self._variables_scope = None # LOTS of bug reports when we include the dock creation in the UI file # see e.g. #16428, #19068 # So just roll it all by hand......! self.propertiesDock = QgsDockWidget(self) self.propertiesDock.setFeatures( QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.propertiesDock.setObjectName("propertiesDock") propertiesDockContents = QWidget() self.verticalDockLayout_1 = QVBoxLayout(propertiesDockContents) self.verticalDockLayout_1.setContentsMargins(0, 0, 0, 0) self.verticalDockLayout_1.setSpacing(0) self.scrollArea_1 = QgsScrollArea(propertiesDockContents) sizePolicy = QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.MinimumExpanding) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) sizePolicy.setHeightForWidth(self.scrollArea_1.sizePolicy().hasHeightForWidth()) self.scrollArea_1.setSizePolicy(sizePolicy) self.scrollArea_1.setFocusPolicy(Qt.WheelFocus) self.scrollArea_1.setFrameShape(QFrame.NoFrame) self.scrollArea_1.setFrameShadow(QFrame.Plain) self.scrollArea_1.setWidgetResizable(True) self.scrollAreaWidgetContents_1 = QWidget() self.gridLayout = QGridLayout(self.scrollAreaWidgetContents_1) self.gridLayout.setContentsMargins(6, 6, 6, 6) self.gridLayout.setSpacing(4) self.label_1 = QLabel(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1) self.textName = QLineEdit(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.textName, 0, 1, 1, 1) self.label_2 = QLabel(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) self.textGroup = QLineEdit(self.scrollAreaWidgetContents_1) self.gridLayout.addWidget(self.textGroup, 1, 1, 1, 1) self.label_1.setText(self.tr("Name")) self.textName.setToolTip(self.tr("Enter model name here")) self.label_2.setText(self.tr("Group")) self.textGroup.setToolTip(self.tr("Enter group name here")) self.scrollArea_1.setWidget(self.scrollAreaWidgetContents_1) self.verticalDockLayout_1.addWidget(self.scrollArea_1) self.propertiesDock.setWidget(propertiesDockContents) self.propertiesDock.setWindowTitle(self.tr("Model Properties")) self.inputsDock = QgsDockWidget(self) self.inputsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.inputsDock.setObjectName("inputsDock") self.inputsDockContents = QWidget() self.verticalLayout_3 = QVBoxLayout(self.inputsDockContents) self.verticalLayout_3.setContentsMargins(0, 0, 0, 0) self.scrollArea_2 = QgsScrollArea(self.inputsDockContents) sizePolicy.setHeightForWidth(self.scrollArea_2.sizePolicy().hasHeightForWidth()) self.scrollArea_2.setSizePolicy(sizePolicy) self.scrollArea_2.setFocusPolicy(Qt.WheelFocus) self.scrollArea_2.setFrameShape(QFrame.NoFrame) self.scrollArea_2.setFrameShadow(QFrame.Plain) self.scrollArea_2.setWidgetResizable(True) self.scrollAreaWidgetContents_2 = QWidget() self.verticalLayout = QVBoxLayout(self.scrollAreaWidgetContents_2) self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.verticalLayout.setSpacing(0) self.inputsTree = QTreeWidget(self.scrollAreaWidgetContents_2) self.inputsTree.setAlternatingRowColors(True) self.inputsTree.header().setVisible(False) self.verticalLayout.addWidget(self.inputsTree) self.scrollArea_2.setWidget(self.scrollAreaWidgetContents_2) self.verticalLayout_3.addWidget(self.scrollArea_2) self.inputsDock.setWidget(self.inputsDockContents) self.addDockWidget(Qt.DockWidgetArea(1), self.inputsDock) self.inputsDock.setWindowTitle(self.tr("Inputs")) self.algorithmsDock = QgsDockWidget(self) self.algorithmsDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.algorithmsDock.setObjectName("algorithmsDock") self.algorithmsDockContents = QWidget() self.verticalLayout_4 = QVBoxLayout(self.algorithmsDockContents) self.verticalLayout_4.setContentsMargins(0, 0, 0, 0) self.scrollArea_3 = QgsScrollArea(self.algorithmsDockContents) sizePolicy.setHeightForWidth(self.scrollArea_3.sizePolicy().hasHeightForWidth()) self.scrollArea_3.setSizePolicy(sizePolicy) self.scrollArea_3.setFocusPolicy(Qt.WheelFocus) self.scrollArea_3.setFrameShape(QFrame.NoFrame) self.scrollArea_3.setFrameShadow(QFrame.Plain) self.scrollArea_3.setWidgetResizable(True) self.scrollAreaWidgetContents_3 = QWidget() self.verticalLayout_2 = QVBoxLayout(self.scrollAreaWidgetContents_3) self.verticalLayout_2.setContentsMargins(0, 0, 0, 0) self.verticalLayout_2.setSpacing(4) self.searchBox = QgsFilterLineEdit(self.scrollAreaWidgetContents_3) self.verticalLayout_2.addWidget(self.searchBox) self.algorithmTree = QgsProcessingToolboxTreeView(None, QgsApplication.processingRegistry()) self.algorithmTree.setAlternatingRowColors(True) self.algorithmTree.header().setVisible(False) self.verticalLayout_2.addWidget(self.algorithmTree) self.scrollArea_3.setWidget(self.scrollAreaWidgetContents_3) self.verticalLayout_4.addWidget(self.scrollArea_3) self.algorithmsDock.setWidget(self.algorithmsDockContents) self.addDockWidget(Qt.DockWidgetArea(1), self.algorithmsDock) self.algorithmsDock.setWindowTitle(self.tr("Algorithms")) self.searchBox.setToolTip(self.tr("Enter algorithm name to filter list")) self.searchBox.setShowSearchIcon(True) self.variables_dock = QgsDockWidget(self) self.variables_dock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable) self.variables_dock.setObjectName("variablesDock") self.variables_dock_contents = QWidget() vl_v = QVBoxLayout() vl_v.setContentsMargins(0, 0, 0, 0) self.variables_editor = QgsVariableEditorWidget() vl_v.addWidget(self.variables_editor) self.variables_dock_contents.setLayout(vl_v) self.variables_dock.setWidget(self.variables_dock_contents) self.addDockWidget(Qt.DockWidgetArea(1), self.variables_dock) self.variables_dock.setWindowTitle(self.tr("Variables")) self.addDockWidget(Qt.DockWidgetArea(1), self.propertiesDock) self.tabifyDockWidget(self.propertiesDock, self.variables_dock) self.variables_editor.scopeChanged.connect(self.variables_changed) self.bar = QgsMessageBar() self.bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) self.centralWidget().layout().insertWidget(0, self.bar) try: self.setDockOptions(self.dockOptions() | QMainWindow.GroupedDragging) except: pass if iface is not None: self.mToolbar.setIconSize(iface.iconSize()) self.setStyleSheet(iface.mainWindow().styleSheet()) self.toolbutton_export_to_script = QToolButton() self.toolbutton_export_to_script.setPopupMode(QToolButton.InstantPopup) self.export_to_script_algorithm_action = QAction(QCoreApplication.translate('ModelerDialog', 'Export as Script Algorithm…')) self.toolbutton_export_to_script.addActions([self.export_to_script_algorithm_action]) self.mToolbar.insertWidget(self.mActionExportImage, self.toolbutton_export_to_script) self.export_to_script_algorithm_action.triggered.connect(self.export_as_script_algorithm) self.mActionOpen.setIcon( QgsApplication.getThemeIcon('/mActionFileOpen.svg')) self.mActionSave.setIcon( QgsApplication.getThemeIcon('/mActionFileSave.svg')) self.mActionSaveAs.setIcon( QgsApplication.getThemeIcon('/mActionFileSaveAs.svg')) self.mActionSaveInProject.setIcon( QgsApplication.getThemeIcon('/mAddToProject.svg')) self.mActionZoomActual.setIcon( QgsApplication.getThemeIcon('/mActionZoomActual.svg')) self.mActionZoomIn.setIcon( QgsApplication.getThemeIcon('/mActionZoomIn.svg')) self.mActionZoomOut.setIcon( QgsApplication.getThemeIcon('/mActionZoomOut.svg')) self.mActionExportImage.setIcon( QgsApplication.getThemeIcon('/mActionSaveMapAsImage.svg')) self.mActionZoomToItems.setIcon( QgsApplication.getThemeIcon('/mActionZoomFullExtent.svg')) self.mActionExportPdf.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsPDF.svg')) self.mActionExportSvg.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsSVG.svg')) self.toolbutton_export_to_script.setIcon( QgsApplication.getThemeIcon('/mActionSaveAsPython.svg')) self.mActionEditHelp.setIcon( QgsApplication.getThemeIcon('/mActionEditHelpContent.svg')) self.mActionRun.setIcon( QgsApplication.getThemeIcon('/mActionStart.svg')) self.addDockWidget(Qt.LeftDockWidgetArea, self.propertiesDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.inputsDock) self.addDockWidget(Qt.LeftDockWidgetArea, self.algorithmsDock) self.tabifyDockWidget(self.inputsDock, self.algorithmsDock) self.inputsDock.raise_() self.setWindowFlags(Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint | Qt.WindowCloseButtonHint) settings = QgsSettings() self.restoreState(settings.value("/Processing/stateModeler", QByteArray())) self.restoreGeometry(settings.value("/Processing/geometryModeler", QByteArray())) self.scene = ModelerScene(self, dialog=self) self.scene.setSceneRect(QRectF(0, 0, self.CANVAS_SIZE, self.CANVAS_SIZE)) self.view.setScene(self.scene) self.view.setAcceptDrops(True) self.view.ensureVisible(0, 0, 10, 10) self.view.scale(QgsApplication.desktop().logicalDpiX() / 96, QgsApplication.desktop().logicalDpiX() / 96) def _dragEnterEvent(event): if event.mimeData().hasText() or event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'): event.acceptProposedAction() else: event.ignore() def _dropEvent(event): def alg_dropped(algorithm_id, pos): alg = QgsApplication.processingRegistry().createAlgorithmById(algorithm_id) if alg is not None: self._addAlgorithm(alg, pos) else: assert False, algorithm_id def input_dropped(id, pos): if id in [param.id() for param in QgsApplication.instance().processingRegistry().parameterTypes()]: self.addInputOfType(itemId, pos) if event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'): data = event.mimeData().data('application/x-vnd.qgis.qgis.algorithmid') stream = QDataStream(data, QIODevice.ReadOnly) algorithm_id = stream.readQString() QTimer.singleShot(0, lambda id=algorithm_id, pos=self.view.mapToScene(event.pos()): alg_dropped(id, pos)) event.accept() elif event.mimeData().hasText(): itemId = event.mimeData().text() QTimer.singleShot(0, lambda id=itemId, pos=self.view.mapToScene(event.pos()): input_dropped(id, pos)) event.accept() else: event.ignore() def _dragMoveEvent(event): if event.mimeData().hasText() or event.mimeData().hasFormat('application/x-vnd.qgis.qgis.algorithmid'): event.accept() else: event.ignore() def _wheelEvent(event): self.view.setTransformationAnchor(QGraphicsView.AnchorUnderMouse) settings = QgsSettings() factor = settings.value('/qgis/zoom_favor', 2.0) # "Normal" mouse has an angle delta of 120, precision mouses provide data # faster, in smaller steps factor = 1.0 + (factor - 1.0) / 120.0 * abs(event.angleDelta().y()) if (event.modifiers() == Qt.ControlModifier): factor = 1.0 + (factor - 1.0) / 20.0 if event.angleDelta().y() < 0: factor = 1 / factor self.view.scale(factor, factor) def _enterEvent(e): QGraphicsView.enterEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mouseReleaseEvent(e): QGraphicsView.mouseReleaseEvent(self.view, e) self.view.viewport().setCursor(Qt.ArrowCursor) def _mousePressEvent(e): if e.button() == Qt.MidButton: self.previousMousePos = e.pos() else: QGraphicsView.mousePressEvent(self.view, e) def _mouseMoveEvent(e): if e.buttons() == Qt.MidButton: offset = self.previousMousePos - e.pos() self.previousMousePos = e.pos() self.view.verticalScrollBar().setValue(self.view.verticalScrollBar().value() + offset.y()) self.view.horizontalScrollBar().setValue(self.view.horizontalScrollBar().value() + offset.x()) else: QGraphicsView.mouseMoveEvent(self.view, e) self.view.setDragMode(QGraphicsView.ScrollHandDrag) self.view.dragEnterEvent = _dragEnterEvent self.view.dropEvent = _dropEvent self.view.dragMoveEvent = _dragMoveEvent self.view.wheelEvent = _wheelEvent self.view.enterEvent = _enterEvent self.view.mousePressEvent = _mousePressEvent self.view.mouseMoveEvent = _mouseMoveEvent def _mimeDataInput(items): mimeData = QMimeData() text = items[0].data(0, Qt.UserRole) mimeData.setText(text) return mimeData self.inputsTree.mimeData = _mimeDataInput self.inputsTree.setDragDropMode(QTreeWidget.DragOnly) self.inputsTree.setDropIndicatorShown(True) self.algorithms_model = ModelerToolboxModel(self, QgsApplication.processingRegistry()) self.algorithmTree.setToolboxProxyModel(self.algorithms_model) self.algorithmTree.setDragDropMode(QTreeWidget.DragOnly) self.algorithmTree.setDropIndicatorShown(True) filters = QgsProcessingToolboxProxyModel.Filters(QgsProcessingToolboxProxyModel.FilterModeler) if ProcessingConfig.getSetting(ProcessingConfig.SHOW_ALGORITHMS_KNOWN_ISSUES): filters |= QgsProcessingToolboxProxyModel.FilterShowKnownIssues self.algorithmTree.setFilters(filters) if hasattr(self.searchBox, 'setPlaceholderText'): self.searchBox.setPlaceholderText(QCoreApplication.translate('ModelerDialog', 'Search…')) if hasattr(self.textName, 'setPlaceholderText'): self.textName.setPlaceholderText(self.tr('Enter model name here')) if hasattr(self.textGroup, 'setPlaceholderText'): self.textGroup.setPlaceholderText(self.tr('Enter group name here')) # Connect signals and slots self.inputsTree.doubleClicked.connect(self.addInput) self.searchBox.textChanged.connect(self.algorithmTree.setFilterString) self.algorithmTree.doubleClicked.connect(self.addAlgorithm) # Ctrl+= should also trigger a zoom in action ctrlEquals = QShortcut(QKeySequence("Ctrl+="), self) ctrlEquals.activated.connect(self.zoomIn) self.mActionOpen.triggered.connect(self.openModel) self.mActionSave.triggered.connect(self.save) self.mActionSaveAs.triggered.connect(self.saveAs) self.mActionSaveInProject.triggered.connect(self.saveInProject) self.mActionZoomIn.triggered.connect(self.zoomIn) self.mActionZoomOut.triggered.connect(self.zoomOut) self.mActionZoomActual.triggered.connect(self.zoomActual) self.mActionZoomToItems.triggered.connect(self.zoomToItems) self.mActionExportImage.triggered.connect(self.exportAsImage) self.mActionExportPdf.triggered.connect(self.exportAsPdf) self.mActionExportSvg.triggered.connect(self.exportAsSvg) #self.mActionExportPython.triggered.connect(self.exportAsPython) self.mActionEditHelp.triggered.connect(self.editHelp) self.mActionRun.triggered.connect(self.runModel) if model is not None: self.model = model.create() self.model.setSourceFilePath(model.sourceFilePath()) self.textGroup.setText(self.model.group()) self.textName.setText(self.model.displayName()) self.repaintModel() else: self.model = QgsProcessingModelAlgorithm() self.model.setProvider(QgsApplication.processingRegistry().providerById('model')) self.update_variables_gui() self.fillInputsTree() self.view.centerOn(0, 0) self.help = None self.hasChanged = False
def otbPath(): folder = ProcessingConfig.getSetting(OTB_FOLDER) if folder is None: folder = "" return folder
def initializeSettings(self): AlgorithmProvider.initializeSettings(self) ProcessingConfig.addSetting( Setting(self.name(), GdalUtils.GDAL_HELP_PATH, self.tr('Location of GDAL docs'), GdalUtils.gdalHelpPath()))
def unload(self): ProcessingConfig.removeSetting('ACTIVATE_GRASS7') if isMac(): ProcessingConfig.removeSetting(Grass7Utils.GRASS_FOLDER) ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS) ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE) ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_PATH) ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_VEXTERNAL)
def fillTreeUsingProviders(self): self.items = {} self.model.clear() self.model.setHorizontalHeaderLabels( [self.tr('Setting'), self.tr('Value')]) settings = ProcessingConfig.getSettings() rootItem = self.model.invisibleRootItem() """ Filter 'General', 'Models' and 'Scripts' items """ priorityKeys = [ self.tr('General'), self.tr('Models'), self.tr('Scripts') ] for group in priorityKeys: groupItem = QStandardItem(group) icon = ProcessingConfig.getGroupIcon(group) groupItem.setIcon(icon) groupItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) rootItem.insertRow(0, [groupItem, emptyItem]) if not group in settings: continue # add menu item only if it has any search matches for setting in settings[group]: if setting.hidden or setting.name.startswith("MENU_"): continue labelItem = QStandardItem(setting.description) labelItem.setIcon(icon) labelItem.setEditable(False) self.items[setting] = SettingItem(setting) groupItem.insertRow(0, [labelItem, self.items[setting]]) """ Filter 'Providers' items """ providersItem = QStandardItem(self.tr('Providers')) icon = QgsApplication.getThemeIcon("/processingAlgorithm.svg") providersItem.setIcon(icon) providersItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) rootItem.insertRow(0, [providersItem, emptyItem]) for group in list(settings.keys()): if group in priorityKeys or group == menusSettingsGroup: continue groupItem = QStandardItem(group) icon = ProcessingConfig.getGroupIcon(group) groupItem.setIcon(icon) groupItem.setEditable(False) for setting in settings[group]: if setting.hidden: continue labelItem = QStandardItem(setting.description) labelItem.setIcon(icon) labelItem.setEditable(False) self.items[setting] = SettingItem(setting) groupItem.insertRow(0, [labelItem, self.items[setting]]) emptyItem = QStandardItem() emptyItem.setEditable(False) providersItem.appendRow([groupItem, emptyItem]) """ Filter 'Menus' items """ self.menusItem = QStandardItem(self.tr('Menus')) icon = QIcon(os.path.join(pluginPath, 'images', 'menu.png')) self.menusItem.setIcon(icon) self.menusItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) rootItem.insertRow(0, [self.menusItem, emptyItem]) button = QPushButton(self.tr('Reset to defaults')) button.clicked.connect(self.resetMenusToDefaults) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) layout.addWidget(button) layout.addStretch() widget = QWidget() widget.setLayout(layout) self.tree.setIndexWidget(emptyItem.index(), widget) for provider in QgsApplication.processingRegistry().providers(): providerDescription = provider.name() groupItem = QStandardItem(providerDescription) icon = provider.icon() groupItem.setIcon(icon) groupItem.setEditable(False) for alg in provider.algorithms(): algItem = QStandardItem(alg.displayName()) algItem.setIcon(icon) algItem.setEditable(False) try: settingMenu = ProcessingConfig.settings["MENU_" + alg.id()] settingButton = ProcessingConfig.settings["BUTTON_" + alg.id()] settingIcon = ProcessingConfig.settings["ICON_" + alg.id()] except: continue self.items[settingMenu] = SettingItem(settingMenu) self.items[settingButton] = SettingItem(settingButton) self.items[settingIcon] = SettingItem(settingIcon) menuLabelItem = QStandardItem("Menu path") menuLabelItem.setEditable(False) buttonLabelItem = QStandardItem("Add button in toolbar") buttonLabelItem.setEditable(False) iconLabelItem = QStandardItem("Icon") iconLabelItem.setEditable(False) emptyItem = QStandardItem() emptyItem.setEditable(False) algItem.insertRow(0, [menuLabelItem, self.items[settingMenu]]) algItem.insertRow(0, [buttonLabelItem, self.items[settingButton]]) algItem.insertRow(0, [iconLabelItem, self.items[settingIcon]]) groupItem.insertRow(0, [algItem, emptyItem]) emptyItem = QStandardItem() emptyItem.setEditable(False) self.menusItem.appendRow([groupItem, emptyItem]) self.tree.sortByColumn(0, Qt.AscendingOrder) self.adjustColumns()
def accept(self): self.settings.setValue("/Processing/dialogBase", self.saveGeometry()) checkCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_CRS) try: self.setParamValues() if checkCRS and not self.alg.checkInputCRS(): reply = QMessageBox.question( self, self.tr("Unmatching CRS's"), self.tr('Layers do not all use the same CRS. This can ' 'cause unexpected results.\nDo you want to ' 'continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return checkExtentCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_EXTENT_CRS) if checkExtentCRS and self.checkExtentCRS(): reply = QMessageBox.question( self, self.tr("Extent CRS"), self. tr('Extent parameters must use the same CRS as the input layers.\n' 'Your input layers do not have the same extent as the project, ' 'so the extent might be in a wrong CRS if you have selected it from the canvas.\n' 'Do you want to continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return msg = self.alg._checkParameterValuesBeforeExecuting() if msg: QMessageBox.warning(self, self.tr('Unable to execute algorithm'), msg) return self.btnRun.setEnabled(False) self.btnClose.setEnabled(False) buttons = self.mainWidget.iterateButtons self.iterateParam = None for i in range(len(list(buttons.values()))): button = list(buttons.values())[i] if button.isChecked(): self.iterateParam = list(buttons.keys())[i] break self.progressBar.setMaximum(0) self.lblProgress.setText(self.tr('Processing algorithm...')) # Make sure the Log tab is visible before executing the algorithm try: self.tabWidget.setCurrentIndex(1) self.repaint() except: pass QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.setInfo( self.tr('<b>Algorithm %s starting...</b>') % self.alg.name) if self.iterateParam: if runalgIterating(self.alg, self.iterateParam, self.feedback): self.finish() else: QApplication.restoreOverrideCursor() self.resetGUI() else: command = self.alg.getAsCommand() if command: ProcessingLog.addToLog(ProcessingLog.LOG_ALGORITHM, command) if runalg(self.alg, self.feedback): self.finish() else: QApplication.restoreOverrideCursor() self.resetGUI() except AlgorithmDialogBase.InvalidParameterValue as e: try: self.buttonBox.accepted.connect( lambda e=e: e.widget.setPalette(QPalette())) palette = e.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) e.widget.setPalette(palette) except: pass self.bar.clearWidgets() self.bar.pushMessage("", "Wrong or missing parameter value: %s" % e.parameter.description, level=QgsMessageBar.WARNING, duration=5)
def accept(self): checkCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_CRS) keepOpen = ProcessingConfig.getSetting( ProcessingConfig.KEEP_DIALOG_OPEN) try: self.setParamValues() if checkCRS and not self.alg.checkInputCRS(): reply = QMessageBox.question( self, "Unmatching CRS's", 'Layers do not all use the same CRS.\n' + 'This can cause unexpected results.\n' + 'Do you want to continue?', QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) if reply == QtGui.QMessageBox.No: return msg = self.alg.checkParameterValuesBeforeExecuting() if msg: QMessageBox.critical(self, 'Unable to execute algorithm', msg) return self.runButton.setEnabled(False) self.buttonBox.button( QtGui.QDialogButtonBox.Close).setEnabled(False) buttons = self.paramTable.iterateButtons self.iterateParam = None for i in range(len(buttons.values())): button = buttons.values()[i] if button.isChecked(): self.iterateParam = buttons.keys()[i] break self.tabWidget.setCurrentIndex(1) # Log tab self.progress.setMaximum(0) self.progressLabel.setText('Processing algorithm...') QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) self.setInfo('<b>Algorithm %s starting...</b>' % self.alg.name) if self.iterateParam: if UnthreadedAlgorithmExecutor.runalgIterating( self.alg, self.iterateParam, self): self.finish() else: QApplication.restoreOverrideCursor() self.resetGUI() else: command = self.alg.getAsCommand() if command: ProcessingLog.addToLog(ProcessingLog.LOG_ALGORITHM, command) if UnthreadedAlgorithmExecutor.runalg(self.alg, self): self.finish() else: QApplication.restoreOverrideCursor() self.resetGUI() except AlgorithmExecutionDialog.InvalidParameterValue, ex: try: self.buttonBox.accepted.connect( lambda: ex.widget.setPalette(QPalette())) palette = ex.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) ex.widget.setPalette(palette) self.progressLabel.setText('<b>Missing parameter value: ' + ex.parameter.description + '</b>') return except: QMessageBox.critical(self, 'Unable to execute algorithm', 'Wrong or missing parameter values')
def isActive(self): return ProcessingConfig.getSetting('ACTIVATE_GDAL')
def processAlgorithm(self, parameters, context, feedback): commands = list() self.exportedLayers = {} self.preProcessInputs() extent = None crs = None # 1: Export rasters to sgrd and vectors to shp # Tables must be in dbf format. We check that. for param in self.parameterDefinitions(): if isinstance(param, QgsProcessingParameterRasterLayer): if param.name() not in parameters or parameters[param.name()] is None: continue if isinstance(parameters[param.name()], str): if parameters[param.name()].lower().endswith('sdat'): self.exportedLayers[param.name()] = parameters[param.name()][:-4] + 'sgrd' elif parameters[param.name()].lower().endswith('sgrd'): self.exportedLayers[param.name()] = parameters[param.name()] else: layer = self.parameterAsRasterLayer(parameters, param.name(), context) exportCommand = self.exportRasterLayer(param.name(), layer) if exportCommand is not None: commands.append(exportCommand) else: if parameters[param.name()].source().lower().endswith('sdat'): self.exportedLayers[param.name()] = parameters[param.name()].source()[:-4] + 'sgrd' if parameters[param.name()].source().lower().endswith('sgrd'): self.exportedLayers[param.name()] = parameters[param.name()].source() else: exportCommand = self.exportRasterLayer(param.name(), parameters[param.name()]) if exportCommand is not None: commands.append(exportCommand) elif isinstance(param, QgsProcessingParameterFeatureSource): if param.name() not in parameters or parameters[param.name()] is None: continue if not crs: source = self.parameterAsSource(parameters, param.name(), context) if source is None: raise QgsProcessingException(self.invalidSourceError(parameters, param.name())) crs = source.sourceCrs() layer_path = self.parameterAsCompatibleSourceLayerPath(parameters, param.name(), context, ['shp'], 'shp', feedback=feedback) if layer_path: self.exportedLayers[param.name()] = layer_path else: raise QgsProcessingException( self.tr('Unsupported file format')) elif isinstance(param, QgsProcessingParameterMultipleLayers): if param.name() not in parameters or parameters[param.name()] is None: continue layers = self.parameterAsLayerList(parameters, param.name(), context) if layers is None or len(layers) == 0: continue if param.layerType() == QgsProcessing.TypeRaster: files = [] for i, layer in enumerate(layers): if layer.source().lower().endswith('sdat'): files.append(layer.source()[:-4] + 'sgrd') if layer.source().lower().endswith('sgrd'): files.append(layer.source()) else: exportCommand = self.exportRasterLayer(param.name(), layer) files.append(self.exportedLayers[param.name()]) if exportCommand is not None: commands.append(exportCommand) self.exportedLayers[param.name()] = files else: for layer in layers: temp_params = {} temp_params[param.name()] = layer if not crs: source = self.parameterAsSource(temp_params, param.name(), context) if source is None: raise QgsProcessingException(self.invalidSourceError(parameters, param.name())) crs = source.sourceCrs() layer_path = self.parameterAsCompatibleSourceLayerPath(temp_params, param.name(), context, ['shp'], 'shp', feedback=feedback) if layer_path: if param.name() in self.exportedLayers: self.exportedLayers[param.name()].append(layer_path) else: self.exportedLayers[param.name()] = [layer_path] else: raise QgsProcessingException( self.tr('Unsupported file format')) # 2: Set parameters and outputs command = self.undecorated_group + ' "' + self.cmdname + '"' command += ' ' + ' '.join(self.hardcoded_strings) for param in self.parameterDefinitions(): if not param.name() in parameters or parameters[param.name()] is None: continue if param.isDestination(): continue if isinstance(param, (QgsProcessingParameterRasterLayer, QgsProcessingParameterFeatureSource)): command += ' -{} "{}"'.format(param.name(), self.exportedLayers[param.name()]) elif isinstance(param, QgsProcessingParameterMultipleLayers): if parameters[param.name()]: # parameter may have been an empty list command += ' -{} "{}"'.format(param.name(), ';'.join(self.exportedLayers[param.name()])) elif isinstance(param, QgsProcessingParameterBoolean): if self.parameterAsBoolean(parameters, param.name(), context): command += ' -{} true'.format(param.name().strip()) else: command += ' -{} false'.format(param.name().strip()) elif isinstance(param, QgsProcessingParameterMatrix): tempTableFile = getTempFilename('txt') with open(tempTableFile, 'w') as f: f.write('\t'.join([col for col in param.headers()]) + '\n') values = self.parameterAsMatrix(parameters, param.name(), context) for i in range(0, len(values), 3): s = '{}\t{}\t{}\n'.format(values[i], values[i + 1], values[i + 2]) f.write(s) command += ' -{} "{}"'.format(param.name(), tempTableFile) elif isinstance(param, QgsProcessingParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize(parameters, context) / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] rect = self.parameterAsExtent(parameters, param.name(), context) values = [] values.append(rect.xMinimum()) values.append(rect.xMaximum()) values.append(rect.yMinimum()) values.append(rect.yMaximum()) for i in range(4): command += ' -{} {}'.format(param.name().split(' ')[i], float(values[i]) + offset[i]) elif isinstance(param, QgsProcessingParameterNumber): if param.dataType() == QgsProcessingParameterNumber.Integer: command += ' -{} {}'.format(param.name(), self.parameterAsInt(parameters, param.name(), context)) else: command += ' -{} {}'.format(param.name(), self.parameterAsDouble(parameters, param.name(), context)) elif isinstance(param, QgsProcessingParameterEnum): command += ' -{} {}'.format(param.name(), self.parameterAsEnum(parameters, param.name(), context)) elif isinstance(param, (QgsProcessingParameterString, QgsProcessingParameterFile)): command += ' -{} "{}"'.format(param.name(), self.parameterAsFile(parameters, param.name(), context)) elif isinstance(param, (QgsProcessingParameterString, QgsProcessingParameterField)): command += ' -{} "{}"'.format(param.name(), self.parameterAsString(parameters, param.name(), context)) output_layers = [] output_files = {} #If the user has entered an output file that has non-ascii chars, we use a different path with only ascii chars output_files_nonascii = {} for out in self.destinationParameterDefinitions(): filePath = self.parameterAsOutputLayer(parameters, out.name(), context) if isinstance(out, (QgsProcessingParameterRasterDestination, QgsProcessingParameterVectorDestination)): output_layers.append(filePath) try: filePath.encode('ascii') except UnicodeEncodeError: nonAsciiFilePath = filePath filePath = QgsProcessingUtils.generateTempFilename(out.name() + os.path.splitext(filePath)[1]) output_files_nonascii[filePath] = nonAsciiFilePath output_files[out.name()] = filePath command += ' -{} "{}"'.format(out.name(), filePath) commands.append(command) # special treatment for RGB algorithm # TODO: improve this and put this code somewhere else for out in self.destinationParameterDefinitions(): if isinstance(out, QgsProcessingParameterRasterDestination): filename = self.parameterAsOutputLayer(parameters, out.name(), context) filename2 = os.path.splitext(filename)[0] + '.sgrd' if self.cmdname == 'RGB Composite': commands.append('io_grid_image 0 -COLOURING 4 -GRID:"{}" -FILE:"{}"'.format(filename2, filename)) # 3: Run SAGA commands = self.editCommands(commands) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) loglines = [] loglines.append(self.tr('SAGA execution commands')) for line in commands: feedback.pushCommandInfo(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): QgsMessageLog.logMessage('\n'.join(loglines), self.tr('Processing'), Qgis.Info) SagaUtils.executeSaga(feedback) if crs is not None: for out in output_layers: prjFile = os.path.splitext(out)[0] + '.prj' with open(prjFile, 'w') as f: f.write(crs.toWkt()) for old, new in output_files_nonascii.items(): oldFolder = os.path.dirname(old) newFolder = os.path.dirname(new) newName = os.path.splitext(os.path.basename(new))[0] files = [f for f in os.listdir(oldFolder)] for f in files: ext = os.path.splitext(f)[1] newPath = os.path.join(newFolder, newName + ext) oldPath = os.path.join(oldFolder, f) shutil.move(oldPath, newPath) result = {} for o in self.outputDefinitions(): if o.name() in output_files: result[o.name()] = output_files[o.name()] return result
def testGrass(self): folder = ProcessingConfig.getSetting(GrassUtils.GRASS_FOLDER) ProcessingConfig.removeSetting(GrassUtils.GRASS_FOLDER) msg = GrassUtils.checkGrassIsInstalled() self.assertIsNone(msg) ProcessingConfig.setSettingValue(GrassUtils.GRASS_FOLDER, folder)
def removeMenus(): for alg in QgsApplication.processingRegistry().algorithms(): menuPath = ProcessingConfig.getSetting("MENU_" + alg.id()) if menuPath: paths = menuPath.split("/") removeAlgorithmEntry(alg, paths[0], paths[-1])
def hasWine(): wine_folder = ProcessingConfig.getSetting(LAStoolsUtils.WINE_FOLDER) return wine_folder is not None and wine_folder != ""
def __init__(self, alg): super(AlgorithmDialogBase, self).__init__(iface.mainWindow()) self.setupUi(self) self.feedback = AlgorithmDialogFeedback(self) self.feedback.progressChanged.connect(self.setPercentage) self.settings = QgsSettings() self.restoreGeometry(self.settings.value("/Processing/dialogBase", QByteArray())) self.executed = False self.mainWidget = None self.alg = alg # Rename OK button to Run self.btnRun = self.buttonBox.button(QDialogButtonBox.Ok) self.btnRun.setText(self.tr('Run')) self.btnClose = self.buttonBox.button(QDialogButtonBox.Close) self.setWindowTitle(self.alg.displayName()) # desktop = QDesktopWidget() # if desktop.physicalDpiX() > 96: # self.txtHelp.setZoomFactor(desktop.physicalDpiX() / 96) algHelp = self.alg.shortHelp() if algHelp is None: self.textShortHelp.setVisible(False) else: self.textShortHelp.document().setDefaultStyleSheet('''.summary { margin-left: 10px; margin-right: 10px; } h2 { color: #555555; padding-bottom: 15px; } a { text-decoration: none; color: #3498db; font-weight: bold; } p { color: #666666; } b { color: #333333; } dl dd { margin-bottom: 5px; }''') self.textShortHelp.setHtml(algHelp) self.textShortHelp.setOpenLinks(False) def linkClicked(url): webbrowser.open(url.toString()) self.textShortHelp.anchorClicked.connect(linkClicked) isText, algHelp = self.alg.help() if algHelp is not None: algHelp = algHelp if isText else QUrl(algHelp) try: if isText: self.txtHelp.setHtml(algHelp) else: html = self.tr('<p>Downloading algorithm help... Please wait.</p>') self.txtHelp.setHtml(html) rq = QNetworkRequest(algHelp) self.reply = QgsNetworkAccessManager.instance().get(rq) self.reply.finished.connect(self.requestFinished) except Exception: self.tabWidget.removeTab(2) else: self.tabWidget.removeTab(2) self.showDebug = ProcessingConfig.getSetting( ProcessingConfig.SHOW_DEBUG_IN_DIALOG)
def unload(self): AlgorithmProvider.unload(self) ProcessingConfig.addSetting(ScriptUtils.SCRIPTS_FOLDER)
def unload(self): ProcessingConfig.removeSetting('ACTIVATE_SAGA') ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_CONSOLE) ProcessingConfig.removeSetting(SagaUtils.SAGA_LOG_COMMANDS)
def setActive(self, active): ProcessingConfig.setSettingValue('ACTIVATE_GDAL', active)
def testSaga(self): folder = ProcessingConfig.getSetting(SAGA_FOLDER) ProcessingConfig.removeSetting(SAGA_FOLDER) self.assertTrue(getSagaInstalledVersion(True) in ["2.1.2", "2.1.3", "2.1.4"]) ProcessingConfig.setSettingValue(SAGA_FOLDER, folder)
def processAlgorithm(self, progress): if system.isWindows(): path = GrassUtils.grassPath() if path == '': raise GeoAlgorithmExecutionException('GRASS folder is not \ configured.\nPlease configure it before running GRASS \ algorithms.') commands = [] self.exportedLayers = {} outputCommands = [] # If GRASS session has been created outside of this algorithm then # get the list of layers loaded in GRASS otherwise start a new # session existingSession = GrassUtils.sessionRunning if existingSession: self.exportedLayers = GrassUtils.getSessionLayers() else: GrassUtils.startGrassSession() # 1: Export layer to grass mapset for param in self.parameters: if isinstance(param, ParameterRaster): if param.value is None: continue value = param.value # Check if the layer hasn't already been exported in, for # example, previous GRASS calls in this session if value in self.exportedLayers.keys(): continue else: self.setSessionProjectionFromLayer(value, commands) commands.append(self.exportRasterLayer(value)) if isinstance(param, ParameterVector): if param.value is None: continue value = param.value if value in self.exportedLayers.keys(): continue else: self.setSessionProjectionFromLayer(value, commands) commands.append(self.exportVectorLayer(value)) if isinstance(param, ParameterTable): pass if isinstance(param, ParameterMultipleInput): if param.value is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == ParameterMultipleInput.TYPE_RASTER: for layer in layers: if layer in self.exportedLayers.keys(): continue else: self.setSessionProjectionFromLayer(layer, commands) commands.append(self.exportRasterLayer(layer)) elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: for layer in layers: if layer in self.exportedLayers.keys(): continue else: self.setSessionProjectionFromLayer(layer, commands) commands.append(self.exportVectorLayer(layer)) self.setSessionProjectionFromProject(commands) region = \ str(self.getParameterValue(self.GRASS_REGION_EXTENT_PARAMETER)) regionCoords = region.split(',') command = 'g.region' command += ' n=' + str(regionCoords[3]) command += ' s=' + str(regionCoords[2]) command += ' e=' + str(regionCoords[1]) command += ' w=' + str(regionCoords[0]) cellsize = self.getParameterValue(self.GRASS_REGION_CELLSIZE_PARAMETER) if cellsize: command += ' res=' + str(cellsize) else: command += ' res=' + str(self.getDefaultCellsize()) alignToResolution = \ self.getParameterValue(self.GRASS_REGION_ALIGN_TO_RESOLUTION) if alignToResolution: command += ' -a' commands.append(command) # 2: Set parameters and outputs command = self.grassName for param in self.parameters: if param.value is None or param.value == '': continue if param.name == self.GRASS_REGION_CELLSIZE_PARAMETER \ or param.name == self.GRASS_REGION_EXTENT_PARAMETER \ or param.name == self.GRASS_MIN_AREA_PARAMETER or param.name \ == self.GRASS_SNAP_TOLERANCE_PARAMETER or param.name \ == self.GRASS_OUTPUT_TYPE_PARAMETER or param.name \ == self.GRASS_REGION_ALIGN_TO_RESOLUTION: continue if isinstance(param, (ParameterRaster, ParameterVector)): value = param.value if value in self.exportedLayers.keys(): command += ' ' + param.name + '=' \ + self.exportedLayers[value] else: command += ' ' + param.name + '=' + value elif isinstance(param, ParameterMultipleInput): s = param.value for layer in self.exportedLayers.keys(): s = s.replace(layer, self.exportedLayers[layer]) s = s.replace(';', ',') command += ' ' + param.name + '=' + s elif isinstance(param, ParameterBoolean): if param.value: command += ' ' + param.name elif isinstance(param, ParameterSelection): idx = int(param.value) command += ' ' + param.name + '=' + str(param.options[idx]) elif isinstance(param, ParameterString): command += ' ' + param.name + '="' + str(param.value) + '"' else: command += ' ' + param.name + '="' + str(param.value) + '"' uniqueSufix = str(uuid.uuid4()).replace('-', '') for out in self.outputs: if isinstance(out, OutputFile): if out.name == 'outputtext': # The 'outputtext' file is generated by piping output # from GRASS, is not an actual grass command command += ' > ' + out.value else: command += ' ' + out.name + '="' + out.value + '"' elif not isinstance(out, OutputHTML): # Html files are not generated by GRASS, only by us to # decorate GRASS output, so we skip them. An output name # to make sure it is unique if the session uses this # algorithm several times. uniqueOutputName = out.name + uniqueSufix command += ' ' + out.name + '=' + uniqueOutputName # Add output file to exported layers, to indicate that # they are present in GRASS self.exportedLayers[out.value] = uniqueOutputName command += ' --overwrite' commands.append(command) # 3: Export resulting layers to a format that qgis can read for out in self.outputs: if isinstance(out, OutputRaster): filename = out.value # Raster layer output: adjust region to layer before # exporting commands.append('g.region rast=' + out.name + uniqueSufix) outputCommands.append('g.region rast=' + out.name + uniqueSufix) if self.grassName == 'r.composite': command = 'r.out.tiff -t --verbose' command += ' input=' command += out.name + uniqueSufix command += ' output="' + filename + '"' commands.append(command) outputCommands.append(command) else: command = 'r.out.gdal -c createopt="TFW=YES,COMPRESS=LZW"' command += ' input=' if self.grassName == 'r.horizon': command += out.name + uniqueSufix + '_0' else: command += out.name + uniqueSufix command += ' output="' + filename + '"' commands.append(command) outputCommands.append(command) if isinstance(out, OutputVector): filename = out.value command = 'v.out.ogr -s -c -e -z input=' + out.name + uniqueSufix command += ' dsn="' + os.path.dirname(out.value) + '"' command += ' format=ESRI_Shapefile' command += ' olayer=' + os.path.basename(out.value)[:-4] typeidx = \ self.getParameterValue(self.GRASS_OUTPUT_TYPE_PARAMETER) outtype = ('auto' if typeidx is None else self.OUTPUT_TYPES[typeidx]) command += ' type=' + outtype commands.append(command) outputCommands.append(command) # 4: Run GRASS loglines = [] loglines.append('GRASS execution commands') for line in commands: progress.setCommand(line) loglines.append(line) if ProcessingConfig.getSetting(GrassUtils.GRASS_LOG_COMMANDS): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) self.consoleOutput = GrassUtils.executeGrass(commands, progress, outputCommands) self.postProcessResults() # If the session has been created outside of this algorithm, add # the new GRASS layers to it otherwise finish the session if existingSession: GrassUtils.addSessionLayers(self.exportedLayers) else: GrassUtils.endGrassSession()
def load(self): ProcessingConfig.settingIcons[self.name()] = self.icon() ProcessingConfig.addSetting(Setting(self.name(), 'ACTIVATE_GRASS7', self.tr('Activate'), True)) if isMac(): ProcessingConfig.addSetting(Setting( self.name(), Grass7Utils.GRASS_FOLDER, self.tr('GRASS7 folder'), Grass7Utils.grassPath(), valuetype=Setting.FOLDER)) ProcessingConfig.addSetting(Setting( self.name(), Grass7Utils.GRASS_LOG_COMMANDS, self.tr('Log execution commands'), False)) ProcessingConfig.addSetting(Setting( self.name(), Grass7Utils.GRASS_LOG_CONSOLE, self.tr('Log console output'), False)) ProcessingConfig.addSetting(Setting( self.name(), Grass7Utils.GRASS_HELP_PATH, self.tr('Location of GRASS docs'), Grass7Utils.grassHelpPath())) # Add a setting for using v.external instead of v.in.ogr # But set it to False by default because some algorithms # can't be used with external data (need a solid v.in.ogr). ProcessingConfig.addSetting(Setting( self.name(), Grass7Utils.GRASS_USE_VEXTERNAL, self.tr('For vector layers, use v.external (faster) instead of v.in.ogr'), False)) ProcessingConfig.readSettings() self.refreshAlgorithms() return True
def runAlgorithm(self): self.feedback = self.createFeedback() self.context = dataobjects.createContext(self.feedback) checkCRS = ProcessingConfig.getSetting(ProcessingConfig.WARN_UNMATCHING_CRS) try: parameters = self.getParameterValues() if checkCRS and not self.algorithm().validateInputCrs(parameters, self.context): reply = QMessageBox.question(self, self.tr("Unmatching CRS's"), self.tr('Parameters do not all use the same CRS. This can ' 'cause unexpected results.\nDo you want to ' 'continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return ok, msg = self.algorithm().checkParameterValues(parameters, self.context) if not ok: QMessageBox.warning( self, self.tr('Unable to execute algorithm'), msg) return self.runButton().setEnabled(False) self.cancelButton().setEnabled(False) buttons = self.mainWidget().iterateButtons self.iterateParam = None for i in range(len(list(buttons.values()))): button = list(buttons.values())[i] if button.isChecked(): self.iterateParam = list(buttons.keys())[i] break self.clearProgress() self.setProgressText(QCoreApplication.translate('AlgorithmDialog', 'Processing algorithm…')) self.setInfo( QCoreApplication.translate('AlgorithmDialog', '<b>Algorithm \'{0}\' starting…</b>').format(self.algorithm().displayName()), escapeHtml=False) self.feedback.pushInfo(self.tr('Input parameters:')) display_params = [] for k, v in parameters.items(): display_params.append("'" + k + "' : " + self.algorithm().parameterDefinition(k).valueAsPythonString(v, self.context)) self.feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }') self.feedback.pushInfo('') start_time = time.time() if self.iterateParam: # Make sure the Log tab is visible before executing the algorithm try: self.showLog() self.repaint() except: pass self.cancelButton().setEnabled(self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel) if executeIterating(self.algorithm(), parameters, self.iterateParam, self.context, self.feedback): self.feedback.pushInfo( self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time)) self.cancelButton().setEnabled(False) self.finish(True, parameters, self.context, self.feedback) else: self.cancelButton().setEnabled(False) self.resetGui() else: command = self.algorithm().asPythonCommand(parameters, self.context) if command: ProcessingLog.addToLog(command) QgsGui.instance().processingRecentAlgorithmLog().push(self.algorithm().id()) self.cancelButton().setEnabled(self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel) def on_complete(ok, results): if ok: self.feedback.pushInfo(self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time)) self.feedback.pushInfo(self.tr('Results:')) self.feedback.pushCommandInfo(pformat(results)) else: self.feedback.reportError( self.tr('Execution failed after {0:0.2f} seconds').format(time.time() - start_time)) self.feedback.pushInfo('') if self.feedback_dialog is not None: self.feedback_dialog.close() self.feedback_dialog.deleteLater() self.feedback_dialog = None self.cancelButton().setEnabled(False) if not self.in_place: self.finish(ok, results, self.context, self.feedback) elif ok: self.close() self.feedback = None self.context = None if not self.in_place and not (self.algorithm().flags() & QgsProcessingAlgorithm.FlagNoThreading): # Make sure the Log tab is visible before executing the algorithm self.showLog() task = QgsProcessingAlgRunnerTask(self.algorithm(), parameters, self.context, self.feedback) task.executed.connect(on_complete) self.setCurrentTask(task) else: self.proxy_progress = QgsProxyProgressTask(QCoreApplication.translate("AlgorithmDialog", "Executing “{}”").format(self.algorithm().displayName())) QgsApplication.taskManager().addTask(self.proxy_progress) self.feedback.progressChanged.connect(self.proxy_progress.setProxyProgress) self.feedback_dialog = self.createProgressDialog() self.feedback_dialog.show() if self.in_place: ok, results = execute_in_place(self.algorithm(), parameters, self.context, self.feedback) else: ok, results = execute(self.algorithm(), parameters, self.context, self.feedback) self.feedback.progressChanged.disconnect() self.proxy_progress.finalize(ok) on_complete(ok, results) except AlgorithmDialogBase.InvalidParameterValue as e: try: self.buttonBox().accepted.connect(lambda e=e: e.widget.setPalette(QPalette())) palette = e.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) e.widget.setPalette(palette) except: pass self.messageBar().clearWidgets() self.messageBar().pushMessage("", self.tr("Wrong or missing parameter value: {0}").format(e.parameter.description()), level=Qgis.Warning, duration=5)
def otbSRTMPath(): return ProcessingConfig.getSetting(OTB_SRTM_FOLDER) or ''
def otbGeoidPath(): return ProcessingConfig.getSetting(OTB_GEOID_FILE) or ''
def otbLibPath(): return ProcessingConfig.getSetting(OTB_LIB_FOLDER) or ''
def unload(self): AlgorithmProvider.unload(self) ProcessingConfig.removeSetting(GdalUtils.GDAL_HELP_PATH)