4

I have used the graphical modeller on QGIS to build a simple model performing some processing on my input layer which would be a vector.

What I want to do is to have the name of the input layer, and then by having that, to look through my file to return some of the numbers in there.

So how do I get the name of my input layer in QGIS please?

Edit:

This is my script:

from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterExtent
from qgis.core import QgsProcessingParameterVectorLayer
from qgis.core import QgsProcessingParameterRasterDestination
import processing
import pandas as pd
df=pd.read_csv("....csv")
def score_list(namee):
 global a,b,c
 for i in range(0, df.shape[0]):
 if namee == df.iloc[i][1]:
 
 a = df.iloc[i][5]
 b = df.iloc[i][6]
 c = df.iloc[i][7]
 
 else:
 pass
 
 
class SiteSearchModel(QgsProcessingAlgorithm):
def initAlgorithm(self, config=None):
 self.addParameter(QgsProcessingParameterExtent('extent', 'extent', defaultValue=None))
 self.addParameter(QgsProcessingParameterVectorLayer('input', 'Input', types=[QgsProcessing.TypeVectorAnyGeometry], defaultValue=None))
 self.addParameter(QgsProcessingParameterRasterDestination('ReclassifiedRaster', 'Reclassified raster', createByDefault=True, defaultValue=None))
 
def processAlgorithm(self, parameters, context, feedback):
 
 source = self.parameterAsVectorLayer(parameters, 'input', context)
 source_name = source.name()
 
 score_list(source_name)
