Les extraits de code sur cette page nécessitent les importations suivantes si vous êtes en dehors de la console pyqgis :

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

from qgis.PyQt.QtGui import (
    QColor,
)

5. Utiliser des couches raster

5.1. Détails d’une couche

Une couche raster est constituée d’une ou de plusieurs bandes rasters — appelées raster à bande unique et à bandes multiples. Une bande représente un raster de valeurs. Une image couleur (par exemple une photo aérienne) est un raster composé de bandes rouges, bleues et vertes. Les rasters à bande unique représentent généralement soit des variables continues (par exemple l’altitude), soit des variables discrètes (par exemple l’utilisation des terres). Dans certains cas, une couche raster est accompagnée d’une palette et les valeurs rasters font référence aux couleurs stockées dans la palette.

Le code suivant suppose que rlayer est un objet 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. Moteur de rendu

Lorsqu’une couche raster est chargée, elle obtient un rendu par défaut en fonction de son type. Il peut être modifié soit dans les propriétés de la couche, soit par programmation.

Pour interroger le moteur de rendu actuel :

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

Pour définir un moteur de rendu, utilisez la méthode setRenderer() de QgsRasterLayer. Il existe un certain nombre de classes de rendu (dérivées de la méthode QgsRasterRenderer) :

Les couches raster à bande unique peuvent être dessinées soit en gris (valeurs basses = noir, valeurs hautes = blanc), soit avec un algorithme de pseudo-couleurs qui attribue des couleurs aux valeurs. Les raster à bande unique avec une palette peuvent également être dessinées à l’aide de la palette. Les couches multibandes sont généralement dessinées en faisant correspondre les bandes à des couleurs RVB. Une autre possibilité est d’utiliser une seule bande pour le dessin .

5.2.1. Rasters mono-bande

Disons que nous voulons un rendu d’une seule bande de la couche raster avec des couleurs allant du vert au jaune (correspondant à des valeurs de pixels de 0 à 255). Dans un premier temps, nous allons préparer un objet QgsRasterShader et configurer sa fonction de shader :

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

Le shader cartographie les couleurs comme le précise sa carte de couleurs. La carte des couleurs est fournie sous la forme d’une liste de valeurs de pixels avec les couleurs associées. Il existe trois modes d’interpolation :

  • linéaire (Interpolated) : la couleur est interpolée linéairement à partir des entrées de la carte des couleurs au-dessus et au-dessous de la valeur du pixel

  • discrete (Discrete) : la couleur est tirée de l’entrée de carte de couleur la plus proche ayant une valeur égale ou supérieure

  • exact (Exact) : la couleur n’est pas interpolée, seuls les pixels dont la valeur est égale aux entrées de la carte de couleur seront dessinés

Dans la deuxième étape, nous associerons ce shader à la couche raster :

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

Le chiffre 1 dans le code ci-dessus est le numéro de la bande (les bandes rasters sont indexées à partir de 1).

Enfin, nous devons utiliser la méthode triggerRepaint() pour voir les résultats :

rlayer.triggerRepaint()

5.2.2. Rasters multi-bandes

Par défaut, QGIS mappe les trois premières bandes en rouge, vert et bleu pour créer une image en couleur (c’est le style de dessin MultiBandColor. Dans certains cas, vous pouvez vouloir passer outre ces paramètres. Le code suivant échange la bande rouge (1) et la bande verte (2) :

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

Dans le cas où une seule bande est nécessaire pour la visualisation du raster, le dessin d’une seule bande peut être choisi, soit en niveaux de gris, soit en pseudo-couleur.

Nous devons utiliser triggerRepaint() pour mettre à jour la carte et voir le résultat :

rlayer_multi.triggerRepaint()

5.3. Interrogation des données

Les valeurs raster peuvent être interrogées en utilisant la méthode sample() de la classe QgsRasterDataProvider. Vous devez spécifier une classe QgsPointXY et le numéro de bande de la couche raster que vous voulez interroger. La méthode retourne un tuple avec la valeur et True ou False selon les résultats :

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

Une autre méthode pour interroger les valeurs raster consiste à utiliser la méthode identify() qui renvoie un objet QgsRasterIdentifyResult.

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

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

Dans ce cas, la méthode results() renvoie un dictionnaire, avec les indices de bande comme clés, et les valeurs de bande comme valeurs. Par exemple, quelque chose comme {1 : 323.0}