3

I have made a function in Python Editor in QGIS, which (among others) performs a raster calculation.

I want to use my function to loop through multiple rasters. However, I run into a memory issue when doing so.

I have found the sinner to be the raster calculator, where the memory is not cleared after processing the raster calculation (calc.processCalculation()). I have tried various solutions including; loading and removing the resulting layer with removeMapLayer, saving the output to a file (instead of using the memory) and using del combined with gc.collect(). But the memory is still not cleared, which ultimately causes the memory to fill up when running the function several times.

Does anybody know how to free the memory after running the raster calculator in PyQGIS?

I have tested the code using QGIS 3.24.4, 3.28.2, and 3.22.12. The relevant part of my code looks like this, where Rasterfile1 and 2 are inputs to the function (full paths to raster files):

lyr1 = QgsRasterLayer(Rasterfile1)
lyr2 = QgsRasterLayer(Rasterfile2)
entries = []
ras = QgsRasterCalculatorEntry()
ras.ref = 'ras@1' 
ras.raster = lyr1
ras.bandNumber = 1
entries.append(ras)
ras = QgsRasterCalculatorEntry()
ras.ref = 'ras@2'
ras.raster = lyr2
ras.bandNumber = 1
entries.append(ras)
  
calc = QgsRasterCalculator('if(ras@1 - ras@2>0,ras@1 - ras@2,0)', "memory", 'GTiff', lyr2.extent(), lyr2.width(), lyr2.height(), entries) 
calc.processCalculation()

result=iface.addRasterLayer("memory",'resultingRaster')
4
  • 1
    What exactly did you del? Commented Jan 7, 2023 at 11:16
  • 1
    All of them; lyr1, lyr2, entries, ras, calc and result
    – KariDren
    Commented Jan 9, 2023 at 12:54
  • a) "memory" does not actually use the RAM to store the image but will write a file to your working directory. Are you sure that this is not the issue of growing memory, e.g. if your directory is a ramdisk? b) Does memory usage grow if you never add the result to your project (no iface.addRasterLayer())? Commented Jan 29, 2023 at 17:22
  • The memory keeps growing even if i don't load the layer, yes :)
    – KariDren
    Commented Sep 4, 2023 at 10:10

1 Answer 1

0

I've finally found a solution to my problem - instead of using QgsRasterCalculator I used the processing algoritm 'qgis:rastercalculator'.

Also, instead of using "memory" as destination I used 'TEMPORARY_OUTPUT'.

The code is now way faster and the memory is released.

#Loading the layers and setting CRS to make sure the calculation can be performed. 

lyr1 = QgsRasterLayer(Rasterfile1)
lyr1.setCrs(QgsCoordinateReferenceSystem('EPSG:25832'))
lyr2 = QgsRasterLayer(Rasterfile2)
lyr2.setCrs(QgsCoordinateReferenceSystem('EPSG:25832'))

#Adding layers to project (apparently they must be in the project for the calculation to work).

QgsProject.instance().addMapLayer(lyr1)
QgsProject.instance().addMapLayer(lyr2) 

Result=processing.run("qgis:rastercalculator", {'EXPRESSION':'max("BandNameLyr1@1"-"BandNameLyr2@1",0)','LAYERS':[lyr1,lyr2],'CELLSIZE':0.4,'EXTENT':lyr1.extent()0,'OUTPUT':'TEMPORARY_OUTPUT'}) #replace BandNameLyr1 and 2 with the actual bandnames.

ResultRaster = QgsRasterLayer(Result['OUTPUT'],'ResultRaster')
QgsProject.instance().addMapLayer(ResultRaster)

#remove layers used for calculation from the project
QgsProject.instance().removeMapLayers([lyr1.id()])
QgsProject.instance().removeMapLayers([lyr2.id()]) 

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.