6

How can I write a QGIS script for making a loop of raster calculator through a set of rasters? I know I can read multiple raster by applying:

lddLrs = qgis.utils.iface.legendInterface().layers()
for lyr in lddLrs:

And I want to apply an easy operation such as "Raster/Raster*Raster" and repeat it through multiple rasters and get the result with the same name of the input raster with a suffix.

Any Idea?

For using the script to make a new tool within the "processing Toolbox - Scripts - Create New Script" I made the following script but it doesn't work. Any idea to fix it?

##NoDATA Background=name 
##lyr=multiple raster
##OUT=output raster
import qgis
from qgis.analysis import QgsRasterCalculatorEntry, QgsRasterCalculator
# Get layer object
layer = processing.getObject(lyr)
lddLrs = qgis.utils.iface.legendInterface().layers()
for lyr in lddLrs:
 entries = [] 
 ras = QgsRasterCalculatorEntry()
 ras.ref = 'lyr@1'
 ras.raster = lyr
 ras.bandNumber = 1
 entries.append( ras ) 
 calc = QgsRasterCalculator( '("lyr@1" / "lyr@1") * "lyr@1"', +lyr.name() + "_suffix.tif", 'GTiff', lyr.extent(), lyr.width(), lyr.height(), entries )
 calc.processCalculation()

resulting tool

Joseph
76.7k8 gold badges173 silver badges286 bronze badges
asked May 13, 2016 at 7:21
2
  • Are you wanting to select individual rasters from the loaded rasters and run the script on those selected? Or do you want the script to apply to all loaded rasters? Commented May 17, 2016 at 11:16
  • Indeed, the usefulness of making a script by using the Processing Toolbox is the possibility of selecting some or all loaded raster through the tool Commented May 17, 2016 at 11:35

2 Answers 2

9

You could use something like the following:

import processing
lddLrs = qgis.utils.iface.legendInterface().layers()
path = "path/to/results//"
for lyr in lddLrs:
 processing.runalg("saga:rastercalculator", lyr, None, "(a/a)*a", True, 7, path + lyr.name() + "_suffix.tif")

EDIT :

If you want to use the QgsRasterCalculator, you could try using the following (based on this post):

from qgis.analysis import QgsRasterCalculatorEntry, QgsRasterCalculator
lddLrs = qgis.utils.iface.legendInterface().layers()
path = "path/to/results"
for lyr in lddLrs:
 entries = []
 ras = QgsRasterCalculatorEntry()
 ras.ref = 'ras@1'
 ras.raster = lyr
 ras.bandNumber = 1
 entries.append( ras )
 calc = QgsRasterCalculator( '(ras@1 / ras@1) * ras@1', path + lyr.name() + "_suffix.tif", 'GTiff', lyr.extent(), lyr.width(), lyr.height(), entries )
 calc.processCalculation()

UPDATE:

You can use the following code in a script which allows you to select individual rasters and run the calculator on them. I've changed the output to a folder so that multiple (or single) rasters can be output to the same directory but you can change this:

##NoDATA Background=name
##Raster=multiple raster
##OUT=folder
import glob, qgis
from PyQt4.QtCore import QFileInfo
from qgis.analysis import QgsRasterCalculatorEntry, QgsRasterCalculator
from qgis.core import QgsMapLayerRegistry, QgsRasterLayer
# Split rasters
layers = Raster.split(';')
output_path = OUT + "/"
suffix = "_suffix.tif"
for ras in layers:
 # Get layer object
 lyr = processing.getObjectFromUri(ras)
 entries = [] 
 ras = QgsRasterCalculatorEntry()
 ras.ref = 'lyr@1'
 ras.raster = lyr
 ras.bandNumber = 1
 entries.append( ras ) 
 calc = QgsRasterCalculator( '(lyr@1 / lyr@1) * lyr@1', output_path + lyr.name() + suffix, 'GTiff', lyr.extent(), lyr.width(), lyr.height(), entries )
 calc.processCalculation()
for results in glob.glob(output_path + "*" + suffix): 
 fileInfo = QFileInfo(results)
 path = fileInfo.filePath()
 baseName = fileInfo.baseName()
 layer = QgsRasterLayer(path, baseName)
 QgsMapLayerRegistry.instance().addMapLayer(layer)
answered May 13, 2016 at 10:55
15
  • Actually I need it to get image background as NoDATA instead of Zero Commented May 13, 2016 at 15:51
  • Is there a way to make it without using SAGA, but with the QGIS Raster Calculator? Commented May 13, 2016 at 15:53
  • I mean the QgsRasterCalculator function Commented May 13, 2016 at 15:54
  • @Nico_77 - Updated my post =) Commented May 16, 2016 at 9:24
  • 1
    The UPDATE works perfectly. Results are saved and loaded into the workspace. Commented May 17, 2016 at 15:09
3

The solution provided by @Joseph needs some adjustments to work in QGIS 3

from qgis.analysis import QgsRasterCalculatorEntry, QgsRasterCalculator
from qgis.core import QgsProject
lddLrs = [tree_layer.layer() for tree_layer in QgsProject.instance().layerTreeRoot().findLayers()]
path = "path/to/output"
for lyr in lddLrs:
 entries = []
 ras = QgsRasterCalculatorEntry()
 ras.ref = 'ras@1'
 ras.raster = lyr
 ras.bandNumber = 1
 entries.append( ras )
 calc = QgsRasterCalculator( '(ras@1 / ras@1) * ras@1', path + lyr.name() + "_suffix.tif", 'GTiff', lyr.extent(), lyr.width(), lyr.height(), entries )
 calc.processCalculation()
answered Nov 12, 2019 at 14:31

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.