def postInputs(self): """ After layer imports, we need to update some internal parameters """ # If projection has not already be set, use the project self.setSessionProjectionFromProject() # Build GRASS region if self.region.isEmpty(): self.region = QgsProcessingUtils.combineLayerExtents(self.inputLayers) command = 'g.region n={} s={} e={} w={}'.format( self.region.yMaximum(), self.region.yMinimum(), self.region.xMaximum(), self.region.xMinimum() ) # Handle cell size if self.parameterDefinition(self.GRASS_REGION_CELLSIZE_PARAMETER): if self.cellSize: cellSize = self.cellSize else: cellSize = self.getDefaultCellSize() command += ' res={}'.format(cellSize) # Handle align to resolution if self.alignToResolution: command += ' -a' # Add the default parameters commands self.commands.append(command) QgsMessageLog.logMessage(self.tr('processInputs end. Commands: {}').format(self.commands), 'Grass7', Qgis.Info)
def processAlgorithm(self, parameters, context, feedback): expression = self.getParameterValue(self.EXPRESSION) layersValue = self.getParameterValue(self.LAYERS) layersDict = {} if layersValue: layers = [QgsProcessingUtils.mapLayerFromString(f, context) for f in layersValue.split(";")] layersDict = {os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers} for lyr in QgsProcessingUtils.compatibleRasterLayers(context.project()): name = lyr.name() if (name + "@") in expression: layersDict[name] = lyr entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): entry = QgsRasterCalculatorEntry() entry.ref = '{:s}@{:d}'.format(name, n + 1) entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) output = self.getOutputValue(self.OUTPUT) extentValue = self.getParameterValue(self.EXTENT) if not extentValue: extentValue = QgsProcessingUtils.combineLayerExtents(layersValue) if extentValue: extent = extentValue.split(',') bbox = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3])) else: if layersDict: bbox = list(layersDict.values())[0].extent() for lyr in layersDict.values(): bbox.combineExtentWith(lyr.extent()) else: raise GeoAlgorithmExecutionException(self.tr("No layers selected")) def _cellsize(layer): return (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width() cellsize = self.getParameterValue(self.CELLSIZE) or min([_cellsize(lyr) for lyr in layersDict.values()]) width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, width, height, entries) res = calc.processCalculation() if res == QgsRasterCalculator.ParserError: raise GeoAlgorithmExecutionException(self.tr("Error parsing formula"))
def processAlgorithm(self, parameters, context, feedback): expression = self.parameterAsString(parameters, self.EXPRESSION, context) layers = self.parameterAsLayerList(parameters, self.LAYERS, context) layersDict = {} if layers: layersDict = {os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers} for lyr in QgsProcessingUtils.compatibleRasterLayers(context.project()): name = lyr.name() if (name + "@") in expression: layersDict[name] = lyr entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): entry = QgsRasterCalculatorEntry() entry.ref = '{:s}@{:d}'.format(name, n + 1) entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) bbox = self.parameterAsExtent(parameters, self.EXTENT, context) if bbox.isNull(): bbox = QgsProcessingUtils.combineLayerExtents(layers) if bbox.isNull(): if layersDict: bbox = list(layersDict.values())[0].extent() for lyr in layersDict.values(): bbox.combineExtentWith(lyr.extent()) else: raise QgsProcessingException(self.tr("No layers selected")) def _cellsize(layer): return (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width() cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context) or min([_cellsize(lyr) for lyr in layersDict.values()]) width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, width, height, entries) res = calc.processCalculation() if res == QgsRasterCalculator.ParserError: raise QgsProcessingException(self.tr("Error parsing formula")) return {self.OUTPUT: output}
def processAlgorithm(self, parameters, context, feedback): commands = [] vector = self.getParameterValue(self.VECTOR) elevation = self.getParameterValue(self.ELEVATION) color = self.getParameterValue(self.COLOR) region = \ str(self.getParameterValue(self.GRASS_REGION_EXTENT_PARAMETER)) if not region: region = QgsProcessingUtils.combineLayerExtents(layers) regionCoords = region.split(',') command = 'g.region ' command += 'n=' + str(regionCoords[3]) command += ' s=' + str(regionCoords[2]) command += ' e=' + str(regionCoords[1]) command += ' w=' + str(regionCoords[0]) cellsize = self.getParameterValue(self.GRASS_REGION_CELLSIZE_PARAMETER) if cellsize: command += ' res=' + str(cellsize) else: command += ' res=' + str(self.getDefaultCellsize(parameters, context)) commands.append(command) command = 'nviz7' if vector: layers = vector.split(';') for layer in layers: (cmd, newfilename) = self.exportVectorLayer(layer) commands.append(cmd) vector = vector.replace(layer, newfilename) command += ' vector=' + vector.replace(';', ',') if color: layers = color.split(';') for layer in layers: (cmd, newfilename) = self.exportRasterLayer(layer) commands.append(cmd) color = color.replace(layer, newfilename) command += ' color=' + color.replace(';', ',') if elevation: layers = elevation.split(';') for layer in layers: (cmd, newfilename) = self.exportRasterLayer(layer) commands.append(cmd) elevation = elevation.replace(layer, newfilename) command += ' elevation=' + elevation.replace(';', ',') if elevation is None and vector is None: command += ' -q' commands.append(command) Grass7Utils.createTempMapset() Grass7Utils.executeGrass7(commands, feedback)
def processAlgorithm(self, parameters, context, feedback): layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context) extent = self.getParameterValue(self.TARGET_AREA).split(',') if not extent: extent = QgsProcessingUtils.combineLayerExtents([layer]) target_crs = QgsCoordinateReferenceSystem(self.getParameterValue(self.TARGET_AREA_CRS)) target_geom = QgsGeometry.fromRect(QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3]))) output_file = self.getOutputValue(self.OUTPUT_HTML_FILE) # make intersection tests nice and fast engine = QgsGeometry.createGeometryEngine(target_geom.geometry()) engine.prepareGeometry() layer_bounds = QgsGeometry.fromRect(layer.extent()) results = [] for srs_id in QgsCoordinateReferenceSystem.validSrsIds(): candidate_crs = QgsCoordinateReferenceSystem.fromSrsId(srs_id) if not candidate_crs.isValid(): continue transform_candidate = QgsCoordinateTransform(candidate_crs, target_crs) transformed_bounds = QgsGeometry(layer_bounds) try: if not transformed_bounds.transform(transform_candidate) == 0: continue except: continue if engine.intersects(transformed_bounds.geometry()): results.append(candidate_crs.authid()) self.createHTML(output_file, results)
def processAlgorithm(self, parameters, context, feedback): expression = self.parameterAsString(parameters, self.EXPRESSION, context) layers = self.parameterAsLayerList(parameters, self.LAYERS, context) layersDict = {} if layers: layersDict = {os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers} crs = self.parameterAsCrs(parameters, self.CRS, context) if not layers and not crs.isValid(): raise QgsProcessingException(self.tr("No reference layer selected nor CRS provided")) if not crs.isValid() and layers: crs = list(layersDict.values())[0].crs() bbox = self.parameterAsExtent(parameters, self.EXTENT, context) if not layers and bbox.isNull(): raise QgsProcessingException(self.tr("No reference layer selected nor extent box provided")) if not bbox.isNull(): bboxCrs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) if bboxCrs != crs: transform = QgsCoordinateTransform(bboxCrs, crs, context.project()) bbox = transform.transformBoundingBox(bbox) if bbox.isNull() and layers: bbox = QgsProcessingUtils.combineLayerExtents(layers, crs) cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context) if not layers and cellsize == 0: raise QgsProcessingException(self.tr("No reference layer selected nor cellsize value provided")) def _cellsize(layer): ext = layer.extent() if layer.crs() != crs: transform = QgsCoordinateTransform(layer.crs(), crs, context.project()) ext = transform.transformBoundingBox(ext) return (ext.xMaximum() - ext.xMinimum()) / layer.width() if cellsize == 0: cellsize = min([_cellsize(lyr) for lyr in layersDict.values()]) for lyr in QgsProcessingUtils.compatibleRasterLayers(context.project()): name = lyr.name() if (name + "@") in expression: layersDict[name] = lyr entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): ref = '{:s}@{:d}'.format(name, n + 1) if ref in expression: entry = QgsRasterCalculatorEntry() entry.ref = ref entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, crs, width, height, entries) res = calc.processCalculation(feedback) if res == QgsRasterCalculator.ParserError: raise QgsProcessingException(self.tr("Error parsing formula")) return {self.OUTPUT: output}
def getConsoleCommands(self, parameters, context, feedback): inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context) srccrs = self.parameterAsCrs(parameters, self.SOURCE_SRS, context).authid() dstcrs = self.parameterAsCrs(parameters, self.DEST_SRS, context).authid() useRasterExtent = self.parameterAsBool(parameters, self.USE_RASTER_EXTENT, context) rasterExtent = self.parameterAsExtent(parameters, self.RASTER_EXTENT, context) if rasterExtent.isNull(): rasterExtent = QgsProcessingUtils.combineLayerExtents([inLayer]) extentCrs = self.parameterAsCrs(parameters, self.EXTENT_CRS, context).authid() opts = self.parameterAsEnum(parameters, self.OPTIONS, context) noData = self.parameterAsString(parameters, self.NO_DATA, context) multithreading = self.parameterAsBool(parameters, self.MULTITHREADING, context) if noData is not None: noData = str(noData) arguments = [] arguments.append('-ot') arguments.append(self.TYPE[self.parameterAsEnum(parameters, self.RTYPE, context)]) if srccrs: arguments.append('-s_srs') arguments.append(srccrs) if dstcrs: arguments.append('-t_srs') arguments.append(dstcrs) if noData: arguments.append('-dstnodata') arguments.append(noData) arguments.append('-r') arguments.append( self.METHOD_OPTIONS[self.parameterAsEnum(parameters, self.METHOD, context)]) arguments.append('-of') out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) arguments.append(GdalUtils.getFormatShortNameFromFilename(out)) if self.parameterAsDouble(parameters, self.TR, context) != 0: arguments.append('-tr') arguments.append(str(self.parameterAsDouble(parameters, self.TR, context))) arguments.append(str(self.parameterAsDouble(parameters, self.TR, context))) if useRasterExtent: arguments.append('-te') arguments.append(rasterExtent.xMinimum()) arguments.append(rasterExtent.yMinimum()) arguments.append(rasterExtent.xMaximum()) arguments.append(rasterExtent.yMaximum()) if extentCrs: arguments.append('-te_srs') arguments.append(extentCrs) if opts: arguments.append('-co') arguments.append(opts) if multithreading: arguments.append('-multi') if GdalUtils.version() in [2010000, 2010100]: arguments.append("--config GDALWARP_IGNORE_BAD_CUTLINE YES") arguments.append(inLayer.source()) arguments.append(out) return ['gdalwarp', GdalUtils.escapeAndJoin(arguments)]
def processAlgorithm(self, parameters, context, feedback): 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.parameterDefinitions(): if isinstance(param, ParameterRaster): if param.name() not in parameters or parameters[param.name()] is None: continue if parameters[param.name()].endswith('sdat'): parameters[param.name()] = parameters[param.name()][:-4] + "sgrd" elif not parameters[param.name()].endswith('sgrd'): exportCommand = self.exportRasterLayer(parameters[param.name()]) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.name() not in parameters or parameters[param.name()] is None: continue layer = QgsProcessingUtils.mapLayerFromString(parameters[param.name()], context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not parameteres[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.name() not in parameters or parameters[param.name()] is None: continue table = QgsProcessingUtils.mapLayerFromString(parameters[param.name()], context, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[parameters[param.name()]] = filename elif not parameters[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.name() not in parameters or parameters[param.name()] 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 in [dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_POINT]: for layerfile in layers: layer = QgsProcessingUtils.mapLayerFromString(layerfile, context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # TODO - set minimum extent if not extent: extent = QgsProcessingUtils.combineLayerExtents([layer]) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' command += ' ' + ' '.join(self.hardcodedStrings) for param in self.parameterDefinitions(): if not param.name() in parameters or parameters[param.name()] is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = parameters[param.name()] if value in list(self.exportedLayers.keys()): command += ' -' + param.name() + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name() + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = parameters[param.name()] for layer in list(self.exportedLayers.keys()): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name() + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if parameters[param.name()]: command += ' -' + param.name().strip() + " true" else: command += ' -' + param.name().strip() + " false" elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') with open(tempTableFile, 'w') as f: f.write('\t'.join([col for col in param.cols]) + '\n') values = parameters[param.name()].split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[i + 2] + '\n' f.write(s) 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(parameters) / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = parameters[param.name()].split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + str(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name() + ' ' + str(param.value) else: command += ' -' + param.name() + ' "' + str(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: feedback.pushCommandInfo(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): QgsMessageLog.logMessage('\n'.join(loglines), self.tr('Processing'), QgsMessageLog.INFO) SagaUtils.executeSaga(feedback) 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 getConsoleCommands(self, parameters, context, feedback): inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context) out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) outsize = str(self.parameterAsInt(parameters, self.OUTSIZE, context)) outsizePerc = self.parameterAsBool(parameters, self.OUTSIZE_PERC, context) noData = self.parameterAsString(parameters, self.NO_DATA, context) expand = self.parameterDefinition( self.EXPAND).options()[self.parameterAsEnum( parameters, self.EXPAND, context)] proj_extent = self.parameterAsExtent(parameters, self.PROJWIN, context) if proj_extent.isNull(): proj_extent = QgsProcessingUtils.combineLayerExtents([inLayer]) crsId = self.parameterAsCrs(parameters, self.SRS, context).authid() sds = self.parameterAsBool(parameters, self.SDS, context) opts = self.parameterAsString(parameters, self.OPTIONS, context) if noData is not None: noData = str(noData) arguments = [] arguments.append('-of') arguments.append(GdalUtils.getFormatShortNameFromFilename(out)) arguments.append('-ot') arguments.append(self.TYPE[self.parameterAsEnum( parameters, self.RTYPE, context)]) if outsizePerc: arguments.append('-outsize') arguments.append(outsize + '%') arguments.append(outsize + '%') else: arguments.append('-outsize') arguments.append(outsize) arguments.append(outsize) if noData and len(noData) > 0: arguments.append('-a_nodata') arguments.append(noData) if expand != 'none': arguments.append('-expand') arguments.append(expand) try: projwin = [] projwin.append('-projwin') projwin.append(proj_extent.xMinimum()) projwin.append(proj_extent.yMaximum()) projwin.append(proj_extent.xMaximum()) projwin.append(proj_extent.yMinimum()) except IndexError: projwin = [] if projwin: arguments.extend(projwin) if crsId: arguments.append('-a_srs') arguments.append(str(crsId)) if sds: arguments.append('-sds') if opts: arguments.append('-co') arguments.append(opts) arguments.append(inLayer.source()) arguments.append(out) return ['gdal_translate', GdalUtils.escapeAndJoin(arguments)]
def processInputs(self, parameters, context): """Prepare the GRASS import commands""" for param in self.parameterDefinitions(): if isinstance(param, ParameterRaster): if not param.name() in parameters(): continue value = parameters[param.name()] # Check if the layer hasn't already been exported in, for # example, previous GRASS calls in this session if value in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer(value, self.commands) self.commands.append(self.exportRasterLayer(value)) if isinstance(param, ParameterVector): if not param.name() in parameters(): continue value = parameters[param.name()] if value in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer(value, self.commands) self.commands.append(self.exportVectorLayer(value)) if isinstance(param, ParameterTable): pass if isinstance(param, ParameterMultipleInput): if not param.name() in parameters(): continue value = parameters[param.name()] layers = value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == dataobjects.TYPE_RASTER: for layer in layers: if layer in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer(layer, self.commands) self.commands.append(self.exportRasterLayer(layer)) elif param.datatype in [dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_POINT]: for layer in layers: if layer in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer(layer, self.commands) self.commands.append(self.exportVectorLayer(layer)) self.setSessionProjectionFromProject(self.commands) region = \ str(self.getParameterValue(self.GRASS_REGION_EXTENT_PARAMETER)) if not region: region = QgsProcessingUtils.combineLayerExtents(layers) regionCoords = region.split(',') command = 'g.region' command += ' n=' + str(regionCoords[3]) command += ' s=' + str(regionCoords[2]) command += ' e=' + str(regionCoords[1]) command += ' w=' + str(regionCoords[0]) cellsize = self.getParameterValue(self.GRASS_REGION_CELLSIZE_PARAMETER) if cellsize: command += ' res=' + str(cellsize) else: command += ' res=' + str(self.getDefaultCellsize(parameters, context)) alignToResolution = \ self.getParameterValue(self.GRASS_REGION_ALIGN_TO_RESOLUTION) if alignToResolution: command += ' -a' self.commands.append(command)
def processAlgorithm(self, parameters, context, feedback): expression = self.parameterAsString(parameters, self.EXPRESSION, context) layers = self.parameterAsLayerList(parameters, self.LAYERS, context) layersDict = {} if layers: layersDict = { os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers } crs = self.parameterAsCrs(parameters, self.CRS, context) if not layers and not crs.isValid(): raise QgsProcessingException( self.tr("No reference layer selected nor CRS provided")) if not crs.isValid() and layers: crs = list(layersDict.values())[0].crs() bbox = self.parameterAsExtent(parameters, self.EXTENT, context) if not layers and bbox.isNull(): raise QgsProcessingException( self.tr("No reference layer selected nor extent box provided")) if not bbox.isNull(): bboxCrs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) if bboxCrs != crs: transform = QgsCoordinateTransform(bboxCrs, crs, context.project()) bbox = transform.transformBoundingBox(bbox) if bbox.isNull() and layers: bbox = QgsProcessingUtils.combineLayerExtents(layers, crs) cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context) if not layers and cellsize == 0: raise QgsProcessingException( self.tr( "No reference layer selected nor cellsize value provided")) def _cellsize(layer): ext = layer.extent() if layer.crs() != crs: transform = QgsCoordinateTransform(layer.crs(), crs, context.project()) ext = transform.transformBoundingBox(ext) return (ext.xMaximum() - ext.xMinimum()) / layer.width() if cellsize == 0: cellsize = min([_cellsize(lyr) for lyr in layersDict.values()]) for lyr in QgsProcessingUtils.compatibleRasterLayers( context.project()): name = lyr.name() if (name + "@") in expression: layersDict[name] = lyr entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): ref = '{:s}@{:d}'.format(name, n + 1) if ref in expression: entry = QgsRasterCalculatorEntry() entry.ref = ref entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, crs, width, height, entries) res = calc.processCalculation(feedback) if res == QgsRasterCalculator.ParserError: raise QgsProcessingException(self.tr("Error parsing formula")) return {self.OUTPUT: output}
def processAlgorithm(self, parameters, context, feedback): expression = self.parameterAsString(parameters, self.EXPRESSION, context) layers = self.parameterAsLayerList(parameters, self.LAYERS, context) layersDict = {} if layers: layersDict = {lyr.source(): lyr for lyr in layers} crs = self.parameterAsCrs(parameters, self.CRS, context) if crs is None or not crs.isValid(): if not layers: raise QgsProcessingException( self.tr("No reference layer selected nor CRS provided")) else: crs = list(layersDict.values())[0].crs() bbox = self.parameterAsExtent(parameters, self.EXTENT, context) if bbox.isNull() and not layers: raise QgsProcessingException( self.tr("No reference layer selected nor extent box provided")) if not bbox.isNull(): bboxCrs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) if bboxCrs != crs: transform = QgsCoordinateTransform(bboxCrs, crs, context.project()) bbox = transform.transformBoundingBox(bbox) if bbox.isNull() and layers: bbox = QgsProcessingUtils.combineLayerExtents(layers, crs, context) cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context) if cellsize == 0 and not layers: raise QgsProcessingException( self.tr( "No reference layer selected nor cellsize value provided")) def _cellsize(layer): ext = layer.extent() if layer.crs() != crs: transform = QgsCoordinateTransform(layer.crs(), crs, context.project()) ext = transform.transformBoundingBox(ext) return (ext.xMaximum() - ext.xMinimum()) / layer.width() if cellsize == 0: cellsize = min([_cellsize(lyr) for lyr in layersDict.values()]) # check for layers available in the model layersDictCopy = layersDict.copy( ) # need a shallow copy because next calls invalidate iterator for lyr in layersDictCopy.values(): expression = self.mappedNameToLayer(lyr, expression, layersDict, context) # check for layers available in the project for lyr in QgsProcessingUtils.compatibleRasterLayers( context.project()): expression = self.mappedNameToLayer(lyr, expression, layersDict, context) # create the list of layers to be passed as inputs to RasterCalculaltor # at this phase expression has been modified to match available layers # in the current scope entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): ref = '{:s}@{:d}'.format(name, n + 1) if ref in expression: entry = QgsRasterCalculatorEntry() entry.ref = ref entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) # Append any missing entry from the current project for entry in QgsRasterCalculatorEntry.rasterEntries(): if not [e for e in entries if e.ref == entry.ref]: entries.append(entry) output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) width = round((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = round((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, crs, width, height, entries, context.transformContext()) res = calc.processCalculation(feedback) if res == QgsRasterCalculator.ParserError: raise QgsProcessingException(self.tr("Error parsing formula")) return {self.OUTPUT: output}
def processInputs(self, parameters, context): """Prepare the GRASS import commands""" for param in self.parameterDefinitions(): if isinstance(param, ParameterRaster): if not param.name() in parameters(): continue value = parameters[param.name()] # Check if the layer hasn't already been exported in, for # example, previous GRASS calls in this session if value in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer(value, self.commands) self.commands.append(self.exportRasterLayer(value)) if isinstance(param, ParameterVector): if not param.name() in parameters(): continue value = parameters[param.name()] if value in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer(value, self.commands) self.commands.append(self.exportVectorLayer(value)) if isinstance(param, ParameterTable): pass if isinstance(param, ParameterMultipleInput): if not param.name() in parameters(): continue value = parameters[param.name()] layers = value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == dataobjects.TYPE_RASTER: for layer in layers: if layer in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer( layer, self.commands) self.commands.append(self.exportRasterLayer(layer)) elif param.datatype in [ dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_POINT ]: for layer in layers: if layer in list(self.exportedLayers.keys()): continue else: self.setSessionProjectionFromLayer( layer, self.commands) self.commands.append(self.exportVectorLayer(layer)) self.setSessionProjectionFromProject(self.commands) region = \ str(self.getParameterValue(self.GRASS_REGION_EXTENT_PARAMETER)) if not region: region = QgsProcessingUtils.combineLayerExtents(layers) regionCoords = region.split(',') command = 'g.region' command += ' n=' + str(regionCoords[3]) command += ' s=' + str(regionCoords[2]) command += ' e=' + str(regionCoords[1]) command += ' w=' + str(regionCoords[0]) cellsize = self.getParameterValue(self.GRASS_REGION_CELLSIZE_PARAMETER) if cellsize: command += ' res=' + str(cellsize) else: command += ' res=' + str( self.getDefaultCellsize(parameters, context)) alignToResolution = \ self.getParameterValue(self.GRASS_REGION_ALIGN_TO_RESOLUTION) if alignToResolution: command += ' -a' self.commands.append(command)
def processAlgorithm(self, parameters, context, feedback): 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.parameterDefinitions(): if isinstance(param, ParameterRaster): if param.name() not in parameters or parameters[param.name()] is None: continue if parameters[param.name()].endswith('sdat'): parameters[param.name()] = parameters[param.name()][:-4] + "sgrd" elif not parameters[param.name()].endswith('sgrd'): exportCommand = self.exportRasterLayer(parameters[param.name()]) if exportCommand is not None: commands.append(exportCommand) if isinstance(param, ParameterVector): if param.name() not in parameters or parameters[param.name()] is None: continue layer = QgsProcessingUtils.mapLayerFromString(parameters[param.name()], context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[param.value] = filename elif not parameteres[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterTable): if param.name() not in parameters or parameters[param.name()] is None: continue table = QgsProcessingUtils.mapLayerFromString(parameters[param.name()], context, False) if table: filename = dataobjects.exportTable(table) self.exportedLayers[parameters[param.name()]] = filename elif not parameters[param.name()].endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) if isinstance(param, ParameterMultipleInput): if param.name() not in parameters or parameters[param.name()] is None: continue layers = param.value.split(';') if layers is None or len(layers) == 0: continue if param.datatype == dataobjects.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 in [dataobjects.TYPE_VECTOR_ANY, dataobjects.TYPE_VECTOR_LINE, dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_POINT]: for layerfile in layers: layer = QgsProcessingUtils.mapLayerFromString(layerfile, context, False) if layer: filename = dataobjects.exportVectorLayer(layer) self.exportedLayers[layerfile] = filename elif not layerfile.endswith('shp'): raise GeoAlgorithmExecutionException( self.tr('Unsupported file format')) # TODO - set minimum extent if not extent: extent = QgsProcessingUtils.combineLayerExtents([layer]) # 2: Set parameters and outputs command = self.undecoratedGroup + ' "' + self.cmdname + '"' command += ' ' + ' '.join(self.hardcodedStrings) for param in self.parameterDefinitions(): if not param.name() in parameters or parameters[param.name()] is None: continue if isinstance(param, (ParameterRaster, ParameterVector, ParameterTable)): value = parameters[param.name()] if value in list(self.exportedLayers.keys()): command += ' -' + param.name() + ' "' \ + self.exportedLayers[value] + '"' else: command += ' -' + param.name() + ' "' + value + '"' elif isinstance(param, ParameterMultipleInput): s = parameters[param.name()] for layer in list(self.exportedLayers.keys()): s = s.replace(layer, self.exportedLayers[layer]) command += ' -' + param.name() + ' "' + s + '"' elif isinstance(param, ParameterBoolean): if parameters[param.name()]: command += ' -' + param.name().strip() + " true" else: command += ' -' + param.name().strip() + " false" elif isinstance(param, ParameterFixedTable): tempTableFile = getTempFilename('txt') with open(tempTableFile, 'w') as f: f.write('\t'.join([col for col in param.cols]) + '\n') values = parameters[param.name()].split(',') for i in range(0, len(values), 3): s = values[i] + '\t' + values[i + 1] + '\t' + values[i + 2] + '\n' f.write(s) 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(parameters) / 2 offset = [halfcell, -halfcell, halfcell, -halfcell] values = parameters[param.name()].split(',') for i in range(4): command += ' -' + self.extentParamNames[i] + ' ' \ + str(float(values[i]) + offset[i]) elif isinstance(param, (ParameterNumber, ParameterSelection)): command += ' -' + param.name() + ' ' + str(param.value) else: command += ' -' + param.name() + ' "' + str(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: feedback.pushCommandInfo(line) loglines.append(line) if ProcessingConfig.getSetting(SagaUtils.SAGA_LOG_COMMANDS): QgsMessageLog.logMessage('\n'.join(loglines), self.tr('Processing'), QgsMessageLog.INFO) SagaUtils.executeSaga(feedback) 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 getConsoleCommands(self, parameters, context, feedback): inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context) srccrs = self.parameterAsCrs(parameters, self.SOURCE_SRS, context).authid() dstcrs = self.parameterAsCrs(parameters, self.DEST_SRS, context).authid() useRasterExtent = self.parameterAsBool(parameters, self.USE_RASTER_EXTENT, context) rasterExtent = self.parameterAsExtent(parameters, self.RASTER_EXTENT, context) if rasterExtent.isNull(): rasterExtent = QgsProcessingUtils.combineLayerExtents([inLayer]) extentCrs = self.parameterAsCrs(parameters, self.EXTENT_CRS, context).authid() opts = self.parameterAsEnum(parameters, self.OPTIONS, context) noData = self.parameterAsString(parameters, self.NO_DATA, context) multithreading = self.parameterAsBool(parameters, self.MULTITHREADING, context) if noData is not None: noData = str(noData) arguments = [] arguments.append('-ot') arguments.append(self.TYPE[self.parameterAsEnum( parameters, self.RTYPE, context)]) if srccrs: arguments.append('-s_srs') arguments.append(srccrs) if dstcrs: arguments.append('-t_srs') arguments.append(dstcrs) if noData: arguments.append('-dstnodata') arguments.append(noData) arguments.append('-r') arguments.append(self.METHOD_OPTIONS[self.parameterAsEnum( parameters, self.METHOD, context)]) arguments.append('-of') out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) arguments.append(GdalUtils.getFormatShortNameFromFilename(out)) if self.parameterAsDouble(parameters, self.TR, context) != 0: arguments.append('-tr') arguments.append( str(self.parameterAsDouble(parameters, self.TR, context))) arguments.append( str(self.parameterAsDouble(parameters, self.TR, context))) if useRasterExtent: arguments.append('-te') arguments.append(rasterExtent.xMinimum()) arguments.append(rasterExtent.yMinimum()) arguments.append(rasterExtent.xMaximum()) arguments.append(rasterExtent.yMaximum()) if extentCrs: arguments.append('-te_srs') arguments.append(extentCrs) if opts: arguments.append('-co') arguments.append(opts) if multithreading: arguments.append('-multi') if GdalUtils.version() in [2010000, 2010100]: arguments.append("--config GDALWARP_IGNORE_BAD_CUTLINE YES") arguments.append(inLayer.source()) arguments.append(out) return ['gdalwarp', GdalUtils.escapeAndJoin(arguments)]
def getConsoleCommands(self, parameters, context, feedback): inLayer = self.parameterAsRasterLayer(parameters, self.INPUT, context) out = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) outsize = str(self.parameterAsInt(parameters, self.OUTSIZE, context)) outsizePerc = self.parameterAsBool(parameters, self.OUTSIZE_PERC, context) noData = self.parameterAsString(parameters, self.NO_DATA, context) expand = self.parameterDefinition(self.EXPAND).options()[self.parameterAsEnum(parameters, self.EXPAND, context)] proj_extent = self.parameterAsExtent(parameters, self.PROJWIN, context) if proj_extent.isNull(): proj_extent = QgsProcessingUtils.combineLayerExtents([inLayer]) crsId = self.parameterAsCrs(parameters, self.SRS, context).authid() sds = self.parameterAsBool(parameters, self.SDS, context) opts = self.parameterAsString(parameters, self.OPTIONS, context) if noData is not None: noData = str(noData) arguments = [] arguments.append('-of') arguments.append(GdalUtils.getFormatShortNameFromFilename(out)) arguments.append('-ot') arguments.append(self.TYPE[self.parameterAsEnum(parameters, self.RTYPE, context)]) if outsizePerc: arguments.append('-outsize') arguments.append(outsize + '%') arguments.append(outsize + '%') else: arguments.append('-outsize') arguments.append(outsize) arguments.append(outsize) if noData and len(noData) > 0: arguments.append('-a_nodata') arguments.append(noData) if expand != 'none': arguments.append('-expand') arguments.append(expand) try: projwin = [] projwin.append('-projwin') projwin.append(proj_extent.xMinimum()) projwin.append(proj_extent.yMaximum()) projwin.append(proj_extent.xMaximum()) projwin.append(proj_extent.yMinimum()) except IndexError: projwin = [] if projwin: arguments.extend(projwin) if crsId: arguments.append('-a_srs') arguments.append(str(crsId)) if sds: arguments.append('-sds') if opts: arguments.append('-co') arguments.append(opts) arguments.append(inLayer.source()) arguments.append(out) return ['gdal_translate', GdalUtils.escapeAndJoin(arguments)]
def processAlgorithm(self, parameters, context, feedback): expression = self.parameterAsString(parameters, self.EXPRESSION, context) layers = self.parameterAsLayerList(parameters, self.LAYERS, context) layersDict = {} if layers: layersDict = {lyr.source(): lyr for lyr in layers} crs = self.parameterAsCrs(parameters, self.CRS, context) if crs is None or not crs.isValid(): if not layers: raise QgsProcessingException(self.tr("No reference layer selected nor CRS provided")) else: crs = list(layersDict.values())[0].crs() bbox = self.parameterAsExtent(parameters, self.EXTENT, context) if bbox.isNull() and not layers: raise QgsProcessingException(self.tr("No reference layer selected nor extent box provided")) if not bbox.isNull(): bboxCrs = self.parameterAsExtentCrs(parameters, self.EXTENT, context) if bboxCrs != crs: transform = QgsCoordinateTransform(bboxCrs, crs, context.project()) bbox = transform.transformBoundingBox(bbox) if bbox.isNull() and layers: bbox = QgsProcessingUtils.combineLayerExtents(layers, crs, context) cellsize = self.parameterAsDouble(parameters, self.CELLSIZE, context) if cellsize == 0 and not layers: raise QgsProcessingException(self.tr("No reference layer selected nor cellsize value provided")) def _cellsize(layer): ext = layer.extent() if layer.crs() != crs: transform = QgsCoordinateTransform(layer.crs(), crs, context.project()) ext = transform.transformBoundingBox(ext) return (ext.xMaximum() - ext.xMinimum()) / layer.width() if cellsize == 0: cellsize = min([_cellsize(lyr) for lyr in layersDict.values()]) # check for layers available in the model layersDictCopy = layersDict.copy() # need a shallow copy because next calls invalidate iterator for lyr in layersDictCopy.values(): expression = self.mappedNameToLayer(lyr, expression, layersDict, context) # check for layers available in the project for lyr in QgsProcessingUtils.compatibleRasterLayers(context.project()): expression = self.mappedNameToLayer(lyr, expression, layersDict, context) # create the list of layers to be passed as inputs to RasterCalculaltor # at this phase expression has been modified to match available layers # in the current scope entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): ref = '{:s}@{:d}'.format(name, n + 1) if ref in expression: entry = QgsRasterCalculatorEntry() entry.ref = ref entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) # Append any missing entry from the current project for entry in QgsRasterCalculatorEntry.rasterEntries(): if not [e for e in entries if e.ref == entry.ref]: entries.append(entry) output = self.parameterAsOutputLayer(parameters, self.OUTPUT, context) width = round((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = round((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, crs, width, height, entries, context.transformContext()) res = calc.processCalculation(feedback) if res == QgsRasterCalculator.ParserError: raise QgsProcessingException(self.tr("Error parsing formula")) return {self.OUTPUT: output}
def processAlgorithm(self, parameters, context, feedback): expression = self.getParameterValue(self.EXPRESSION) layersValue = self.getParameterValue(self.LAYERS) layersDict = {} if layersValue: layers = [ QgsProcessingUtils.mapLayerFromString(f, context) for f in layersValue.split(";") ] layersDict = { os.path.basename(lyr.source().split(".")[0]): lyr for lyr in layers } for lyr in QgsProcessingUtils.compatibleRasterLayers( context.project()): name = lyr.name() if (name + "@") in expression: layersDict[name] = lyr entries = [] for name, lyr in layersDict.items(): for n in range(lyr.bandCount()): entry = QgsRasterCalculatorEntry() entry.ref = '{:s}@{:d}'.format(name, n + 1) entry.raster = lyr entry.bandNumber = n + 1 entries.append(entry) output = self.getOutputValue(self.OUTPUT) extentValue = self.getParameterValue(self.EXTENT) if not extentValue: extentValue = QgsProcessingUtils.combineLayerExtents(layersValue) if extentValue: extent = extentValue.split(',') bbox = QgsRectangle(float(extent[0]), float(extent[2]), float(extent[1]), float(extent[3])) else: if layersDict: bbox = list(layersDict.values())[0].extent() for lyr in layersDict.values(): bbox.combineExtentWith(lyr.extent()) else: raise GeoAlgorithmExecutionException( self.tr("No layers selected")) def _cellsize(layer): return (layer.extent().xMaximum() - layer.extent().xMinimum()) / layer.width() cellsize = self.getParameterValue(self.CELLSIZE) or min( [_cellsize(lyr) for lyr in layersDict.values()]) width = math.floor((bbox.xMaximum() - bbox.xMinimum()) / cellsize) height = math.floor((bbox.yMaximum() - bbox.yMinimum()) / cellsize) driverName = GdalUtils.getFormatShortNameFromFilename(output) calc = QgsRasterCalculator(expression, output, driverName, bbox, width, height, entries) res = calc.processCalculation() if res == QgsRasterCalculator.ParserError: raise GeoAlgorithmExecutionException( self.tr("Error parsing formula"))