Important

La traduction est le fruit d’un effort communautaire auquel vous pouvez vous joindre. Cette page est actuellement traduite à 100.00%.

5. Utiliser des couches raster

Indication

Les extraits de code sur cette page nécessitent les importations suivantes si vous êtes en dehors de la console 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. 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())
RasterLayerType.GrayOrUndefined
 # 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 :

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)

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 apparie les trois premières bandes au rouge, vert et bleu pour créer une image en couleurs( c’est le rendu de style MultiBandColor). Dans certaines situations, vous pourriez vouloir les personnaliser. Le code ci-après interchange les bandes rouge (1) et vertes (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}

5.4. Édition de données rasters

Vous pouvez créer une couche raster à l’aide la classe QgsRasterBlock. Par exemple, pour créer un bloc de raster 2x2 d’un bit par pixel :

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

Les pixels de raster peuvent être modifiés à l’aide la méthode writeBlock(). Pour modifier un raster existant, en sa position 0,0 à l’aide d’un bloc 2x2 :

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