A while ago, I asked for a method to assign new QgsRasterBlock objects to a QgsRasterDataProvider objects at Assign new QgsRasterBlock object to a QgsRasterDataProvider object. The reason was for using only PyQGIS methods to manipulate raster layers avoiding GDAL/OGR python module. Recently, I found out a potential solution, posted as an answer; however original provider is not preserved in original raster.
I found out that QgsRasterDataProvider missing methods in my first post were 'setEditable' and 'writeBlock'. I also found out, for avoiding QGIS crashing during each test, it is necessary to add as last line
provider = None.
Following simplified version of original code looks as follow:
layer = iface.activeLayer() provider = layer.dataProvider() extent = provider.extent() rows = layer.height() cols = layer.width() xsize = layer.rasterUnitsPerPixelX() ysize = layer.rasterUnitsPerPixelY() block = provider.block(1, extent, cols, rows) provider.setEditable(True) for i in range(rows): for j in range(cols): if block.value(i,j) == 4: block.setValue(i, j, 25) provider.writeBlock(block, 1) pipe = QgsRasterPipe() pipe.set(provider) rasterWriter = QgsRasterFileWriter("/home/zeito/pyqgis_data/test_write.tif") xSize = provider.xSize() ySize = provider.ySize() CRS = layer.crs() error = rasterWriter.writeRaster(pipe, xSize, ySize, provider.extent(), CRS) if error == QgsRasterFileWriter.NoError: print ("Raster was saved successfully!") else: print ("Raster was not saved!") provider = None
After running above code in Python Console of QGIS, with a copy of test_sample, this one looks identical to original; as it can be observed in following image:
However, Value Tool Plugin corroborates that it effectively changed:
When I load test_write resulting layer and test_sample_copy (from hard disk), both layers look as expected (corroborated again by Value Tool Plugin).
However, after erasing test_write and test_sample_copy and reloading both layers again, it was corroborated that test_sample_copy effectively and unexpectedly changed.
So, there is something wrong in the way I created the provider for resulting layer because modify unexpectedly the provider of original raster layer.
How can the provider of original raster layer be preserved when it is modified for another raster layer?