Thursday, 9 November 2017

Saving Multiple Raster with PyQGIS?


I have hundreds of raster files of some agricultural fields. I am using a PyQgis code that takes each raster from a specific folder then calculate the raster's minimum pixel values and maximum pixel values then assign a newly created color ramp to the raster. Here is the codes


from PyQt4.QtCore import *

from PyQt4.QtGui import *
import glob, os

# collect each raster file location
rast_path = r"E:\NDVI"
rasters = glob.glob(os.path.join(rast_path, "*.tif"))


for fileName in rasters:


#extraction of Information of the raster
fileInfo = QFileInfo(fileName)
baseName = fileInfo.baseName()
layer = QgsRasterLayer(fileName, baseName)
QgsMapLayerRegistry.instance().addMapLayer(layer)

#rendering details
renderer = layer.renderer()
provider = layer.dataProvider()
extent = layer.extent()


#max and min value calculation
stats = provider.bandStatistics(1, QgsRasterBandStats.All,extent, 0)
min= stats.minimumValue
max = stats.maximumValue
range = max - min
add = range/2
interval = min + add
valueList =[min, interval, max]


#defining color ramp and assining values
colDic = {'red':'#ff0000', 'yellow':'#ffff00','green':'#36fc09'}
lst = [ QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['red'])), QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['yellow'])), QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['green']))]

#applying color ramp
myRasterShader = QgsRasterShader()
myColorRamp = QgsColorRampShader()
myColorRamp.setColorRampItemList(lst)
myColorRamp.setColorRampType(QgsColorRampShader.INTERPOLATED)
myRasterShader.setRasterShaderFunction(myColorRamp)

myPseudoRenderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), layer.type(), myRasterShader)

#refreshing layers
layer.setRenderer(myPseudoRenderer)
layer.triggerRepaint()

The code automatically imports each raster, calculate max and min values, finally applying the color ramp I would like to have. The raster layers are now visiable on the display and present on the layer panels (as shown below).


enter image description here


I need to export or save the rasters with the exisiting color ramp and the exact same name (what it has now on the layer panel) to a directory ("E:\NDVI\save\"). Is there anyway to do that?


I have tried the following codes by placing inside the loop after the previous codes -



-----Continuation of previous Codes -----------
#refreshing layers
layer.setRenderer(myPseudoRenderer)
layer.triggerRepaint()
------------------new codes ------------------
pa_name, file_name = os.path.split(fileName)
save_folder = "E:/NDVI/save"
save_raster = os.path.join(save_folder, file_name)
width, height = layer.width(), layer.height()
crs = layer.crs().toWkt()


pipe = QgsRasterPipe()
pipe.set(provider.clone())
pipe.set(renderer.clone())
file_writer = QgsRasterFileWriter(save_raster)
file_writer.writeRaster(pipe, width, height, extent, layer.crs())

It is providing the following errors - enter image description here


Seems like I need different codes for saving the raster.



Answer




The following codes are working like a charm. The code was missing the first three lines where qgis.core, qgis.utils, and qgis.gui are imported


#these Codes were missing 
#missing code addation starts#

from qgis.core import *
from qgis.utils import *
from qgis.gui import *

#missing code addation ends#



from PyQt4.QtGui import *
from PyQt4.QtCore import *
import glob, os

#
rast_path = r"E:\temp\Batch 2\NDVI"
rasters = glob.glob(os.path.join(rast_path, "*.tif"))
save_path = r"E:\temp\Batch 2\NDVI\save"



for fileName in rasters:
#extraction of Information
fileInfo = QFileInfo(fileName)
baseName = fileInfo.baseName()
layer = QgsRasterLayer(fileName, baseName)
QgsMapLayerRegistry.instance().addMapLayer(layer)

#rendering details
renderer = layer.renderer()

provider = layer.dataProvider()
extent = layer.extent()

#max and min value
stats = provider.bandStatistics(1, QgsRasterBandStats.All,extent, 0)
min= stats.minimumValue
max = stats.maximumValue
range = max - min
add = range/2
interval = min + add

valueList =[min, interval, max]

#defining color ramp and assining values
colDic = {'red':'#ff0000', 'yellow':'#ffff00','green':'#36fc09'}
lst = [ QgsColorRampShader.ColorRampItem(valueList[0], QColor(colDic['red'])), QgsColorRampShader.ColorRampItem(valueList[1], QColor(colDic['yellow'])), QgsColorRampShader.ColorRampItem(valueList[2], QColor(colDic['green']))]

#applying color ramo
myRasterShader = QgsRasterShader()
myColorRamp = QgsColorRampShader()
myColorRamp.setColorRampItemList(lst)

myColorRamp.setColorRampType(QgsColorRampShader.INTERPOLATED)
myRasterShader.setRasterShaderFunction(myColorRamp)
myPseudoRenderer = QgsSingleBandPseudoColorRenderer(layer.dataProvider(), layer.type(), myRasterShader)

#refreshing layers
layer.setRenderer(myPseudoRenderer)
layer.triggerRepaint()

#saving files
extent = layer.extent()

width, height = layer.width(), layer.height()
renderer = layer.renderer()
provider=layer.dataProvider()
crs = layer.crs().toWkt()
pipe = QgsRasterPipe()
pipe.set(provider.clone())
pipe.set(renderer.clone())
pa_name, file_name = os.path.split(fileName)
save_raster = os.path.join(save_path, file_name)
p = os.path.join(save_path, str(i))

file_writer = QgsRasterFileWriter(p)
file_writer.writeRaster(pipe,
width,
height,
extent,
layer.crs())



pa_name, file_name = os.path.split(fileName)

save_raster = os.path.join(save_path, file_name)
width, height = layer.width(), layer.height()
crs = layer.crs().toWkt()

pipe = QgsRasterPipe()
pipe.set(provider.clone())
pipe.set(renderer.clone())
file_writer = QgsRasterFileWriter(save_raster)
file_writer.writeRaster(pipe, width, height, extent, layer.crs())

No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...