def processAlgorithm(self, parameters, context, model_feedback):
 # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
 # overall progress through the model
 feedback = QgsProcessingMultiStepFeedback(3, model_feedback)
 results = {}
 outputs = {}
 # Rasterize (vector to raster)
 alg_params = {
 'BURN': 1,
 'DATA_TYPE': 5, # Float32
 'EXTENT': parameters['extent'],
 'EXTRA': '',
 'FIELD': '',
 'HEIGHT': 50,
 'INIT': None,
 'INPUT': parameters['input'],
 'INVERT': False,
 'NODATA': 0,
 'OPTIONS': '',
 'UNITS': 1, # Georeferenced units
 'USE_Z': False,
 'WIDTH': 50,
 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
 }
 outputs['RasterizeVectorToRaster'] = processing.run('gdal:rasterize', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
 feedback.setCurrentStep(1)
 if feedback.isCanceled():
 return {}
 # PM
 alg_params = {
 'BAND': 1,
 'DATA_TYPE': 5, # Float32
 'EXTRA': '',
 'INPUT': outputs['RasterizeVectorToRaster']['OUTPUT'],
 'MAX_DISTANCE': None,
 'NODATA': 0,
 'OPTIONS': '',
 'REPLACE': None,
 'UNITS': 0, # Georeferenced coordinates
 'VALUES': '1',
 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
 }
 outputs['Pm'] = processing.run('gdal:proximity', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
 feedback.setCurrentStep(2)
 if feedback.isCanceled():
 return {}
 
 
 # Reclassify by table
 alg_params = {
 'DATA_TYPE': 5, # Float32
 'INPUT_RASTER': outputs['Pm']['OUTPUT'],
 'NODATA_FOR_MISSING': False,
 'NO_DATA': -9999,
 'RANGE_BOUNDARIES': 0, # min < value <= max
 'RASTER_BAND': 1,
 'TABLE': ['0','0', a ,'0','10000', b ,'10000','', c],
 'OUTPUT': parameters['ReclassifiedRaster']
 }
 outputs['ReclassifyByTable'] = processing.run('native:reclassifybytable', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
 results['ReclassifiedRaster'] = outputs['ReclassifyByTable']['OUTPUT']
 return results
def name(self):
 return 'Site search model'
def displayName(self):
 return 'Site search model'
def group(self):
 return 'Site search'
def groupId(self):
 return 'Site search'
def createInstance(self):
 return SiteSearchModel()
asked Aug 30, 2022 at 21:19

1 Answer 1

6

To get the name of your input layer you can just do something like:

def processAlgorithm(self, parameters, context, feedback):
 source = self.parameterAsVectorLayer(parameters, 'input', context)
 source_name = source.name()

Edit: It looks like you added a second processAlogorithm() method, which is not the right way- processAlgorithm() is a re-implemented class method for overriding. I also added a file parameter so you can select the csv from the file system rather than hard-coding the path.

Edit 2: I have tested this version which runs without error and produces (I think) a reasonable output.

Edit 3 (in response to last comment):

To rename the output layer, taking the name from the input vector- the recommended way to do this is to use the QgsProcessingLayerPostProcessorInterface class. (Credit to Nyall Dawson for the original example which I have adapted here). I have edited this answer again to include this functionality. If you save the output to a permanent file, you can just call it whatever name you like, but if you leave the [Save to temporary file] default, with Open output file after running algorithm checked, the temporary output layer will be loaded with the same name as the input vector layer instead of the generic name 'Reclassified raster'.

from qgis.core import QgsRasterLayer
from qgis.core import QgsProcessing
from qgis.core import QgsProcessingAlgorithm
from qgis.core import QgsProcessingMultiStepFeedback
from qgis.core import QgsProcessingParameterExtent
from qgis.core import QgsProcessingParameterFile
from qgis.core import QgsProcessingParameterVectorLayer
from qgis.core import QgsProcessingParameterRasterDestination
from qgis.core import QgsProcessingLayerPostProcessorInterface
import processing
import pandas as pd
class SiteSearchModel(QgsProcessingAlgorithm):
 def initAlgorithm(self, config=None):
 self.addParameter(QgsProcessingParameterFile('csv', 'Input csv', extension='csv'))
 self.addParameter(QgsProcessingParameterVectorLayer('input', 'Input', types=[QgsProcessing.TypeVectorAnyGeometry], defaultValue=None))
 self.addParameter(QgsProcessingParameterExtent('extent', 'Extent', defaultValue=None))
 self.addParameter(QgsProcessingParameterRasterDestination('ReclassifiedRaster', 'Reclassified raster', createByDefault=True, defaultValue=None))
 
 def processAlgorithm(self, parameters, context, model_feedback):
 # Use a multi-step feedback, so that individual child algorithm progress reports are adjusted for the
 # overall progress through the model
 feedback = QgsProcessingMultiStepFeedback(3, model_feedback)
 results = {}
 outputs = {}
 source = self.parameterAsVectorLayer(parameters, 'input', context)
 csv = self.parameterAsFile(parameters, 'csv', context)
 
 df = pd.read_csv(csv)
 
 for i in range(0, df.shape[0]):
 if source.name() == df.iloc[i][1]:
 a = df.iloc[i][5]
 b = df.iloc[i][6]
 c = df.iloc[i][7]
 else:
 pass
 
 # Rasterize (vector to raster)
 alg_params = {
 'BURN': 1,
 'DATA_TYPE': 5, # Float32
 'EXTENT': parameters['extent'],
 'EXTRA': '',
 'FIELD': '',
 'HEIGHT': 50,
 'INIT': None,
 'INPUT': parameters['input'],
 'INVERT': False,
 'NODATA': 0,
 'OPTIONS': '',
 'UNITS': 1, # Georeferenced units
 'USE_Z': False,
 'WIDTH': 50,
 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
 }
 outputs['RasterizeVectorToRaster'] = processing.run('gdal:rasterize', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
 feedback.setCurrentStep(1)
 if feedback.isCanceled():
 return {}
 # PM
 alg_params = {
 'BAND': 1,
 'DATA_TYPE': 5, # Float32
 'EXTRA': '',
 'INPUT': outputs['RasterizeVectorToRaster']['OUTPUT'],
 'MAX_DISTANCE': None,
 'NODATA': 0,
 'OPTIONS': '',
 'REPLACE': None,
 'UNITS': 0, # Georeferenced coordinates
 'VALUES': '',
 'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
 }
 outputs['Pm'] = processing.run('gdal:proximity', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
 feedback.setCurrentStep(2)
 if feedback.isCanceled():
 return {}
 
 # Reclassify by table
 alg_params = {
 'DATA_TYPE': 5, # Float32
 'INPUT_RASTER': outputs['Pm']['OUTPUT'],
 'NODATA_FOR_MISSING': False,
 'NO_DATA': -9999,
 'RANGE_BOUNDARIES': 0, # min < value <= max
 'RASTER_BAND': 1,
 'TABLE': ['0','0', f'{a}' ,'0','10000', f'{b}' ,'10000','', f'{c}'],
 'OUTPUT': parameters['ReclassifiedRaster']
 }
 
 outputs['ReclassifyByTable'] = processing.run('native:reclassifybytable', alg_params, context=context, feedback=feedback, is_child_algorithm=True)
 results['ReclassifiedRaster'] = outputs['ReclassifyByTable']['OUTPUT']
 
 if context.willLoadLayerOnCompletion(results['ReclassifiedRaster']):
 context.layerToLoadOnCompletionDetails(results['ReclassifiedRaster']).setPostProcessor(MyLayerPostProcessor.create(source.name()))
 return results
 def name(self):
 return 'Site search model'
 def displayName(self):
 return 'Site search model'
 def group(self):
 return 'Site search'
 def groupId(self):
 return 'Site search'
 def createInstance(self):
 return SiteSearchModel()
 
class MyLayerPostProcessor(QgsProcessingLayerPostProcessorInterface):
 instance = None
 layer_name = None
 def postProcessLayer(self, layer, context, feedback):
 if not isinstance(layer, QgsRasterLayer):
 return
 # If output is a temporary layer, set layer name from input vector
 if layer.name() == 'Reclassified raster':
 layer.setName(MyLayerPostProcessor.layer_name)
 # You could load a saved style or whatever...
 
 # Hack to work around sip bug!
 @staticmethod
 def create(lyr_name) -> 'MyLayerPostProcessor':
 """
 Returns a new instance of the post processor, keeping a reference to the sip
 wrapper so that sip doesn't get confused with the Python subclass and call
 the base wrapper implementation instead... ahhh sip, you wonderful piece of sip
 """
 MyLayerPostProcessor.layer_name = lyr_name
 MyLayerPostProcessor.instance = MyLayerPostProcessor()
 return MyLayerPostProcessor.instance
answered Aug 31, 2022 at 6:57
11
  • thanks so much for taking your time. I was literally lost in this. I have added your piece of code, but it gives me an error that 'a' is not defined. Can you please have a look at my code and kindly give me a help of what might be wrong ? ('a' is supposed to be the output of my function defined which is used in my raster reclassification.) I will put my code in below. Commented Sep 1, 2022 at 10:31
  • Ben, I have edited my first post to include the script. Your help would be much appreciated. Hope you have a lovely flight btw :). Commented Sep 1, 2022 at 11:02
  • Hi Ben, I think I really need to take a course for PyQGIS!! :) . Thanks for the revision, I have tried it and it gives me an error of ''Invalid output value''. Just wondering where the 'source' is defined in the script as 'parameterAsVectorLayer' ~ source = self.parameterAsVectorLayer(parameters, 'input', context), shouldn't this be defined as 'parameterAsSource' ? This seems to make more sense maybe? Even though I am not sure how to define it. I have seen this here: qgis.org/pyqgis/3.2/core/Processing/… Commented Sep 2, 2022 at 9:37
  • I guess the problem is that source.name() is not returning the name of the vector layer. And the bad thing is that you are somehow in the dark in this environment, while on Jupyter you can check what each code is doing simply. Commented Sep 2, 2022 at 9:48
  • @Soheil, no- self.parameterAsSource would be correct if the input was a QgsProcessingParameterFeatureSource, but since your input is a QgsProcessingParameterVectorLayer, self.parameterAsVectorLayer is correct. The error is coming from elsewhere. Would it be possible for you to share your input files (the csv and a vector layer)? I could probably fix the problem fairly quickly if I had test data. Commented Sep 2, 2022 at 10:26

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.