0

I want to use and re-use a raster layer to write pixel values with different zoom levels. But I cannot figure out how to update the pixel size accordingly with the data I write inside the layer. The layer has the same dimensions than the canvas in screen pixels and the extent of the image according to the image pixel size.

I start with a full-view of my image, with a scale defined by the w_out / w_in (w_out is the canvas width, w_in is the image width).

ds = gdal.OpenEx('daas:path/to/metadata', open_options=["PIXEL_ENCODING=RAW"])
band = ds.GetRasterBand(1)

scale = w_out / w_in
pixel_size = 1/scale

origin_x = 0
origin_y = 0
end_x = canvas_size.width()*pixel_size
end_y = canvas_size.height()*pixel_size

canvas_extent = QgsRectangle()
canvas_extent.setXMinimum(origin_x)
canvas_extent.setYMinimum(origin_y)
canvas_extent.setXMaximum(end_x)
canvas_extent.setYMaximum(end_y)
params = {
    'EXTENT': canvas_extent,
    'PIXEL_SIZE': pixel_size,
    'NUMBER': 0,
    'OUTPUT_TYPE': 2,
    'TARGET_CRS': crs,
    'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
}
r = processing.run('qgis:createconstantrasterlayer', params)['OUTPUT']
rlayer = QgsRasterLayer(r, 'temp', 'gdal')

array = band.ReadRaster(0,0, w_in, h_in, w_out, h_out)

block = QgsRasterBlock(Qgis.UInt16,w_out,h_out)
block.setData(array)

provider = rlayer.dataProvider()
provider.setEditable(True)
provider.writeBlock(block, 1, offset_x, offset_y)
provider.setEditable(False)

I add this layer to Qgis and it is displayed nicely.

Afterwards, I want to display a 1:1 image portion by replacing the layer content by a part of the image, something like :

w_out = canvas_size.width()
h_out = canvas_size.height()

canvas_extent = QgsRectangle()
canvas_extent.setXMinimum(0)
canvas_extent.setYMinimum(0)
canvas_extent.setXMaximum(w_out)
canvas_extent.setYMaximum(h_out)
rlayer.setExtent(canvas_extent)

array = band.ReadRaster(0, 0, w_out, h_out, w_out, h_out)
block = QgsRasterBlock(Qgis.UInt16,w_out,h_out)
block.setData(array)

provider = rlayer.dataProvider()
provider.setEditable(True)
provider.writeBlock(block, 1, 0, 0)
provider.setEditable(False)

rlayer.triggerRepaint()

But I don't see how to change the layer pixel size (or geotransform) and the image is display with the previously defined pixel size with is too large for a correct rendering.

How can I update the 'PIXEL_SIZE' option of qgis:createconstantrasterlayer used initilly to create the raster layer ? Or to change the layer geotransform ?

2
  • Why you want to do this? For better Performance?
    – fsg
    Commented Jun 27, 2023 at 16:11
  • Yes, exactly. Just loading the dataset is too slow for my application
    – vpa
    Commented Jun 29, 2023 at 21:23

1 Answer 1

0

For a better performance you can compute Pyramids for your Raster. That is exactly what you want. The same image in different resolutions.

For computing go to the Layer Properties and then Pyramids. Then you can select the resolutions you want and if the pyramids are stored internal or external. Better use external, because internal could destroy your data.

Alternative you could use the tool gdal:overviews, which you can use in PyQGIS if you want.

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.