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()
Example #2
0
 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_()
Example #3
0
 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      
Example #4
0
def alghelp(name):
    alg = Processing.getAlgorithm(name)
    if alg is not None:
        print str(alg)
        algoptions(name)
    else:
        print 'Algorithm not found'
Example #5
0
 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_()
Example #6
0
 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
Example #7
0
def alghelp(name):
    alg = Processing.getAlgorithm(name)
    if alg != None:
        print(str(alg))
        algoptions(name)
    else:
        print "Algorithm not found"
Example #8
0
    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)
Example #9
0
def alghelp(name):
    alg = Processing.getAlgorithm(name)
    if alg != None:
        print (str(alg))
        algoptions(name)
    else:
        print "Algorithm not found"
Example #10
0
 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()
Example #11
0
    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)
Example #12
0
def alghelp(name):
    alg = Processing.getAlgorithm(name)
    if alg is not None:
        print str(alg)
        algoptions(name)
    else:
        print 'Algorithm not found'
Example #13
0
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')
Example #14
0
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')
Example #15
0
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"
Example #16
0
 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
Example #17
0
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())
Example #19
0
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)
Example #20
0
 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
Example #21
0
 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)
Example #22
0
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"
Example #23
0
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')
Example #24
0
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))
Example #25
0
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"
Example #26
0
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')
Example #27
0
 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
Example #28
0
 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
Example #29
0
 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
Example #30
0
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)
Example #31
0
    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
Example #32
0
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
Example #33
0
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)
Example #34
0
 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()
Example #35
0
 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()
Example #36
0
File: utils.py Project: wsyscu/QGIS
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)
Example #38
0
 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)
Example #39
0
 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()
Example #40
0
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_()
Example #41
0
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
Example #43
0
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())
Example #45
0
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
Example #46
0
    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))
Example #47
0
 def editRenderingStyles(self):
     item = self.algorithmTree.currentItem()
     if isinstance(item, TreeAlgorithmItem):
         alg = Processing.getAlgorithm(item.alg.commandLineName())
         dlg = EditRenderingStylesDialog(alg)
         dlg.exec_()
Example #48
0
def createAlgorithmHelp(algName, folder):
    alg = Processing.getAlgorithm(algName)
    baseHelpForAlgorithm(alg, folder)
Example #49
0
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
Example #51
0
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_()
Example #52
0
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_()
Example #53
0
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
Example #54
0
    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__())
Example #55
0
 def editRenderingStyles(self):
     item = self.algorithmTree.currentItem()
     if isinstance(item, TreeAlgorithmItem):
         alg = Processing.getAlgorithm(item.alg.commandLineName())
         dlg = EditRenderingStylesDialog(alg)
         dlg.exec_()
Example #56
0
def createAlgorithmHelp(algName, folder):
    alg = Processing.getAlgorithm(algName)
    baseHelpForAlgorithm(alg, folder)
Example #57
0
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_()
Example #58
0
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_()