def processInputs(alg, parameters, context, feedback): # Grab the projection from the input vector layer layer = alg.parameterAsLayer(parameters, 'input', context) alg.setSessionProjectionFromLayer(layer) layerCrs = layer.crs().toProj() # Creates a new location with this Crs wkt_file_name = Grass7Utils.exportCrsWktToFile(layer.crs()) newLocation = 'newProj{}'.format(alg.uniqueSuffix) alg.commands.append('g.proj wkt="{}" location={}'.format( wkt_file_name, newLocation)) # Go to the newly created location alg.commands.append( 'g.mapset mapset=PERMANENT location={}'.format(newLocation)) # Import the layer alg.loadVectorLayerFromParameter('input', parameters, context, feedback, False) # Go back to default location alg.commands.append('g.mapset mapset=PERMANENT location=temp_location') # Grab the projected Crs crs = alg.parameterAsCrs(parameters, 'crs', context) wkt_file_name = Grass7Utils.exportCrsWktToFile(crs) alg.commands.append('g.proj -c wkt="{}"'.format(wkt_file_name)) # Remove crs parameter alg.removeParameter('crs') # Add the location parameter with proper value location = QgsProcessingParameterString( 'location', 'new location', 'newProj{}'.format(alg.uniqueSuffix)) alg.addParameter(location)
def processInputs(alg, parameters, context, feedback): # Grab the projection from the input vector layer layer = alg.parameterAsLayer(parameters, 'input', context) # Creates a new location with this Crs wkt_file_name = Grass7Utils.exportCrsWktToFile(layer.crs()) newLocation = 'newProj{}'.format(alg.uniqueSuffix) alg.commands.append('g.proj wkt="{}" location={}'.format( wkt_file_name, newLocation)) # Go to the newly created location alg.commands.append('g.mapset mapset=PERMANENT location={}'.format( newLocation)) # Import the layer alg.loadRasterLayerFromParameter( 'input', parameters, context, False) # Go back to default location alg.commands.append('g.mapset mapset=PERMANENT location=temp_location') # Grab the projected Crs crs = alg.parameterAsCrs(parameters, 'crs', context) wkt_file_name = Grass7Utils.exportCrsWktToFile(crs) alg.commands.append('g.proj -c wkt="{}"'.format(wkt_file_name)) # Remove crs parameter alg.removeParameter('crs') # Add the location parameter with proper value location = QgsProcessingParameterString( 'location', 'new location', 'newProj{}'.format(alg.uniqueSuffix) ) alg.addParameter(location) # And set the region grassName = alg.exportedLayers['input'] # We use the shell to capture the results from r.proj -g if isWindows(): # TODO: make some tests under a non POSIX shell alg.commands.append('set regVar=') alg.commands.append('for /f "delims=" %%a in (\'r.proj -g input^="{}" location^="{}"\') do @set regVar=%%a'.format( grassName, newLocation)) alg.commands.append('g.region -a %regVar%') else: alg.commands.append('g.region -a $(r.proj -g input="{}" location="{}")'.format( grassName, newLocation))
def setUpClass(cls): start_app() cls.provider = Grass7AlgorithmProvider() QgsApplication.processingRegistry().addProvider(cls.provider) cls.cleanup_paths = [] assert Grass7Utils.installedVersion()
def processOutputs(alg, parameters, context, feedback): # We take all the outputs and we export them to the output directory outputDir = alg.parameterAsString(parameters, 'output_dir', context) output = alg.parameterAsString(parameters, 'output', context) outfile = alg.parameterAsString(parameters, 'outfile', context) outs = [] if output: outs = output.split(',') elif outfile: # Handle file manually to find the name of the layers with open(outfile) as f: for line in f: if '|' in line: outs.append(line.split('|')[0]) createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) for out in outs: # We need to export the raster with all its bands and its color table fileName = os.path.join(outputDir, out) outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) alg.exportRasterLayer(out, fileName, True, outFormat, createOpt, metaOpt)
def load(self): with QgsRuntimeProfiler.profile('Grass Provider'): ProcessingConfig.settingIcons[self.name()] = self.icon() ProcessingConfig.addSetting( Setting(self.name(), Grass7Utils.GRASS_LOG_COMMANDS, self.tr('Log execution commands'), False)) ProcessingConfig.addSetting( Setting(self.name(), Grass7Utils.GRASS_LOG_CONSOLE, self.tr('Log console output'), False)) ProcessingConfig.addSetting( Setting(self.name(), Grass7Utils.GRASS_HELP_PATH, self.tr('Location of GRASS docs'), Grass7Utils.grassHelpPath())) # Add settings for using r.external/v.external instead of r.in.gdal/v.in.ogr # but set them to False by default because the {r,v}.external implementations # have some bugs on windows + there are algorithms that can't be used with # external data (need a solid r.in.gdal/v.in.ogr). # For more info have a look at e.g. https://trac.osgeo.org/grass/ticket/3927 ProcessingConfig.addSetting( Setting( self.name(), Grass7Utils.GRASS_USE_REXTERNAL, self. tr('For raster layers, use r.external (faster) instead of r.in.gdal' ), False)) ProcessingConfig.addSetting( Setting( self.name(), Grass7Utils.GRASS_USE_VEXTERNAL, self. tr('For vector layers, use v.external (faster) instead of v.in.ogr' ), False)) ProcessingConfig.readSettings() self.refreshAlgorithms() return True
def setUpClass(cls): start_app() cls.provider = Grass7AlgorithmProvider() QgsApplication.processingRegistry().addProvider(cls.provider) cls.cleanup_paths = [] cls.temp_dir = tempfile.mkdtemp() cls.cleanup_paths.append(cls.temp_dir) assert Grass7Utils.installedVersion()
def exportSigFile(alg, group, subgroup, dest, sigDir='sig'): """ Export a signature file from internal GRASSDB to final destination """ shortSigFile = os.path.basename(dest) interSig = os.path.join(Grass7Utils.grassMapsetFolder(), 'PERMANENT', 'group', group, 'subgroup', subgroup, sigDir, shortSigFile) moveFile(alg, interSig, dest) return interSig
def importSigFile(alg, group, subgroup, src, sigDir='sig'): """ Import a signature file into an internal GRASSDB folder """ shortSigFile = os.path.basename(src) interSig = os.path.join(Grass7Utils.grassMapsetFolder(), 'PERMANENT', 'group', group, 'subgroup', subgroup, sigDir, shortSigFile) copyFile(alg, src, interSig) return shortSigFile
def loadAlgorithms(self): version = Grass7Utils.installedVersion(True) if version is None: QgsMessageLog.logMessage( self. tr('Problem with GRASS installation: GRASS was not found or is not correctly installed' ), self.tr('Processing'), Qgis.Critical) return self.algs = self.createAlgsList() for a in self.algs: self.addAlgorithm(a)
def processOutputs(alg, parameters, context, feedback): createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) # We need to export the raster with all its bands and its color table fileName = alg.parameterAsOutputLayer(parameters, 'output', context) outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) grassName = alg.exportedLayers['input'] alg.exportRasterLayer(grassName, fileName, True, outFormat, createOpt, metaOpt)
def processOutputs(alg, parameters, context, feedback): createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) # Export the results from correctedoutput grassName = 'correctedoutput{}'.format(alg.uniqueSuffix) fileName = alg.parameterAsOutputLayer(parameters, 'routput', context) outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) alg.exportRasterLayer(grassName, fileName, True, outFormat, createOpt, metaOpt)
def processOutputs(alg, parameters, context, feedback): createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) # Export all rasters with their color tables (and their bands) rasters = alg.parameterAsLayerList(parameters, 'map', context) outputDir = alg.parameterAsString(parameters, 'output_dir', context) for idx, raster in enumerate(rasters): rasterName = 'map_{}'.format(idx) fileName = os.path.join(outputDir, rasterName) outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) alg.exportRasterLayer(alg.exportedLayers[rasterName], fileName, True, outFormat, createOpt, metaOpt)
def processOutputs(alg, parameters, context, feedback): outputName = alg.parameterAsString(parameters, 'output', context) createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) for channel in ['red', 'green', 'blue']: fileName = alg.parameterAsOutputLayer(parameters, '{}output'.format(channel), context) grassName = '{}_{}'.format(outputName, channel) outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) alg.exportRasterLayer(grassName, fileName, True, outFormat, createOpt, metaOpt)
def processOutputs(alg, parameters, context, feedback): createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) outputDir = alg.parameterAsString(parameters, 'output_dir', context) outputParam = alg.parameterAsString(parameters, 'output', context) outputs = outputParam.split(',') # We need to export each of the output for output in outputs: fileName = os.path.join(outputDir, output) outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) alg.exportRasterLayer(output, fileName, True, outFormat, createOpt, metaOpt)
def processOutputs(alg, parameters, context, feedback): createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) # Export each color raster colors = ['red', 'green', 'blue'] for color in colors: fileName = os.path.normpath( alg.parameterAsOutputLayer(parameters, 'output_{}'.format(color), context)) outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) alg.exportRasterLayer('blended.{}'.format(color[0]), fileName, True, outFormat, createOpt, metaOpt)
def exportInputRasters(alg, parameters, context, rasterDic): """ Export input rasters Use a dict to make input/output link: { 'inputName1': 'outputName1', 'inputName2': 'outputName2'} """ createOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_OPT, context) metaOpt = alg.parameterAsString(parameters, alg.GRASS_RASTER_FORMAT_META, context) # Get inputs and outputs for inputName, outputName in rasterDic.items(): fileName = os.path.normpath( alg.parameterAsOutputLayer(parameters, outputName, context)) grassName = alg.exportedLayers[inputName] outFormat = Grass7Utils.getRasterFormatFromFilename(fileName) alg.exportRasterLayer(grassName, fileName, True, outFormat, createOpt, metaOpt)
def processOutputs(alg, parameters, context, feedback): crs = alg.parameterAsCrs(parameters, 'sourceproj', context) wkt_file_name = Grass7Utils.exportCrsWktToFile(crs) alg.commands.insert(0, 'g.proj -c wkt="{}"'.format(wkt_file_name))
def longName(self): version = Grass7Utils.installedVersion() return 'GRASS GIS ({})'.format( version) if version is not None else "GRASS GIS"
def supportedOutputRasterLayerExtensions(self): return Grass7Utils.getSupportedOutputRasterExtensions()
class Grass7AlgorithmProvider(QgsProcessingProvider): descriptionFolder = Grass7Utils.grassDescriptionPath() def __init__(self): super().__init__() self.algs = [] def load(self): with QgsRuntimeProfiler.profile('Grass Provider'): ProcessingConfig.settingIcons[self.name()] = self.icon() ProcessingConfig.addSetting( Setting(self.name(), Grass7Utils.GRASS_LOG_COMMANDS, self.tr('Log execution commands'), False)) ProcessingConfig.addSetting( Setting(self.name(), Grass7Utils.GRASS_LOG_CONSOLE, self.tr('Log console output'), False)) ProcessingConfig.addSetting( Setting(self.name(), Grass7Utils.GRASS_HELP_PATH, self.tr('Location of GRASS docs'), Grass7Utils.grassHelpPath())) # Add settings for using r.external/v.external instead of r.in.gdal/v.in.ogr # but set them to False by default because the {r,v}.external implementations # have some bugs on windows + there are algorithms that can't be used with # external data (need a solid r.in.gdal/v.in.ogr). # For more info have a look at e.g. https://trac.osgeo.org/grass/ticket/3927 ProcessingConfig.addSetting( Setting( self.name(), Grass7Utils.GRASS_USE_REXTERNAL, self. tr('For raster layers, use r.external (faster) instead of r.in.gdal' ), False)) ProcessingConfig.addSetting( Setting( self.name(), Grass7Utils.GRASS_USE_VEXTERNAL, self. tr('For vector layers, use v.external (faster) instead of v.in.ogr' ), False)) ProcessingConfig.readSettings() self.refreshAlgorithms() return True def unload(self): ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_COMMANDS) ProcessingConfig.removeSetting(Grass7Utils.GRASS_LOG_CONSOLE) ProcessingConfig.removeSetting(Grass7Utils.GRASS_HELP_PATH) ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_REXTERNAL) ProcessingConfig.removeSetting(Grass7Utils.GRASS_USE_VEXTERNAL) def createAlgsList(self): algs = [] folder = self.descriptionFolder for descriptionFile in os.listdir(folder): if descriptionFile.endswith('txt'): try: alg = Grass7Algorithm(os.path.join(folder, descriptionFile)) if alg.name().strip() != '': algs.append(alg) else: QgsMessageLog.logMessage( self.tr('Could not open GRASS GIS 7 algorithm: {0}' ).format(descriptionFile), self.tr('Processing'), Qgis.Critical) except Exception as e: QgsMessageLog.logMessage( self.tr( 'Could not open GRASS GIS 7 algorithm: {0}\n{1}'). format(descriptionFile, str(e)), self.tr('Processing'), Qgis.Critical) return algs def loadAlgorithms(self): version = Grass7Utils.installedVersion(True) if version is None: QgsMessageLog.logMessage( self. tr('Problem with GRASS installation: GRASS was not found or is not correctly installed' ), self.tr('Processing'), Qgis.Critical) return self.algs = self.createAlgsList() for a in self.algs: self.addAlgorithm(a) def name(self): return 'GRASS' def longName(self): version = Grass7Utils.installedVersion() return 'GRASS GIS ({})'.format( version) if version is not None else "GRASS GIS" def id(self): return 'grass7' def helpId(self): return 'grass7' def icon(self): return QgsApplication.getThemeIcon("/providerGrass.svg") def svgIconPath(self): return QgsApplication.iconPath("/providerGrass.svg") def defaultVectorFileExtension(self, hasGeometry=True): # By default,'gpkg', but if OGR has not been compiled with sqlite3, then # we take "SHP" if 'GPKG' in [ o.driverName for o in QgsVectorFileWriter.ogrDriverList() ]: return 'gpkg' else: return 'shp' if hasGeometry else 'dbf' def supportsNonFileBasedOutput(self): """ GRASS7 Provider doesn't support non file based outputs """ return False def supportedOutputVectorLayerExtensions(self): # We use the same extensions than QGIS because: # - QGIS is using OGR like GRASS # - There are very chances than OGR version used in GRASS is # different from QGIS OGR version. return QgsVectorFileWriter.supportedFormatExtensions() def supportedOutputRasterLayerExtensions(self): return Grass7Utils.getSupportedOutputRasterExtensions() def canBeActivated(self): return not bool(Grass7Utils.checkGrassIsInstalled()) def tr(self, string, context=''): if context == '': context = 'Grass7AlgorithmProvider' return QCoreApplication.translate(context, string)
def canBeActivated(self): return not bool(Grass7Utils.checkGrassIsInstalled())