import math import glob import os import multiprocessing import subprocess from osgeo import gdal from osgeo.gdalconst import GA_Update from time import sleep from qgis.core import QgsProject from pathlib import Path import concurrent.futures import shutil from itertools import repeat CATEGORY = 'SetNoData' source_directory = "C:/Users/david/Documents/Minecraft/Source" #enter directory with your tiff files thread_count = None #Set to the number of threads you want to use. Preferably don't use all threads at once. Leave at at None to use all threads nodata = 0 #Set the value of nodata def processFiles(task, filesData): result=len(filesData) QgsMessageLog.logMessage( 'Started processing {count} files'.format(count=len(filesData)), CATEGORY, Qgis.Info) cpu_count = 1 if thread_count is None: cpu_count = multiprocessing.cpu_count() else: cpu_count = thread_count ex = concurrent.futures.ThreadPoolExecutor(max_workers=cpu_count) f = ex.map(processFile, repeat(nodata), filesData) p = 0 for res in f: QgsMessageLog.logMessage( 'Processed file {name}'.format(name=res), CATEGORY, Qgis.Info) p += 1 task.setProgress(int((p * 100) / len(filesData))) sleep(0.05) return result def filesProccesed(task, result=None): if result is not None: QgsMessageLog.logMessage('Done setting nodata value for {files_count} files'.format(files_count=result),CATEGORY, Qgis.Info) def processFile(no_data, file_data): ds = gdal.Open(file_data[0], GA_Update) sleep(0.01) for i in range(1, ds.RasterCount + 1): rb = ds.GetRasterBand(i) rb.SetNoDataValue(no_data) rb = None ds = None sleep(0.01) return file_data[1] files = [] #Change the asc or xyz extension, to whatever extension your raster data source uses, but first check if gdal can open it. for raw_file in glob.iglob(source_directory + '**/**', recursive=True): if (raw_file.endswith(".tif") or raw_file.endswith(".tiff") or raw_file.endswith(".img") or raw_file.endswith(".IMG")): raw_file = raw_file.replace("\\","/") fileinfo = QFileInfo(raw_file) filename = fileinfo.completeBaseName() files.append([raw_file, filename]) QgsMessageLog.logMessage('Found {count} files'.format(count=len(files)),CATEGORY, Qgis.Info) process_task = QgsTask.fromFunction('Setting nodata value', processFiles, on_finished=filesProccesed, filesData=files) QgsApplication.taskManager().addTask(process_task)