def runFusion(commands, progress): loglines = [] loglines.append("Fusion execution console output") proc = subprocess.Popen(commands, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=False).stdout for line in iter(proc.readline, ""): loglines.append(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
def processAlgorithm(self, feedback): ns = {} ns['feedback'] = feedback ns['scriptDescriptionFile'] = self.descriptionFile for param in self.parameters: ns[param.name] = param.value for out in self.outputs: ns[out.name] = out.value variables = re.findall('@[a-zA-Z0-9_]*', self.script) script = 'import processing\n' script += self.script context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope(QgsProject.instance())) for var in variables: varname = var[1:] if context.hasVariable(varname): script = script.replace(var, context.variable(varname)) else: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Cannot find variable: %s' % varname) exec((script), ns) for out in self.outputs: out.setValue(ns[out.name])
def executeOtb(commands, progress, addToLog=True): loglines = [] loglines.append(tr("OTB execution console output")) os.putenv("ITK_AUTOLOAD_PATH", otbLibPath()) fused_command = "".join(['"%s" ' % re.sub(r'^"|"$', "", c) for c in commands]) with subprocess.Popen( fused_command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, ) as proc: if isMac(): # This trick avoids having an uninterrupted system call exception if OTB is not installed time.sleep(1) for line in iter(proc.stdout.readline, ""): if "[*" in line: idx = line.find("[*") perc = int(line[idx - 4 : idx - 2].strip(" ")) if perc != 0: progress.setPercentage(perc) else: loglines.append(line) progress.setConsoleInfo(line) if addToLog: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) return loglines
def defineCharacteristicsFromFile(self): lines = open(self.descriptionFile) line = lines.readline().strip("\n").strip() self.appkey = line line = lines.readline().strip("\n").strip() self.cliName = line line = lines.readline().strip("\n").strip() self.name = line line = lines.readline().strip("\n").strip() self.group = line while line != "": try: line = line.strip("\n").strip() if line.startswith("Parameter"): param = ParameterFactory.getFromString(line) # Hack for initializing the elevation parameters from Processing configuration if param.name == "-elev.dem.path" or param.name == "-elev.dem": param.default = OTBUtils.otbSRTMPath() elif param.name == "-elev.dem.geoid" or param.name == "-elev.geoid": param.default = OTBUtils.otbGeoidPath() self.addParameter(param) elif line.startswith("*Parameter"): param = ParameterFactory.getFromString(line[1:]) param.isAdvanced = True self.addParameter(param) elif line.startswith("Extent"): self.addParameter(ParameterExtent(self.REGION_OF_INTEREST, "Region of interest", "0,1,0,1")) self.hasROI = True else: self.addOutput(OutputFactory.getFromString(line)) line = lines.readline().strip("\n").strip() except Exception,e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, "Could not open OTB algorithm: " + self.descriptionFile + "\n" + line) raise e
def openModel(self): filename = unicode(QFileDialog.getOpenFileName(self, self.tr('Open Model'), ModelerUtils.modelsFolder(), self.tr('Processing models (*.model *.MODEL)'))) if filename: try: alg = ModelerAlgorithm.fromFile(filename) self.alg = alg self.alg.setModelerView(self) self.textGroup.setText(alg.group) self.textName.setText(alg.name) self.repaintModel() self.view.centerOn(0, 0) self.hasChanged = False except WrongModelException as e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not load model %s\n%s') % (filename, e.msg)) QMessageBox.critical(self, self.tr('Could not open model'), self.tr('The selected model could not be loaded.\n' 'See the log for more information.')) except Exception as e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not load model %s\n%s') % (filename, e.args[0])) QMessageBox.critical(self, self.tr('Could not open model'), self.tr('The selected model could not be loaded.\n' 'See the log for more information.'))
def defineCharacteristicsFromFile(self): with codecs.open(self.descriptionFile, encoding='utf-8') as f: line = f.readline().strip('\n').strip() self.name = line self.i18n_name = self.tr(line) line = f.readline().strip('\n').strip() self.cmdName = line line = f.readline().strip('\n').strip() self.group = line self.i18n_group = self.tr(line) line = f.readline().strip('\n').strip() while line != '': try: line = line.strip('\n').strip() if line.startswith('Parameter'): param = getParameterFromString(line) self.addParameter(param) else: self.addOutput(getOutputFromString(line)) line = f.readline().strip('\n').strip() except Exception as e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not load TauDEM algorithm: {}\n{}'.format(self.descriptionFile, line))) raise e
def __init__(self, alg): super(HelpEditionDialog, self).__init__(None) self.setupUi(self) self.alg = alg self.descriptions = {} if isinstance(self.alg, ModelerAlgorithm): self.descriptions = self.alg.helpContent else: if self.alg.descriptionFile is not None: helpfile = alg.descriptionFile + '.help' if os.path.exists(helpfile): try: with open(helpfile) as f: self.descriptions = json.load(f) except Exception: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('Cannot open help file: %s') % helpfile) self.currentName = self.ALG_DESC if self.ALG_DESC in self.descriptions: self.text.setText(self.descriptions[self.ALG_DESC]) self.tree.itemClicked.connect(self.changeItem) self.fillTree() self.updateHtmlView()
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) tolerance = self.getParameterValue(self.TOLERANCE) pointsBefore = 0 pointsAfter = 0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields().toList(), layer.wkbType(), layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, f in enumerate(features): featGeometry = QgsGeometry(f.geometry()) attrs = f.attributes() pointsBefore += self.geomVertexCount(featGeometry) newGeometry = featGeometry.simplify(tolerance) pointsAfter += self.geomVertexCount(newGeometry) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrs) writer.addFeature(feature) progress.setPercentage(int(current * total)) del writer ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Simplify: Input geometries have been simplified from %s to %s points' % (pointsBefore, pointsAfter)))
def executeSaga(progress): if ProcessingUtils.isWindows(): command = ["cmd.exe", "/C ", SagaUtils.sagaBatchJobFilename()] else: os.chmod(SagaUtils.sagaBatchJobFilename(), stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE) command = [SagaUtils.sagaBatchJobFilename()] loglines = [] loglines.append("SAGA execution console output") proc = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True, ).stdout for line in iter(proc.readline, ""): if "%" in line: s = "".join([x for x in line if x.isdigit()]) try: progress.setPercentage(int(s)) except: pass else: line = line.strip() if line != "/" and line != "-" and line != "\\" and line != "|": loglines.append(line) progress.setConsoleInfo(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_CONSOLE): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
def processAlgorithm(self, progress): layer = QGisLayers.getObjectFromUri(self.getParameterValue(self.INPUT)) tolerance =self.getParameterValue(self.TOLERANCE) pointsBefore = 0 pointsAfter = 0 writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.pendingFields().toList(), layer.wkbType(), layer.crs()) current = 0 selection = QGisLayers.features(layer) total = 100.0 / float(len(selection)) for f in selection: featGeometry = QgsGeometry(f.geometry()) attrs = f.attributes() pointsBefore += self.geomVertexCount(featGeometry) newGeometry = featGeometry.simplify(tolerance) pointsAfter += self.geomVertexCount(newGeometry) feature = QgsFeature() feature.setGeometry(newGeometry) feature.setAttributes(attrs) writer.addFeature(feature) current += 1 progress.setPercentage(int(current * total)) del writer ProcessingLog.addToLog(ProcessingLog.LOG_INFO, "Simplify: Input geometries have been simplified from" + str(pointsBefore) + " to " + str(pointsAfter) + " points.")
def initialize(): # Add the basic providers Processing.addProvider(QGISAlgorithmProvider()) Processing.addProvider(ModelerOnlyAlgorithmProvider()) Processing.addProvider(GdalOgrAlgorithmProvider()) Processing.addProvider(LidarToolsAlgorithmProvider()) Processing.addProvider(OTBAlgorithmProvider()) Processing.addProvider(RAlgorithmProvider()) Processing.addProvider(SagaAlgorithmProvider()) Processing.addProvider(GrassAlgorithmProvider()) Processing.addProvider(Grass7AlgorithmProvider()) Processing.addProvider(ScriptAlgorithmProvider()) Processing.addProvider(TauDEMAlgorithmProvider()) Processing.addProvider(Processing.modeler) Processing.modeler.initializeSettings() # And initialize AlgorithmDecorator.loadClassification() ProcessingLog.startLogging() ProcessingConfig.initialize() ProcessingConfig.readSettings() RenderingStyles.loadStyles() Processing.loadFromProviders() # Inform registered listeners that all providers' algorithms have been loaded Processing.fireAlgsListHasChanged()
def _loadAlgorithms(self): self.algs = [] version = SagaUtils.getSagaInstalledVersion(True) if version is None: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr("Problem with SAGA installation: SAGA was not found or is not correctly installed"), ) return if version not in self.supportedVersions: lastVersion = sorted(self.supportedVersions.keys())[-1] if version > lastVersion: version = lastVersion else: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr("Problem with SAGA installation: installed SAGA version (%s) is not supported" % version), ) return folder = SagaUtils.sagaDescriptionPath() folder = os.path.join(folder, self.supportedVersions[version][0]) for descriptionFile in os.listdir(folder): if descriptionFile.endswith("txt"): f = os.path.join(folder, descriptionFile) self._loadAlgorithm(f, version) self.algs.append(SplitRGBBands())
def execute(self, progress=SilentProgress(), model=None): """The method to use to call a processing algorithm. Although the body of the algorithm is in processAlgorithm(), it should be called using this method, since it performs some additional operations. Raises a GeoAlgorithmExecutionException in case anything goes wrong. """ self.model = model try: self.setOutputCRS() self.resolveOutputs() self.evaluateParameterValues() self.runPreExecutionScript(progress) self.processAlgorithm(progress) progress.setPercentage(100) self.convertUnsupportedFormats(progress) self.runPostExecutionScript(progress) except GeoAlgorithmExecutionException as gaee: lines = [self.tr('Error while executing algorithm')] lines.append(traceback.format_exc()) ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, gaee.msg) raise GeoAlgorithmExecutionException(gaee.msg, lines, gaee) except Exception as e: # If something goes wrong and is not caught in the # algorithm, we catch it here and wrap it lines = [self.tr('Uncaught error while executing algorithm')] lines.append(traceback.format_exc()) ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, lines) raise GeoAlgorithmExecutionException(str(e) + self.tr('\nSee log for more details'), lines, e)
def processAlgorithm(self, progress): if not ogrAvailable: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, "OGR bindings not installed" ) return input = self.getParameterValue(self.INPUT_LAYER) sql = self.getParameterValue(self.SQL) ogrLayer = self.ogrConnectionString(input) output = self.getOutputValue(self.OUTPUT) qDebug("Opening data source '%s'" % ogrLayer) poDS = ogr.Open( ogrLayer, False ) if poDS is None: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.failure(ogrLayer)) return result = self.select_values(poDS, sql) f = open(output, "w") f.write("<table>") for row in result: f.write("<tr>") for col in row: f.write("<td>"+col+"</td>") f.write("</tr>") f.write("</table>") f.close()
def executeSaga(progress): if isWindows(): command = ['cmd.exe', '/C ', SagaUtils.sagaBatchJobFilename()] else: os.chmod(SagaUtils.sagaBatchJobFilename(), stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE) command = [SagaUtils.sagaBatchJobFilename()] loglines = [] loglines.append('SAGA execution console output') proc = subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stdin=open(os.devnull), stderr=subprocess.STDOUT, universal_newlines=True, ).stdout for line in iter(proc.readline, ''): if '%' in line: s = ''.join([x for x in line if x.isdigit()]) try: progress.setPercentage(int(s)) except: pass else: line = line.strip() if line != '/' and line != '-' and line != '\\' and line \ != '|': loglines.append(line) progress.setConsoleInfo(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_CONSOLE): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
def processAlgorithm(self, progress): commands = [] commands.append(os.path.join(TauDEMUtils.mpiexecPath(), 'mpiexec')) processNum = ProcessingConfig.getSetting(TauDEMUtils.MPI_PROCESSES) if processNum <= 0: raise GeoAlgorithmExecutionException('Wrong number of MPI \ processes used.\nPlease set correct number before running \ TauDEM algorithms.') commands.append('-n') commands.append(str(processNum)) commands.append(os.path.join(TauDEMUtils.taudemPath(), self.cmdName)) commands.append('-slp') commands.append(self.getParameterValue(self.SLOPE_GRID)) commands.append('-sca') commands.append(self.getParameterValue(self.AREA_GRID)) commands.append('-par') commands.append(str(self.getParameterValue(self.SLOPE_EXPONENT))) commands.append(str(self.getParameterValue(self.AREA_EXPONENT))) commands.append('-sa') commands.append(self.getOutputValue(self.SLOPE_AREA_GRID)) loglines = [] loglines.append('TauDEM execution command') for line in commands: loglines.append(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) TauDEMUtils.executeTauDEM(commands, progress)
def accept(self): keepOpen = ProcessingConfig.getSetting( ProcessingConfig.KEEP_DIALOG_OPEN) try: if self.setParamValues(): QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) ProcessingLog.addToLog(ProcessingLog.LOG_ALGORITHM, self.alg.getAsCommand()) ret = runalg(self.alg, self) QApplication.restoreOverrideCursor() if ret: handleAlgorithmResults(self.alg, self, not keepOpen) self.executed = True QDialog.reject(self) else: QMessageBox.critical(self, self.tr('Unable to execute algorithm'), self.tr('Wrong or missing parameter ' 'values')) return except GeoAlgorithmExecutionException, e: QApplication.restoreOverrideCursor() QMessageBox.critical(self, "Error",e.msg) ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, e.msg) self.executed = False QDialog.reject(self)
def check_extension(self, path, progress): """ Due to the wider range of the accepted file types by QGIS the file extensions are checked and given a boolean value for further processing if they are accepted by GIS Cloud :param path: Path to check if valid dataset :type path: str :param progress: Interface to the processing window :type progress: processing.gui.AlgorithmDialog.AlgorithmDialog :rtype: bool """ filename, file_extension = os.path.splitext(path) if file_extension in (".shp", ".mif", ".mid", ".tab", ".kml", ".gpx", ".tif", ".tiff", ".ecw", ".img", ".jp2", ".jpg", ".png", ".pdf", ".json", ".geojson"): return True else: # progress.error(path + " is not compatible with GISCloud.") # provides feedback on the rejection of a filetype if path: # i.e. not an empty string progress.error(path + " is not compatible with GISCloud.") ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, "{} is not an accepted filetype".format(path) ) return False
def bounds(self): """ Function for recalculating the bounded extents of the layers as they are processed. Under construction :return: """ # Requires refinement for raster manipulation of bounds selected_extent = unicode(self.getParameterValue(self.MAP_EXTENT)).split(',') xMin = float(selected_extent[0]) xMax = float(selected_extent[1]) yMin = float(selected_extent[2]) yMax = float(selected_extent[3]) extent = QgsRectangle(xMin, yMin, xMax, yMax) mapCRS = iface.mapCanvas().mapSettings().destinationCrs() transform = QgsCoordinateTransform( mapCRS, QgsCoordinateReferenceSystem('EPSG:4326') # WGS84 # QgsCoordinateReferenceSystem('EPSG:3785') # Popular vis mercator ) try: layer_extent = transform.transform(extent) except QgsCsException: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "exception in transform layer srs") layer_extent = QgsRectangle(-180, -90, 180, 90) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, layer_extent.toString()) return layer_extent
def processAlgorithm(self, progress): commands = [] commands.append(os.path.join(TauDEMUtils.mpiexecPath(), "mpiexec")) processNum = ProcessingConfig.getSetting(TauDEMUtils.MPI_PROCESSES) if processNum <= 0: raise GeoAlgorithmExecutionException("Wrong number of MPI processes used.\nPlease set correct number before running TauDEM algorithms.") commands.append("-n") commands.append(str(processNum)) commands.append(os.path.join(TauDEMUtils.taudemPath(), self.cmdName)) commands.append("-plen") commands.append(self.getParameterValue(self.LENGTH_GRID)) commands.append("-ad8") commands.append(self.getParameterValue(self.CONTRIB_AREA_GRID)) commands.append("-par") commands.append(str(self.getParameterValue(self.THRESHOLD))) commands.append(str(self.getParameterValue(self.EXPONENT))) commands.append("-ss") commands.append(self.getOutputValue(self.STREAM_SOURCE_GRID)) loglines = [] loglines.append("TauDEM execution command") for line in commands: loglines.append(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) TauDEMUtils.executeTauDEM(commands, progress)
def processAlgorithm(self, progress): commands.append(os.path.join(TauDEMUtils.mpiexecPath(), "mpiexec")) processNum = ProcessingConfig.getSetting(TauDEMUtils.MPI_PROCESSES) if processNum <= 0: raise GeoAlgorithmExecutionException("Wrong number of MPI processes used.\nPlease set correct number before running TauDEM algorithms.") commands.append("-n") commands.append(str(processNum)) commands.append(os.path.join(TauDEMUtils.taudemPath(), self.cmdName)) commands.append("-ad8") commands.append(self.getParameterValue(self.D8_CONTRIB_AREA_GRID)) commands.append("-p") commands.append(self.getParameterValue(self.D8_FLOW_DIR_GRID)) commands.append("-fel") commands.append(self.getParameterValue(self.PIT_FILLED_GRID)) commands.append("-ssa") commands.append(self.getParameterValue(self.ACCUM_STREAM_SOURCE_GRID)) commands.append("-o") commands.append(self.getParameterValue(self.OUTLETS_SHAPE)) commands.append("-par") commands.append(str(self.getParameterValue(self.MIN_TRESHOLD))) commands.append(str(self.getParameterValue(self.MAX_THRESHOLD))) commands.append(str(self.getParameterValue(self.TRESHOLD_NUM))) commands.append(str(self.getParameterValue(self.STEPS))) commands.append("-drp") commands.append(self.getOutputValue(self.DROP_ANALYSIS_FILE)) loglines = [] loglines.append("TauDEM execution command") for line in commands: loglines.append(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) TauDEMUtils.executeTauDEM(commands, progress)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_LAYER)) writer = self.getOutputFromName( self.OUTPUT_LAYER).getVectorWriter( layer.fields(), QgsWkbTypes.Point, layer.crs()) features = vector.features(layer) total = 100.0 / len(features) for current, input_feature in enumerate(features): output_feature = input_feature if input_feature.geometry(): output_geometry = input_feature.geometry().centroid() if not output_geometry: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Error calculating centroid for feature {}'.format(input_feature.id())) output_feature.setGeometry(output_geometry) writer.addFeature(output_feature) progress.setPercentage(int(current * total)) del writer
def executeSaga(feedback): if isWindows(): command = ['cmd.exe', '/C ', sagaBatchJobFilename()] else: os.chmod(sagaBatchJobFilename(), stat.S_IEXEC | stat.S_IREAD | stat.S_IWRITE) command = [sagaBatchJobFilename()] loglines = [] loglines.append(QCoreApplication.translate('SagaUtils', 'SAGA execution console output')) with subprocess.Popen( command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.DEVNULL, stderr=subprocess.STDOUT, universal_newlines=True, ) as proc: try: for line in iter(proc.stdout.readline, ''): if '%' in line: s = ''.join([x for x in line if x.isdigit()]) try: feedback.setProgress(int(s)) except: pass else: line = line.strip() if line != '/' and line != '-' and line != '\\' and line != '|': loglines.append(line) feedback.pushConsoleInfo(line) except: pass if ProcessingConfig.getSetting(SAGA_LOG_CONSOLE): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
def error(self, msg): QApplication.restoreOverrideCursor() QMessageBox.critical(self, "Error", msg) ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, msg) if self.algEx: self.algEx.terminate() self.table.setEnabled(True)
def processAlgorithm(self, progress): # Do the thing, Julie inputFilename = self.getParameterValue(self.RASTER) what = self.tsel[self.getParameterValue(self.TRANSFORM)] polyn = self.getParameterValue(self.POLYNOM) output = self.getOutputValue(self.OUT) # Starting transformation progress.setConsoleInfo("Transforming input raster layer with %s " % (str( what ))) func.updateProcessing(progress,1,3) raster = gdal.Open(str(inputFilename)) columns = raster.RasterXSize rows = raster.RasterYSize driver = raster.GetDriver() if(raster.RasterCount==1): band = raster.GetRasterBand(1) data_type = band.DataType nodata = band.GetNoDataValue() # Raise Notice that no no-data value has been selected progress.setConsoleInfo("!!! - Found no nodata-value for band %s . Transforming all values - !!!" % (str(1)) ) try: array = band.ReadAsArray() except Exception, e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,"Could not transform the raster to an array.") work = array[array!=nodata] res = self.transformArray(work,what,polyn) # Transformation result = numpy.copy(array) result[result!=nodata] = res # Replace new values with the one sampled func.updateProcessing(progress,2,3)
def processAlgorithm(self, progress): commands = [] commands.append(os.path.join(TauDEMUtils.mpiexecPath(), "mpiexec")) processNum = ProcessingConfig.getSetting(TauDEMUtils.MPI_PROCESSES) if processNum <= 0: raise GeoAlgorithmExecutionException("Wrong number of MPI processes used.\nPlease set correct number before running TauDEM algorithms.") commands.append("-n") commands.append(str(processNum)) commands.append(os.path.join(TauDEMUtils.taudemPath(), self.cmdName)) commands.append("-ang") commands.append(self.getParameterValue(self.DINF_FLOW_DIR_GRID)) commands.append("-fel") commands.append(self.getParameterValue(self.PIT_FILLED_GRID)) commands.append("-m") commands.append(str(self.STAT_DICT[self.getParameterValue(self.STAT_METHOD)])) commands.append(str(self.DIST_DICT[self.getParameterValue(self.DIST_METHOD)])) commands.append("-thresh") commands.append(str(self.getParameterValue(self.THRESHOLD))) if str(self.getParameterValue(self.EDGE_CONTAM)).lower() == "false": commands.append("-nc") commands.append("-du") commands.append(self.getOutputValue(self.DIST_UP_GRID)) loglines = [] loglines.append("TauDEM execution command") for line in commands: loglines.append(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) TauDEMUtils.executeTauDEM(commands, progress)
def createAlgsList(self): # First we populate the list of algorithms with those created # extending GeoAlgorithm directly (those that execute GDAL # using the console) self.preloadedAlgs = [nearblack(), information(), warp(), translate(), rgb2pct(), pct2rgb(), merge(), buildvrt(), polygonize(), gdaladdo(), ClipByExtent(), ClipByMask(), contour(), rasterize(), proximity(), sieve(), fillnodata(), ExtractProjection(), gdal2xyz(), hillshade(), slope(), aspect(), tri(), tpi(), roughness(), ColorRelief(), GridInvDist(), GridAverage(), GridNearest(), GridDataMetrics(), gdaltindex(), gdalcalc(), rasterize_over(), # ----- OGR tools ----- OgrInfo(), Ogr2Ogr(), Ogr2OgrClip(), Ogr2OgrClipExtent(), Ogr2OgrToPostGis(), Ogr2OgrToPostGisList(), Ogr2OgrPointsOnLines(), Ogr2OgrBuffer(), Ogr2OgrDissolve(), Ogr2OgrOneSideBuffer(), Ogr2OgrTableToPostGisList(), OgrSql(), ] # And then we add those that are created as python scripts folder = self.scriptsFolder() if os.path.exists(folder): for descriptionFile in os.listdir(folder): if descriptionFile.endswith('py'): try: fullpath = os.path.join(self.scriptsFolder(), descriptionFile) alg = GdalScriptAlgorithm(fullpath) self.preloadedAlgs.append(alg) except WrongScriptException as e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, e.msg)
def processAlgorithm(self, progress): ns = {} ns["progress"] = progress ns["scriptDescriptionFile"] = self.descriptionFile for param in self.parameters: ns[param.name] = param.value for out in self.outputs: ns[out.name] = out.value variables = re.findall("@[a-zA-Z0-9_]*", self.script) script = "import processing\n" script += self.script context = QgsExpressionContext() context.appendScope(QgsExpressionContextUtils.globalScope()) context.appendScope(QgsExpressionContextUtils.projectScope()) for var in variables: varname = var[1:] if context.hasVariable(varname): script = script.replace(var, context.variable(varname)) else: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, "Cannot find variable: %s" % varname) exec((script), ns) for out in self.outputs: out.setValue(ns[out.name])
def defineCharacteristicsFromFile(self): lines = open(self.descriptionFile) line = lines.readline().strip('\n').strip() self.name = line self.i18n_name = QCoreApplication.translate("TAUDEMAlgorithm", line) line = lines.readline().strip('\n').strip() self.cmdName = line line = lines.readline().strip('\n').strip() self.group = line self.i18n_group = QCoreApplication.translate("TAUDEMAlgorithm", line) line = lines.readline().strip('\n').strip() while line != '': try: line = line.strip('\n').strip() if line.startswith('Parameter'): param = getParameterFromString(line) self.addParameter(param) else: self.addOutput(getOutputFromString(line)) line = lines.readline().strip('\n').strip() except Exception as e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not load TauDEM algorithm: %s\n%s' % (self.descriptionFile, line))) raise e lines.close()
def executeGrass(commands, progress, outputCommands = None): loglines = [] loglines.append("GRASS execution console output") grassOutDone = False command = GrassUtils.prepareGrassExecution(commands) proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True).stdout for line in iter(proc.readline, ""): if "GRASS_INFO_PERCENT" in line: try: progress.setPercentage(int(line[len("GRASS_INFO_PERCENT")+ 2:])) except: pass else: if "r.out" in line or "v.out" in line: grassOutDone = True loglines.append(line) progress.setConsoleInfo(line) # Some GRASS scripts, like r.mapcalculator or r.fillnulls, call other GRASS scripts during execution. This may override any commands that are # still to be executed by the subprocess, which are usually the output ones. If that is the case runs the output commands again. if not grassOutDone and outputCommands: command = GrassUtils.prepareGrassExecution(outputCommands) proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stdin=subprocess.PIPE,stderr=subprocess.STDOUT, universal_newlines=True).stdout for line in iter(proc.readline, ""): if "GRASS_INFO_PERCENT" in line: try: progress.setPercentage(int(line[len("GRASS_INFO_PERCENT")+ 2:])) except: pass else: loglines.append(line) progress.setConsoleInfo(line) if ProcessingConfig.getSetting(GrassUtils.GRASS_LOG_CONSOLE): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) return loglines;
def processAlgorithm(self, progress): currentOs = os.name path = OTBUtils.otbPath() commands = [] commands.append(path + os.sep + self.cliName) self.roiVectors = {} self.roiRasters = {} for param in self.parameters: # get the given input(s) if param.name in ["-il", "-in"]: newparams = "" listeParameters = param.value.split(";") for inputParameter in listeParameters: # if HDF5 file if "HDF5" in inputParameter: if currentOs == "posix": data = inputParameter[6:] else: data = inputParameter[5:] dataset = data #on windows, there isn't " #if data[-1] == '"': if currentOs == "posix": data = data[:data.index('"')] else: data = data[:data.index('://')] #try : if currentOs == "posix": dataset.index('"') dataset = os.path.basename( data) + dataset[dataset.index('"'):] #except ValueError : else: #dataset = os.path.basename( data ) + '"' + dataset[dataset.index('://'):] dataset = dataset[dataset.index('://'):] #get index of the subdataset with gdal if currentOs == "posix": commandgdal = "gdalinfo " + data + " | grep '" + dataset + "$'" else: commandgdal = "gdalinfo " + data + " | findstr \"" + dataset + "$\"" resultGDAL = os.popen(commandgdal).readlines() indexSubdataset = -1 if resultGDAL: indexSubdatasetString = re.search( "SUBDATASET_(\d+)_", resultGDAL[0]) if indexSubdatasetString: #match between () indexSubdataset = indexSubdatasetString.group( 1) else: indexSubdataset = -1 else: #print "Error : no match of ", dataset, "$ in gdalinfo " + data indexSubdataset = -1 if not indexSubdataset == -1: indexSubdataset = int(indexSubdataset) - 1 newParam = "\'" + data + "?&sdataidx=" + unicode( indexSubdataset) + "\'" else: newParam = inputParameter newparams += newParam # no hdf5 else: newparams += inputParameter newparams += ";" if newparams[-1] == ";": newparams = newparams[:-1] param.value = newparams if param.value is None or param.value == "": continue if isinstance(param, ParameterVector): commands.append(param.name) if self.hasROI: roiFile = getTempFilename('shp') commands.append(roiFile) self.roiVectors[param.value] = roiFile else: commands.append("\"" + param.value + "\"") elif isinstance(param, ParameterRaster): commands.append(param.name) if self.hasROI: roiFile = getTempFilename('tif') commands.append(roiFile) self.roiRasters[param.value] = roiFile else: commands.append("\"" + param.value + "\"") elif isinstance(param, ParameterMultipleInput): commands.append(param.name) files = unicode(param.value).split(";") paramvalue = " ".join(["\"" + f + " \"" for f in files]) commands.append(paramvalue) elif isinstance(param, ParameterSelection): commands.append(param.name) idx = int(param.value) commands.append(unicode(param.options[idx])) elif isinstance(param, ParameterBoolean): if param.value: commands.append(param.name) commands.append(unicode(param.value).lower()) elif isinstance(param, ParameterExtent): self.roiValues = param.value.split(",") else: commands.append(param.name) commands.append(unicode(param.value)) for out in self.outputs: commands.append(out.name) commands.append('"' + out.value + '"') for roiInput, roiFile in self.roiRasters.items(): startX, startY = float(self.roiValues[0]), float(self.roiValues[1]) sizeX = float(self.roiValues[2]) - startX sizeY = float(self.roiValues[3]) - startY helperCommands = [ "otbcli_ExtractROI", "-in", roiInput, "-out", roiFile, "-startx", unicode(startX), "-starty", unicode(startY), "-sizex", unicode(sizeX), "-sizey", unicode(sizeY) ] ProcessingLog.addToLog(ProcessingLog.LOG_INFO, helperCommands) progress.setCommand(helperCommands) OTBUtils.executeOtb(helperCommands, progress) if self.roiRasters: supportRaster = self.roiRasters.itervalues().next() for roiInput, roiFile in self.roiVectors.items(): helperCommands = [ "otbcli_VectorDataExtractROIApplication", "-vd.in", roiInput, "-io.in", supportRaster, "-io.out", roiFile, "-elev.dem.path", OTBUtils.otbSRTMPath() ] ProcessingLog.addToLog(ProcessingLog.LOG_INFO, helperCommands) progress.setCommand(helperCommands) OTBUtils.executeOtb(helperCommands, progress) loglines = [] loglines.append(self.tr('OTB execution command')) for line in commands: loglines.append(line) progress.setCommand(line) ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) import processing.algs.otb.OTBSpecific_XMLLoading module = processing.algs.otb.OTBSpecific_XMLLoading found = False if 'adapt%s' % self.appkey in dir(module): found = True commands = getattr(module, 'adapt%s' % self.appkey)(commands) else: the_key = 'adapt%s' % self.appkey if '-' in the_key: base_key = the_key.split("-")[0] if base_key in dir(module): found = True commands = getattr(module, base_key)(commands) if not found: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr("Adapter for %s not found") % the_key) #frames = inspect.getouterframes(inspect.currentframe())[1:] #for a_frame in frames: # frame,filename,line_number,function_name,lines,index = a_frame # ProcessingLog.addToLog(ProcessingLog.LOG_INFO, "%s %s %s %s %s %s" % (frame,filename,line_number,function_name,lines,index)) OTBUtils.executeOtb(commands, progress)
def processAlgorithm(self, feedback): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_B)) sameLayer = self.getParameterValue( self.INPUT_A) == self.getParameterValue(self.INPUT_B) fieldList = layerA.fields() writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QgsWkbTypes.LineString, layerA.crs()) spatialIndex = vector.spatialindex(layerB) outFeat = QgsFeature() features = vector.features(layerA) total = 100.0 / float(len(features)) for current, inFeatA in enumerate(features): inGeom = inFeatA.geometry() attrsA = inFeatA.attributes() outFeat.setAttributes(attrsA) inLines = [inGeom] lines = spatialIndex.intersects(inGeom.boundingBox()) engine = None if len(lines) > 0: # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(inGeom.geometry()) engine.prepareGeometry() if len(lines) > 0: # hasIntersections splittingLines = [] request = QgsFeatureRequest().setFilterFids( lines).setSubsetOfAttributes([]) for inFeatB in layerB.getFeatures(request): # check if trying to self-intersect if sameLayer: if inFeatA.id() == inFeatB.id(): continue splitGeom = inFeatB.geometry() if engine.intersects(splitGeom.geometry()): splittingLines.append(splitGeom) if len(splittingLines) > 0: for splitGeom in splittingLines: splitterPList = vector.extractPoints(splitGeom) outLines = [] split_geom_engine = QgsGeometry.createGeometryEngine( splitGeom.geometry()) split_geom_engine.prepareGeometry() while len(inLines) > 0: inGeom = inLines.pop() inPoints = vector.extractPoints(inGeom) if split_geom_engine.intersects(inGeom.geometry()): try: result, newGeometries, topoTestPoints = inGeom.splitGeometry( splitterPList, False) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Geometry exception while splitting' )) result = 1 # splitGeometry: If there are several intersections # between geometry and splitLine, only the first one is considered. if result == 0: # split occurred if inPoints == vector.extractPoints( inGeom): # bug in splitGeometry: sometimes it returns 0 but # the geometry is unchanged outLines.append(inGeom) else: inLines.append(inGeom) for aNewGeom in newGeometries: inLines.append(aNewGeom) else: outLines.append(inGeom) else: outLines.append(inGeom) inLines = outLines for aLine in inLines: if len(aLine.asPolyline()) > 2 or \ (len(aLine.asPolyline()) == 2 and aLine.asPolyline()[0] != aLine.asPolyline()[1]): # sometimes splitting results in lines of zero length outFeat.setGeometry(aLine) writer.addFeature(outFeat) feedback.setProgress(int(current * total)) del writer
def processAlgorithm(self, progress): vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(Union.INPUT)) vlayerB = dataobjects.getObjectFromUri( self.getParameterValue(Union.INPUT2)) GEOS_EXCEPT = True FEATURE_EXCEPT = True vproviderA = vlayerA.dataProvider() fields = vector.combineVectorFields(vlayerA, vlayerB) names = [field.name() for field in fields] ProcessingLog.addToLog(ProcessingLog.LOG_INFO, unicode(names)) writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter( fields, vproviderA.geometryType(), vproviderA.crs()) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() indexA = vector.spatialindex(vlayerB) indexB = vector.spatialindex(vlayerA) count = 0 nElement = 0 featuresA = vector.features(vlayerA) nFeat = len(featuresA) for inFeatA in featuresA: progress.setPercentage(nElement / float(nFeat) * 50) nElement += 1 lstIntersectingB = [] geom = QgsGeometry(inFeatA.geometry()) atMapA = inFeatA.attributes() intersects = indexA.intersects(geom.boundingBox()) if len(intersects) < 1: try: outFeat.setGeometry(geom) outFeat.setAttributes(atMapA) writer.addFeature(outFeat) except: # This really shouldn't happen, as we haven't # edited the input geom at all raise GeoAlgorithmExecutionException( self.tr('Feature exception while computing union')) else: for id in intersects: count += 1 request = QgsFeatureRequest().setFilterFid(id) inFeatB = vlayerB.getFeatures(request).next() atMapB = inFeatB.attributes() tmpGeom = QgsGeometry(inFeatB.geometry()) if geom.intersects(tmpGeom): int_geom = geom.intersection(tmpGeom) lstIntersectingB.append(tmpGeom) if int_geom is None: # There was a problem creating the intersection raise GeoAlgorithmExecutionException( self.tr('Geometry exception while computing ' 'intersection')) else: int_geom = QgsGeometry(int_geom) if int_geom.wkbType( ) == QGis.WKBUnknown or QgsWKBTypes.flatType( int_geom.geometry().wkbType( )) == QgsWKBTypes.GeometryCollection: # Intersection produced different geomety types temp_list = int_geom.asGeometryCollection() for i in temp_list: if i.type() == geom.type(): int_geom = QgsGeometry(i) try: outFeat.setGeometry(int_geom) attrs = [] attrs.extend(atMapA) attrs.extend(atMapB) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except Exception as err: raise GeoAlgorithmExecutionException( self.tr( 'Feature exception while computing union')) try: # the remaining bit of inFeatA's geometry # if there is nothing left, this will just silently fail and we're good diff_geom = QgsGeometry(geom) if len(lstIntersectingB) != 0: intB = QgsGeometry.unaryUnion(lstIntersectingB) diff_geom = diff_geom.difference(intB) if diff_geom.wkbType() == 0 or QgsWKBTypes.flatType( int_geom.geometry().wkbType( )) == QgsWKBTypes.GeometryCollection: temp_list = diff_geom.asGeometryCollection() for i in temp_list: if i.type() == geom.type(): diff_geom = QgsGeometry(i) outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMapA) writer.addFeature(outFeat) except Exception as err: raise GeoAlgorithmExecutionException( self.tr('Feature exception while computing union')) length = len(vproviderA.fields()) featuresA = vector.features(vlayerB) nFeat = len(featuresA) for inFeatA in featuresA: progress.setPercentage(nElement / float(nFeat) * 100) add = False geom = QgsGeometry(inFeatA.geometry()) diff_geom = QgsGeometry(geom) atMap = [None] * length atMap.extend(inFeatA.attributes()) intersects = indexB.intersects(geom.boundingBox()) if len(intersects) < 1: try: outFeat.setGeometry(geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except Exception as err: raise GeoAlgorithmExecutionException( self.tr('Feature exception while computing union')) else: for id in intersects: request = QgsFeatureRequest().setFilterFid(id) inFeatB = vlayerA.getFeatures(request).next() atMapB = inFeatB.attributes() tmpGeom = QgsGeometry(inFeatB.geometry()) try: if diff_geom.intersects(tmpGeom): add = True diff_geom = QgsGeometry( diff_geom.difference(tmpGeom)) else: # Ihis only happends if the bounding box # intersects, but the geometry doesn't outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except Exception as err: raise GeoAlgorithmExecutionException( self. tr('Geometry exception while computing intersection' )) if add: try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except Exception as err: raise err FEATURE_EXCEPT = False nElement += 1 del writer if not GEOS_EXCEPT: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('Geometry exception while computing intersection')) if not FEATURE_EXCEPT: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('Feature exception while computing intersection'))
def ovals(self, writer, features, width, height, rotation, segments): ft = QgsFeature() if rotation is not None: for current, feat in enumerate(features): w = feat[width] h = feat[height] angle = feat[rotation] if not w or not h or not angle: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('Feature {} has empty ' 'width, height or angle. ' 'Skipping...'.format(feat.id()))) continue xOffset = w / 2.0 yOffset = h / 2.0 phi = angle * math.pi / 180 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append( (xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[ QgsPoint(i[0] * math.cos(phi) + i[1] * math.sin(phi) + x, -i[0] * math.sin(phi) + i[1] * math.cos(phi) + y) for i in points ]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft) else: for current, feat in enumerate(features): w = feat[width] h = feat[height] if not w or not h: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr('Feature {} has empty ' 'width or height. ' 'Skipping...'.format(feat.id()))) continue xOffset = w / 2.0 yOffset = h / 2.0 point = feat.geometry().asPoint() x = point.x() y = point.y() points = [] for t in [(2 * math.pi) / segments * i for i in range(segments)]: points.append( (xOffset * math.cos(t), yOffset * math.sin(t))) polygon = [[QgsPoint(i[0] + x, i[1] + y) for i in points]] ft.setGeometry(QgsGeometry.fromPolygon(polygon)) ft.setAttributes(feat.attributes()) writer.addFeature(ft)
def runAlgorithm(self): self.feedback = self.createFeedback() self.context = dataobjects.createContext(self.feedback) checkCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_CRS) try: parameters = self.getParameterValues() if checkCRS and not self.algorithm().validateInputCrs( parameters, self.context): reply = QMessageBox.question( self, self.tr("Unmatching CRS's"), self.tr('Parameters do not all use the same CRS. This can ' 'cause unexpected results.\nDo you want to ' 'continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return ok, msg = self.algorithm().checkParameterValues( parameters, self.context) if not ok: QMessageBox.warning(self, self.tr('Unable to execute algorithm'), msg) return self.runButton().setEnabled(False) self.cancelButton().setEnabled(False) buttons = self.mainWidget().iterateButtons self.iterateParam = None for i in range(len(list(buttons.values()))): button = list(buttons.values())[i] if button.isChecked(): self.iterateParam = list(buttons.keys())[i] break self.clearProgress() self.setProgressText( QCoreApplication.translate('AlgorithmDialog', 'Processing algorithm…')) self.setInfo(QCoreApplication.translate( 'AlgorithmDialog', '<b>Algorithm \'{0}\' starting…</b>').format( self.algorithm().displayName()), escapeHtml=False) self.feedback.pushInfo(self.tr('Input parameters:')) display_params = [] for k, v in parameters.items(): display_params.append("'" + k + "' : " + self.algorithm( ).parameterDefinition(k).valueAsPythonString(v, self.context)) self.feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }') self.feedback.pushInfo('') start_time = time.time() if self.iterateParam: # Make sure the Log tab is visible before executing the algorithm try: self.showLog() self.repaint() except: pass self.cancelButton().setEnabled( self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel) if executeIterating(self.algorithm(), parameters, self.iterateParam, self.context, self.feedback): self.feedback.pushInfo( self.tr('Execution completed in {0:0.2f} seconds'). format(time.time() - start_time)) self.cancelButton().setEnabled(False) self.finish(True, parameters, self.context, self.feedback) else: self.cancelButton().setEnabled(False) self.resetGui() else: command = self.algorithm().asPythonCommand( parameters, self.context) if command: ProcessingLog.addToLog(command) QgsGui.instance().processingRecentAlgorithmLog().push( self.algorithm().id()) self.cancelButton().setEnabled( self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel) def on_complete(ok, results): if ok: self.feedback.pushInfo( self.tr('Execution completed in {0:0.2f} seconds'). format(time.time() - start_time)) self.feedback.pushInfo(self.tr('Results:')) self.feedback.pushCommandInfo(pformat(results)) else: self.feedback.reportError( self.tr('Execution failed after {0:0.2f} seconds'). format(time.time() - start_time)) self.feedback.pushInfo('') if self.feedback_dialog is not None: self.feedback_dialog.close() self.feedback_dialog.deleteLater() self.feedback_dialog = None self.cancelButton().setEnabled(False) if not self.in_place: self.finish(ok, results, self.context, self.feedback) elif ok: self.close() self.feedback = None self.context = None if not self.in_place and not ( self.algorithm().flags() & QgsProcessingAlgorithm.FlagNoThreading): # Make sure the Log tab is visible before executing the algorithm self.showLog() task = QgsProcessingAlgRunnerTask(self.algorithm(), parameters, self.context, self.feedback) task.executed.connect(on_complete) self.setCurrentTask(task) else: self.proxy_progress = QgsProxyProgressTask( QCoreApplication.translate( "AlgorithmDialog", "Executing “{}”").format( self.algorithm().displayName())) QgsApplication.taskManager().addTask(self.proxy_progress) self.feedback.progressChanged.connect( self.proxy_progress.setProxyProgress) self.feedback_dialog = self.createProgressDialog() self.feedback_dialog.show() if self.in_place: ok, results = execute_in_place(self.algorithm(), parameters, self.context, self.feedback) else: ok, results = execute(self.algorithm(), parameters, self.context, self.feedback) self.feedback.progressChanged.disconnect() self.proxy_progress.finalize(ok) on_complete(ok, results) except AlgorithmDialogBase.InvalidParameterValue as e: try: self.buttonBox().accepted.connect( lambda e=e: e.widget.setPalette(QPalette())) palette = e.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) e.widget.setPalette(palette) except: pass self.messageBar().clearWidgets() self.messageBar().pushMessage( "", self.tr("Wrong or missing parameter value: {0}").format( e.parameter.description()), level=Qgis.Warning, duration=5)
def processAlgorithm(self, progress): vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(Union.INPUT)) vlayerB = dataobjects.getObjectFromUri( self.getParameterValue(Union.INPUT2)) geomType = vlayerA.wkbType() fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(Union.OUTPUT).getVectorWriter( fields, geomType, vlayerA.crs()) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() indexA = vector.spatialindex(vlayerB) indexB = vector.spatialindex(vlayerA) count = 0 nElement = 0 featuresA = vector.features(vlayerA) nFeat = len(featuresA) for inFeatA in featuresA: progress.setPercentage(nElement / float(nFeat) * 50) nElement += 1 lstIntersectingB = [] geom = inFeatA.geometry() atMapA = inFeatA.attributes() intersects = indexA.intersects(geom.boundingBox()) if len(intersects) < 1: try: outFeat.setGeometry(geom) outFeat.setAttributes(atMapA) writer.addFeature(outFeat) except: # This really shouldn't happen, as we haven't # edited the input geom at all ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) else: for id in intersects: count += 1 request = QgsFeatureRequest().setFilterFid(id) inFeatB = vlayerB.getFeatures(request).next() atMapB = inFeatB.attributes() tmpGeom = inFeatB.geometry() if geom.intersects(tmpGeom): int_geom = geom.intersection(tmpGeom) lstIntersectingB.append(tmpGeom) if not int_geom: # There was a problem creating the intersection ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('GEOS geoprocessing error: One or more input features have invalid geometry.' )) int_geom = QgsGeometry() else: int_geom = QgsGeometry(int_geom) if int_geom.wkbType( ) == QgsWkbTypes.Unknown or QgsWkbTypes.flatType( int_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: # Intersection produced different geomety types temp_list = int_geom.asGeometryCollection() for i in temp_list: if i.type() == geom.type(): int_geom = QgsGeometry(i) try: outFeat.setGeometry(int_geom) outFeat.setAttributes(atMapA + atMapB) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) else: # Geometry list: prevents writing error # in geometries of different types # produced by the intersection # fix #3549 if int_geom.wkbType() in wkbTypeGroups[ wkbTypeGroups[int_geom.wkbType()]]: try: outFeat.setGeometry(int_geom) outFeat.setAttributes(atMapA + atMapB) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) # the remaining bit of inFeatA's geometry # if there is nothing left, this will just silently fail and we're good diff_geom = QgsGeometry(geom) if len(lstIntersectingB) != 0: intB = QgsGeometry.unaryUnion(lstIntersectingB) diff_geom = diff_geom.difference(intB) if diff_geom.isGeosEmpty() or not diff_geom.isGeosValid(): ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self. tr('GEOS geoprocessing error: One or more input features have invalid geometry.' )) if diff_geom.wkbType() == 0 or QgsWkbTypes.flatType( diff_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: temp_list = diff_geom.asGeometryCollection() for i in temp_list: if i.type() == geom.type(): diff_geom = QgsGeometry(i) try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMapA) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) length = len(vlayerA.fields()) atMapA = [None] * length featuresA = vector.features(vlayerB) nFeat = len(featuresA) for inFeatA in featuresA: progress.setPercentage(nElement / float(nFeat) * 100) add = False geom = inFeatA.geometry() diff_geom = QgsGeometry(geom) atMap = [None] * length atMap.extend(inFeatA.attributes()) intersects = indexB.intersects(geom.boundingBox()) if len(intersects) < 1: try: outFeat.setGeometry(geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) else: for id in intersects: request = QgsFeatureRequest().setFilterFid(id) inFeatB = vlayerA.getFeatures(request).next() atMapB = inFeatB.attributes() tmpGeom = inFeatB.geometry() if diff_geom.intersects(tmpGeom): add = True diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) if diff_geom.isGeosEmpty( ) or not diff_geom.isGeosValid(): ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self. tr('GEOS geoprocessing error: One or more input features have invalid geometry.' )) else: try: # Ihis only happends if the bounding box # intersects, but the geometry doesn't outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) if add: try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(atMap) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) nElement += 1 del writer
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.VECTOR)) value = float(self.getParameterValue(self.VALUE)) minDistance = float(self.getParameterValue(self.MIN_DISTANCE)) strategy = self.getParameterValue(self.STRATEGY) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QGis.WKBPoint, layer.dataProvider().crs()) request = QgsFeatureRequest() da = QgsDistanceArea() features = vector.features(layer) for current, f in enumerate(features): fGeom = QgsGeometry(f.geometry()) bbox = fGeom.boundingBox() if strategy == 0: pointCount = int(value) else: pointCount = int(round(value * da.measure(fGeom))) index = QgsSpatialIndex() points = dict() nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 total = 100.0 / pointCount random.seed() while nIterations < maxIterations and nPoints < pointCount: rx = bbox.xMinimum() + bbox.width() * random.random() ry = bbox.yMinimum() + bbox.height() * random.random() pnt = QgsPoint(rx, ry) geom = QgsGeometry.fromPoint(pnt) if geom.within(fGeom) and \ vector.checkMinDistance(pnt, index, minDistance, points): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', nPoints) f.setGeometry(geom) writer.addFeature(f) index.insertFeature(f) points[nPoints] = pnt nPoints += 1 progress.setPercentage(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Can not generate requested number of random ' 'points. Maximum number of attempts exceeded.')) progress.setPercentage(0) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.OVERLAY)) providerA = layerA.dataProvider() providerB = layerB.dataProvider() GEOS_EXCEPT = True FEATURE_EXCEPT = True fields = vector.combineVectorFields(layerA, layerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, providerA.geometryType(), providerA.crs()) featB = QgsFeature() outFeat = QgsFeature() indexA = vector.spatialindex(layerB) indexB = vector.spatialindex(layerA) featuresA = vector.features(layerA) featuresB = vector.features(layerB) total = 100.0 / (len(featuresA) * len(featuresB)) count = 0 for featA in featuresA: add = True geom = QgsGeometry(featA.geometry()) diffGeom = QgsGeometry(geom) attrs = featA.attributes() intersects = indexA.intersects(geom.boundingBox()) for i in intersects: providerB.getFeatures( QgsFeatureRequest().setFilterFid(i)).nextFeature(featB) tmpGeom = QgsGeometry(featB.geometry()) try: if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) except: add = False GEOS_EXCEPT = False break if add: try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: FEATURE_EXCEPT = False continue count += 1 progress.setPercentage(int(count * total)) length = len(providerA.fields()) for featA in featuresB: add = True geom = QgsGeometry(featA.geometry()) diffGeom = QgsGeometry(geom) attrs = featA.attributes() attrs = [NULL] * length + attrs intersects = indexB.intersects(geom.boundingBox()) for i in intersects: providerA.getFeatures( QgsFeatureRequest().setFilterFid(i)).nextFeature(featB) tmpGeom = QgsGeometry(featB.geometry()) try: if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) except: add = False GEOS_EXCEPT = False break if add: try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: FEATURE_EXCEPT = False continue count += 1 progress.setPercentage(int(count * total)) del writer if not GEOS_EXCEPT: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Geometry exception while computing symetrical difference')) if not FEATURE_EXCEPT: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self.tr( 'Feature exception while computing symetrical difference'))
def processAlgorithm(self, progress): commands = list() self.exportedLayers = {} self.preProcessInputs() # 1: Export rasters to sgrd and vectors to shp # Tables must be in dbf format. We check that. for param in self.parameters: if isinstance(param, ParameterRaster): if param.value is None: continue if param.value.endswith('sdat'): param.value = param.value[:-4] + "sgrd" elif not param.value.endswith('sgrd'): exportCommand = self.exportRasterLayer(param.value) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.value is None: continue layer = dataobjects.getObjectFromUri(param.value, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.value is None: continue table = dataobjects.getObjectFromUri(param.value, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[param.value] = filename elif not param.value.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.value is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == ParameterMultipleInput.TYPE_RASTER: for i, layerfile in enumerate(layers): if layerfile.endswith('sdat'): layerfile = param.value[:-4] + "sgrd" layers[i] = layerfile elif not layerfile.endswith('sgrd'): exportCommand = self.exportRasterLayer(layerfile) if exportCommand is not None: commands.append(exportCommand) param.value = ";".join(layers) elif param.datatype == ParameterMultipleInput.TYPE_VECTOR_ANY: for layerfile in layers: layer = dataobjects.getObjectFromUri(layerfile, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' if self.hardcodedStrings: for s in self.hardcodedStrings: command += ' ' + s for param in self.parameters: if param.value is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = param.value if value in self.exportedLayers.keys(): command += ' -' + param.name + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = param.value for layer in self.exportedLayers.keys(): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if param.value: command += ' -' + param.name.strip() + " true" else: command += ' -' + param.name.strip() + " false" elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') f = open(tempTableFile, 'w') f.write('\t'.join([col for col in param.cols]) + '\n') values = param.value.split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[i + 2] + '\n' f.write(s) f.close() command += ' -' + param.name + ' "' + tempTableFile + '"' elif isinstance(param, ParameterExtent): # 'We have to substract/add half cell size, since SAGA is # center based, not corner based halfcell = self.getOutputCellsize() / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = param.value.split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + unicode(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name + ' ' + unicode(param.value) else: command += ' -' + param.name + ' "' + unicode(param.value) + '"' for out in self.outputs: command += ' -' + out.name + ' "' + out.getCompatibleFileName(self) + '"' commands.append(command) # special treatment for RGB algorithm #TODO: improve this and put this code somewhere else for out in self.outputs: if isinstance(out, OutputRaster): filename = out.getCompatibleFileName(self) filename2 = filename + '.sgrd' if self.cmdname == 'RGB Composite': commands.append('io_grid_image 0 -IS_RGB -GRID:"' + filename2 + '" -FILE:"' + filename + '"') # 3: Run SAGA commands = self.editCommands(commands) SagaUtils.createSagaBatchJobFileFromSagaCommands(commands) loglines = [] loglines.append(self.tr('SAGA execution commands')) for line in commands: progress.setCommand(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) SagaUtils.executeSaga(progress) if self.crs is not None: for out in self.outputs: if isinstance(out, (OutputVector, OutputRaster)): prjFile = os.path.splitext(out.getCompatibleFileName(self))[0] + ".prj" with open(prjFile, "w") as f: f.write(self.crs.toWkt())
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri(self.getParameterValue( self.INPUT)) hSpacing = self.getParameterValue(self.HSPACING) vSpacing = self.getParameterValue(self.VSPACING) if hSpacing <= 0 or vSpacing <= 0: raise GeoAlgorithmExecutionException( 'Invalid grid spacing: %s/%s' % (hSpacing, vSpacing)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( layer.pendingFields(), layer.wkbType(), layer.crs()) features = vector.features(layer) count = len(features) total = 100.0 / float(count) for count, f in enumerate(features): geom = f.geometry() geomType = geom.wkbType() if geomType == QGis.WKBPoint: points = self._gridify([geom.asPoint()], hSpacing, vSpacing) newGeom = QgsGeometry.fromPoint(points[0]) elif geomType == QGis.WKBMultiPoint: points = self._gridify(geom.aMultiPoint(), hSpacing, vSpacing) newGeom = QgsGeometry.fromMultiPoint(points) elif geomType == QGis.WKBLineString: points = self._gridify(geom.asPolyline(), hSpacing, vSpacing) if len(points) < 2: ProcessingLog.addToLog( Processing.LOG_INFO, 'Failed to gridify feature with FID %s' % f.id()) newGeom = None else: newGeom = QgsGeometry.fromPolyline(points) elif geomType == QGis.WKBMultiLineString: polyline = [] for line in geom.asMultiPolyline(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polyline.append(points) if len(polyline) <= 0: ProcessingLog.addToLog( Processing.LOG_INFO, 'Failed to gridify feature with FID %s' % f.id()) newGeom = None else: newGeom = QgsGeometry.fromMultiPolyline(polyline) elif geomType == QGis.WKBPolygon: polygon = [] for line in geom.asPolygon(): points = self._gridify(line, hSpacing, vSpacing) if len(points) > 1: polygon.append(points) if len(polygon) <= 0: ProcessingLog.addToLog( Processing.LOG_INFO, 'Failed to gridify feature with FID %s' % f.id()) newGeom = None else: newGeom = QgsGeometry.fromPolygon(polygon) elif geomType == QGis.WKBMultiPolygon: multipolygon = [] for polygon in geometry.asMultiPolygon(): newPolygon = [] for line in polygon: points = self._gridify(line, hSpacing, vSpacing) if len(points) > 2: newPolygon.append(points) if len(newPolygon) > 0: multipolygon.append(newPolygon) if len(multipolygon) <= 0: ProcessingLog.addToLog( Processing.LOG_INFO, 'Failed to gridify feature with FID %s' % f.id()) newGeom = None else: newGeom = QgsGeometry.fromMultiPolygon(multipolygon) if newGeom is not None: feat = QgsFeature() feat.setGeometry(newGeom) feat.setAttributes(f.attributes()) writer.addFeature(feat) progress.setPercentage(int(count * total)) del writer
def buffering(progress, writer, distance, field, useField, layer, dissolve, segments, endCapStyle=1, joinStyle=1, mitreLimit=2): if useField: field = layer.fields().lookupField(field) outFeat = QgsFeature() current = 0 features = vector.features(layer) total = 100.0 / float(len(features)) # With dissolve if dissolve: first = True buffered_geometries = [] for inFeat in features: attrs = inFeat.attributes() if useField: value = attrs[field] else: value = distance inGeom = inFeat.geometry() if not inGeom: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has empty geometry. Skipping...'.format(inFeat.id())) continue if not inGeom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has invalid geometry. Skipping...'.format(inFeat.id())) continue buffered_geometries.append(inGeom.buffer(float(value), segments, endCapStyle, joinStyle, mitreLimit)) current += 1 progress.setPercentage(int(current * total)) final_geometry = QgsGeometry.unaryUnion(buffered_geometries) outFeat.setGeometry(final_geometry) outFeat.setAttributes(attrs) writer.addFeature(outFeat) else: # Without dissolve for inFeat in features: attrs = inFeat.attributes() if useField: value = attrs[field] else: value = distance inGeom = inFeat.geometry() outFeat = QgsFeature() if inGeom.isEmpty() or inGeom.isGeosEmpty(): pass elif not inGeom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, 'Feature {} has invalid geometry. Skipping...'.format(inFeat.id())) continue else: outGeom = inGeom.buffer(float(value), segments, endCapStyle, joinStyle, mitreLimit) outFeat.setGeometry(outGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
def runAlgorithm(algOrName, onFinish, *args, **kwargs): if isinstance(algOrName, GeoAlgorithm): alg = algOrName else: alg = Processing.getAlgorithm(algOrName) if alg is None: # fix_print_with_import print('Error: Algorithm not found\n') QgsMessageLog.logMessage( Processing.tr('Error: Algorithm {0} not found\n').format( algOrName), Processing.tr("Processing")) return alg = alg.getCopy() if len(args) == 1 and isinstance(args[0], dict): # Set params by name and try to run the alg even if not all parameter values are provided, # by using the default values instead. setParams = [] for (name, value) in list(args[0].items()): param = alg.getParameterFromName(name) if param and param.setValue(value): setParams.append(name) continue output = alg.getOutputFromName(name) if output and output.setValue(value): continue # fix_print_with_import print('Error: Wrong parameter value %s for parameter %s.' % (value, name)) QgsMessageLog.logMessage( Processing.tr( 'Error: Wrong parameter value {0} for parameter {1}.'). format(value, name), Processing.tr("Processing")) ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, Processing. tr('Error in %s. Wrong parameter value %s for parameter %s.' ) % (alg.name, value, name)) return # fill any missing parameters with default values if allowed for param in alg.parameters: if param.name not in setParams: if not param.setDefaultValue(): # fix_print_with_import print( 'Error: Missing parameter value for parameter %s.' % param.name) QgsMessageLog.logMessage( Processing. tr('Error: Missing parameter value for parameter {0}.' ).format(param.name), Processing.tr("Processing")) ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, Processing. tr('Error in %s. Missing parameter value for parameter %s.' ) % (alg.name, param.name)) return else: if len(args) != alg.getVisibleParametersCount( ) + alg.getVisibleOutputsCount(): # fix_print_with_import print('Error: Wrong number of parameters') QgsMessageLog.logMessage( Processing.tr('Error: Wrong number of parameters'), Processing.tr("Processing")) processing.alghelp(algOrName) return i = 0 for param in alg.parameters: if not param.hidden: if not param.setValue(args[i]): # fix_print_with_import print('Error: Wrong parameter value: ' + str(args[i])) QgsMessageLog.logMessage( Processing.tr('Error: Wrong parameter value: ') + str(args[i]), Processing.tr("Processing")) return i = i + 1 for output in alg.outputs: if not output.hidden: if not output.setValue(args[i]): # fix_print_with_import print('Error: Wrong output value: ' + str(args[i])) QgsMessageLog.logMessage( Processing.tr('Error: Wrong output value: ') + str(args[i]), Processing.tr("Processing")) return i = i + 1 msg = alg._checkParameterValuesBeforeExecuting() if msg: # fix_print_with_import print('Unable to execute algorithm\n' + str(msg)) QgsMessageLog.logMessage( Processing.tr('Unable to execute algorithm\n{0}').format(msg), Processing.tr("Processing")) return if not alg.checkInputCRS(): print('Warning: Not all input layers use the same CRS.\n' + 'This can cause unexpected results.') QgsMessageLog.logMessage( Processing. tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.' ), Processing.tr("Processing")) # Don't set the wait cursor twice, because then when you # restore it, it will still be a wait cursor. overrideCursor = False if iface is not None: cursor = QApplication.overrideCursor() if cursor is None or cursor == 0: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) overrideCursor = True elif cursor.shape() != Qt.WaitCursor: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) overrideCursor = True progress = None if kwargs is not None and "progress" in list(kwargs.keys()): progress = kwargs["progress"] elif iface is not None: progress = MessageBarProgress(alg.name) ret = runalg(alg, progress) if ret: if onFinish is not None: onFinish(alg, progress) else: QgsMessageLog.logMessage( Processing.tr("There were errors executing the algorithm."), Processing.tr("Processing")) if overrideCursor: QApplication.restoreOverrideCursor() if isinstance(progress, MessageBarProgress): progress.close() return alg
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.VECTOR)) pointCount = float(self.getParameterValue(self.POINT_NUMBER)) minDistance = float(self.getParameterValue(self.MIN_DISTANCE)) fields = QgsFields() fields.append(QgsField('id', QVariant.Int, '', 10, 0)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, QgsWkbTypes.Point, layer.crs()) nPoints = 0 nIterations = 0 maxIterations = pointCount * 200 featureCount = layer.featureCount() total = 100.0 / pointCount index = QgsSpatialIndex() points = dict() da = QgsDistanceArea() request = QgsFeatureRequest() random.seed() while nIterations < maxIterations and nPoints < pointCount: # pick random feature fid = random.randint(0, featureCount - 1) f = next(layer.getFeatures(request.setFilterFid(fid).setSubsetOfAttributes([]))) fGeom = f.geometry() if fGeom.isMultipart(): lines = fGeom.asMultiPolyline() # pick random line lineId = random.randint(0, len(lines) - 1) vertices = lines[lineId] else: vertices = fGeom.asPolyline() # pick random segment if len(vertices) == 2: vid = 0 else: vid = random.randint(0, len(vertices) - 2) startPoint = vertices[vid] endPoint = vertices[vid + 1] length = da.measureLine(startPoint, endPoint) dist = length * random.random() if dist > minDistance: d = dist / (length - dist) rx = (startPoint.x() + d * endPoint.x()) / (1 + d) ry = (startPoint.y() + d * endPoint.y()) / (1 + d) # generate random point pnt = QgsPoint(rx, ry) geom = QgsGeometry.fromPoint(pnt) if vector.checkMinDistance(pnt, index, minDistance, points): f = QgsFeature(nPoints) f.initAttributes(1) f.setFields(fields) f.setAttribute('id', nPoints) f.setGeometry(geom) writer.addFeature(f) index.insertFeature(f) points[nPoints] = pnt nPoints += 1 progress.setPercentage(int(nPoints * total)) nIterations += 1 if nPoints < pointCount: ProcessingLog.addToLog(ProcessingLog.LOG_INFO, self.tr('Can not generate requested number of random points. ' 'Maximum number of attempts exceeded.')) del writer
def processAlgorithm(self, progress): inLayer = dataobjects.getObjectFromUri(self.getParameterValue(self.INPUT)) boundary = self.getParameterValue(self.MODE) == self.MODE_BOUNDARY smallestArea = self.getParameterValue(self.MODE) == self.MODE_SMALLEST_AREA keepSelection = self.getParameterValue(self.KEEPSELECTION) processLayer = vector.duplicateInMemory(inLayer) if not keepSelection: # Make a selection with the values provided attribute = self.getParameterValue(self.ATTRIBUTE) comparison = self.comparisons[self.getParameterValue(self.COMPARISON)] comparisonvalue = self.getParameterValue(self.COMPARISONVALUE) selectindex = vector.resolveFieldIndex(processLayer, attribute) selectType = processLayer.fields()[selectindex].type() selectionError = False if selectType == 2: try: y = int(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to integer' % unicode(comparisonvalue)) elif selectType == 6: try: y = float(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to float' % unicode(comparisonvalue)) elif selectType == 10: # 10: string, boolean try: y = unicode(comparisonvalue) except ValueError: selectionError = True msg = self.tr('Cannot convert "%s" to unicode' % unicode(comparisonvalue)) elif selectType == 14: # date dateAndFormat = comparisonvalue.split(' ') if len(dateAndFormat) == 1: # QDate object y = QLocale.system().toDate(dateAndFormat[0]) if y.isNull(): msg = self.tr('Cannot convert "%s" to date with system date format %s' % (unicode(dateAndFormat), QLocale.system().dateFormat())) elif len(dateAndFormat) == 2: y = QDate.fromString(dateAndFormat[0], dateAndFormat[1]) if y.isNull(): msg = self.tr('Cannot convert "%s" to date with format string "%s"' % (unicode(dateAndFormat[0]), dateAndFormat[1])) else: y = QDate() msg = '' if y.isNull(): # Conversion was unsuccessfull selectionError = True msg += self.tr('Enter the date and the date format, e.g. "07.26.2011" "MM.dd.yyyy".') if (comparison == 'begins with' or comparison == 'contains') \ and selectType != 10: selectionError = True msg = self.tr('"%s" can only be used with string fields' % comparison) selected = [] if selectionError: raise GeoAlgorithmExecutionException( self.tr('Error in selection input: %s' % msg)) else: for feature in processLayer.getFeatures(): aValue = feature.attributes()[selectindex] if aValue is None: continue if selectType == 2: x = int(aValue) elif selectType == 6: x = float(aValue) elif selectType == 10: # 10: string, boolean x = unicode(aValue) elif selectType == 14: # date x = aValue # should be date match = False if comparison == '==': match = x == y elif comparison == '!=': match = x != y elif comparison == '>': match = x > y elif comparison == '>=': match = x >= y elif comparison == '<': match = x < y elif comparison == '<=': match = x <= y elif comparison == 'begins with': match = x.startswith(y) elif comparison == 'contains': match = x.find(y) >= 0 if match: selected.append(feature.id()) processLayer.setSelectedFeatures(selected) if processLayer.selectedFeatureCount() == 0: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('%s: (No selection in input layer "%s")' % (self.commandLineName(), self.getParameterValue(self.INPUT)))) # Keep references to the features to eliminate featToEliminate = [] for aFeat in processLayer.selectedFeatures(): featToEliminate.append(aFeat) # Delete all features to eliminate in processLayer (we won't save this) processLayer.startEditing() processLayer.deleteSelectedFeatures() # ANALYZE if len(featToEliminate) > 0: # Prevent zero division start = 20.00 add = 80.00 / len(featToEliminate) else: start = 100 progress.setPercentage(start) madeProgress = True # We go through the list and see if we find any polygons we can # merge the selected with. If we have no success with some we # merge and then restart the whole story. while madeProgress: # Check if we made any progress madeProgress = False featNotEliminated = [] # Iterate over the polygons to eliminate for i in range(len(featToEliminate)): feat = featToEliminate.pop() geom2Eliminate = QgsGeometry(feat.geometry()) bbox = geom2Eliminate.boundingBox() fit = processLayer.getFeatures( QgsFeatureRequest().setFilterRect(bbox)) mergeWithFid = None mergeWithGeom = None max = 0 min = -1 selFeat = QgsFeature() while fit.nextFeature(selFeat): selGeom = QgsGeometry(selFeat.geometry()) if geom2Eliminate.intersects(selGeom): # We have a candidate iGeom = geom2Eliminate.intersection(selGeom) if iGeom is None: continue if boundary: selValue = iGeom.length() else: # area. We need a common boundary in # order to merge if 0 < iGeom.length(): selValue = selGeom.area() else: selValue = -1 if -1 != selValue: useThis = True if smallestArea: if -1 == min: min = selValue else: if selValue < min: min = selValue else: useThis = False else: if selValue > max: max = selValue else: useThis = False if useThis: mergeWithFid = selFeat.id() mergeWithGeom = QgsGeometry(selGeom) # End while fit if mergeWithFid is not None: # A successful candidate newGeom = mergeWithGeom.combine(geom2Eliminate) if processLayer.changeGeometry(mergeWithFid, newGeom): madeProgress = True else: raise GeoAlgorithmExecutionException( self.tr('Could not replace geometry of feature with id %s' % mergeWithFid)) start = start + add progress.setPercentage(start) else: featNotEliminated.append(feat) # End for featToEliminate featToEliminate = featNotEliminated # End while # Create output provider = processLayer.dataProvider() output = self.getOutputFromName(self.OUTPUT) writer = output.getVectorWriter(provider.fields(), provider.geometryType(), processLayer.crs()) # Write all features that are left over to output layer iterator = processLayer.getFeatures() for feature in iterator: writer.addFeature(feature) # Leave processLayer untouched processLayer.rollBack() for feature in featNotEliminated: writer.addFeature(feature)
def processAlgorithm(self, feedback): useField = not self.getParameterValue(Dissolve.DISSOLVE_ALL) field_names = self.getParameterValue(Dissolve.FIELD) vlayerA = dataobjects.getObjectFromUri( self.getParameterValue(Dissolve.INPUT)) writer = self.getOutputFromName( Dissolve.OUTPUT).getVectorWriter( vlayerA.fields().toList(), vlayerA.wkbType(), vlayerA.crs()) outFeat = QgsFeature() features = vector.features(vlayerA) total = 100.0 / len(features) if not useField: first = True # we dissolve geometries in blocks using unaryUnion geom_queue = [] for current, inFeat in enumerate(features): feedback.setProgress(int(current * total)) if first: outFeat.setAttributes(inFeat.attributes()) first = False tmpInGeom = inFeat.geometry() if tmpInGeom.isNull() or tmpInGeom.isEmpty(): continue errors = tmpInGeom.validateGeometry() if len(errors) != 0: for error in errors: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('ValidateGeometry()' 'error: One or more ' 'input features have ' 'invalid geometry: ') + error.what()) continue geom_queue.append(tmpInGeom) if len(geom_queue) > 10000: # queue too long, combine it try: temp_output_geometry = QgsGeometry.unaryUnion(geom_queue) geom_queue = [temp_output_geometry] except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) try: outFeat.setGeometry(QgsGeometry.unaryUnion(geom_queue)) except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) writer.addFeature(outFeat) else: field_indexes = [vlayerA.fields().lookupField(f) for f in field_names.split(';')] attribute_dict = {} geometry_dict = defaultdict(lambda: []) for inFeat in features: attrs = inFeat.attributes() index_attrs = tuple([attrs[i] for i in field_indexes]) tmpInGeom = QgsGeometry(inFeat.geometry()) if tmpInGeom and tmpInGeom.isEmpty(): continue errors = tmpInGeom.validateGeometry() if len(errors) != 0: for error in errors: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('ValidateGeometry() ' 'error: One or more input' 'features have invalid ' 'geometry: ') + error.what()) if not index_attrs in attribute_dict: # keep attributes of first feature attribute_dict[index_attrs] = attrs geometry_dict[index_attrs].append(tmpInGeom) nFeat = len(attribute_dict) nElement = 0 for key, value in list(geometry_dict.items()): outFeat = QgsFeature() nElement += 1 feedback.setProgress(int(nElement * 100 / nFeat)) try: tmpOutGeom = QgsGeometry.unaryUnion(value) except: raise GeoAlgorithmExecutionException( self.tr('Geometry exception while dissolving')) outFeat.setGeometry(tmpOutGeom) outFeat.setAttributes(attribute_dict[key]) writer.addFeature(outFeat) del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.OVERLAY)) geomType = QgsWkbTypes.multiType(layerA.wkbType()) fields = vector.combineVectorFields(layerA, layerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, geomType, layerA.crs()) featB = QgsFeature() outFeat = QgsFeature() indexA = vector.spatialindex(layerB) indexB = vector.spatialindex(layerA) featuresA = vector.features(layerA) featuresB = vector.features(layerB) total = 100.0 / (len(featuresA) * len(featuresB)) count = 0 for featA in featuresA: add = True geom = featA.geometry() diffGeom = QgsGeometry(geom) attrs = featA.attributes() intersects = indexA.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([]) for featB in layerB.getFeatures(request): tmpGeom = featB.geometry() if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) if not diffGeom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) add = False break if add: try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.')) continue count += 1 progress.setPercentage(int(count * total)) length = len(layerA.fields()) for featA in featuresB: add = True geom = featA.geometry() diffGeom = QgsGeometry(geom) attrs = featA.attributes() attrs = [NULL] * length + attrs intersects = indexB.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(intersects).setSubsetOfAttributes([]) for featB in layerA.getFeatures(request): tmpGeom = featB.geometry() if diffGeom.intersects(tmpGeom): diffGeom = QgsGeometry(diffGeom.difference(tmpGeom)) if not diffGeom.isGeosValid(): ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) add = False break if add: try: outFeat.setGeometry(diffGeom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, self.tr('Feature geometry error: One or more output features ignored due to invalid geometry.')) continue count += 1 progress.setPercentage(int(count * total)) del writer
def accept(self): super(AlgorithmDialog, self)._saveGeometry() feedback = self.createFeedback() context = dataobjects.createContext(feedback) checkCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_CRS) try: parameters = self.getParamValues() if checkCRS and not self.alg.validateInputCrs(parameters, context): reply = QMessageBox.question( self, self.tr("Unmatching CRS's"), self.tr('Layers do not all use the same CRS. This can ' 'cause unexpected results.\nDo you want to ' 'continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return checkExtentCRS = ProcessingConfig.getSetting( ProcessingConfig.WARN_UNMATCHING_EXTENT_CRS) # TODO if False and checkExtentCRS and self.checkExtentCRS(): reply = QMessageBox.question( self, self.tr("Extent CRS"), self. tr('Extent parameters must use the same CRS as the input layers.\n' 'Your input layers do not have the same extent as the project, ' 'so the extent might be in a wrong CRS if you have selected it from the canvas.\n' 'Do you want to continue?'), QMessageBox.Yes | QMessageBox.No, QMessageBox.No) if reply == QMessageBox.No: return ok, msg = self.alg.checkParameterValues(parameters, context) if msg: QMessageBox.warning(self, self.tr('Unable to execute algorithm'), msg) return self.btnRun.setEnabled(False) self.btnClose.setEnabled(False) buttons = self.mainWidget.iterateButtons self.iterateParam = None for i in range(len(list(buttons.values()))): button = list(buttons.values())[i] if button.isChecked(): self.iterateParam = list(buttons.keys())[i] break self.progressBar.setMaximum(0) self.lblProgress.setText(self.tr('Processing algorithm...')) # Make sure the Log tab is visible before executing the algorithm try: self.tabWidget.setCurrentIndex(1) self.repaint() except: pass self.setInfo( self.tr('<b>Algorithm \'{0}\' starting...</b>').format( self.alg.displayName()), escape_html=False) feedback.pushInfo(self.tr('Input parameters:')) feedback.pushCommandInfo(pformat(parameters)) feedback.pushInfo('') start_time = time.time() if self.iterateParam: self.buttonCancel.setEnabled( self.alg.flags() & QgsProcessingAlgorithm.FlagCanCancel) if executeIterating(self.alg, parameters, self.iterateParam, context, feedback): feedback.pushInfo( self.tr( 'Execution completed in {0:0.2f} seconds'.format( time.time() - start_time))) self.buttonCancel.setEnabled(False) self.finish(True, parameters, context, feedback) else: self.buttonCancel.setEnabled(False) self.resetGUI() else: command = self.alg.asPythonCommand(parameters, context) if command: ProcessingLog.addToLog(command) self.buttonCancel.setEnabled( self.alg.flags() & QgsProcessingAlgorithm.FlagCanCancel) def on_complete(ok, results): if ok: feedback.pushInfo( self.tr('Execution completed in {0:0.2f} seconds'. format(time.time() - start_time))) feedback.pushInfo(self.tr('Results:')) feedback.pushCommandInfo(pformat(results)) else: feedback.reportError( self.tr('Execution failed after {0:0.2f} seconds'. format(time.time() - start_time))) feedback.pushInfo('') self.buttonCancel.setEnabled(False) self.finish(ok, results, context, feedback) task = QgsProcessingAlgRunnerTask(self.alg, parameters, context, feedback) task.executed.connect(on_complete) QgsApplication.taskManager().addTask(task) except AlgorithmDialogBase.InvalidParameterValue as e: try: self.buttonBox.accepted.connect( lambda e=e: e.widget.setPalette(QPalette())) palette = e.widget.palette() palette.setColor(QPalette.Base, QColor(255, 255, 0)) e.widget.setPalette(palette) except: pass self.bar.clearWidgets() self.bar.pushMessage( "", self.tr("Wrong or missing parameter value: {0}").format( e.parameter.description()), level=QgsMessageBar.WARNING, duration=5)
def processAlgorithm(self, progress): layer = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_VECTOR)) startPoint = self.getParameterValue(self.START_POINT) endPoints = dataobjects.getObjectFromUri( self.getParameterValue(self.END_POINTS)) strategy = self.getParameterValue(self.STRATEGY) directionFieldName = self.getParameterValue(self.DIRECTION_FIELD) forwardValue = self.getParameterValue(self.VALUE_FORWARD) backwardValue = self.getParameterValue(self.VALUE_BACKWARD) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) bothValue = self.getParameterValue(self.VALUE_BOTH) defaultDirection = self.getParameterValue(self.DEFAULT_DIRECTION) speedFieldName = self.getParameterValue(self.SPEED_FIELD) defaultSpeed = self.getParameterValue(self.DEFAULT_SPEED) tolerance = self.getParameterValue(self.TOLERANCE) fields = QgsFields() fields.append(QgsField('start', QVariant.String, '', 254, 0)) fields.append(QgsField('end', QVariant.String, '', 254, 0)) fields.append(QgsField('cost', QVariant.Double, '', 20, 7)) feat = QgsFeature() feat.setFields(fields) writer = self.getOutputFromName(self.OUTPUT_LAYER).getVectorWriter( fields.toList(), QgsWkbTypes.LineString, layer.crs()) tmp = startPoint.split(',') startPoint = QgsPoint(float(tmp[0]), float(tmp[1])) directionField = -1 if directionFieldName is not None: directionField = layer.fields().lookupField(directionFieldName) speedField = -1 if speedFieldName is not None: speedField = layer.fields().lookupField(speedFieldName) director = QgsVectorLayerDirector(layer, directionField, forwardValue, backwardValue, bothValue, defaultDirection) distUnit = iface.mapCanvas().mapSettings().destinationCrs().mapUnits() multiplier = QgsUnitTypes.fromUnitToUnitFactor( distUnit, QgsUnitTypes.DistanceMeters) if strategy == 0: strategy = QgsNetworkDistanceStrategy() else: strategy = QgsNetworkSpeedStrategy(speedField, defaultSpeed, multiplier * 1000.0 / 3600.0) multiplier = 3600 director.addStrategy(strategy) builder = QgsGraphBuilder( iface.mapCanvas().mapSettings().destinationCrs(), iface.mapCanvas().hasCrsTransformEnabled(), tolerance) progress.setInfo(self.tr('Loading end points...')) request = QgsFeatureRequest() request.setFlags(request.flags() ^ QgsFeatureRequest.SubsetOfAttributes) features = vector.features(endPoints, request) count = len(features) points = [startPoint] for f in features: points.append(f.geometry().asPoint()) progress.setInfo(self.tr('Building graph...')) snappedPoints = director.makeGraph(builder, points) progress.setInfo(self.tr('Calculating shortest paths...')) graph = builder.graph() idxStart = graph.findVertex(snappedPoints[0]) tree, cost = QgsGraphAnalyzer.dijkstra(graph, idxStart, 0) route = [] total = 100.0 / count for i in range(1, count + 1): idxEnd = graph.findVertex(snappedPoints[i]) if tree[idxEnd] == -1: msg = self.tr( 'There is no route from start point ({}) to end point ({}).' .format(startPoint.toString(), points[i].toString())) progress.setText(msg) ProcessingLog.addToLog(ProcessingLog.LOG_WARNING, msg) continue cost = 0.0 current = idxEnd while current != idxStart: cost += graph.edge(tree[current]).cost(0) route.append( graph.vertex(graph.edge(tree[current]).inVertex()).point()) current = graph.edge(tree[current]).outVertex() route.append(snappedPoints[0]) route.reverse() geom = QgsGeometry.fromPolyline(route) feat.setGeometry(geom) feat['start'] = startPoint.toString() feat['end'] = points[i].toString() feat['cost'] = cost / multiplier writer.addFeature(feat) route[:] = [] progress.setPercentage(int(i * total)) del writer
def processAlgorithm(self, feedback): vlayerA = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT)) vlayerB = dataobjects.getLayerFromString( self.getParameterValue(self.INPUT2)) geomType = QgsWkbTypes.multiType(vlayerA.wkbType()) fields = vector.combineVectorFields(vlayerA, vlayerB) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fields, geomType, vlayerA.crs()) outFeat = QgsFeature() index = vector.spatialindex(vlayerB) selectionA = vector.features(vlayerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): feedback.setProgress(int(current * total)) geom = inFeatA.geometry() atMapA = inFeatA.attributes() intersects = index.intersects(geom.boundingBox()) request = QgsFeatureRequest().setFilterFids(intersects) engine = None if len(intersects) > 0: # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine(geom.geometry()) engine.prepareGeometry() for inFeatB in vlayerB.getFeatures(request): tmpGeom = inFeatB.geometry() if engine.intersects(tmpGeom.geometry()): atMapB = inFeatB.attributes() int_geom = QgsGeometry(geom.intersection(tmpGeom)) if int_geom.wkbType( ) == QgsWkbTypes.Unknown or QgsWkbTypes.flatType( int_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: int_com = geom.combine(tmpGeom) int_geom = QgsGeometry() if int_com: int_sym = geom.symDifference(tmpGeom) int_geom = QgsGeometry(int_com.difference(int_sym)) if int_geom.isEmpty() or not int_geom.isGeosValid(): ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('GEOS geoprocessing error: One or ' 'more input features have invalid ' 'geometry.')) try: if int_geom.wkbType() in wkbTypeGroups[wkbTypeGroups[ int_geom.wkbType()]]: outFeat.setGeometry(int_geom) attrs = [] attrs.extend(atMapA) attrs.extend(atMapB) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) continue del writer
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_A)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(self.INPUT_B)) fieldList = layerA.pendingFields() writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( fieldList, QGis.WKBLineString, layerA.dataProvider().crs()) spatialIndex = vector.spatialindex(layerB) inFeatA = QgsFeature() inFeatB = QgsFeature() outFeat = QgsFeature() inGeom = QgsGeometry() splitGeom = QgsGeometry() features = vector.features(layerA) current = 0 total = 100.0 / float(len(features)) for inFeatA in features: inGeom = inFeatA.geometry() attrsA = inFeatA.attributes() outFeat.setAttributes(attrsA) inLines = [inGeom] lines = spatialIndex.intersects(inGeom.boundingBox()) if len(lines) > 0: #hasIntersections splittingLines = [] for i in lines: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() splitGeom = QgsGeometry(inFeatB.geometry()) if inGeom.intersects(splitGeom): splittingLines.append(splitGeom) if len(splittingLines) > 0: for splitGeom in splittingLines: splitterPList = vector.extractPoints(splitGeom) outLines = [] while len(inLines) > 0: inGeom = inLines.pop() inPoints = vector.extractPoints(inGeom) if inGeom.intersects(splitGeom): try: result, newGeometries, topoTestPoints = inGeom.splitGeometry( splitterPList, False) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Geometry exception while splitting' )) result = 1 # splitGeometry: If there are several intersections # between geometry and splitLine, only the first one is considered. if result == 0: #split occured if inPoints == vector.extractPoints( inGeom): # bug in splitGeometry: sometimes it returns 0 but # the geometry is unchanged outLines.append(inGeom) else: inLines.append(inGeom) for aNewGeom in newGeometries: inLines.append(aNewGeom) else: outLines.append(inGeom) else: outLines.append(inGeom) inLines = outLines for aLine in inLines: outFeat.setGeometry(aLine) writer.addFeature(outFeat) current += 1 progress.setPercentage(int(current * total)) del writer
feedback.setProgressText("Looking for matching files.") getFiles( os.path.dirname(dataDir), filenameFormat, outputFileFormat, groupFiles, outputFiles, groupBy, ) os.chdir(oldDir) if len(groupFiles) == 0 or len(outputFiles) == 0: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, "No matching files found! r.series will not be executed.", ) raise GeoAlgorithmExecutionException( "No matching files found! r.series will not be executed." ) else: # run r.series for each group of files GrassUtils.startGrassSession() feedback.setProgressText("Starting GRASS r.series executions") loglines.append("Starting GRASS r.series executions") iteration = 1.0 for date in sorted(groupFiles.iterkeys()): progress.setPercentage(int(iteration / float(len(groupFiles)) * 100)) feedback.setProgressText("Processing date string: " + date) loglines.append("Processing date string: " + date) params = {
class GeoAlgorithm: _icon = QtGui.QIcon(os.path.dirname(__file__) + '/../images/alg.png') def __init__(self): # Parameters needed by the algorithm self.parameters = list() # Outputs generated by the algorithm self.outputs = list() # Name and group for normal toolbox display self.name = '' self.group = '' # The crs taken from input layers (if possible), and used when # loading output layers self.crs = None # Change any of the following if your algorithm should not # appear in the toolbox or modeler self.showInToolbox = True self.showInModeler = True #if true, will show only loaded layers in parameters dialog. #Also, if True, the algorithm does not run on the modeler #or batch ptocessing interface self.allowOnlyOpenedLayers = False # False if it should not be run a a batch process self.canRunInBatchMode = True # To be set by the provider when it loads the algorithm self.provider = None # If the algorithm is run as part of a model, the parent model # can be set in this variable, to allow for customized # behaviour, in case some operations should be run differently # when running as part of a model self.model = None self.defineCharacteristics() def getCopy(self): """Returns a new instance of this algorithm, ready to be used for being executed. """ newone = copy.copy(self) newone.parameters = copy.deepcopy(self.parameters) newone.outputs = copy.deepcopy(self.outputs) return newone # methods to overwrite when creating a custom geoalgorithm def getIcon(self): return self._icon @staticmethod def getDefaultIcon(): return GeoAlgorithm._icon def help(self): """Returns the help with the description of this algorithm. It returns a tuple boolean, string. IF the boolean value is true, it means that the string contains the actual description. If false, it is an url or path to a file where the description is stored. In both cases, the string or the content of the file have to be HTML, ready to be set into the help display component. Returns None if there is no help file available. The default implementation looks for an rst file in a help folder under the folder where the algorithm is located. The name of the file is the name console name of the algorithm, without the namespace part """ name = self.commandLineName().split(':')[1].lower() filename = os.path.join( os.path.dirname(inspect.getfile(self.__class__)), 'help', name + '.rst') try: html = getHtmlFromRstFile(filename) return True, html except: return False, None def processAlgorithm(self): """Here goes the algorithm itself. There is no return value from this method. A GeoAlgorithmExecutionException should be raised in case something goes wrong. """ pass def defineCharacteristics(self): """Here is where the parameters and outputs should be defined. """ pass def getCustomParametersDialog(self): """If the algorithm has a custom parameters dialog, it should be returned here, ready to be executed. """ return None def getCustomModelerParametersDialog(self, modelAlg, algIndex=None): """If the algorithm has a custom parameters dialog when called from the modeler, it should be returned here, ready to be executed. """ return None def getParameterDescriptions(self): """Returns a dict with param names as keys and detailed descriptions of each param as value. These descriptions are used as tool tips in the parameters dialog. If a description does not exist, the parameter's human-readable name is used. """ descs = {} return descs def checkBeforeOpeningParametersDialog(self): """If there is any check to perform before the parameters dialog is opened, it should be done here. This method returns an error message string if there is any problem (for instance, an external app not configured yet), or None if the parameters dialog can be opened. Note that this check should also be done in the processAlgorithm method, since algorithms can be called without opening the parameters dialog. """ return None def checkParameterValuesBeforeExecuting(self): """If there is any check to do before launching the execution of the algorithm, it should be done here. If values are not correct, a message should be returned explaining the problem. This check is called from the parameters dialog, and also when calling from the console. """ return None # ========================================================= def execute(self, progress=None, model=None): """The method to use to call a processing algorithm. Although the body of the algorithm is in processAlgorithm(), it should be called using this method, since it performs some additional operations. Raises a GeoAlgorithmExecutionException in case anything goes wrong. """ self.model = model try: self.setOutputCRS() self.resolveTemporaryOutputs() self.checkOutputFileExtensions() self.runPreExecutionScript(progress) self.processAlgorithm(progress) progress.setPercentage(100) self.convertUnsupportedFormats(progress) self.runPostExecutionScript(progress) except GeoAlgorithmExecutionException, gaee: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, gaee.msg) raise gaee except Exception, e: # If something goes wrong and is not caught in the # algorithm, we catch it here and wrap it lines = [self.tr('Uncaught error while executing algorithm')] errstring = traceback.format_exc() newline = errstring.find('\n') if newline != -1: lines.append(errstring[:newline]) else: lines.append(errstring) lines.append(errstring.replace('\n', '|')) ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, lines) raise GeoAlgorithmExecutionException( str(e) + self.tr('\nSee log for more details'))
def processAlgorithm(self, feedback): source_layer = dataobjects.getObjectFromUri( self.getParameterValue(Clip.INPUT)) mask_layer = dataobjects.getObjectFromUri( self.getParameterValue(Clip.OVERLAY)) writer = self.getOutputFromName(self.OUTPUT).getVectorWriter( source_layer.fields(), QgsWkbTypes.multiType(source_layer.wkbType()), source_layer.crs()) # first build up a list of clip geometries clip_geoms = [] for maskFeat in vector.features( mask_layer, QgsFeatureRequest().setSubsetOfAttributes([])): clip_geoms.append(maskFeat.geometry()) # are we clipping against a single feature? if so, we can show finer progress reports if len(clip_geoms) > 1: combined_clip_geom = QgsGeometry.unaryUnion(clip_geoms) single_clip_feature = False else: combined_clip_geom = clip_geoms[0] single_clip_feature = True # use prepared geometries for faster intersection tests engine = QgsGeometry.createGeometryEngine( combined_clip_geom.geometry()) engine.prepareGeometry() tested_feature_ids = set() for i, clip_geom in enumerate(clip_geoms): input_features = [ f for f in vector.features( source_layer, QgsFeatureRequest().setFilterRect(clip_geom.boundingBox())) ] if not input_features: continue if single_clip_feature: total = 100.0 / len(input_features) else: total = 0 for current, in_feat in enumerate(input_features): if not in_feat.geometry(): continue if in_feat.id() in tested_feature_ids: # don't retest a feature we have already checked continue tested_feature_ids.add(in_feat.id()) if not engine.intersects(in_feat.geometry().geometry()): continue if not engine.contains(in_feat.geometry().geometry()): cur_geom = in_feat.geometry() new_geom = combined_clip_geom.intersection(cur_geom) if new_geom.wkbType( ) == QgsWkbTypes.Unknown or QgsWkbTypes.flatType( new_geom.geometry().wkbType( )) == QgsWkbTypes.GeometryCollection: int_com = in_feat.geometry().combine(new_geom) int_sym = in_feat.geometry().symDifference(new_geom) new_geom = int_com.difference(int_sym) else: # clip geometry totally contains feature geometry, so no need to perform intersection new_geom = in_feat.geometry() try: out_feat = QgsFeature() out_feat.setGeometry(new_geom) out_feat.setAttributes(in_feat.attributes()) writer.addFeature(out_feat) except: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self.tr('Feature geometry error: One or more ' 'output features ignored due to ' 'invalid geometry.')) continue if single_clip_feature: feedback.setProgress(int(current * total)) if not single_clip_feature: # coarse progress report for multiple clip geometries feedback.setProgress(100.0 * i / len(clip_geoms)) del writer
def getFiles( dataDir, filenameFormat, outputFileFormat, groupFiles, outputFiles, groupBy ): # year-month if groupBy == 0: regex = "(Y{2,4}M{2})D{0,3}" # year-month-day elif groupBy == 1: regex = "(Y{2,4}M{2}D{2,3})" # month-day elif groupBy == 2: regex = "Y{0,4}(M{2}D{2})" # year elif groupBy == 3: regex = "(Y{2,4})M{0,2}D{0,3}" # month elif groupBy == 4: regex = "Y{0,4}(M{2})D{0,3}" # day elif groupBy == 5: regex = "Y{0,4}M{0,2}(D{2,3})" # decadal elif groupBy == 6: regex = "((Y{0,4})(M{0,2})(D{2,3}))" # whole directory elif groupBy == 7: fileName, fileExtension = os.path.splitext(filenameFormat) regex = "(" + fileName + ")" + fileExtension else: return # first find where the date string is located in the filename and construct a # regex to match it match = re.search(regex, filenameFormat) if not match: ProcessingLog.addToLog( ProcessingLog.LOG_INFO, "No match for date string in filename format!" ) raise GeoAlgorithmExecutionException( "No match for date string in filename format!" ) startDateString = match.start(1) lengthDateString = match.end(1) - match.start(1) # if grouping by format the regex has to be different to when grouping by date if groupBy == 7: dateRegex = fileExtension + "$" else: dateRegex = ( "(?<=^.{" + str(startDateString) + "})\d{" + str(lengthDateString) + "}" ) # then replace it with * to find all the files that match the filename format matchingFormat = re.sub(regex, "*", filenameFormat) # For decadal grouping need to save the length of year, month and day strings # to be able to convert the date to doy later on if groupBy == 6: lengthYearString = len(match.group(2)) lengthMonthString = len(match.group(3)) lengthDayString = len(match.group(4)) # find all the matching files in the data dir os.chdir(dataDir) matchingFiles = sorted(glob.glob(matchingFormat)) # now group them according to the date for filename in matchingFiles: match = re.search(dateRegex, filename) if not match: continue # If aggregation is by decade and the datestring doesn't specify DOY then DOY must be # calculated so that the images can be grouped by year and last two digits of DOY if groupBy == 6: date = convertDatetoDoy( match.group(), lengthYearString, lengthMonthString, lengthDayString ) # need to subtract 1 and add 10 since decade 1 has days 1-10, decade 2 has days 11-20, etc. date = str(int(date) - 1 + 10)[:-1] else: date = match.group() if date in groupFiles: groupFiles[date] += ";" + dataDir + os.sep + filename else: groupFiles[date] = dataDir + os.sep + filename # create an output filename for date for date in groupFiles: outputFile = re.sub("YMD", str(date), outputFileFormat) outputFile = re.sub("\..{2,4}$", ".tif", outputFile) # make sure it's a tiff outputFiles[date] = outputFile
res = self.transformArray(work,what,polyn) # Transformation result = numpy.copy(array) result[result!=nodata] = res # Replace new values with the one sampled func.updateProcessing(progress,2,3) else: result = [] for i in range(0,raster.RasterCount): band = raster.GetRasterBand(i) data_type = band.DataType nodata = band.GetNoDataValue() # Raise Notice that no no-data value has been selected progress.setConsoleInfo("!!! - Found no nodata-value for band %s . Transforming all values - !!!" % (str(i+1)) ) try: array = band.ReadAsArray() except Exception, e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,"Could not transform the raster to an array.") work = array[array!=nodata] tran = self.transformArray(work,what,polyn) r = numpy.copy(array) r[r!=nodata] = tran # Replace new values with the one sampled result.append(r) # Create Output metadata = driver.GetMetadata() if metadata.has_key( gdal.DCAP_CREATE ) and metadata[ gdal.DCAP_CREATE ] == "YES": pass else: progress.setConsoleInfo("Creation of input Fileformat is not supported by gdal. Create GTiff by default.") driver = gdal.GetDriverByName("GTiff") try:
def runAlgorithm(algOrName, onFinish, *args): if isinstance(algOrName, GeoAlgorithm): alg = algOrName else: alg = Processing.getAlgorithm(algOrName) if alg is None: print 'Error: Algorithm not found\n' return if len(args) != alg.getVisibleParametersCount() \ + alg.getVisibleOutputsCount(): print 'Error: Wrong number of parameters' processing.alghelp(algOrName) return alg = alg.getCopy() if isinstance(args, dict): # Set params by name for (name, value) in args.items(): if alg.getParameterFromName(name).setValue(value): continue if alg.getOutputFromName(name).setValue(value): continue print 'Error: Wrong parameter value %s for parameter %s.' \ % (value, name) return else: i = 0 for param in alg.parameters: if not param.hidden: if not param.setValue(args[i]): print 'Error: Wrong parameter value: ' \ + unicode(args[i]) return i = i + 1 for output in alg.outputs: if not output.hidden: if not output.setValue(args[i]): print 'Error: Wrong output value: ' + unicode(args[i]) return i = i + 1 msg = alg.checkParameterValuesBeforeExecuting() if msg: print 'Unable to execute algorithm\n' + msg return if not alg.checkInputCRS(): print 'Warning: Not all input layers use the same CRS.\n' \ + 'This can cause unexpected results.' ProcessingLog.addToLog(ProcessingLog.LOG_ALGORITHM, alg.getAsCommand()) # Don't set the wait cursor twice, because then when you # restore it, it will still be a wait cursor. cursor = QApplication.overrideCursor() if cursor is None or cursor == 0: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) elif cursor.shape() != Qt.WaitCursor: QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) progress = MessageBarProgress() ret = UnthreadedAlgorithmExecutor.runalg(alg, progress) if onFinish is not None and ret: onFinish(alg, progress) QApplication.restoreOverrideCursor() progress.close() return alg
def processAlgorithm(self, progress): layerA = dataobjects.getObjectFromUri( self.getParameterValue(Difference.INPUT)) layerB = dataobjects.getObjectFromUri( self.getParameterValue(Difference.OVERLAY)) ignoreInvalid = self.getParameterValue(Difference.IGNORE_INVALID) geomType = QgsWKBTypes.multiType(QGis.fromOldWkbType(layerA.wkbType())) writer = self.getOutputFromName(Difference.OUTPUT).getVectorWriter( layerA.pendingFields(), geomType, layerA.crs()) outFeat = QgsFeature() index = vector.spatialindex(layerB) selectionA = vector.features(layerA) total = 100.0 / len(selectionA) for current, inFeatA in enumerate(selectionA): add = True geom = QgsGeometry(inFeatA.geometry()) diff_geom = QgsGeometry(geom) attrs = inFeatA.attributes() intersections = index.intersects(geom.boundingBox()) for i in intersections: request = QgsFeatureRequest().setFilterFid(i) inFeatB = layerB.getFeatures(request).next() tmpGeom = QgsGeometry(inFeatB.geometry()) if diff_geom.intersects(tmpGeom): diff_geom = QgsGeometry(diff_geom.difference(tmpGeom)) if diff_geom.isGeosEmpty(): ProcessingLog.addToLog( ProcessingLog.LOG_INFO, self.tr('Feature with NULL geometry found.')) if not diff_geom.isGeosValid(): if ignoreInvalid: ProcessingLog.addToLog( ProcessingLog.LOG_ERROR, self. tr('GEOS geoprocessing error: One or more input features have invalid geometry.' )) add = False else: raise GeoAlgorithmExecutionException( self. tr('Features with invalid geometries found. Please fix these errors or specify the "Ignore invalid input features" flag' )) break if add: try: outFeat.setGeometry(diff_geom) outFeat.setAttributes(attrs) writer.addFeature(outFeat) except: ProcessingLog.addToLog( ProcessingLog.LOG_WARNING, self. tr('Feature geometry error: One or more output features ignored due to invalid geometry.' )) continue progress.setPercentage(int(current * total)) del writer
def processAlgorithm(self, progress): # Do the stuff vector = self.getParameterValue(self.VECTOR) v = Processing.getObject(vector) scl = self.getParameterValue(self.SPEC_COL) what = self.m[self.getParameterValue(self.METHOD)] ext = self.getParameterValue(self.EXTENT) try: ext = string.split(ext,",") # split except AttributeError: # Extent was empty, raise error raise GeoAlgorithmExecutionException("Please set an extent for the generated raster") cs = self.getParameterValue(self.GRAIN_SIZE) output = self.getOutputValue(self.GRID) # Create output layer xmin = float(ext[0]) xmax = float(ext[1]) ymin = float(ext[2]) ymax = float(ext[3]) gt = (xmin,cs,0.0,ymax,0.0,-cs) nodata = -9999 cols = int( abs( (xmax-xmin)/gt[1] ) ) rows = int( abs( (ymax-ymin)/gt[5] ) ) try: fin_array = numpy.zeros((rows,cols)) # Create empty grid except MemoryError: raise GeoAlgorithmExecutionException("MemoryError: Resolution is too fine. Please choose a higher value.") #if vector is a point do the following, else calculate for overlapping range sizes if v.geometryType() == QGis.Point: progress.setConsoleInfo("Using the point layers to calculate %s for resulting grid." % (what)) progress.setConsoleInfo("---") # Make the Array one line bigger to capute points not entirely inside the array heightFP,widthFP = fin_array.shape #define hight and width of input matrix withBorders = numpy.zeros((heightFP+(2*1),widthFP+(2*1)))*0 # set the border to borderValue withBorders[1:heightFP+1,1:widthFP+1]=fin_array # set the interior region to the input matrix fin_array = withBorders rows, cols = fin_array.shape # Get the number of species noSpecies = func.getUniqueAttributeList( v, scl) progress.setConsoleInfo("Processing %s number of different species" % (str(len(noSpecies))) ) ds = ogr.Open(vector) name = ds.GetLayer().GetName() proj = ds.GetLayer().GetSpatialRef() proj = proj.ExportToWkt() n = ds.GetLayer().GetFeatureCount() arrayDict = dict() k = 1 for spec in noSpecies: # Make a copy of the final_array work_array = numpy.zeros_like(fin_array) # Vector layer subsetting to the specific species v_id = [] # Iter through subset of species request= QgsFeatureRequest() request.setFilterExpression( scl + " = " + "'" + spec + "'" ) iter = v.getFeatures( request ) # Set the selection for feature in iter: v_id.append( feature.id() ) geom = feature.geometry().asPoint() mx = geom.x() my = geom.y() pp = func.world2Pixel(gt, mx,my) x = round(pp[0]) y = round(pp[1]) if x < 0 or y < 0 or x >= work_array.shape[1] or y >= work_array.shape[0]: progress.setConsoleInfo("Point %s outside given exent" % (str( f.GetFID() )) ) else: #set grid cell to 1 work_array[y,x] = 1 arrayDict[spec] = work_array # Save the working array in the dictionary k += 1 if what == 'Species Richness': #SR = K (the total number of species in a grid cell) for spec_ar in arrayDict.itervalues(): fin_array = fin_array + spec_ar # Simply add up the values elif what == 'Weighted Endemism': # WE = ∑ 1/C (C is the number of grid cells each endemic occurs in) for spec_ar in arrayDict.itervalues(): # Construct vector of total number of cells each species is found ncell = func.count_nonzero(spec_ar) work = spec_ar.astype(float) out = numpy.divide(work, ncell) # Now divide all cells by the number fin_array = fin_array + out # Simply add up the values elif what == 'Corrected Weighted Endemism': # CWE = WE/K (K is the total number of species in a grid cell) nspec = numpy.zeros_like(fin_array).astype(float) for spec_ar in arrayDict.itervalues(): # Construct vector of total number of cells each species is found ncell = func.count_nonzero(spec_ar) work = spec_ar.astype(float) out = numpy.divide(work, ncell) # Now divide all cells by the number fin_array = fin_array + out # Simply add up the values to calculate the WE nspec = nspec + spec_ar # Simply add up the values for species richness fin_array = numpy.divide(fin_array,nspec) # Now divide through number of species elif v.geometryType() == QGis.Polygon: progress.setConsoleInfo("Using the range size polygons to calculate %s for resulting grid." % (what)) progress.setConsoleInfo("---") noSpecies = func.getUniqueAttributeList( v, scl) progress.setConsoleInfo("Processing %s number of different species" % (str(len(noSpecies))) ) ds = ogr.Open(vector) name = ds.GetLayer().GetName() proj = ds.GetLayer().GetSpatialRef().ExportToWkt() n = ds.GetLayer().GetFeatureCount() k = 1 for spec in noSpecies: work_array = numpy.zeros_like(fin_array) layers = ds.ExecuteSQL("SELECT * FROM %s WHERE %s = '%s'" % (name, scl, spec) ) progress.setConsoleInfo("Gridding range of species %s " % (spec )) if str(layers.GetFeatureCount()) == 0: raise GeoAlgorithmExecutionException("Species could not be queried from the point layer.") func.updateProcessing(progress,k,n) work2 = numpy.copy(work_array) # temporary working array for i in range(0,layers.GetFeatureCount()): f = layers.GetFeature(i) geom = f.GetGeometryRef() res = self.clipArray(layers,gt,geom,work_array) work2 = work2 + res if res == None: raise GeoAlgorithmExecutionException("Feature %s of species %s could not be rasterized. Possibly because it is a multipolygon. Split data beforehand." % (str(i),spec) ) work_array = work2 # Set back if err != 0: raise GeoAlgorithmExecutionException("Features of species %s could not be rasterized." % (spec) ) # Get Array if work_array.shape != fin_array.shape: raise GeoAlgorithmExecutionException("Rasterized grids could not be merged together." ) if what == 'Species Richness': fin_array = fin_array + work_array # Simply add up the values elif what == 'Weighted Endemism': # Weighted Endemism (WE), which is the sum of the reciprocal of the total number of cells each # species in a grid cell is found in. A WE emphasizes areas that have a high proportion of animals # with restricted ranges. # WE = ∑ 1/C (C is the number of grid cells each endemic occurs in) ncell = func.count_nonzero(work_array) elif what == 'Corrected Weighted Endemism': #Corrected Weighted Endemism (CWE). The corrected weighted endemism is simply the # weighted endemism divided by the total number of species in a cell (Crisp 2001). A CWE # emphasizes areas that have a high proportion of animals with restricted ranges, but are not # necessarily areas that are species rich. # CWE = WE/K (K is the total number of species in a grid cell) pass if func.count_nonzero(fin_array) == 0: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR,"No values were rasterized. Check GeometryType and Vector Projection.") # Create output raster func.createRaster(output,cols,rows,fin_array,nodata,gt,proj,'GTiff')
def processAlgorithm(self, progress): if system.isWindows(): path = Grass7Utils.grassPath() if path == '': raise GeoAlgorithmExecutionException( self.tr( 'GRASS GIS 7 folder is not configured. Please ' 'configure it before running GRASS GIS 7 algorithms.')) # Create brand new commands lists self.commands = [] self.outputCommands = [] self.exportedLayers = {} # If GRASS session has been created outside of this algorithm then # get the list of layers loaded in GRASS otherwise start a new # session existingSession = Grass7Utils.sessionRunning if existingSession: self.exportedLayers = Grass7Utils.getSessionLayers() else: Grass7Utils.startGrass7Session() # Handle ext functions for inputs/command/outputs if self.module: if hasattr(self.module, 'processInputs'): func = getattr(self.module, 'processInputs') func(self) else: self.processInputs() if hasattr(self.module, 'processCommand'): func = getattr(self.module, 'processCommand') func(self) else: self.processCommand() if hasattr(self.module, 'processOutputs'): func = getattr(self.module, 'processOutputs') func(self) else: self.processOutputs() else: self.processInputs() self.processCommand() self.processOutputs() # Run GRASS loglines = [] loglines.append(self.tr('GRASS GIS 7 execution commands')) for line in self.commands: progress.setCommand(line) loglines.append(line) if ProcessingConfig.getSetting(Grass7Utils.GRASS_LOG_COMMANDS): ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) Grass7Utils.executeGrass7(self.commands, progress, self.outputCommands) for out in self.outputs: if isinstance(out, OutputHTML): with open(self.getOutputFromName("rawoutput").value) as f: rawOutput = "".join(f.readlines()) with open(out.value, "w") as f: f.write("<pre>%s</pre>" % rawOutput) # If the session has been created outside of this algorithm, add # the new GRASS GIS 7 layers to it otherwise finish the session if existingSession: Grass7Utils.addSessionLayers(self.exportedLayers) else: Grass7Utils.endGrass7Session()
class OTBAlgorithm(GeoAlgorithm): REGION_OF_INTEREST = "ROI" def __init__(self, descriptionfile): GeoAlgorithm.__init__(self) self.roiFile = None self.descriptionFile = descriptionfile self.defineCharacteristicsFromFile() self.numExportedLayers = 0 self.hasROI = None; def __str__(self): return( "Algo : " + self.name + " from app : " + self.cliName + " in : " + self.group ) def getCopy(self): newone = OTBAlgorithm(self.descriptionFile) newone.provider = self.provider return newone def getIcon(self): return PyQt4.QtGui.QIcon(os.path.dirname(__file__) + "/../../images/otb.png") def help(self): folder = os.path.join( OTBUtils.otbDescriptionPath(), 'doc' ) helpfile = os.path.join( str(folder), self.appkey + ".html") if os.path.exists(helpfile): return False, helpfile else: raise False, None def adapt_list_to_string(self, c_list): a_list = c_list[1:] if a_list[0] in ["ParameterVector", "ParameterMultipleInput"]: if c_list[0] == "ParameterType_InputImageList": a_list[3] = 3 elif c_list[0] == "ParameterType_InputFilenameList": a_list[3] = 4 else: a_list[3] = -1 a_list[1] = "-%s" % a_list[1] def mystr(par): if type(par) == type([]): return ";".join(par) return str(par) b_list = map(mystr, a_list) res = "|".join(b_list) return res def get_list_from_node(self, myet): all_params = [] for parameter in myet.iter('parameter'): rebuild = [] par_type = parameter.find('parameter_type').text key = parameter.find('key').text name = parameter.find('name').text source_par_type = parameter.find('parameter_type').attrib['source_parameter_type'] rebuild.append(source_par_type) rebuild.append(par_type) rebuild.append(key) rebuild.append(name) for each in parameter[4:]: if not each.tag in ["hidden"]: if len(list(each)) == 0: rebuild.append(each.text) else: rebuild.append([item.text for item in each.iter('choice')]) all_params.append(rebuild) return all_params def defineCharacteristicsFromFile(self): content = open(self.descriptionFile).read() dom_model = ET.fromstring(content) self.appkey = dom_model.find('key').text self.cliName = dom_model.find('exec').text self.name = dom_model.find('longname').text self.group = dom_model.find('group').text rebu = None the_result = None try: rebu = self.get_list_from_node(dom_model) the_result = map(self.adapt_list_to_string,rebu) except Exception, e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not open OTB algorithm: %s\n%s' % (self.descriptionFile, traceback.format_exc()))) raise e for line in the_result: try: if line.startswith("Parameter") or line.startswith("*Parameter"): if line.startswith("*Parameter"): param = getParameterFromString(line[1:]) param.isAdvanced = True else: param = getParameterFromString(line) # Hack for initializing the elevation parameters from Processing configuration if param.name == "-elev.dem.path" or param.name == "-elev.dem" or "elev.dem" in param.name: param.default = OTBUtils.otbSRTMPath() elif param.name == "-elev.dem.geoid" or param.name == "-elev.geoid" or "elev.geoid" in param.name: param.default = OTBUtils.otbGeoidPath() self.addParameter(param) elif line.startswith("Extent"): self.addParameter(ParameterExtent(self.REGION_OF_INTEREST, "Region of interest", "0,1,0,1")) self.hasROI = True else: self.addOutput(getOutputFromString(line)) except Exception,e: ProcessingLog.addToLog(ProcessingLog.LOG_ERROR, self.tr('Could not open OTB algorithm: %s\n%s' % (self.descriptionFile, line))) raise e