2

Lets say I have two functions:

class AnalyseDTM(): def __init__(self): self.DTM = ('C:/Users/EH/QGis/Kvit_Tiny.tif') self.CreatePolygons() self.test() def CreatePolygons(self): translateFeatures = processing.runAndLoadResults("gdal:translate", { 'INPUT':self.DTM, 'TARGET_CRS':QgsCoordinateReferenceSystem('EPSG:5110'), 'NODATA':0, 'COPY_SUBDATASETS':False, 'OPTIONS':'', 'EXTRA':'', 'DATA_TYPE':0, 'OUTPUT': 'TEMPORARY_OUTPUT'}) return !HERE! RemoveSub0values = processing.runAndLoadResults("qgis:rastercalculator", { 'EXPRESSION':'((\"OUTPUT@1\">0)*\"OUTPUT@1\") / ((\"OUTPUT@1\">0)*1 + (\"OUTPUT@1\"<=0)*0)', 'LAYERS': translateFeatures['OUTPUT'], 'CELLSIZE':None, 'EXTENT':None, 'CRS':QgsCoordinateReferenceSystem('EPSG:32633'), 'OUTPUT': 'TEMPORARY_OUTPUT' }) 

I've removed about 20 other processing functions as the above should hopefully explains what I'm looking for. So you see I have a def CreatePolygons, which currently has two processing. functions in it. This works fine, however I'm wondering if where I have written !HERE! I can separate the two functions. For example I could call it def test(self):

Therefore, I'm wondering if I can pass the 'OUTPUT' from translateFeatures and have it as the input for RemoveSub0values even when they are in separate def 's. I know that if I save it to file and have it in the __init__ then yes, I can, as this is part of a large model I don't want to save multiple outputs to file every time.

I have a fully working class, but its extremely slow, and I therefore wanted to test if grouping processing algorithms would speed this up, but I therefore need to be able to pass temporary outputs between functions.

2
  • Can you provide more context? Can you show the full class definition (but only including the relevant methods, if it's large)? Commented Mar 25, 2020 at 17:01
  • @Tom I've updated the Q, hopefully easier to see what im looking for Commented Mar 25, 2020 at 17:25

2 Answers 2

3

You need a class like this: (Follow the highlighted numbers)

class AnalyseDTM(): def __init__(self): self.DTM = ('C:/Users/EH/QGis/Kvit_Tiny.tif') output_lyr = self.CreatePolygons() ### (1) ### self.test(output_lyr) ### (2) ### def CreatePolygons(self): # only 'run' method gives you the reference of the output memory layer # use 'run' instead od 'runAndLoadResults' here. skipped some parameters translateFeatures = processing.run("gdal:translate", {'INPUT':self.DTM, ....., 'OUTPUT': 'TEMPORARY_OUTPUT'}) output = translateFeatures["OUTPUT"] # If adding the output to project is required, use the next line # QgsProject.instance().addMapLayer(output) return output ### (3) ### def test(self, in_lyr): ### (4) ### ### (5) ### expression = '((\"{0}@1\">0)*\"{0}@1\") / ((\"{0}@1\">0)*1 + (\"{0}@1\"<=0)*0)'.format(in_lyr.name()) processing.runAndLoadResults("qgis:rastercalculator", {'EXPRESSION': expression, ### (6) ### 'LAYERS': in_lyr, ### (7) ### 'CELLSIZE':None, 'EXTENT':None, 'CRS':QgsCoordinateReferenceSystem('EPSG:32633'), 'OUTPUT': 'TEMPORARY_OUTPUT' }) 
1
  • This is exactly what I had tried, I had just forgotten to put the in_lyr in my def test()! Works now, thanks. Commented Mar 26, 2020 at 7:30
1

If you try to print the content of translatefeatures['OUTPUT'], you'll see that it is a string. That string is a unique id of the layer created in the processing.

To work further on, you need to get hold of the layer.

 layer=QgsProject.instance().mapLayer(translatefeatures['OUTPUT']) 

Then you can set up your next processing step using that layer.

You can see it in a bit more context here: https://github.com/sickel/altitudecorrector/blob/d5565/altitudecorrector.py#L314

(Funfact, but probably not useful here, if you go to Layer properties -> Variables, you'll find that id under Layer -> layer_id)

Hope this helps.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.