def executeAlgorithm(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) message = alg.checkBeforeOpeningParametersDialog() if message: dlg = MissingDependencyDialog(message) dlg.exec_() #QMessageBox.warning(self, self.tr("Warning"), message) return alg = alg.getCopy() dlg = alg.getCustomParametersDialog() if not dlg: dlg = ParametersDialog(alg) canvas = QGisLayers.iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool()!=prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool) if dlg.executed: showRecent = ProcessingConfig.getSetting(ProcessingConfig.SHOW_RECENT_ALGORITHMS) if showRecent: self.addRecentAlgorithms(True) if isinstance(item, TreeActionItem): action = item.action action.setData(self) action.execute()
def executeAlgorithmAsBatchProcess(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) alg = alg.getCopy() dlg = BatchProcessingDialog(alg) dlg.exec_()
def get_args_man(self, alg): alg = Processing.getAlgorithm(alg) # make sure you don't overwrite default values! alg = alg.getCopy() vals = [] params = [] output = [] type_name = [] opts = list() if alg is None: sys.exit('Specified algorithm does not exist!') # return 'Specified algorithm does not exist!' for param in alg.parameters: params.append(param.name) vals.append(param.getValueAsCommandLineParameter()) opts.append(isinstance(param, ParameterSelection)) output.append(False) type_name.append(param.typeName()) for out in alg.outputs: params.append(out.name) vals.append(out.getValueAsCommandLineParameter()) opts.append(isinstance(out, ParameterSelection)) output.append(True) type_name.append(param.typeName()) # args = [params, vals, opts, type_name] args = dict(zip(["params", "vals", "opts", "output", "type_name"], \ [params, vals, opts, output, type_name])) return args
def alghelp(name): alg = Processing.getAlgorithm(name) if alg is not None: print str(alg) algoptions(name) else: print 'Algorithm not found'
def executeAlgorithmAsBatchProcess(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) alg = alg.getCopy() dlg = BatchProcessingDialog(alg) dlg.exec_()
def get_args_man(self, alg): alg = Processing.getAlgorithm(alg) vals = [] params = [] output = [] type_name = [] opts = list() if alg is None: sys.exit('Specified algorithm does not exist!') # return 'Specified algorithm does not exist!' alg = alg.getCopy() for param in alg.parameters: params.append(param.name) vals.append(param.getValueAsCommandLineParameter()) opts.append(isinstance(param, ParameterSelection)) output.append(False) type_name.append(param.typeName()) for out in alg.outputs: params.append(out.name) vals.append(out.getValueAsCommandLineParameter()) opts.append(isinstance(out, ParameterSelection)) output.append(True) type_name.append(param.typeName()) # args = [params, vals, opts, type_name] args = dict(zip(["params", "vals", "opts", "output", "type_name"], \ [params, vals, opts, output, type_name])) return args
def alghelp(name): alg = Processing.getAlgorithm(name) if alg != None: print(str(alg)) algoptions(name) else: print "Algorithm not found"
def run(self): alg = Processing.getAlgorithm("squadtoolbox:squadtool") # Instantiate the commander window and open the algorithm's interface cw = CommanderWindow(self.iface.mainWindow(), self.iface.mapCanvas()) if alg is not None: cw.runAlgorithm(alg)
def alghelp(name): alg = Processing.getAlgorithm(name) if alg != None: print (str(alg)) algoptions(name) else: print "Algorithm not found"
def executeAlgorithm(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) message = alg.checkBeforeOpeningParametersDialog() if message: dlg = MessageDialog() dlg.setTitle(self.tr("Missing dependency")) dlg.setMessage( self.tr("<h3>Missing dependency. This algorithm cannot " "be run :-( </h3>\n%s") % message ) dlg.exec_() return alg = alg.getCopy() dlg = alg.getCustomParametersDialog() if not dlg: dlg = AlgorithmDialog(alg) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool) if dlg.executed: showRecent = ProcessingConfig.getSetting(ProcessingConfig.SHOW_RECENT_ALGORITHMS) if showRecent: self.addRecentAlgorithms(True) if isinstance(item, TreeActionItem): action = item.action action.setData(self) action.execute()
def addRecentAlgorithms(self, updating): showRecent = ProcessingConfig.getSetting( ProcessingConfig.SHOW_RECENT_ALGORITHMS) if showRecent: recent = ProcessingLog.getRecentAlgorithms() if len(recent) != 0: found = False if updating: recentItem = self.algorithmTree.topLevelItem(0) treeWidget = recentItem.treeWidget() treeWidget.takeTopLevelItem( treeWidget.indexOfTopLevelItem(recentItem)) recentItem = QTreeWidgetItem() recentItem.setText(0, self.tr('Recently used algorithms')) for algname in recent: alg = Processing.getAlgorithm(algname) if alg is not None: algItem = TreeAlgorithmItem(alg) recentItem.addChild(algItem) found = True if found: self.algorithmTree.insertTopLevelItem(0, recentItem) recentItem.setExpanded(True) self.algorithmTree.setWordWrap(True)
def alghelp(name): alg = Processing.getAlgorithm(name) if alg is not None: print str(alg) algoptions(name) else: print 'Algorithm not found'
def alghelp(name): alg = Processing.getAlgorithm(name) if alg is not None: alg = alg.getCopy() print(str(alg)) algoptions(name) else: print('Algorithm not found')
def alghelp(name): alg = Processing.getAlgorithm(name) if alg is not None: alg = alg.getCopy() print(str(alg)) algoptions(name) else: print('Algorithm not found')
def alghelp(name): alg = Processing.getAlgorithm(name) if alg is not None: alg = alg.getCopy() print unicode(alg) algoptions(name) else: print "Algorithm not found"
def check_args(self, alg, args): alg = Processing.getAlgorithm(alg) i = 0 d = dict() for param in alg.parameters: if not param.hidden: if not param.setValue(args[i]): d[param.name] = args[i] i = i + 1 return d
def algorithmHelp(name): """Prints algorithm parameters with their types. Also provides information about options if any. """ alg = Processing.getAlgorithm(name) if alg is not None: alg = alg.getCopy() print(str(alg)) algorithmOptions(name) else: print('Algorithm "{}" not found.'.format(name))
def addAlgorithm(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) alg = alg.getCopy()#copy.deepcopy(alg) # create a tab for this algorithm stepDialog = StepDialog(alg, self) self.canvasTabWidget.addTab(stepDialog, alg.name) # add this step to the workflow self.workflow.addStep(alg, stepDialog.getMode(), stepDialog.getInstructions())
def importLayerIntoPostgis(layer, host, port, username, password, dbname, schema, tablename): extent = '{},{},{},{}'.format(layer.extent().xMinimum(), layer.extent().xMaximum(), layer.extent().yMinimum(), layer.extent().yMaximum()) geomtypes = { QGis.WKBPoint: 3, QGis.WKBLineString: 4, QGis.WKBPolygon: 5, QGis.WKBMultiPoint: 7, QGis.WKBMultiLineString: 9, QGis.WKBMultiPolygon: 8 } geomtype = geomtypes.get(layer.wkbType(), 0) params = { ogr2ogr.INPUT_LAYER: layer, ogr2ogr.DBNAME: dbname, ogr2ogr.PORT: port, ogr2ogr.HOST: host, ogr2ogr.USER: username, ogr2ogr.PASSWORD: password, ogr2ogr.SCHEMA: schema, ogr2ogr.GTYPE: geomtype, ogr2ogr.TABLE: tablename, ogr2ogr.A_SRS: "EPSG:3857", ogr2ogr.S_SRS: layer.crs().authid(), ogr2ogr.T_SRS: "EPSG:3857", ogr2ogr.DIM: 0, ogr2ogr.OVERWRITE: True, ogr2ogr.APPEND: False, ogr2ogr.SPAT: extent, ogr2ogr.GT: '', ogr2ogr.SEGMENTIZE: '', ogr2ogr.SIMPLIFY: '', ogr2ogr.OPTIONS: '', ogr2ogr.PK: '', ogr2ogr.GEOCOLUMN: '', ogr2ogr.WHERE: '' } alg = Processing.getAlgorithm( "gdalogr:importvectorintopostgisdatabasenewconnection") for name, value in params.iteritems(): param = alg.getParameterFromName(name) if param and param.setValue(value): continue output = alg.getOutputFromName(name) if output and output.setValue(value): continue AlgorithmExecutor.runalg(alg)
def get_options(self, alg): alg = Processing.getAlgorithm(alg) # create a dictionary d = dict() for param in alg.parameters: if isinstance(param, ParameterSelection): # keys of the dictionary are the function parameters for which one can # specify a selection d[param.name] = [] for option in param.options: # the values are the several options for a specific parameter d[param.name].append(option) return d
def open_help(self, alg): alg = Processing.getAlgorithm(alg) alg = alg.getCopy() provider = alg.provider.getName().lower() # to which group does the algorithm belong (e.g., vector_table_tools) groupName = alg.group.lower() # format the groupName in the QGIS way groupName = groupName.replace('[', '').replace(']', '').replace(' - ', '_') groupName = groupName.replace(' ', '_') if provider == 'saga': alg2 = alg.getCopy() groupName = alg2.undecoratedGroup groupName = groupName.replace('ta_', 'terrain_analysis_') groupName = groupName.replace('statistics_kriging', 'kriging') groupName = re.sub('^statistics_.*', 'geostatistics', groupName) groupName = re.sub('visualisation', 'visualization', groupName) groupName = re.sub('_preprocessor', '_hydrology', groupName) groupName = groupName.replace('sim_', 'simulation_') # retrieve the command line name (worked for 2.8...) # "cmdLineName = alg.commandLineName()", # "algName = cmdLineName[cmdLineName.find(':') + 1:].lower()", # for 2.14 we cannot use the algorithm name # (now you have to test all SAGA and QGIS functions again...) algName = alg.name.lower().replace(' ', '-') # just use valid characters validChars = ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS' + 'TUVWXYZ0123456789_') safeGroupName = ''.join(c for c in groupName if c in validChars) validChars = validChars + '-' safeAlgName = ''.join(c for c in algName if c in validChars) # which QGIS version are we using version = '.'.join(QGis.QGIS_VERSION.split('.')[0:2]) # build the html to the help file url = ('https:///docs.qgis.org/%s/en/docs/user_manual/' + 'processing_algs/%s/%s.html#%s') % (version, provider, safeGroupName, safeAlgName) # suppress error messages raised by the browser, e.g., # console.error: CustomizableUI: # TypeError: aNode.previousSibling is null -- # resource://app/modules/CustomizableUI.jsm:4294 # Solution was found here: # paste0("http://stackoverflow.com/questions/2323080/", # "how-can-i-disable-the-webbrowser-message-in-python") savout = os.dup(1) os.close(1) os.open(os.devnull, os.O_RDWR) try: webbrowser.open(url) finally: os.dup2(savout, 1)
def algoptions(name): alg = Processing.getAlgorithm(name) if alg != None: s = "" for param in alg.parameters: if isinstance(param, ParameterSelection): s += param.name + "(" + param.description + ")\n" i = 0 for option in param.options: s += "\t" + str(i) + " - " + str(option) + "\n" i += 1 print(s) else: print "Algorithm not found"
def algoptions(name): alg = Processing.getAlgorithm(name) if alg is not None: s = '' for param in alg.parameters: if isinstance(param, ParameterSelection): s += param.name + '(' + param.description + ')\n' i = 0 for option in param.options: s += '\t' + str(i) + ' - ' + str(option) + '\n' i += 1 print(s) else: print('Algorithm not found')
def algorithmOptions(name): """Prints all algorithm options with their values. """ alg = Processing.getAlgorithm(name) if alg is not None: opts = '' for param in alg.parameters: if isinstance(param, ParameterSelection): opts += '{} ({})\n'.format(param.name, param.description) for option in enumerate(param.options): opts += '\t{} - {}\n'.format(option[0], option[1]) print(opts) else: print('Algorithm "{}" not found.'.format(name))
def algoptions(name): alg = Processing.getAlgorithm(name) if alg != None: s = "" for param in alg.parameters: if isinstance(param, ParameterSelection): s += param.name + "(" + param.description + ")\n" i = 0 for option in param.options: s += "\t" + str(i) + " - " + str(option) + "\n" i += 1 print (s) else: print "Algorithm not found"
def algoptions(name): alg = Processing.getAlgorithm(name) if alg is not None: s = '' for param in alg.parameters: if isinstance(param, ParameterSelection): s += param.name + '(' + param.description + ')\n' i = 0 for option in param.options: s += '\t' + str(i) + ' - ' + str(option) + '\n' i += 1 print(s) else: print('Algorithm not found')
def get_options(self, alg): alg = Processing.getAlgorithm(alg) # just in case, make sure to not overwrite any default values alg = alg.getCopy() # create a dictionary d = dict() for param in alg.parameters: if isinstance(param, ParameterSelection): # keys of the dictionary are the function parameters for which one can # specify a selection d[param.name] = [] for option in param.options: # the values are the several options for a specific parameter d[param.name].append(option) return d
def check_args(self, alg, args): alg = Processing.getAlgorithm(alg) # make sure to not overwrite any default values # using param.setValue would do so alg = alg.getCopy() i = 0 d = dict() # alg.parameters does not return output values # alg.outputs would do so (see get_args_man) for param in alg.parameters: if not param.hidden: if not param.setValue(args[i]): d[param.name] = args[i] i = i + 1 return d
def check_args(self, alg, args): alg = Processing.getAlgorithm(alg) # make sure to not overwrite any default values # using param.setValue would do so alg = alg.getCopy() i = 0 d = dict() # alg.parameters does not return output values # alg.outputs would do so (see get_args_man) for param in alg.parameters: if not param.hidden: if not param.setValue(args[i]): d[param.name] = args[i] i = i + 1 return d
def addAlgorithmEntry(algname, menuName, submenuName, actionText=None, icon=None, addButton=False): alg = Processing.getAlgorithm(algname) if alg is None: return if menuName: menu = getMenu(menuName, iface.mainWindow().menuBar()) submenu = getMenu(submenuName, menu) action = QtGui.QAction(icon or alg.getIcon(), actionText or alg.name, iface.mainWindow()) action.triggered.connect(lambda: _executeAlgorithm(alg)) submenu.addAction(action) if addButton: global algorithmsToolbar if algorithmsToolbar is None: algorithmsToolbar = iface.addToolBar("ProcessingAlgorithms") algorithmsToolbar.addAction(action)
def run_wholeOfBlockAnalysis(self): """Run method for the fit to block grid dialog""" # https://gis.stackexchange.com/a/160146 result = check_R_dependency() if result is not True: self.iface.messageBar().pushMessage("R configuration", result, level=QgsMessageBar.WARNING, duration=15) return proc_alg_mess = ProcessingAlgMessages(self.iface) QgsMessageLog.instance().messageReceived.connect(proc_alg_mess.processingCatcher) # Then get the algorithm you're interested in (for instance, Join Attributes): alg = Processing.getAlgorithm("r:wholeofblockanalysis") if alg is None: self.iface.messageBar().pushMessage("Whole-of-block analysis algorithm could not" " be found", level=QgsMessageBar.CRITICAL) return # Instantiate the commander window and open the algorithm's interface cw = CommanderWindow(self.iface.mainWindow(), self.iface.mapCanvas()) if alg is not None: cw.runAlgorithm(alg) # if proc_alg_mess.alg_name == '' then cancel was clicked if proc_alg_mess.error: self.iface.messageBar().pushMessage("Whole-of-block analysis", proc_alg_mess.error_msg, level=QgsMessageBar.CRITICAL, duration=0) elif proc_alg_mess.alg_name != '': data_column = proc_alg_mess.parameters['Data_Column'] # load rasters into qgis as grouped layers. for key, val in proc_alg_mess.output_files.items(): grplyr = os.path.join('Whole-of-block {}'.format(data_column), val['title']) for ea_file in val['files']: removeFileFromQGIS(ea_file) raster_layer = addRasterFileToQGIS(ea_file, group_layer_name=grplyr, atTop=False) if key in ['p_val']: raster_apply_unique_value_renderer(raster_layer) self.iface.messageBar().pushMessage("Whole-of-block analysis Completed Successfully!", level=QgsMessageBar.INFO, duration=15) del proc_alg_mess
def executeAlgorithm(value, iface): for providerName in Processing.algs.keys(): provider = Processing.algs[providerName] algs = provider.values() for alg in algs: if value == alg.name: try: alg = Processing.getAlgorithm(alg.commandLineName()) message = alg.checkBeforeOpeningParametersDialog() except: iface.messageBar().pushMessage( "Error: ", "Error loading Processing Algorithm.", level=QgsMessageBar.CRITICAL, duration=3) return if message: dlg = MessageDialog() dlg.setTitle(tr('Missing dependency')) dlg.setMessage( tr('<h3>Missing dependency. This algorithm cannot ' 'be run :-( </h3>\n%s') % message) dlg.exec_() return alg = alg.getCopy() dlg = alg.getCustomParametersDialog() if not dlg: try: dlg = AlgorithmDialog(alg) except: iface.messageBar().pushMessage( "Info: ", "Error loading Processing Algorithm.", level=QgsMessageBar.INFO, duration=3) return canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool) return
def importLayerIntoPostgis(layer, host, port, username, password, dbname, schema, tablename): extent = '{},{},{},{}'.format( layer.extent().xMinimum(), layer.extent().xMaximum(), layer.extent().yMinimum(), layer.extent().yMaximum()) geomtypes = {QGis.WKBPoint: 3, QGis.WKBLineString: 4, QGis.WKBPolygon: 5, QGis.WKBMultiPoint: 7, QGis.WKBMultiLineString: 9, QGis.WKBMultiPolygon: 8} geomtype = geomtypes.get(layer.wkbType(), 0) params = {ogr2ogr.INPUT_LAYER: layer, ogr2ogr.DBNAME: dbname, ogr2ogr.PORT : port, ogr2ogr.HOST : host, ogr2ogr.USER : username, ogr2ogr.PASSWORD: password, ogr2ogr.SCHEMA: schema, ogr2ogr.GTYPE: geomtype, ogr2ogr.TABLE: tablename, ogr2ogr.A_SRS: "EPSG:3857", ogr2ogr.S_SRS: layer.crs().authid(), ogr2ogr.T_SRS: "EPSG:3857", ogr2ogr.DIM: 0, ogr2ogr.OVERWRITE: True, ogr2ogr.APPEND: False, ogr2ogr.SPAT: extent, ogr2ogr.GT: '', ogr2ogr.SEGMENTIZE: '', ogr2ogr.SIMPLIFY: '', ogr2ogr.OPTIONS: '', ogr2ogr.PK: '', ogr2ogr.GEOCOLUMN: '', ogr2ogr.WHERE: '' } alg = Processing.getAlgorithm("gdalogr:importvectorintopostgisdatabasenewconnection") for name, value in params.iteritems(): param = alg.getParameterFromName(name) if param and param.setValue(value): continue output = alg.getOutputFromName(name) if output and output.setValue(value): continue AlgorithmExecutor.runalg(alg)
def executeAlgorithm(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) message = alg.checkBeforeOpeningParametersDialog() if message: dlg = MessageDialog() dlg.setTitle(self.tr('Error executing algorithm')) dlg.setMessage( self.tr('<h3>This algorithm cannot ' 'be run :-( </h3>\n%s') % message) dlg.exec_() return alg = alg.getCopy() if (alg.getVisibleParametersCount() + alg.getVisibleOutputsCount()) > 0: dlg = alg.getCustomParametersDialog() if not dlg: dlg = AlgorithmDialog(alg) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool) if dlg.executed: showRecent = ProcessingConfig.getSetting( ProcessingConfig.SHOW_RECENT_ALGORITHMS) if showRecent: self.addRecentAlgorithms(True) else: progress = MessageBarProgress() runalg(alg, progress) handleAlgorithmResults(alg, progress) progress.close() if isinstance(item, TreeActionItem): action = item.action action.setData(self) action.execute()
def executeAlgorithm(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) message = alg.checkBeforeOpeningParametersDialog() if message: dlg = MessageDialog() dlg.setTitle(self.tr('Error executing algorithm')) dlg.setMessage( self.tr('<h3>This algorithm cannot ' 'be run :-( </h3>\n%s') % message) dlg.exec_() return alg = alg.getCopy() if (alg.getVisibleParametersCount() + alg.getVisibleOutputsCount()) > 0: dlg = alg.getCustomParametersDialog() if not dlg: dlg = AlgorithmDialog(alg) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool) if dlg.executed: showRecent = ProcessingConfig.getSetting( ProcessingConfig.SHOW_RECENT_ALGORITHMS) if showRecent: self.addRecentAlgorithms(True) else: progress = MessageBarProgress() runalg(alg, progress) handleAlgorithmResults(alg, progress) progress.close() if isinstance(item, TreeActionItem): action = item.action action.setData(self) action.execute()
def addAlgorithmEntry(algname, menuName, submenuName, actionText=None, icon=None, addButton=False): alg = Processing.getAlgorithm(algname) if alg is None: return if menuName: menu = getMenu(menuName, iface.mainWindow().menuBar()) submenu = getMenu(submenuName, menu) action = QtGui.QAction(icon or alg.getIcon(), actionText or alg.name, iface.mainWindow()) action.triggered.connect(lambda: _executeAlgorithm(alg)) submenu.addAction(action) if addButton: global algorithmsToolbar if algorithmsToolbar is None: algorithmsToolbar = iface.addToolBar("ProcessingAlgorithms") algorithmsToolbar.addAction(action)
def runWorkflow(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) message = alg.checkBeforeOpeningParametersDialog() if message: QtGui.QMessageBox.warning(self, self.tr("Warning"), message) return alg = alg.getCopy() dlg = alg.getCustomParametersDialog() if not dlg: dlg = ParametersDialog(alg) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool()!=prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool)
def open_help(self, alg): alg = Processing.getAlgorithm(alg) alg = alg.getCopy() provider = alg.provider.getName().lower() # to which group does the algorithm belong (e.g., vector_table_tools) groupName = alg.group.lower() # format the groupName in the QGIS way groupName = groupName.replace('[', '').replace(']', '').replace(' - ', '_') groupName = groupName.replace(' ', '_') if provider == 'saga': alg2 = alg.getCopy() groupName = alg2.undecoratedGroup groupName = groupName.replace('ta_', 'terrain_analysis_') groupName = groupName.replace('statistics_kriging', 'kriging') groupName = re.sub('^statistics_.*', 'geostatistics', groupName) groupName = re.sub('visualisation', 'visualization', groupName) groupName = re.sub('_preprocessor', '_hydrology', groupName) groupName = groupName.replace('sim_', 'simulation_') # retrieve the command line name (worked for 2.8...) # "cmdLineName = alg.commandLineName()", # "algName = cmdLineName[cmdLineName.find(':') + 1:].lower()", # for 2.14 we cannot use the algorithm name # (now you have to test all SAGA and QGIS functions again...) algName = alg.name.lower().replace(' ', '-') # just use valid characters validChars = ('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS' + 'TUVWXYZ0123456789_') safeGroupName = ''.join(c for c in groupName if c in validChars) validChars = validChars + '-' safeAlgName = ''.join(c for c in algName if c in validChars) # which QGIS version are we using version = '.'.join(QGis.QGIS_VERSION.split('.')[0:2]) # build the html to the help file url = ('https:///docs.qgis.org/%s/en/docs/user_manual/' + 'processing_algs/%s/%s.html#%s') % (version, provider, safeGroupName, safeAlgName) return(url)
def executeAlgorithm(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) message = alg.checkBeforeOpeningParametersDialog() if message: dlg = MessageDialog() dlg.setTitle(self.tr('Missing dependency')) dlg.setMessage( self.tr('<h3>Missing dependency. This algorithm cannot ' 'be run :-( </h3>\n%s') % message) dlg.exec_() return alg = alg.getCopy() dlg = alg.getCustomParametersDialog() if not dlg: dlg = AlgorithmDialog(alg) canvas = iface.mapCanvas() prevMapTool = canvas.mapTool() dlg.show() dlg.exec_() if canvas.mapTool() != prevMapTool: try: canvas.mapTool().reset() except: pass canvas.setMapTool(prevMapTool) if dlg.executed: showRecent = ProcessingConfig.getSetting( ProcessingConfig.SHOW_RECENT_ALGORITHMS) if showRecent: self.addRecentAlgorithms(True) if isinstance(item, TreeActionItem): action = item.action action.setData(self) action.execute()
def createTest(text): definition = {} tokens = list(parseParameters(text[len('processing.runalg('):-1])) cmdname = tokens[0] alg = Processing.getAlgorithm(cmdname) definition['name'] = 'Test ({})'.format(cmdname) definition['algorithm'] = cmdname params = {} results = {} i = 0 for param in alg.parameters: if param.hidden: continue i += 1 token = tokens[i] # Handle empty parameters that are optionals if param.optional and token is None: continue if isinstance(param, ParameterVector): schema, filepath = extractSchemaPath(token) p = { 'type': 'vector', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterRaster): schema, filepath = extractSchemaPath(token) p = { 'type': 'raster', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterTable): schema, filepath = extractSchemaPath(token) p = { 'type': 'table', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterMultipleInput): multiparams = token.split(';') newparam = [] # Handle datatype detection dataType = param.dataType() if dataType in ['points', 'lines', 'polygons', 'any vectors']: dataType = 'vector' else: dataType = 'raster' for mp in multiparams: schema, filepath = extractSchemaPath(mp) newparam.append({ 'type': dataType, 'name': filepath }) p = { 'type': 'multi', 'params': newparam } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterFile): schema, filepath = extractSchemaPath(token) p = { 'type': 'file', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterString): params[param.name] = token elif isinstance(param, ParameterBoolean): params[param.name] = token elif isinstance(param, ParameterNumber): if param.isInteger: params[param.name] = int(token) else: params[param.name] = float(token) else: if token[0] == '"': token = token[1:] if token[-1] == '"': token = token[:-1] params[param.name] = token definition['params'] = params for i, out in enumerate([out for out in alg.outputs if not out.hidden]): token = tokens[i - alg.getVisibleOutputsCount()] if isinstance(out, (OutputNumber, OutputString)): results[out.name] = str(out) elif isinstance(out, OutputRaster): if token is None: QMessageBox.warning(None, tr('Error'), tr('Seems some outputs are temporary ' 'files. To create test you need to ' 'redirect all algorithm outputs to ' 'files')) return dataset = gdal.Open(token, GA_ReadOnly) dataArray = nan_to_num(dataset.ReadAsArray(0)) strhash = hashlib.sha224(dataArray.data).hexdigest() results[out.name] = { 'type': 'rasterhash', 'hash': strhash } elif isinstance(out, OutputVector): schema, filepath = extractSchemaPath(token) results[out.name] = { 'type': 'vector', 'name': filepath } if not schema: results[out.name]['location'] = '[The expected result data is not in the testdata directory. Please write it to processing/tests/testdata/expected. Prefer gml files.]' elif isinstance(out, OutputHTML) or isinstance(out, OutputFile): schema, filepath = extractSchemaPath(token) results[out.name] = { 'type': 'file', 'name': filepath } if not schema: results[out.name]['location'] = '[The expected result file is not in the testdata directory. Please redirect the output to processing/tests/testdata/expected.]' definition['results'] = results dlg = ShowTestDialog(yaml.dump([definition], default_flow_style=False)) dlg.exec_()
def createTest(text): definition = {} tokens = list(parseParameters(text[len('processing.runalg('):-1])) cmdname = tokens[0] alg = Processing.getAlgorithm(cmdname) definition['name'] = 'Test ({})'.format(cmdname) definition['algorithm'] = cmdname params = {} results = {} i = 0 for param in alg.parameters: if param.hidden: continue i += 1 token = tokens[i] # Handle empty parameters that are optionals if param.optional and token is None: continue if isinstance(param, ParameterVector): schema, filepath = extractSchemaPath(token) p = { 'type': 'vector', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterRaster): schema, filepath = extractSchemaPath(token) p = { 'type': 'raster', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterMultipleInput): multiparams = token.split(';') newparam = [] # Handle datatype detection dataType = param.dataType() if dataType in ['points', 'lines', 'polygons', 'any vectors']: dataType = 'vector' else: dataType = 'raster' for mp in multiparams: schema, filepath = extractSchemaPath(mp) newparam.append({ 'type': dataType, 'name': filepath }) p = { 'type': 'multi', 'params': newparam } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterFile): schema, filepath = extractSchemaPath(token) p = { 'type': 'file', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterString): params[param.name] = token elif isinstance(param, ParameterBoolean): params[param.name] = token elif isinstance(param, ParameterNumber): if param.isInteger: params[param.name] = int(token) else: params[param.name] = float(token) else: if token[0] == '"': token = token[1:] if token[-1] == '"': token = token[:-1] params[param.name] = token definition['params'] = params for i, out in enumerate([out for out in alg.outputs if not out.hidden]): token = tokens[i - alg.getVisibleOutputsCount()] if isinstance(out, (OutputNumber, OutputString)): results[out.name] = str(out) elif isinstance(out, OutputRaster): if token is None: QMessageBox.warning(None, tr('Error'), tr('Seems some outputs are temporary ' 'files. To create test you need to ' 'redirect all algorithm outputs to ' 'files')) return dataset = gdal.Open(token, GA_ReadOnly) dataArray = nan_to_num(dataset.ReadAsArray(0)) strhash = hashlib.sha224(dataArray.data).hexdigest() results[out.name] = { 'type': 'rasterhash', 'hash': strhash } elif isinstance(out, OutputVector): schema, filepath = extractSchemaPath(token) results[out.name] = { 'type': 'vector', 'name': filepath } if not schema: results[out.name]['location'] = '[The expected result data is not in the testdata directory. Please write it to processing/tests/testdata/expected. Prefer gml files.]' elif isinstance(out, OutputHTML) or isinstance(out, OutputFile): schema, filepath = extractSchemaPath(token) results[out.name] = { 'type': 'file', 'name': filepath } if not schema: results[out.name]['location'] = '[The expected result file is not in the testdata directory. Please redirect the output to processing/tests/testdata/expected.]' definition['results'] = results dlg = ShowTestDialog(yaml.dump([definition], default_flow_style=False)) dlg.exec_()
def openWorkflow(self, filename): self._steps = list() self.descriptionFile = filename instructions = False try: for line in fileinput.input(filename, openhook = fileinput.hook_encoded("utf-8")): line= line.rstrip() # comment line if line.startswith("#"): pass if line.startswith(".NAME:"): self.name = line[len(".NAME:"):] elif line.startswith(".GROUP:"): self.group = line[len(".GROUP:"):] elif line.startswith(".ALGORITHM:"): alg = Processing.getAlgorithm(line[len(".ALGORITHM:"):]) if alg: alg = alg.getCopy() self.addStep(alg, NORMAL_MODE, '') else: raise(WrongWorkflowException()) elif line.startswith(".MODE:"): if line[len(".MODE:"):] == NORMAL_MODE: self._steps[-1]['mode'] = NORMAL_MODE elif line[len(".MODE:"):] == BATCH_MODE: self._steps[-1]['mode'] = BATCH_MODE else: raise(WrongWorkflowException()) elif line.startswith(".PARAMETERS:"): try: params = json.loads(line[len(".PARAMETERS:"):]) except: pass else: if type(params) == dict: self._steps[-1]['parameters'] = params self.setStepParameters(self._steps[-1]) else: raise(WrongWorkflowException()) elif line.startswith(".INSTRUCTIONS"): instructions = line[len(".INSTRUCTIONS:"):]+"\n" self._steps[-1]['instructions'] = instructions instructions = True elif instructions: if line == "!INSTRUCTIONS": instructions = False elif line == "": self._steps[-1]['instructions'] +="\n" else: self._steps[-1]['instructions'] +=line+"\n" except WrongWorkflowException: msg = "Error on line number "+unicode(fileinput.filelineno())+": "+line+"\n" fileinput.close() raise WrongWorkflowException(msg) except Exception, e: fileinput.close() raise e
def QGISProcessFactory(alg_name): """This is the bridge between SEXTANTE and PyWPS: it creates PyWPS processes based on SEXTANTE alg name""" from pywps.Process import WPSProcess from new import classobj import types from processing.core.Processing import Processing # Sanitize name class_name = alg_name.replace(':', '_') alg = Processing.getAlgorithm(alg_name) def process_init(self): # Automatically init the process attributes WPSProcess.__init__(self, identifier=alg_name, # must be same, as filename title=alg_name, version = "0.1", storeSupported = "true", statusSupported = "true", abstract= '<![CDATA[' + str(alg) + ']]>', grassLocation=False) self.alg = alg # Add I/O i = 1 for parm in alg.parameters: if getattr(parm, 'optional', False): minOccurs = 0 else: minOccurs = 1 # TODO: create "LiteralValue", "ComplexValue" or "BoundingBoxValue" # this can be done checking the class: # parm.__class__, one of # ['Parameter', 'ParameterBoolean', 'ParameterCrs', 'ParameterDataObject', 'ParameterExtent', 'ParameterFile', 'ParameterFixedTable', 'ParameterMultipleInput', 'ParameterNumber', 'ParameterRange', 'ParameterRaster', 'ParameterSelection', 'ParameterString', 'ParameterTable','ParameterTableField', 'ParameterVector'] if parm.__class__.__name__ == 'ParameterBoolean': type = types.BooleanType else: type = types.StringType self._inputs['Input%s' % i] = self.addLiteralInput(parm.name, parm.description, minOccurs=minOccurs, type=type, default=getattr(parm, 'default', None)) i += 1 i = 1 for parm in alg.outputs: self._outputs['Output%s' % i] = self.addLiteralOutput(identifier = parm.name, title = parm.description) i += 1 for k in self._inputs: setattr(self, k, self._inputs[k]) for k in self._outputs: setattr(self, k, self._outputs[k]) def execute(self): # Run alg with params # TODO: get args args = {} for k in self._inputs: v = getattr(self, k) args[v.identifier] = v.getValue() # Adds None for output parameter(s) for k in self._outputs: v = getattr(self, k) args[v.identifier] = None #processing.runalg("grass:v.hull","/home/ale/Documenti/maps/regioni_semplificato_4326.shp",False,"6.6268611901,18.5188598654,35.4930324712,47.0862707258",-1,0.0001,0,None) from processing import runalg alg = Processing.runAlgorithm(self.alg, None, args) if alg is not None: result = alg.getOutputValuesAsDictionary() for k in self._outputs: v = getattr(self, k) args[v.identifier] = result.get(k, None) return new_class = classobj('%sProcess' % class_name, (WPSProcess, ), { '__init__' : process_init, 'execute' : execute, 'params' : [], 'alg' : alg, '_inputs' : {}, '_outputs' : {}, }) return new_class
from qgis.core import * from osgeo import ogr from osgeo import gdal from PyQt4.QtCore import QFile, QFileInfo qgs = QgsApplication([],True, None) #qgs.setPrefixPath("/usr", True) qgs.initQgis() print(QgsApplication.showSettings()) from processing.core.Processing import Processing from processing.tools import * Processing.initialize() print Processing.getAlgorithm("qgis:creategrid") print Processing.getAlgorithm("grass:r.to.vect") ''' Define datapath ''' datapath = r"C:\Users\tnauss\permanent\edu\msc-phygeo-if-error-continue\data" dgmpath = datapath + os.sep + "KU_DGM10\KU_DGM10.tif" gipfelpath = datapath + os.sep + r"gipfelliste\brandenberger_alpen.shp" tmppath = datapath + os.sep + r"temp" ''' Read geo files ''' # Summit list s = QgsVectorLayer(gipfelpath, "gipfel", "ogr") print(s.isValid())
def QGISProcessFactory(alg_name, project='', vectors=[], rasters=[], crss=[]): """This is the bridge between SEXTANTE and PyWPS: it creates PyWPS processes based on SEXTANTE alg name""" from pywps.Process import WPSProcess from new import classobj import types # Sanitize name class_name = alg_name.replace(':', '_') alg = Processing.getAlgorithm(alg_name) algDesc = alg.shortHelp() if not algDesc: algDesc = '' else: algDesc = re.sub(r'[^\x00-\x7F]', '@', algDesc) algDesc = algDesc.replace('<p></p>', '') algDesc = '<![CDATA[' + algDesc + ']]>' # layer inputs rasterLayers = rasters vectorLayers = vectors def process_init(self): # Automatically init the process attributes WPSProcess.__init__( self, identifier=alg_name, # must be same, as filename title=escape(alg.name).replace('\\', ''), version="0.1", storeSupported="true", statusSupported="true", abstract=algDesc, grassLocation=False) self.alg = alg # Test parameters if not len(self.alg.parameters): self.alg.defineCharacteristics() # Get parameters description algParamDescs = alg.getParameterDescriptions() # Add I/O i = 1 for parm in alg.parameters: minOccurs = 1 if getattr(parm, 'optional', False): minOccurs = 0 parmDesc = '' if algParamDescs and parm.name in algParamDescs: parmDesc = algParamDescs[parm.name] parmDesc = '<![CDATA[' + parmDesc + ']]>' # TODO: create "LiteralValue", "ComplexValue" or "BoundingBoxValue" # this can be done checking the class: # parm.__class__, one of # ['Parameter', 'ParameterBoolean', 'ParameterCrs', 'ParameterDataObject', 'ParameterExtent', 'ParameterFile', 'ParameterFixedTable', 'ParameterMultipleInput', 'ParameterNumber', 'ParameterRange', 'ParameterRaster', 'ParameterSelection', 'ParameterString', 'ParameterTable','ParameterTableField', 'ParameterVector'] if parm.__class__.__name__ == 'ParameterVector': values = [] if vectorLayers and ParameterVector.VECTOR_TYPE_ANY in parm.shapetype: values = [l['name'] for l in vectorLayers] elif vectorLayers: if ParameterVector.VECTOR_TYPE_POINT in parm.shapetype: values += [ l['name'] for l in vectorLayers if l['geometry'] == 'Point' ] if ParameterVector.VECTOR_TYPE_LINE in parm.shapetype: values += [ l['name'] for l in vectorLayers if l['geometry'] == 'Line' ] if ParameterVector.VECTOR_TYPE_POLYGON in parm.shapetype: values += [ l['name'] for l in vectorLayers if l['geometry'] == 'Polygon' ] if values: self._inputs['Input%s' % i] = self.addLiteralInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, type=types.StringType) self._inputs['Input%s' % i].values = values else: self._inputs['Input%s' % i] = self.addComplexInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, formats=[{ 'mimeType': 'text/xml' }]) elif parm.__class__.__name__ == 'ParameterRaster': if rasterLayers: self._inputs['Input%s' % i] = self.addLiteralInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, type=types.StringType) self._inputs['Input%s' % i].values = [l['name'] for l in rasterLayers] else: self._inputs['Input%s' % i] = self.addComplexInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, formats=[{ 'mimeType': 'image/tiff' }]) elif parm.__class__.__name__ == 'ParameterTable': self._inputs['Input%s' % i] = self.addComplexInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, formats=[{ 'mimeType': 'text/csv' }]) elif parm.__class__.__name__ == 'ParameterExtent': self._inputs['Input%s' % i] = self.addBBoxInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs) # Add supported CRSs from project or config if crss: self._inputs['Input%s' % i].crss = crss elif parm.__class__.__name__ == 'ParameterSelection': self._inputs['Input%s' % i] = self.addLiteralInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, type=types.StringType, default=getattr(parm, 'default', None)) self._inputs['Input%s' % i].values = parm.options elif parm.__class__.__name__ == 'ParameterRange': tokens = parm.default.split(',') n1 = float(tokens[0]) n2 = float(tokens[1]) self._inputs['Input%s' % i] = self.addLiteralInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, type=types.FloatType, default=n1) self._inputs['Input%s' % i].values = ((n1, n2)) else: type = types.StringType if parm.__class__.__name__ == 'ParameterBoolean': type = types.BooleanType elif parm.__class__.__name__ == 'ParameterNumber': type = types.FloatType self._inputs['Input%s' % i] = self.addLiteralInput( escape(parm.name), escape(parm.description).replace('\\', ''), parmDesc, minOccurs=minOccurs, type=type, default=getattr(parm, 'default', None)) if parm.__class__.__name__ == 'ParameterBoolean': self._inputs['Input%s' % i].values = (True, False) i += 1 i = 1 for parm in alg.outputs: # TODO: create "LiteralOutput", "ComplexOutput" or "BoundingBoxOutput" # this can be done checking the class: # parm.__class__, one of # ['Output', 'OutputDirectory', 'OutputExtent', 'OutputFile', 'OutputHtml', 'OutputNumber', 'OutputRaster', 'OutputString', 'OutputTable', 'OutputVector'] if parm.__class__.__name__ == 'OutputVector': outputFormats = [{ 'mimeType': 'text/xml', 'encoding': 'utf-8' }, { 'mimeType': 'text/xml; subtype=gml/2.1.2', 'encoding': 'utf-8' }, { 'mimeType': 'text/xml; subtype=gml/3.1.1', 'encoding': 'utf-8' }, { 'mimeType': 'application/gml+xml', 'encoding': 'utf-8' }, { 'mimeType': 'application/gml+xml; version=2.1.2', 'encoding': 'utf-8' }, { 'mimeType': 'application/gml+xml; version=3.1.1', 'encoding': 'utf-8' }, { 'mimeType': 'application/json', 'encoding': 'utf-8' }, { 'mimeType': 'application/x-zipped-shp', 'encoding': 'utf-8' }, { 'mimeType': 'application/x-zipped-tab', 'encoding': 'utf-8' }, { 'mimeType': 'application/x-ogc-wms', 'encoding': 'utf-8' }, { 'mimeType': 'application/x-ogc-wfs', 'encoding': 'utf-8' }] if pywpsConfig.config.has_option('qgis', 'outputs_minetypes_vector'): outputsMimetypes = pywpsConfig.getConfigValue( 'qgis', 'outputs_minetypes_vector').strip() if outputsMimetypes: outputsMimetypes = outputsMimetypes.split(',') outputFormats = [{ 'mimeType': m.strip(), 'encoding': 'utf-8' } for m in outputsMimetypes] self._outputs['Output%s' % i] = self.addComplexOutput( parm.name, parm.description, formats=outputFormats) if pywpsConfig.getConfigValue("qgis", "qgisserveraddress"): self._outputs['Output%s' % i].useQgisServer = True elif parm.__class__.__name__ == 'OutputRaster': outputFormats = [{ 'mimeType': 'image/tiff' }, { 'mimeType': 'application/x-ogc-wms', 'encoding': 'utf-8' }, { 'mimeType': 'application/x-ogc-wcs', 'encoding': 'utf-8' }] if pywpsConfig.config.has_option('qgis', 'outputs_minetypes_raster'): outputsMimetypes = pywpsConfig.getConfigValue( 'qgis', 'outputs_minetypes_raster').strip() if outputsMimetypes: outputsMimetypes = outputsMimetypes.split(',') outputFormats = [{ 'mimeType': m.strip(), 'encoding': 'utf-8' } for m in outputsMimetypes] self._outputs['Output%s' % i] = self.addComplexOutput( parm.name, parm.description, formats=outputFormats) if pywpsConfig.getConfigValue("qgis", "qgisserveraddress"): self._outputs['Output%s' % i].useQgisServer = True elif parm.__class__.__name__ == 'OutputTable': self._outputs['Output%s' % i] = self.addComplexOutput( parm.name, parm.description, formats=[{ 'mimeType': 'text/csv' }]) elif parm.__class__.__name__ == 'OutputHtml': self._outputs['Output%s' % i] = self.addComplexOutput( parm.name, parm.description, formats=[{ 'mimeType': 'text/html' }]) elif parm.__class__.__name__ == 'OutputExtent': self._outputs['Output%s' % i] = self.addBBoxOutput( parm.name, parm.description) else: type = types.StringType if parm.__class__.__name__ == 'OutputNumber': type = types.FloatType self._outputs['Output%s' % i] = self.addLiteralOutput( parm.name, parm.description, type=type) i += 1 for k in self._inputs: setattr(self, k, self._inputs[k]) for k in self._outputs: setattr(self, k, self._outputs[k]) def execute(self): # create a project p = QgsProject.instance() mlr = QgsMapLayerRegistry.instance() # Run alg with params # TODO: get args args = {} # get vector and raster inputs inputCrs = None for k in self._inputs: v = getattr(self, k) parm = self.alg.getParameterFromName(v.identifier) # vector layers if parm.__class__.__name__ == 'ParameterVector': values = [] if vectorLayers and ParameterVector.VECTOR_TYPE_ANY in parm.shapetype: values = [l for l in vectorLayers] elif vectorLayers: if ParameterVector.VECTOR_TYPE_POINT in parm.shapetype: values += [ l for l in vectorLayers if l['geometry'] == 'Point' ] if ParameterVector.VECTOR_TYPE_LINE in parm.shapetype: values += [ l for l in vectorLayers if l['geometry'] == 'Line' ] if ParameterVector.VECTOR_TYPE_POLYGON in parm.shapetype: values += [ l for l in vectorLayers if l['geometry'] == 'Polygon' ] if values: layerName = v.getValue() values = [l for l in values if l['name'] == layerName] l = values[0] layer = QgsVectorLayer(l['datasource'], l['name'], l['provider']) crs = l['crs'] qgsCrs = None if str(crs).startswith('USER:'******'proj4'])) else: qgsCrs = QgsCoordinateReferenceSystem(str(crs)) if qgsCrs: layer.setCrs(qgsCrs) mlr.addMapLayer(layer, False) args[v.identifier] = layer inputCrs = layer.crs() else: fileName = v.getValue() fileInfo = QFileInfo(fileName) # move fileName to fileName.gml for ogr with open(fileName, 'r') as f: o = open(fileName + '.gml', 'w') o.write(f.read()) o.close() #import shutil #shutil.copy2(fileName+'.gml', '/tmp/test.gml' ) # get layer layer = QgsVectorLayer(fileName + '.gml', fileInfo.baseName(), 'ogr') pr = layer.dataProvider() e = layer.extent() mlr.addMapLayer(layer, False) args[v.identifier] = layer inputCrs = layer.crs() # raster layers elif parm.__class__.__name__ == 'ParameterRaster': if rasterLayers: layerName = v.getValue() values = [ l for l in rasterLayers if l['name'] == layerName ] l = values[0] layer = QgsRasterLayer(l['datasource'], l['name'], l['provider']) crs = l['crs'] qgsCrs = None if str(crs).startswith('USER:'******'proj4'])) else: qgsCrs = QgsCoordinateReferenceSystem(str(crs)) if qgsCrs: layer.setCrs(qgsCrs) mlr.addMapLayer(layer, False) args[v.identifier] = layer inputCrs = layer.crs() else: fileName = v.getValue() fileInfo = QFileInfo(fileName) layer = QgsRasterLayer(fileName, fileInfo.baseName(), 'gdal') mlr.addMapLayer(layer, False) args[v.identifier] = layer inputCrs = layer.crs() elif parm.__class__.__name__ == 'ParameterExtent': coords = v.getValue().coords args[v.identifier] = str(coords[0][0]) + ',' + str( coords[1][0]) + ',' + str(coords[0][1]) + ',' + str( coords[1][1]) else: args[v.identifier] = v.getValue() # if extent in inputs, transform it to the alg CRS if inputCrs: for k in self._inputs: v = getattr(self, k) parm = self.alg.getParameterFromName(v.identifier) if parm.__class__.__name__ == 'ParameterExtent': coords = v.getValue().coords coordCrs = None if v.getValue().crs: coordCrs = QgsCoordinateReferenceSystem( str(v.getValue().crs)) elif crss: coordCrs = QgsCoordinateReferenceSystem(str(crss[0])) else: coordCrs = QgsCoordinateReferenceSystem('EPSG:4326') if coordCrs: coordExtent = QgsRectangle(coords[0][0], coords[0][1], coords[1][0], coords[1][1]) xform = QgsCoordinateTransform(coordCrs, inputCrs) coordExtent = xform.transformBoundingBox(coordExtent) args[v.identifier] = str( coordExtent.xMinimum()) + ',' + str( coordExtent.xMaximum()) + ',' + str( coordExtent.yMinimum()) + ',' + str( coordExtent.yMaximum()) # Adds None for output parameter(s) for k in self._outputs: v = getattr(self, k) args[v.identifier] = None if not len(self.alg.parameters): self.alg.defineCharacteristics() tAlg = Processing.runAlgorithm(self.alg, None, args) # if runalg failed return exception message if not tAlg: return 'Error in processing' # clear map layer registry mlr.removeAllMapLayers() # get result result = tAlg.getOutputValuesAsDictionary() for k in self._outputs: v = getattr(self, k) parm = self.alg.getOutputFromName(v.identifier) # Output Vector if parm.__class__.__name__ == 'OutputVector': outputName = result.get(v.identifier, None) if not outputName: return 'No output file' # get output file info outputInfo = QFileInfo(outputName) # get the output QGIS vector layer outputLayer = QgsVectorLayer(outputName, outputInfo.baseName(), 'ogr') # Update input CRS if not inputCrs.authid(): inputCrs.saveAsUserCRS('') crs = QgsCoordinateReferenceSystem() crs.createFromProj4(inputCrs.toProj4()) inputCrs = crs # Update CRS if not outputLayer.dataProvider().crs().authid(): outputLayer.setCrs(inputCrs) # define destination CRS destCrs = None if outputLayer.crs().authid().startswith('USER:'******'EPSG:4326') v.projection = 'EPSG:4326' # define the file extension outputExt = 'gml' if v.format['mimetype'] == 'application/json': outputExt = 'geojson' elif v.format['mimetype'] == 'application/x-zipped-shp': outputExt = 'shp' elif v.format['mimetype'] == 'application/x-zipped-tab': outputExt = 'tab' # define the output file path outputFile = os.path.join( outputInfo.absolutePath(), outputInfo.baseName() + '.' + outputExt) # write the output GML file if v.format['mimetype'] == 'application/x-zipped-shp': if destCrs: outputFile = os.path.join( outputInfo.absolutePath(), outputInfo.baseName() + '_' + str(destCrs.srsid()) + '.' + outputExt) outputInfo = QFileInfo(outputFile) error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', destCrs, 'ESRI Shapefile', False, None) # compress files import zipfile try: import zlib compression = zipfile.ZIP_DEFLATED except: compression = zipfile.ZIP_STORED zFile = os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.zip') with zipfile.ZipFile(zFile, 'w') as zf: zf.write(os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.shp'), compress_type=compression, arcname=outputInfo.baseName() + '.shp') zf.write(os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.shx'), compress_type=compression, arcname=outputInfo.baseName() + '.shx') zf.write(os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.dbf'), compress_type=compression, arcname=outputInfo.baseName() + '.dbf') if os.path.exists( os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.prj')): zf.write(os.path.join( outputInfo.absolutePath(), outputInfo.baseName() + '.prj'), compress_type=compression, arcname=outputInfo.baseName() + '.prj') zf.close() outputFile = zFile elif v.format['mimetype'] == 'application/x-zipped-tab': error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', destCrs, 'Mapinfo File', False, None) # compress files import zipfile try: import zlib compression = zipfile.ZIP_DEFLATED except: compression = zipfile.ZIP_STORED zFile = os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.zip') with zipfile.ZipFile(zFile, 'w') as zf: zf.write(os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.tab'), compress_type=compression, arcname=outputInfo.baseName() + '.tab') zf.write(os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.dat'), compress_type=compression, arcname=outputInfo.baseName() + '.dat') zf.write(os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.map'), compress_type=compression, arcname=outputInfo.baseName() + '.map') if os.path.exists( os.path.join(outputInfo.absolutePath(), outputInfo.baseName() + '.id')): zf.write(os.path.join( outputInfo.absolutePath(), outputInfo.baseName() + '.id'), compress_type=compression, arcname=outputInfo.baseName() + '.id') zf.close() outputFile = zFile elif v.format['mimetype'] == 'application/json': error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', destCrs, 'GeoJSON', False, None) elif v.format['mimetype'] in ( 'text/xml; subtype=gml/3.1.1', 'application/gml+xml; version=3.1.1'): error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', destCrs, 'GML', False, None, [ 'XSISCHEMAURI=http://schemas.opengis.net/gml/3.1.1/base/feature.xsd', 'FORMAT=GML3' ]) else: error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', destCrs, 'GML', False, None, [ 'XSISCHEMAURI=http://schemas.opengis.net/gml/2.1.2/feature.xsd' ]) args[v.identifier] = outputFile # get OWS getCapabilities URL if not v.asReference and v.format['mimetype'] in ( 'application/x-ogc-wms', 'application/x-ogc-wfs'): from pywps.Wps.Execute import QGIS qgis = QGIS.QGIS(self, self.pywps.UUID) v.setValue(outputFile) outputFile = qgis.getReference(v) args[v.identifier] = outputFile # Output Raster elif parm.__class__.__name__ == 'OutputRaster': outputName = result.get(v.identifier, None) # get output file info outputInfo = QFileInfo(outputName) # get the output QGIS vector layer outputLayer = QgsRasterLayer(outputName, outputInfo.baseName(), 'gdal') # Update CRS if not outputLayer.dataProvider().crs().authid(): outputLayer.setCrs(inputCrs) v.projection = 'proj4:' + inputCrs.toProj4() if not outputName: return 'No output file' args[v.identifier] = outputName # get OWS getCapabilities URL if not v.asReference and v.format['mimetype'] in ( 'application/x-ogc-wms', 'application/x-ogc-wcs'): from pywps.Wps.Execute import QGIS qgis = QGIS.QGIS(self, self.pywps.UUID) v.setValue(outputName) outputFile = qgis.getReference(v) args[v.identifier] = outputFile else: args[v.identifier] = result.get(v.identifier, None) for k in self._outputs: v = getattr(self, k) v.setValue(args[v.identifier]) return try: new_class = classobj( str('%sProcess' % class_name), (WPSProcess, ), { '__init__': process_init, 'execute': execute, 'params': [], 'alg': alg, '_inputs': {}, '_outputs': {} }) return new_class except TypeError, e: QgsMessageLog.logMessage("QGISProcessFactory " + e.__str__()) return None
def responseComplete(self): QgsMessageLog.logMessage("wpsFilter.responseComplete") request = self.serverInterface().requestHandler() params = request.parameterMap() service = params.get('SERVICE', '') if service and service.upper() == 'WPS': # prepare query inputQuery = '&'.join([ "%s=%s" % (k, params[k]) for k in params if k.lower() != 'map' and k.lower() != 'config' and k.lower != 'request_body' ]) request_body = params.get('REQUEST_BODY', '') # get config configPath = os.getenv("PYWPS_CFG") if not configPath and 'config' in params: configPath = params['config'] elif not configPath and 'CONFIG' in params: configPath = params['CONFIG'] QgsMessageLog.logMessage("configPath " + str(configPath)) if configPath: os.environ["PYWPS_CFG"] = configPath pywpsConfig.loadConfiguration() try: providerList = '' algList = '' algsFilter = '' if pywpsConfig.config.has_section('qgis'): # get the providers to publish if pywpsConfig.config.has_option('qgis', 'providers'): providerList = pywpsConfig.getConfigValue( 'qgis', 'providers') if providerList: providerList = providerList.split(',') # get the algorithm list to publish if pywpsConfig.config.has_option('qgis', 'algs'): algList = pywpsConfig.getConfigValue('qgis', 'algs') if algList: algList = algList.split(',') # get the algorithm filter if pywpsConfig.config.has_option('qgis', 'algs_filter'): algsFilter = pywpsConfig.getConfigValue( 'qgis', 'algs_filter') # init Processing Processing.initialize() # load QGIS Processing config if pywpsConfig.config.has_section('qgis_processing'): for opt in pywpsConfig.config.options('qgis_processing'): opt_val = pywpsConfig.getConfigValue( 'qgis_processing', opt) ProcessingConfig.setSettingValue(opt.upper(), opt_val) # Reload algorithms Processing.loadAlgorithms() # modify processes path and reload algorithms if pywpsConfig.config.has_section( 'qgis') and pywpsConfig.config.has_option( 'qgis', 'processing_folder'): processingPath = pywpsConfig.getConfigValue( 'qgis', 'processing_folder') if not os.path.exists(processingPath): if configPath and os.path.exists(configPath): processingPath = os.path.join( os.path.dirname(configPath), processingPath) processingPath = os.path.abspath(processingPath) else: configFilesLocation = pywpsConfig._getDefaultConfigFilesLocation( ) for configFileLocation in configFilesLocation: if os.path.exists(configFileLocation): processingPath = os.path.join( os.path.dirname(configFileLocation), processingPath) processingPath = os.path.abspath( processingPath) QgsMessageLog.logMessage("processing_folder: " + processingPath) if os.path.exists(processingPath) and os.path.isdir( processingPath): ProcessingConfig.setSettingValue( 'MODELS_FOLDER', os.path.join(processingPath, 'models')) ProcessingConfig.setSettingValue( 'SCRIPTS_FOLDER', os.path.join(processingPath, 'scripts')) ProcessingConfig.setSettingValue( 'R_SCRIPTS_FOLDER', os.path.join(processingPath, 'rscripts')) # Reload algorithms Processing.loadAlgorithms() crsList = [] if pywpsConfig.config.has_section( 'qgis') and pywpsConfig.config.has_option( 'qgis', 'input_bbox_crss'): inputBBoxCRSs = pywpsConfig.getConfigValue( 'qgis', 'input_bbox_crss') inputBBoxCRSs = inputBBoxCRSs.split(',') crsList = [proj.strip().upper() for proj in inputBBoxCRSs] # get QGIS project path projectPath = os.getenv("QGIS_PROJECT_FILE") if not projectPath and 'map' in params: projectPath = params['map'] elif not projectPath and 'MAP' in params: projectPath = params['MAP'] #projectFolder projectFolder = '' if projectPath and os.path.exists(projectPath): projectFolder = os.path.dirname(projectPath) QgsMessageLog.logMessage("projectPath " + str(projectPath)) rasterLayers = [] vectorLayers = [] if projectPath and os.path.exists(projectPath): p_dom = minidom.parse(projectPath) for ml in p_dom.getElementsByTagName('maplayer'): l = { 'type': ml.attributes["type"].value, 'name': ml.getElementsByTagName( 'layername')[0].childNodes[0].data, 'datasource': ml.getElementsByTagName( 'datasource')[0].childNodes[0].data, 'provider': ml.getElementsByTagName( 'provider')[0].childNodes[0].data, 'crs': ml.getElementsByTagName( 'srs')[0].getElementsByTagName( 'authid')[0].childNodes[0].data, 'proj4': ml.getElementsByTagName('srs')[0]. getElementsByTagName('proj4')[0].childNodes[0].data } # Update relative path if l['provider'] in ['ogr', 'gdal'] and str( l['datasource']).startswith('.'): l['datasource'] = os.path.abspath( os.path.join(projectFolder, l['datasource'])) if not os.path.exists(l['datasource']): continue elif l['provider'] in ['gdal'] and str( l['datasource']).startswith('NETCDF:'): theURIParts = l['datasource'].split(":") src = theURIParts[1] src = src.replace('"', '') if src.startswith('.'): src = os.path.abspath( os.path.join(projectFolder, src)) theURIParts[1] = '"' + src + '"' l['datasource'] = ':'.join(theURIParts) if l['type'] == "raster": rasterLayers.append(l) elif l['type'] == "vector": l['geometry'] = ml.attributes["geometry"].value vectorLayers.append(l) deafultCrs = '' for mapcanvas in p_dom.getElementsByTagName('mapcanvas'): for destinationsrs in mapcanvas.getElementsByTagName( 'destinationsrs'): for authid in destinationsrs.getElementsByTagName( 'authid'): defaultCrs = authid.childNodes[0].data crsList.append(defaultCrs) for wmsCrsList in p_dom.getElementsByTagName('WMSCrsList'): for wmsCrs in wmsCrsList.getElementsByTagName('value'): wmsCrsValue = wmsCrs.childNodes[0].data if wmsCrsValue and wmsCrsValue != defaultCrs: crsList.append(wmsCrsValue) processes = [ None ] # if no processes found no processes return (deactivate default pywps process) identifier = params.get('IDENTIFIER', '').lower() for i in Processing.algs: if providerList and i not in providerList: continue QgsMessageLog.logMessage("provider " + i + " " + str(len(Processing.algs[i]))) for m in Processing.algs[i]: if identifier and identifier != m: continue if algList and m not in algList: continue if algsFilter: alg = Processing.getAlgorithm(m) if algsFilter.lower() not in alg.name.lower( ) and algsFilter.lower() not in m.lower(): continue QgsMessageLog.logMessage("provider " + i + " " + m) processes.append( QGISProcessFactory(m, projectPath, vectorLayers, rasterLayers, crsList)) #pywpsConfig.setConfigValue("server","outputPath", '/tmp/wpsoutputs') #pywpsConfig.setConfigValue("server","logFile", '/tmp/pywps.log') qgisaddress = self.serverInterface().getEnv( 'SERVER_NAME') + self.serverInterface().getEnv( 'SCRIPT_NAME') if self.serverInterface().getEnv('HTTPS'): qgisaddress = 'https://' + qgisaddress else: qgisaddress = 'http://' + qgisaddress qgisaddress = qgisaddress + '?' if 'map' in params: qgisaddress = qgisaddress + 'map=' + params['map'] + '&' elif 'MAP' in params: qgisaddress = qgisaddress + 'MAP=' + params['MAP'] + '&' if 'config' in params: qgisaddress = qgisaddress + 'config=' + params[ 'config'] + '&' elif 'CONFIG' in params: qgisaddress = qgisaddress + 'CONFIG=' + params[ 'CONFIG'] + '&' #pywpsConfig.setConfigValue("wps","serveraddress", qgisaddress) QgsMessageLog.logMessage("qgisaddress " + qgisaddress) #pywpsConfig.setConfigValue("qgis","qgisserveraddress", qgisaddress) # init wps method = 'GET' if request_body: method = 'POST' QgsMessageLog.logMessage("method " + method) wps = pywps.Pywps(method) # create the request file for POST request if request_body: tmpPath = pywpsConfig.getConfigValue("server", "tempPath") requestFile = open( os.path.join(tmpPath, "request-" + str(wps.UUID)), "w") requestFile.write(str(request_body)) requestFile.close() requestFile = open( os.path.join(tmpPath, "request-" + str(wps.UUID)), "r") inputQuery = requestFile if wps.parseRequest(inputQuery): try: response = wps.performRequest(processes=processes) if response: request.clearHeaders() request.clearBody() #request.setHeader('Content-type', 'text/xml') QgsMessageLog.logMessage("contentType " + wps.request.contentType) request.setInfoFormat(wps.request.contentType) resp = wps.response if not pywpsConfig.getConfigValue( "wps", "serveraddress" ) and wps.request.contentType == 'application/xml': import re import xml.sax.saxutils as saxutils resp = re.sub( r'Get xlink:href=".*"', 'Get xlink:href="' + saxutils.escape(qgisaddress) + '"', resp) resp = re.sub( r'Post xlink:href=".*"', 'Post xlink:href="' + saxutils.escape(qgisaddress) + '"', resp) elif pywpsConfig.getConfigValue( "wps", "serveraddress" ) and wps.request.contentType == 'application/xml': import re m = re.search(r'Get xlink:href="(.*)"', resp) if m and m.group(1).count('?') == 2: import xml.sax.saxutils as saxutils resp = re.sub( r'Get xlink:href=".*"', 'Get xlink:href="' + m.group(1)[:-1] + saxutils.escape('&') + '"', resp) # test response type if isinstance(resp, file): request.appendBody(resp.read()) else: request.appendBody(resp) else: QgsMessageLog.logMessage("no response") except: QgsMessageLog.logMessage("Exception perform request") else: QgsMessageLog.logMessage("parseRequest False") except WPSException as e: QgsMessageLog.logMessage("WPSException: " + str(e)) request.clearHeaders() #request.setHeader('Content-type', 'text/xml') request.clearBody() request.setInfoFormat('text/xml') request.appendBody(str(e)) except Exception as e: QgsMessageLog.logMessage("Exception: " + str(e)) request.clearHeaders() #request.setHeader('Content-type', 'text/xml') request.clearBody() request.setInfoFormat('text/xml') request.appendBody(str(e))
def editRenderingStyles(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) dlg = EditRenderingStylesDialog(alg) dlg.exec_()
def createAlgorithmHelp(algName, folder): alg = Processing.getAlgorithm(algName) baseHelpForAlgorithm(alg, folder)
def createTest(text): s = '' tokens = text[len('processing.runalg('):-1].split(',') cmdname = (tokens[0])[1:-1] methodname = 'test_' + cmdname.replace(':', '') s += 'def ' + methodname + '(self):\n' alg = Processing.getAlgorithm(cmdname) execcommand = 'processing.runalg(' i = 0 for token in tokens: if i < alg.getVisibleParametersCount() + 1: if os.path.exists(token[1:-1]): token = os.path.basename(token[1:-1])[:-4] + '()' execcommand += token + ',' else: execcommand += 'None,' i += 1 s += '\toutputs=' + execcommand[:-1] + ')\n' i = -1 * len(alg.outputs) for out in alg.outputs: filename = (tokens[i])[1:-1] if tokens[i] == str(None): QtGui.QMessageBox.critical( None, tr('Error'), tr('Cannot create unit test for that algorithm execution. The ' 'output cannot be a temporary file')) return s += "\toutput=outputs['" + out.name + "']\n" if isinstance(out, (OutputNumber, OutputString)): s += 'self.assertTrue(' + str(out) + ', output.value)\n' if isinstance(out, OutputRaster): dataset = gdal.Open(filename, GA_ReadOnly) strhash = hash(str(dataset.ReadAsArray(0).tolist())) s += '\tself.assertTrue(os.path.isfile(output))\n' s += '\tdataset=gdal.Open(output, GA_ReadOnly)\n' s += '\tstrhash=hash(str(dataset.ReadAsArray(0).tolist()))\n' s += '\tself.assertEqual(strhash,' + str(strhash) + ')\n' if isinstance(out, OutputVector): layer = processing.getObject(filename) fields = layer.pendingFields() s += '\tlayer=dataobjects.getObjectFromUri(output, True)\n' s += '\tfields=layer.pendingFields()\n' s += '\texpectednames=[' + ','.join( ["'" + str(f.name()) + "'" for f in fields]) + ']\n' s += '\texpectedtypes=[' + ','.join( ["'" + str(f.typeName()) + "'" for f in fields]) + ']\n' s += '\tnames=[str(f.name()) for f in fields]\n' s += '\ttypes=[str(f.typeName()) for f in fields]\n' s += '\tself.assertEqual(expectednames, names)\n' s += '\tself.assertEqual(expectedtypes, types)\n' features = vector.features(layer) numfeat = len(features) s += '\tfeatures=processing.features(layer)\n' s += '\tself.assertEqual(' + str(numfeat) + ', len(features))\n' if numfeat > 0: feature = features.next() attrs = feature.attributes() s += '\tfeature=features.next()\n' s += '\tattrs=feature.attributes()\n' s += '\texpectedvalues=[' + ','.join( ['"' + str(attr) + '"' for attr in attrs]) + ']\n' s += '\tvalues=[str(attr) for attr in attrs]\n' s += '\tself.assertEqual(expectedvalues, values)\n' s += "\twkt='" + str(feature.geometry().exportToWkt()) + "'\n" s += '\tself.assertEqual(wkt, \ str(feature.geometry().exportToWkt()))' dlg = ShowTestDialog(s) dlg.exec_()
def QGISProcessFactory(alg_name): """This is the bridge between QGIS Processing and PyWPS: it creates PyWPS processes based on QGIS Processing alg name it is inspired by Alessandro Pasotti work """ from pywps.Process import WPSProcess from new import classobj import types from processing.core.Processing import Processing # Sanitize name class_name = alg_name.replace(':', '_') alg = Processing.getAlgorithm(alg_name) # Get project projectsFolder = config.getConfigValue( 'qgis', 'projects_folder' ) projectPath = None if os.path.exists(projectsFolder) and os.path.exists( os.path.join( projectsFolder, class_name+'.qgs' ) ) : projectPath = os.path.join( projectsFolder, class_name+'.qgs' ) rasterLayers = [] vectorLayers = [] if projectPath and os.path.exists( projectPath ) : p_dom = minidom.parse( projectPath ) for ml in p_dom.getElementsByTagName('maplayer') : l= {'type':ml.attributes["type"].value, 'name':ml.getElementsByTagName('layername')[0].childNodes[0].data, 'datasource':ml.getElementsByTagName('datasource')[0].childNodes[0].data, 'provider':ml.getElementsByTagName('provider')[0].childNodes[0].data, 'crs':ml.getElementsByTagName('srs')[0].getElementsByTagName('authid')[0].childNodes[0].data, 'proj4':ml.getElementsByTagName('srs')[0].getElementsByTagName('proj4')[0].childNodes[0].data } # Update relative path if l['provider'] in ['ogr','gdal'] and str(l['datasource']).startswith('.'): l['datasource'] = os.path.abspath( os.path.join( projectsFolder, l['datasource'] ) ) if not os.path.exists( l['datasource'] ) : continue elif l['provider'] in ['gdal'] and str(l['datasource']).startswith('NETCDF:'): theURIParts = l['datasource'].split( ":" ); src = theURIParts[1] src = src.replace( '"', '' ) if src.startswith('.') : src = os.path.abspath( os.path.join( projectsFolder, src ) ) theURIParts[1] = '"' + src + '"' l['datasource'] = ':'.join( theURIParts ) if l['type'] == "raster" : rasterLayers.append( l ) elif l['type'] == "vector" : l['geometry'] = ml.attributes["geometry"].value vectorLayers.append( l ) def process_init(self): # Automatically init the process attributes # Start with help for description #isText, help = self.alg.help() #logging.info( help ) #if not isText and help is not None: # with open(help, 'r') as helpFile : # help = helpFile.read() # because of a print in ModelerAlgorithm # get help can't be used # and because of some changes in help method too help = None # Init WPS Process WPSProcess.__init__(self, identifier=alg_name, # must be same, as filename title=escape(alg.name), version = "0.1", storeSupported = "true", statusSupported = "true", abstract= '<![CDATA[' + (help is None and str(alg) or str(help)) + ']]>', grassLocation=False) # Test parameters if not len( self.alg.parameters ): self.alg.defineCharacteristics() # Add I/O i = 1 for parm in alg.parameters: minOccurs = 1 if getattr(parm, 'optional', False): minOccurs = 0 # TODO: create "LiteralValue", "ComplexValue" or "BoundingBoxValue" # this can be done checking the class: # parm.__class__, one of # ['Parameter', 'ParameterBoolean', 'ParameterCrs', 'ParameterDataObject', 'ParameterExtent', 'ParameterFile', 'ParameterFixedTable', 'ParameterMultipleInput', 'ParameterNumber', 'ParameterRange', 'ParameterRaster', 'ParameterSelection', 'ParameterString', 'ParameterTable','ParameterTableField', 'ParameterVector'] if parm.__class__.__name__ == 'ParameterVector': values = [] if vectorLayers and ParameterVector.VECTOR_TYPE_ANY in parm.shapetype : values = [l['name'] for l in vectorLayers] elif vectorLayers : if ParameterVector.VECTOR_TYPE_POINT in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Point'] if ParameterVector.VECTOR_TYPE_LINE in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Line'] if ParameterVector.VECTOR_TYPE_POLYGON in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Polygon'] if values : self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.StringType) self._inputs['Input%s' % i].values = values else : self._inputs['Input%s' % i] = self.addComplexInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, formats = [{'mimeType':'text/xml'}]) elif parm.__class__.__name__ == 'ParameterRaster': if rasterLayers : self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.StringType) self._inputs['Input%s' % i].values = [l['name'] for l in rasterLayers] else : self._inputs['Input%s' % i] = self.addComplexInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, formats = [{'mimeType':'image/tiff'}]) elif parm.__class__.__name__ == 'ParameterTable': self._inputs['Input%s' % i] = self.addComplexInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, formats = [{'mimeType':'text/csv'}]) elif parm.__class__.__name__ == 'ParameterExtent': self._inputs['Input%s' % i] = self.addBBoxInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs) elif parm.__class__.__name__ == 'ParameterSelection': self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.StringType, default=getattr(parm, 'default', None)) self._inputs['Input%s' % i].values = parm.options elif parm.__class__.__name__ == 'ParameterRange': tokens = self.value.split(',') n1 = float(tokens[0]) n2 = float(tokens[1]) self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.FloatType, default=n1) self._inputs['Input%s' % i].values = ((n1,n2)) else: type = types.StringType if parm.__class__.__name__ == 'ParameterBoolean': type = types.BooleanType elif parm.__class__.__name__ =='ParameterNumber': type = types.FloatType self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=type, default=getattr(parm, 'default', None)) if parm.__class__.__name__ == 'ParameterBoolean': self._inputs['Input%s' % i].values=(True,False) i += 1 i = 1 for parm in alg.outputs: # TODO: create "LiteralOutput", "ComplexOutput" or "BoundingBoxOutput" # this can be done checking the class: # parm.__class__, one of # ['Output', 'OutputDirectory', 'OutputExtent', 'OutputFile', 'OutputHtml', 'OutputNumber', 'OutputRaster', 'OutputString', 'OutputTable', 'OutputVector'] if parm.__class__.__name__ == 'OutputVector': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{'mimeType':'text/xml'}]) elif parm.__class__.__name__ == 'OutputRaster': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{'mimeType':'image/tiff'}]) elif parm.__class__.__name__ == 'OutputTable': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{'mimeType':'text/csv'}]) elif parm.__class__.__name__ == 'OutputHtml': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{'mimeType':'text/html'}]) elif parm.__class__.__name__ == 'OutputExtent': self._outputs['Output%s' % i] = self.addBBoxOutput(parm.name, parm.description, minOccurs=minOccurs) else: type = types.StringType if parm.__class__.__name__ =='OutputNumber': type = types.FloatType self._outputs['Output%s' % i] = self.addLiteralOutput(parm.name, parm.description, type=type) i += 1 for k in self._inputs: setattr(self, k, self._inputs[k]) for k in self._outputs: setattr(self, k, self._outputs[k]) def execute(self): # create a project p = QgsProject.instance() mlr = QgsMapLayerRegistry.instance() # Run alg with params # TODO: get args args = {} for k in self._inputs: v = getattr(self, k) parm = self.alg.getParameterFromName( v.identifier ) if parm.__class__.__name__ == 'ParameterVector': values = [] if vectorLayers and ParameterVector.VECTOR_TYPE_ANY in parm.shapetype : values = [l['name'] for l in vectorLayers] elif vectorLayers : if ParameterVector.VECTOR_TYPE_POINT in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Point'] if ParameterVector.VECTOR_TYPE_LINE in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Line'] if ParameterVector.VECTOR_TYPE_POLYGON in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Polygon'] if values : layerName = v.getValue() values = [l for l in values if l['name'] == layerName] l = values[0] layer = QgsVectorLayer( l['datasource'], l['name'], l['provider'] ) mlr.addMapLayer( layer, False ) args[v.identifier] = layer else : fileName = v.getValue() fileInfo = QFileInfo( fileName ) # move fileName to fileName.gml for ogr with open( fileName, 'r' ) as f : o = open( fileName+'.gml', 'w' ) o.write( f.read() ) o.close() import shutil shutil.copy2(fileName+'.gml', '/tmp/test.gml' ) # get layer layer = QgsVectorLayer( fileName+'.gml', fileInfo.baseName(), 'ogr' ) pr = layer.dataProvider() e = layer.extent() mlr.addMapLayer( layer, False ) args[v.identifier] = layer elif parm.__class__.__name__ == 'ParameterRaster': if rasterLayers : layerName = v.getValue() values = [l for l in rasterLayers if l['name'] == layerName] l = values[0] layer = QgsRasterLayer( l['datasource'], l['name'], l['provider'] ) crs = l['crs'] qgsCrs = None if str(crs).startswith('USER:'******'proj4']) ) else : qgsCrs = QgsCoordinateReferenceSystem(crs, QgsCoordinateReferenceSystem.EpsgCrsId) if qgsCrs : layer.setCrs( qgsCrs ) mlr.addMapLayer( layer, False ) args[v.identifier] = layer else : fileName = v.getValue() fileInfo = QFileInfo( fileName ) layer = QgsRasterLayer( fileName, fileInfo.baseName(), 'gdal' ) mlr.addMapLayer( layer, False ) args[v.identifier] = layer elif parm.__class__.__name__ == 'ParameterExtent': coords = v.getValue().coords args[v.identifier] = str(coords[0][0])+','+str(coords[1][0])+','+str(coords[0][1])+','+str(coords[1][1]) else: args[v.identifier] = v.getValue() # Adds None for output parameter(s) for k in self._outputs: v = getattr(self, k) args[v.identifier] = None if not len( self.alg.parameters ): self.alg.defineCharacteristics() tAlg = Processing.runAlgorithm(self.alg, None, args) # if runalg failed return exception message if not tAlg: return 'Error in processing' # clear map layer registry mlr.removeAllMapLayers() # get result result = tAlg.getOutputValuesAsDictionary() for k in self._outputs: v = getattr(self, k) parm = self.alg.getOutputFromName( v.identifier ) if parm.__class__.__name__ == 'OutputVector': outputName = result.get(v.identifier, None) if not outputName : return 'No output file' # get output file info outputInfo = QFileInfo( outputName ) # get the output QGIS vector layer outputLayer = QgsVectorLayer( outputName, outputInfo.baseName(), 'ogr' ) # create the output GML file for pywps # define the output GML file path outputFile = os.path.join( outputInfo.absolutePath(), outputInfo.baseName()+'.gml' ) # write the output GML file error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', None, 'GML', False, None, ['XSISCHEMAURI=http://schemas.opengis.net/gml/2.1.2/feature.xsd'] ) args[v.identifier] = outputFile # add output layer to map layer registry #outputLayer = QgsVectorLayer( outputFile, v.identifier, 'ogr' ) #mlr.addMapLayer( outputLayer ) elif parm.__class__.__name__ == 'OutputRaster': outputName = result.get(v.identifier, None) if not outputName : return 'No output file' args[v.identifier] = outputName else: args[v.identifier] = result.get(v.identifier, None) for k in self._outputs: v = getattr(self, k) v.setValue( args[v.identifier] ) return try: new_class = classobj( '%sProcess' % class_name, (WPSProcess, ), { '__init__' : process_init, 'execute' : execute, 'params' : [], 'alg' : alg, '_inputs' : {}, '_outputs' : {} }) return new_class except TypeError, e: #logging.info('TypeError %sProcess: %s' % (class_name, e)) return None
def createTest(text): definition = {} tokens = text[len('processing.runalg('):-1].split(',') cmdname = (tokens[0])[1:-1] alg = Processing.getAlgorithm(cmdname) definition['name'] = 'Test ({})'.format(cmdname) definition['algorithm'] = cmdname params = {} results = {} i = 0 for param in alg.parameters: if param.hidden: continue i += 1 token = tokens[i] if isinstance(param, ParameterVector): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) p = { 'type': 'vector', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterRaster): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) p = { 'type': 'raster', 'name': filepath } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterMultipleInput): multiparams = token[1:-1].split(';') newparam = [] for mp in multiparams: schema, filepath = extractSchemaPath(mp) newparam.append({ 'type': 'vector', 'name': filepath }) p = { 'type': 'multi', 'params': newparam } if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p else: params[param.name] = token definition['params'] = params for i, out in enumerate([out for out in alg.outputs if not out.hidden]): token = tokens[i - alg.getVisibleOutputsCount()] if isinstance(out, (OutputNumber, OutputString)): results[out.name] = unicode(out) elif isinstance(out, OutputRaster): filename = token[1:-1] dataset = gdal.Open(filename, GA_ReadOnly) strhash = hashlib.sha224(dataset.ReadAsArray(0).data).hexdigest() results[out.name] = { 'type': 'rasterhash', 'hash': strhash } elif isinstance(out, OutputVector): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) results[out.name] = { 'type': 'vector', 'name': filepath } if not schema: results[out.name]['location'] = '[The expected result data is not in the testdata directory. Please write it to processing/tests/testdata/expected. Prefer gml files.]' elif isinstance(out, OutputHTML): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) results[out.name] = { 'type': 'file', 'name': filepath } if not schema: results[out.name]['location'] = '[The expected result file is not in the testdata directory. Please redirect the output to processing/tests/testdata/expected.]' definition['results'] = results dlg = ShowTestDialog(yaml.dump([definition], default_flow_style=False)) dlg.exec_()
def createTest(text): s = "" tokens = text[len("processing.runalg("):-1].split(",") cmdname = tokens[0][1:-1]; methodname = "test_" + cmdname.replace(":","") s += "def " + methodname + "(self):\n" alg = Processing.getAlgorithm(cmdname) execcommand = "processing.runalg(" i = 0 for token in tokens: if i < alg.getVisibleParametersCount() + 1: if os.path.exists(token[1:-1]): token = os.path.basename(token[1:-1])[:-4] + "()" execcommand += token + "," else: execcommand += "None," i+=1 s += "\toutputs=" + execcommand[:-1] + ")\n" i = -1 * len(alg.outputs) for out in alg.outputs: filename = tokens[i][1:-1] if (tokens[i] == str(None)): QtGui.QMessageBox.critical(None, "Error", "Cannot create unit test for that algorithm execution.\nThe output cannot be a temporary file") return s+="\toutput=outputs['" + out.name + "']\n" if isinstance(out, (OutputNumber, OutputString)): s+="self.assertTrue(" + str(out) + ", output.value)\n" if isinstance(out, OutputRaster): dataset = gdal.Open(filename, GA_ReadOnly) strhash = hash(str(dataset.ReadAsArray(0).tolist())) s+="\tself.assertTrue(os.path.isfile(output))\n" s+="\tdataset=gdal.Open(output, GA_ReadOnly)\n" s+="\tstrhash=hash(str(dataset.ReadAsArray(0).tolist()))\n" s+="\tself.assertEqual(strhash," + str(strhash) + ")\n" if isinstance(out, OutputVector): layer = Processing.getObject(filename) fields = layer.pendingFields() s+="\tlayer=QGisLayers.getObjectFromUri(output, True)\n" s+="\tfields=layer.pendingFields()\n" s+="\texpectednames=[" + ",".join(["'" + str(f.name()) + "'" for f in fields]) + "]\n" s+="\texpectedtypes=[" + ",".join(["'" + str(f.typeName()) +"'" for f in fields]) + "]\n" s+="\tnames=[str(f.name()) for f in fields]\n" s+="\ttypes=[str(f.typeName()) for f in fields]\n" s+="\tself.assertEqual(expectednames, names)\n" s+="\tself.assertEqual(expectedtypes, types)\n" features = QGisLayers.features(layer) numfeat = len(features) s+="\tfeatures=processing.getfeatures(layer)\n" s+="\tself.assertEqual(" + str(numfeat) + ", len(features))\n" if numfeat > 0: feature = features.next() attrs = feature.attributes() s+="\tfeature=features.next()\n" s+="\tattrs=feature.attributes()\n" s+="\texpectedvalues=[" + ",".join(['"' + str(attr) + '"' for attr in attrs]) + "]\n" s+="\tvalues=[str(attr) for attr in attrs]\n" s+="\tself.assertEqual(expectedvalues, values)\n" s+="\twkt='" + str(feature.geometry().exportToWkt()) + "'\n" s+="\tself.assertEqual(wkt, str(feature.geometry().exportToWkt()))" dlg = ShowTestDialog(s) dlg.exec_()
def QGISProcessFactory(alg_name, project='', vectors=[], rasters=[], crss=[]): """This is the bridge between SEXTANTE and PyWPS: it creates PyWPS processes based on SEXTANTE alg name""" from pywps.Process import WPSProcess from new import classobj import types # Sanitize name class_name = alg_name.replace(':', '_') alg = Processing.getAlgorithm(alg_name) # layer inputs rasterLayers = rasters vectorLayers = vectors def process_init(self): # Automatically init the process attributes WPSProcess.__init__(self, identifier=alg_name, # must be same, as filename title=escape(alg.name).replace('\\',''), version = "0.1", storeSupported = "true", statusSupported = "true", abstract= '<![CDATA[' + str(alg) + ']]>', grassLocation=False) self.alg = alg # Test parameters if not len( self.alg.parameters ): self.alg.defineCharacteristics() # Add I/O i = 1 for parm in alg.parameters: minOccurs = 1 if getattr(parm, 'optional', False): minOccurs = 0 # TODO: create "LiteralValue", "ComplexValue" or "BoundingBoxValue" # this can be done checking the class: # parm.__class__, one of # ['Parameter', 'ParameterBoolean', 'ParameterCrs', 'ParameterDataObject', 'ParameterExtent', 'ParameterFile', 'ParameterFixedTable', 'ParameterMultipleInput', 'ParameterNumber', 'ParameterRange', 'ParameterRaster', 'ParameterSelection', 'ParameterString', 'ParameterTable','ParameterTableField', 'ParameterVector'] if parm.__class__.__name__ == 'ParameterVector': values = [] if vectorLayers and ParameterVector.VECTOR_TYPE_ANY in parm.shapetype : values = [l['name'] for l in vectorLayers] elif vectorLayers : if ParameterVector.VECTOR_TYPE_POINT in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Point'] if ParameterVector.VECTOR_TYPE_LINE in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Line'] if ParameterVector.VECTOR_TYPE_POLYGON in parm.shapetype : values += [l['name'] for l in vectorLayers if l['geometry'] == 'Polygon'] if values : self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.StringType) self._inputs['Input%s' % i].values = values else : self._inputs['Input%s' % i] = self.addComplexInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, formats = [{'mimeType':'text/xml'}]) elif parm.__class__.__name__ == 'ParameterRaster': if rasterLayers : self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.StringType) self._inputs['Input%s' % i].values = [l['name'] for l in rasterLayers] else : self._inputs['Input%s' % i] = self.addComplexInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, formats = [{'mimeType':'image/tiff'}]) elif parm.__class__.__name__ == 'ParameterTable': self._inputs['Input%s' % i] = self.addComplexInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, formats = [{'mimeType':'text/csv'}]) elif parm.__class__.__name__ == 'ParameterExtent': self._inputs['Input%s' % i] = self.addBBoxInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs) # Add supported CRSs from project or config if crss: self._inputs['Input%s' % i].crss = crss elif parm.__class__.__name__ == 'ParameterSelection': self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.StringType, default=getattr(parm, 'default', None)) self._inputs['Input%s' % i].values = parm.options elif parm.__class__.__name__ == 'ParameterRange': tokens = parm.default.split(',') n1 = float(tokens[0]) n2 = float(tokens[1]) self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=types.FloatType, default=n1) self._inputs['Input%s' % i].values = ((n1,n2)) else: type = types.StringType if parm.__class__.__name__ == 'ParameterBoolean': type = types.BooleanType elif parm.__class__.__name__ =='ParameterNumber': type = types.FloatType self._inputs['Input%s' % i] = self.addLiteralInput(escape(parm.name), '<![CDATA[' + parm.description + ']]>', minOccurs=minOccurs, type=type, default=getattr(parm, 'default', None)) if parm.__class__.__name__ == 'ParameterBoolean': self._inputs['Input%s' % i].values=(True,False) i += 1 i = 1 for parm in alg.outputs: # TODO: create "LiteralOutput", "ComplexOutput" or "BoundingBoxOutput" # this can be done checking the class: # parm.__class__, one of # ['Output', 'OutputDirectory', 'OutputExtent', 'OutputFile', 'OutputHtml', 'OutputNumber', 'OutputRaster', 'OutputString', 'OutputTable', 'OutputVector'] if parm.__class__.__name__ == 'OutputVector': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{ 'mimeType':'text/xml', 'encoding': 'utf-8' },{ 'mimeType':'text/xml; subtype=gml/2.1.2', 'encoding': 'utf-8' },{ 'mimeType':'text/xml; subtype=gml/3.1.1', 'encoding': 'utf-8' },{ 'mimeType':'application/gml+xml', 'encoding': 'utf-8' },{ 'mimeType':'application/gml+xml; version=2.1.2', 'encoding': 'utf-8' },{ 'mimeType':'application/gml+xml; version=3.1.1', 'encoding': 'utf-8' },{ 'mimeType':'application/json', 'encoding': 'utf-8' }] ) if pywpsConfig.getConfigValue("qgis","qgisserveraddress") : self._outputs['Output%s' % i].useQgisServer = True elif parm.__class__.__name__ == 'OutputRaster': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{'mimeType':'image/tiff'}]) if pywpsConfig.getConfigValue("qgis","qgisserveraddress") : self._outputs['Output%s' % i].useQgisServer = True elif parm.__class__.__name__ == 'OutputTable': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{'mimeType':'text/csv'}]) elif parm.__class__.__name__ == 'OutputHtml': self._outputs['Output%s' % i] = self.addComplexOutput(parm.name, parm.description, formats = [{'mimeType':'text/html'}]) elif parm.__class__.__name__ == 'OutputExtent': self._outputs['Output%s' % i] = self.addBBoxOutput(parm.name, parm.description) else: type = types.StringType if parm.__class__.__name__ =='OutputNumber': type = types.FloatType self._outputs['Output%s' % i] = self.addLiteralOutput(parm.name, parm.description, type=type) i += 1 for k in self._inputs: setattr(self, k, self._inputs[k]) for k in self._outputs: setattr(self, k, self._outputs[k]) def execute(self): # create a project p = QgsProject.instance() mlr = QgsMapLayerRegistry.instance() # Run alg with params # TODO: get args args = {} # get vector and raster inputs inputCrs = None for k in self._inputs: v = getattr(self, k) parm = self.alg.getParameterFromName( v.identifier ) # vector layers if parm.__class__.__name__ == 'ParameterVector': values = [] if vectorLayers and ParameterVector.VECTOR_TYPE_ANY in parm.shapetype : values = [l for l in vectorLayers] elif vectorLayers : if ParameterVector.VECTOR_TYPE_POINT in parm.shapetype : values += [l for l in vectorLayers if l['geometry'] == 'Point'] if ParameterVector.VECTOR_TYPE_LINE in parm.shapetype : values += [l for l in vectorLayers if l['geometry'] == 'Line'] if ParameterVector.VECTOR_TYPE_POLYGON in parm.shapetype : values += [l for l in vectorLayers if l['geometry'] == 'Polygon'] if values : layerName = v.getValue() values = [l for l in values if l['name'] == layerName] l = values[0] layer = QgsVectorLayer( l['datasource'], l['name'], l['provider'] ) crs = l['crs'] qgsCrs = None if str(crs).startswith('USER:'******'proj4']) ) else : qgsCrs = QgsCoordinateReferenceSystem( str(crs) ) if qgsCrs : layer.setCrs( qgsCrs ) mlr.addMapLayer( layer, False ) args[v.identifier] = layer inputCrs = layer.crs() else : fileName = v.getValue() fileInfo = QFileInfo( fileName ) # move fileName to fileName.gml for ogr with open( fileName, 'r' ) as f : o = open( fileName+'.gml', 'w' ) o.write( f.read() ) o.close() import shutil shutil.copy2(fileName+'.gml', '/tmp/test.gml' ) # get layer layer = QgsVectorLayer( fileName+'.gml', fileInfo.baseName(), 'ogr' ) pr = layer.dataProvider() e = layer.extent() mlr.addMapLayer( layer, False ) args[v.identifier] = layer inputCrs = layer.crs() # raster layers elif parm.__class__.__name__ == 'ParameterRaster': if rasterLayers : layerName = v.getValue() values = [l for l in rasterLayers if l['name'] == layerName] l = values[0] layer = QgsRasterLayer( l['datasource'], l['name'], l['provider'] ) crs = l['crs'] qgsCrs = None if str(crs).startswith('USER:'******'proj4']) ) else : qgsCrs = QgsCoordinateReferenceSystem( str(crs) ) if qgsCrs : layer.setCrs( qgsCrs ) mlr.addMapLayer( layer, False ) args[v.identifier] = layer inputCrs = layer.crs() else : fileName = v.getValue() fileInfo = QFileInfo( fileName ) layer = QgsRasterLayer( fileName, fileInfo.baseName(), 'gdal' ) mlr.addMapLayer( layer, False ) args[v.identifier] = layer inputCrs = layer.crs() elif parm.__class__.__name__ == 'ParameterExtent': coords = v.getValue().coords args[v.identifier] = str(coords[0][0])+','+str(coords[1][0])+','+str(coords[0][1])+','+str(coords[1][1]) else: args[v.identifier] = v.getValue() # if extent in inputs, transform it to the alg CRS if inputCrs: for k in self._inputs: v = getattr(self, k) parm = self.alg.getParameterFromName( v.identifier ) if parm.__class__.__name__ == 'ParameterExtent': coords = v.getValue().coords coordCrs = QgsCoordinateReferenceSystem( str( v.getValue().crs ) ) coordExtent = QgsRectangle( coords[0][0], coords[0][1], coords[1][0], coords[1][1] ) xform = QgsCoordinateTransform( coordCrs, inputCrs ) coordExtent = xform.transformBoundingBox( coordExtent ) args[v.identifier] = str(coordExtent.xMinimum())+','+str(coordExtent.xMaximum())+','+str(coordExtent.yMinimum())+','+str(coordExtent.yMaximum()) # Adds None for output parameter(s) for k in self._outputs: v = getattr(self, k) args[v.identifier] = None if not len( self.alg.parameters ): self.alg.defineCharacteristics() tAlg = Processing.runAlgorithm(self.alg, None, args) # if runalg failed return exception message if not tAlg: return 'Error in processing' # clear map layer registry mlr.removeAllMapLayers() # get result result = tAlg.getOutputValuesAsDictionary() for k in self._outputs: v = getattr(self, k) parm = self.alg.getOutputFromName( v.identifier ) if parm.__class__.__name__ == 'OutputVector': outputName = result.get(v.identifier, None) if not outputName : return 'No output file' # get output file info outputInfo = QFileInfo( outputName ) # get the output QGIS vector layer outputLayer = QgsVectorLayer( outputName, outputInfo.baseName(), 'ogr' ) # Update CRS # outputLayer.setCrs( tAlg.crs ) # define the file extension outputExt = 'gml' if v.format['mimetype'] == 'application/json': outputExt = 'geojson' # define the output file path outputFile = os.path.join( outputInfo.absolutePath(), outputInfo.baseName()+'.'+outputExt ) # write the output GML file if v.format['mimetype'] == 'application/json': error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', None, 'GeoJSON', False, None ) elif v.format['mimetype'] in ('text/xml; subtype=gml/3.1.1','application/gml+xml; version=3.1.1') : error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', None, 'GML', False, None, ['XSISCHEMAURI=http://schemas.opengis.net/gml/3.1.1/base/feature.xsd','FORMAT=GML3'] ) else: error = QgsVectorFileWriter.writeAsVectorFormat( outputLayer, outputFile, 'utf-8', None, 'GML', False, None, ['XSISCHEMAURI=http://schemas.opengis.net/gml/2.1.2/feature.xsd'] ) args[v.identifier] = outputFile # add output layer to map layer registry #outputLayer = QgsVectorLayer( outputFile, v.identifier, 'ogr' ) #mlr.addMapLayer( outputLayer ) elif parm.__class__.__name__ == 'OutputRaster': outputName = result.get(v.identifier, None) if not outputName : return 'No output file' args[v.identifier] = outputName else: args[v.identifier] = result.get(v.identifier, None) for k in self._outputs: v = getattr(self, k) v.setValue( args[v.identifier] ) return try: new_class = classobj( str('%sProcess' % class_name), (WPSProcess, ), { '__init__' : process_init, 'execute' : execute, 'params' : [], 'alg' : alg, '_inputs' : {}, '_outputs' : {} }) return new_class except TypeError, e: QgsMessageLog.logMessage("QGISProcessFactory "+e.__str__()) return None
def responseComplete(self): QgsMessageLog.logMessage("wpsFilter.responseComplete") request = self.serverInterface().requestHandler() params = request.parameterMap() service = params.get('SERVICE', '') if service and service.upper() == 'WPS': # prepare query inputQuery = '&'.join(["%s=%s" % (k, params[k]) for k in params if k.lower() != 'map' and k.lower() != 'config' and k.lower != 'request_body']) request_body = params.get('REQUEST_BODY', '') # get config configPath = os.getenv("PYWPS_CFG") if not configPath and 'config' in params : configPath = params['config'] elif not configPath and 'CONFIG' in params : configPath = params['CONFIG'] QgsMessageLog.logMessage("configPath "+str(configPath)) if configPath : os.environ["PYWPS_CFG"] = configPath pywpsConfig.loadConfiguration() try: providerList = '' algList = '' algsFilter = '' if pywpsConfig.config.has_section( 'qgis' ) : # get the providers to publish if pywpsConfig.config.has_option( 'qgis', 'providers' ) : providerList = pywpsConfig.getConfigValue( 'qgis', 'providers' ) if providerList : providerList = providerList.split(',') # get the algorithm list to publish if pywpsConfig.config.has_option( 'qgis', 'algs' ) : algList = pywpsConfig.getConfigValue( 'qgis', 'algs' ) if algList : algList = algList.split(',') # get the algorithm filter if pywpsConfig.config.has_option( 'qgis', 'algs_filter' ) : algsFilter = pywpsConfig.getConfigValue( 'qgis', 'algs_filter' ) # init Processing Processing.initialize() # modify processes path and reload algorithms if pywpsConfig.config.has_section( 'qgis' ) and pywpsConfig.config.has_option( 'qgis', 'processing_folder' ) : processingPath = pywpsConfig.getConfigValue( 'qgis', 'processing_folder' ) if os.path.exists( processingPath ) and os.path.isdir( processingPath ) : ProcessingConfig.setSettingValue( 'MODELS_FOLDER', os.path.join( processingPath, 'models' ) ) ProcessingConfig.setSettingValue( 'SCRIPTS_FOLDER', os.path.join( processingPath, 'scripts' ) ) ProcessingConfig.setSettingValue( 'R_FOLDER', os.path.join( processingPath, 'rscripts' ) ) # Reload algorithms Processing.loadAlgorithms() # get QGIS project path projectPath = os.getenv("QGIS_PROJECT_FILE") if not projectPath and 'map' in params : projectPath = params['map'] elif not projectPath and 'MAP' in params : projectPath = params['MAP'] #projectFolder projectFolder = '' if projectPath and os.path.exists( projectPath ) : projectFolder = os.path.dirname( projectPath ) QgsMessageLog.logMessage("projectPath "+str(projectPath)) rasterLayers = [] vectorLayers = [] crsList = [] if projectPath and os.path.exists( projectPath ) : p_dom = minidom.parse( projectPath ) for ml in p_dom.getElementsByTagName('maplayer') : l= {'type':ml.attributes["type"].value, 'name':ml.getElementsByTagName('layername')[0].childNodes[0].data, 'datasource':ml.getElementsByTagName('datasource')[0].childNodes[0].data, 'provider':ml.getElementsByTagName('provider')[0].childNodes[0].data, 'crs':ml.getElementsByTagName('srs')[0].getElementsByTagName('authid')[0].childNodes[0].data, 'proj4':ml.getElementsByTagName('srs')[0].getElementsByTagName('proj4')[0].childNodes[0].data } # Update relative path if l['provider'] in ['ogr','gdal'] and str(l['datasource']).startswith('.'): l['datasource'] = os.path.abspath( os.path.join( projectFolder, l['datasource'] ) ) if not os.path.exists( l['datasource'] ) : continue elif l['provider'] in ['gdal'] and str(l['datasource']).startswith('NETCDF:'): theURIParts = l['datasource'].split( ":" ); src = theURIParts[1] src = src.replace( '"', '' ); if src.startswith('.') : src = os.path.abspath( os.path.join( projectFolder, src ) ) theURIParts[1] = '"' + src + '"' l['datasource'] = ':'.join( theURIParts ) if l['type'] == "raster" : rasterLayers.append( l ) elif l['type'] == "vector" : l['geometry'] = ml.attributes["geometry"].value vectorLayers.append( l ) deafultCrs = '' for mapcanvas in p_dom.getElementsByTagName('mapcanvas'): for destinationsrs in mapcanvas.getElementsByTagName('destinationsrs'): for authid in destinationsrs.getElementsByTagName('authid'): defaultCrs = authid.childNodes[0].data crsList.append( defaultCrs ) for wmsCrsList in p_dom.getElementsByTagName('WMSCrsList') : for wmsCrs in wmsCrsList.getElementsByTagName('value') : wmsCrsValue = wmsCrs.childNodes[0].data if wmsCrsValue and wmsCrsValue != defaultCrs: crsList.append( wmsCrsValue ) processes = [None] # if no processes found no processes return (deactivate default pywps process) identifier = params.get('IDENTIFIER', '').lower() for i in Processing.algs : if providerList and i not in providerList : continue QgsMessageLog.logMessage("provider "+i+" "+str(len(Processing.algs[i]))) for m in Processing.algs[i]: if identifier and identifier != m : continue if algList and m not in algList : continue if algsFilter : alg = Processing.getAlgorithm( m ) if algsFilter.lower() not in alg.name.lower() and algsFilter.lower() not in m.lower(): continue #QgsMessageLog.logMessage("provider "+i+" "+m) processes.append(QGISProcessFactory(m, projectPath, vectorLayers, rasterLayers, crsList)) #pywpsConfig.setConfigValue("server","outputPath", '/tmp/wpsoutputs') #pywpsConfig.setConfigValue("server","logFile", '/tmp/pywps.log') qgisaddress = self.serverInterface().getEnv('SERVER_NAME')+self.serverInterface().getEnv('SCRIPT_NAME') if self.serverInterface().getEnv('HTTPS') : qgisaddress = 'https://'+qgisaddress else : qgisaddress = 'http://'+qgisaddress qgisaddress = qgisaddress+'?' if 'map' in params : qgisaddress = qgisaddress +'map='+ params['map'] +'&' elif 'MAP' in params : qgisaddress = qgisaddress +'MAP='+ params['MAP'] +'&' if 'config' in params : qgisaddress = qgisaddress +'config='+ params['config'] +'&' elif 'CONFIG' in params : qgisaddress = qgisaddress +'CONFIG='+ params['CONFIG'] +'&' #pywpsConfig.setConfigValue("wps","serveraddress", qgisaddress) #QgsMessageLog.logMessage("qgisaddress "+qgisaddress) #pywpsConfig.setConfigValue("qgis","qgisserveraddress", qgisaddress) # init wps method = 'GET' if request_body : method = 'POST' wps = pywps.Pywps(method) # create the request file for POST request if request_body : tmpPath=pywpsConfig.getConfigValue("server","tempPath") requestFile = open(os.path.join(tmpPath, "request-"+str(wps.UUID)),"w") requestFile.write(str(request_body)) requestFile.close() requestFile = open(os.path.join(tmpPath, "request-"+str(wps.UUID)),"r") inputQuery = requestFile if wps.parseRequest(inputQuery): response = wps.performRequest(processes=processes) if response: request.clearHeaders() request.clearBody() #request.setHeader('Content-type', 'text/xml') request.setInfoFormat(wps.request.contentType) resp = wps.response if wps.request.contentType == 'application/xml': import re import xml.sax.saxutils as saxutils resp = re.sub(r'Get xlink:href=".*"', 'Get xlink:href="'+saxutils.escape(qgisaddress)+'"', resp) resp = re.sub(r'Post xlink:href=".*"', 'Post xlink:href="'+saxutils.escape(qgisaddress)+'"', resp) # test response type if isinstance( resp, str ): request.appendBody(resp) elif isinstance( resp, file ) : request.appendBody(resp.read()) except WPSException,e: request.clearHeaders() #request.setHeader('Content-type', 'text/xml') request.clearBody() request.setInfoFormat('text/xml') request.appendBody(e.__str__())
def editRenderingStyles(self): item = self.algorithmTree.currentItem() if isinstance(item, TreeAlgorithmItem): alg = Processing.getAlgorithm(item.alg.commandLineName()) dlg = EditRenderingStylesDialog(alg) dlg.exec_()
def createAlgorithmHelp(algName, folder): alg = Processing.getAlgorithm(algName) baseHelpForAlgorithm(alg, folder)
def createTest(text): s = '' tokens = text[len('processing.runalg('):-1].split(',') cmdname = (tokens[0])[1:-1] methodname = 'test_' + cmdname.replace(':', '') s += 'def ' + methodname + '(self):\n' alg = Processing.getAlgorithm(cmdname) execcommand = 'processing.runalg(' i = 0 for token in tokens: if i < alg.getVisibleParametersCount() + 1: if os.path.exists(token[1:-1]): token = os.path.basename(token[1:-1])[:-4] + '()' execcommand += token + ',' else: execcommand += 'None,' i += 1 s += '\toutputs=' + execcommand[:-1] + ')\n' i = -1 * len(alg.outputs) for out in alg.outputs: filename = (tokens[i])[1:-1] if tokens[i] == unicode(None): QMessageBox.critical(None, tr('Error'), tr('Cannot create unit test for that algorithm execution. The ' 'output cannot be a temporary file')) return s += "\toutput=outputs['" + out.name + "']\n" if isinstance(out, (OutputNumber, OutputString)): s += 'self.assertTrue(' + unicode(out) + ', output.value)\n' if isinstance(out, OutputRaster): dataset = gdal.Open(filename, GA_ReadOnly) strhash = hash(unicode(dataset.ReadAsArray(0).tolist())) s += '\tself.assertTrue(os.path.isfile(output))\n' s += '\tdataset=gdal.Open(output, GA_ReadOnly)\n' s += '\tstrhash=hash(unicode(dataset.ReadAsArray(0).tolist()))\n' s += '\tself.assertEqual(strhash,' + unicode(strhash) + ')\n' if isinstance(out, OutputVector): layer = dataobjects.getObject(filename) fields = layer.pendingFields() s += '\tlayer=dataobjects.getObjectFromUri(output, True)\n' s += '\tfields=layer.pendingFields()\n' s += '\texpectednames=[' + ','.join(["'" + unicode(f.name()) + "'" for f in fields]) + ']\n' s += '\texpectedtypes=[' + ','.join(["'" + unicode(f.typeName()) + "'" for f in fields]) + ']\n' s += '\tnames=[unicode(f.name()) for f in fields]\n' s += '\ttypes=[unicode(f.typeName()) for f in fields]\n' s += '\tself.assertEqual(expectednames, names)\n' s += '\tself.assertEqual(expectedtypes, types)\n' features = vector.features(layer) numfeat = len(features) s += '\tfeatures=processing.features(layer)\n' s += '\tself.assertEqual(' + unicode(numfeat) + ', len(features))\n' if numfeat > 0: feature = features.next() attrs = feature.attributes() s += '\tfeature=features.next()\n' s += '\tattrs=feature.attributes()\n' s += '\texpectedvalues=[' + ','.join(['"' + unicode(attr) + '"' for attr in attrs]) + ']\n' s += '\tvalues=[unicode(attr) for attr in attrs]\n' s += '\tself.assertEqual(expectedvalues, values)\n' s += "\twkt='" + unicode(feature.geometry().exportToWkt()) + "'\n" s += '\tself.assertEqual(wkt, \ unicode(feature.geometry().exportToWkt()))' dlg = ShowTestDialog(s) dlg.exec_()
def createTest(text): definition = {} tokens = text[len('processing.runalg('):-1].split(',') cmdname = (tokens[0])[1:-1] alg = Processing.getAlgorithm(cmdname) definition['name'] = 'Test ({})'.format(cmdname) definition['algorithm'] = cmdname params = {} results = {} i = 0 for param in alg.parameters: if param.hidden: continue i += 1 token = tokens[i] if isinstance(param, ParameterVector): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) p = {'type': 'vector', 'name': filepath} if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterRaster): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) p = {'type': 'raster', 'name': filepath} if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p elif isinstance(param, ParameterMultipleInput): multiparams = token[1:-1].split(';') newparam = [] for mp in multiparams: schema, filepath = extractSchemaPath(mp) newparam.append({'type': 'vector', 'name': filepath}) p = {'type': 'multi', 'params': newparam} if not schema: p['location'] = '[The source data is not in the testdata directory. Please use data in the processing/tests/testdata folder.]' params[param.name] = p else: params[param.name] = token definition['params'] = params for i, out in enumerate([out for out in alg.outputs if not out.hidden]): token = tokens[i - alg.getVisibleOutputsCount()] if isinstance(out, (OutputNumber, OutputString)): results[out.name] = unicode(out) elif isinstance(out, OutputRaster): filename = token[1:-1] dataset = gdal.Open(filename, GA_ReadOnly) strhash = hashlib.sha224(dataset.ReadAsArray(0).data).hexdigest() results[out.name] = {'type': 'rasterhash', 'hash': strhash} elif isinstance(out, OutputVector): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) results[out.name] = {'type': 'vector', 'name': filepath} if not schema: results[out.name][ 'location'] = '[The expected result data is not in the testdata directory. Please write it to processing/tests/testdata/expected. Prefer gml files.]' elif isinstance(out, OutputHTML): filename = token[1:-1] schema, filepath = extractSchemaPath(filename) results[out.name] = {'type': 'file', 'name': filepath} if not schema: results[out.name][ 'location'] = '[The expected result file is not in the testdata directory. Please redirect the output to processing/tests/testdata/expected.]' definition['results'] = results dlg = ShowTestDialog(yaml.dump([definition], default_flow_style=False)) dlg.exec_()