5. Usar las capas ráster

Consejo

Los fragmentos de código en esta página necesitan las siguientes adiciones si está fuera de la consola de pyqgis:

 1from qgis.core import (
 2    QgsRasterLayer,
 3    QgsProject,
 4    QgsPointXY,
 5    QgsRaster,
 6    QgsRasterShader,
 7    QgsColorRampShader,
 8    QgsSingleBandPseudoColorRenderer,
 9    QgsSingleBandColorDataRenderer,
10    QgsSingleBandGrayRenderer,
11)
12
13from qgis.PyQt.QtGui import (
14    QColor,
15)

5.1. Detalles de la capa

Una capa ráster está compuesta por una o más bandas ráster — denominadas como raster monobanda o multibanda. Una banda representa una matriz de valores. Una imagen a color (p. ej. una fotografía aérea) es un ráster que está constituido por bandas roja, azul y verde. Los rásteres de banda única, representan generalmente variables continuas (p. ej. elevación) o variables discretas (p. ej. uso del suelo). En algunos casos, una capa ráster viene con una paleta y los valores ráster se refieren a los colores almacenados en la paleta.

El código a continuación, asume que rlayer es un objeto de QgsRasterLayer .

rlayer = QgsProject.instance().mapLayersByName('srtm')[0]
# get the resolution of the raster in layer unit
print(rlayer.width(), rlayer.height())
919 619
# get the extent of the layer as QgsRectangle
print(rlayer.extent())
<QgsRectangle: 20.06856808199999875 -34.27001076999999896, 20.83945284300000012 -33.75077500700000144>
# get the extent of the layer as Strings
print(rlayer.extent().toString())
20.0685680819999988,-34.2700107699999990 : 20.8394528430000001,-33.7507750070000014
# get the raster type: 0 = GrayOrUndefined (single band), 1 = Palette (single band), 2 = Multiband
print(rlayer.rasterType())
0
 # get the total band count of the raster
print(rlayer.bandCount())
1
# get the first band name of the raster
print(rlayer.bandName(1))
Band 1: Height
# get all the available metadata as a QgsLayerMetadata object
print(rlayer.metadata())
<qgis._core.QgsLayerMetadata object at 0x13711d558>

5.2. Renderizador

Cuando una capa ráster es cargada, recibe en base a su tipo, el valor del renderizador de forma predeterminada. Esto puede ser modificado tanto en las propiedades de capa o mediante programación.

Para consultar el actual renderizador:

print(rlayer.renderer())
<qgis._core.QgsSingleBandGrayRenderer object at 0x7f471c1da8a0>
print(rlayer.renderer().type())
singlebandgray

Para establecer un renderizador, use el método setRenderer() de QgsRasterLayer. Hay una serie de clases de renderizado (derivadas de QgsRasterRenderer):

Las capas ráster de banda única pueden ser dibujadas tanto en colores grises (valor menor = negro, valor alto = blanco) o con un algoritmo pseudocolor que asigna colores a los valores. Rásters de banda única con una paleta puedes ser dibujados usando la paleta. Las capas multibanda generalmente se dibujan asignando las bandas a colores RGB. Otra posibilidad es usar una sola banda para dibujar.

5.2.1. Rásters de una sola banda

Supongamos que queremos renderizar una capa ráster de una sola banda con colores que van del verde al amarillo (correspondiente a los valores de píxel de 0 a 255). En la primera etapa prepararemos un objeto QgsRasterShader y configuraremos su función shader:

1fcn = QgsColorRampShader()
2fcn.setColorRampType(QgsColorRampShader.Interpolated)
3lst = [ QgsColorRampShader.ColorRampItem(0, QColor(0,255,0)),
4      QgsColorRampShader.ColorRampItem(255, QColor(255,255,0)) ]
5fcn.setColorRampItemList(lst)
6shader = QgsRasterShader()
7shader.setRasterShaderFunction(fcn)

El sombreador asigna los colores según lo especificado por su mapa de colores. El mapa de colores es proveído como una lista de valores de pixeles con colores asociados. Hay tres modos de interpolación:

  • lineal (Interpolated): el color es linealmente interpolado desde las entradas en el mapa de colores, que están por encima y por debajo de el valor de pixel.

  • discreto (Discrete): el color es tomado desde la entrada más cercana con igual o mayor valor en el mapa de colores.

  • exacto (Exact): el color no es interpolado, solo los pixeles con un valor igual a las entradas del mapa de colores serán dibujados.

En el segundo paso asociaremos el sombreador con una capa ráster:

renderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1, shader)
rlayer.setRenderer(renderer)

El número 1 en el código anterior es el número de la banda (bandas ráster son indexadas de uno).

Finálmente tenemos que usar el método triggerRepaint() para ver los resultados:

rlayer.triggerRepaint()

5.2.2. Rásters multibanda

De forma predeterminada, QGIS asigna las tres primeras bandas a rojo, verde y azul para crear una imagen en color (este es el estilo de dibujo MultiBandColor). En algunos casos, es posible que desee anular esta configuración. El siguiente código intercambia la banda roja (1) y la banda verde (2):

rlayer_multi = QgsProject.instance().mapLayersByName('multiband')[0]
rlayer_multi.renderer().setGreenBand(1)
rlayer_multi.renderer().setRedBand(2)

En caso de que sea necesaria solo una banda para la visualización del ráster, se puede elegir el dibujo de una banda única, ya sea niveles grises o pseudocolor.

Tenemos que usar triggerRepaint() para actualizar el mapa y ver el resultado:

rlayer_multi.triggerRepaint()

5.3. Valores de consulta

Los valores rster ´pueden ser consultados usando el método sample() de la clase QgsRasterDataProvider . Tienes que especificar una QgsPointXY y el número de banda de la capa ráster que quiera consultar. El método devuelve una tupla con el valor y True o False dependiendo del resultado:

val, res = rlayer.dataProvider().sample(QgsPointXY(20.50, -34), 1)

Otro método para consultar valores ráster es usar el método identify() que devuelve un objeto QgsRasterIdentifyResult.

ident = rlayer.dataProvider().identify(QgsPointXY(20.5, -34), QgsRaster.IdentifyFormatValue)

if ident.isValid():
  print(ident.results())
{1: 323.0}

En este caso, el método results() devuelve un diccionario, con el índice de banda como clave, y valores de banda como valores. Por ejemplo, algo como {1: 323.0}

5.4. Edición de datos ráster

Puede crear una capa ráster utilizando la clase QgsRasterBlock. Por ejemplo, para crear un bloque ráster de 2x2 con un byte por píxel:

block = QgsRasterBlock(Qgis.Byte, 2, 2)
block.setData(b'\xaa\xbb\xcc\xdd')

Los píxeles de trama se pueden sobrescribir gracias al método writeBlock(). Para sobrescribir datos ráster existentes en la posición 0,0 por el bloque 2x2:

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