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()
-
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?Joseph– Joseph2016年05月17日 11:16:36 +00:00Commented 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 toolNico_77– Nico_772016年05月17日 11:35:21 +00:00Commented May 17, 2016 at 11:35
2 Answers 2
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)
-
Actually I need it to get image background as NoDATA instead of ZeroNico_77– Nico_772016年05月13日 15:51:35 +00:00Commented May 13, 2016 at 15:51
-
Is there a way to make it without using SAGA, but with the QGIS Raster Calculator?Nico_77– Nico_772016年05月13日 15:53:43 +00:00Commented May 13, 2016 at 15:53
-
I mean the QgsRasterCalculator functionNico_77– Nico_772016年05月13日 15:54:30 +00:00Commented May 13, 2016 at 15:54
-
@Nico_77 - Updated my post =)Joseph– Joseph2016年05月16日 09:24:58 +00:00Commented May 16, 2016 at 9:24
-
1The UPDATE works perfectly. Results are saved and loaded into the workspace.Nico_77– Nico_772016年05月17日 15:09:03 +00:00Commented May 17, 2016 at 15:09
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()