1

I have several raster files (.tif) in a folder that have different resolution and extent but are all in the same study area.

Before merging them, I want to bring them to the same resolution (5 m) and extent. For this, I used the Raster Calculator inside of QGIS and manually defined Xmin, Xmax, Ymin and Ymax and the number of columns and rows. This solution worked fine and I could merge the resulting files.

I want to automate this processing with the Python Plugin, but so far I am not getting the correct results, because I struggling with defining the extent in the RasterCalculator. My code looks like this:

import os

pathin =  r'C:\Documents\Raster_files'
pathout = r'C:\Documents\Processed'
filelist = os.listdir(pathin)

llc = QgsPointXY(319660,4624088)# lower left corner
urc = QgsPointXY(396425,4742843)# upper right corner
aoi = QgsRectangle(llc,urc)

for f in filelist:
    lyr1 = QgsRasterLayer(f)
    output = os.path.join(pathout,'5m_'+f)
    entries = []
    ras = QgsRasterCalculatorEntry()
    ras.ref = 'ras@1'
    ras.raster = lyr1
    ras.bandNumber = 1
    entries.append(ras)
    calc = QgsRasterCalculator('ras@1', output, 'GTiff', aoi, 15353, 23751, entries)
    calc.processCalculation()

So far, he is creating new files like expected but they are in a completetly wrong location and have values from -inf to +inf (probably because he does not use the UTM crs of the raster files). Does anybode have suggestions?

After this part is working, I intend to include gdal merging of the resulting files with very high compression.

3
  • Thanks, but I don't see any possiblity of resampling or subsetting in gdal_translate? At least if I open it from the QGIS toolbox.
    – PDistl
    Commented Dec 7, 2021 at 10:34
  • If I understand the documentation correctly (qgis.org/api/classQgsRasterCalculator.html), then I can pass another argument of the type "QgsCoordinateTransformContext". Can I somehow pass here the crs?
    – PDistl
    Commented Dec 7, 2021 at 10:50
  • As I said in my comments in your other question, the non-deprecated overloaded QgsRasterCalculator constructor qgis.org/api/… takes outputCrs and transformContext arguments, which should handle your output extent rectangle. But I would still suggest gdal.Translate as a better option for your use case.
    – Ben W
    Commented Dec 7, 2021 at 12:53

1 Answer 1

3

Since you are not actually performing any raster calculations, I would recommend using a more appropriate tool such as gdal_translate for this. You can call the command line utility as a library function in Python (Geo tips & tricks- GDAL and OGR utilities as library functions).

Here is an example of how to use it on your raster directory to clip your rasters to your study area and adjust the resolution to 5m with a bilinear re-sampling method (You can use a different method or if you don't want to resample, simply omit that argument). *just double check that the upper-left and lower-right corner coordinates are correct.

from osgeo import gdal
import os

in_folder = 'C:\\Documents\\Raster_files'
out_folder = 'C:\\Documents\\Processed'

ulx = 319660
uly = 4742843
lrx = 396425
lry = 4624088

testdir = os.scandir(in_folder)

for file in testdir:
    if file.name.endswith('.tif'):
        name = f'{os.path.splitext(file.name)[0]}_5m.tif'
        input = file.path
        output = os.path.join(out_folder, name)
        ds = gdal.Open(input)
        ds = gdal.Translate(output, ds, projWin = [ulx, uly, lrx, lry], xRes = 5, yRes = -5, resampleAlg = 'bilinear')
        ds = None

You can see more about translateOptions here.

6
  • BTW nice profile photo! But honestly saying I liked the previous one, which was less serious and more authentic :D
    – Taras
    Commented Dec 7, 2021 at 12:58
  • 1
    Thanks @Taras. The old pic was taken on a field trip nearly 5 years ago. I liked it too but with the hat & sunglasses I thought it looked very 'covered up'. I felt it was time for a change but maybe I can find one that captures both sides.
    – Ben W
    Commented Dec 7, 2021 at 13:23
  • 1
    Thanks, I run your script now from an external editor. There is a small mistake, it should be "output = os.path.join(out_folder, name)".
    – PDistl
    Commented Dec 7, 2021 at 13:54
  • 1
    @PDistl, yes- you are right, good catch! I have corrected my answer. I hope it's working ok now and fits your needs. Cheers.
    – Ben W
    Commented Dec 7, 2021 at 14:26
  • 1
    @PDistl, great. Just for clarity, this will also work fine in the Python console inside QGIS. Undoubtedly there are several ways to accomplish this e.g. the 'Clip raster by extent' processing algorithm calls gdal_translate, so that's another option if you want to chain processing scripts together with processing.run()
    – Ben W
    Commented Dec 8, 2021 at 1:47

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.