5. Usare Layer Raster
Suggerimento
I frammenti di codice di questa pagina necessitano delle seguenti importazioni se se fuori dalla 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. Dettagli del raster
Un layer raster è costituito da una o più bande raster, denominate raster a banda singola e raster multibanda. Una banda rappresenta una matrice di valori. Un’immagine a colori (ad esempio una foto aerea) è un raster composto da bande rosse, blu e verdi. I raster a banda singola rappresentano tipicamente variabili continue (ad esempio, l’altitudine) o discrete (ad esempio, l’uso del suolo). In alcuni casi, un layer raster viene fornito con una tavolozza e i valori raster si riferiscono ai colori memorizzati nella tavolozza.
Il codice seguente presuppone che rlayer
sia un oggetto 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. Visualizzatore
Quando un layer raster viene caricato, prende una visualizzazione predefinita in base al suo tipo. Può essere modificato nelle proprietà del layer o a programma.
Per consultare il visualizzatore corrente:
print(rlayer.renderer())
<qgis._core.QgsSingleBandGrayRenderer object at 0x7f471c1da8a0>
print(rlayer.renderer().type())
singlebandgray
Per impostare una visualizzazione, utilizza il metodo setRenderer()
di QgsRasterLayer
. Esistono diverse classi di visualizzatori (derivate da QgsRasterRenderer
):
I layer raster a banda singola possono essere disegnati con colori grigi (valori bassi = nero, valori alti = bianco) o con un algoritmo pseudocolore che assegna i colori ai valori. Anche i raster a banda singola con tavolozza possono essere disegnati utilizzando la tavolozza. I layer multibanda sono in genere disegnati mappando le bande ai colori RGB. Un’altra possibilità è quella di utilizzare una sola banda per il disegno.
5.2.1. Raster a Banda Singola
Supponiamo di voler visualizzare un layer raster a banda singola con colori che vanno dal verde al giallo (corrispondenti a valori di pixel da 0 a 255). Nella prima fase prepareremo un oggetto QgsRasterShader
e configureremo la sua funzione 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)
Lo shader mappa i colori come specificato dalla sua mappa dei colori. La mappa dei colori viene fornita come un elenco di valori di pixel con i colori associati. Esistono tre modalità di interpolazione:
lineare (
Interpolated
): il colore è interpolato linearmente dalle registrazioni della mappa di colore sopra e sotto il valore del pixeldiscreto (
Discrete
): il colore viene preso dalla registrazione della mappa di colore più vicina con valore uguale o maggioreexact (
Exact
): il colore non viene interpolato, verranno disegnati solo i pixel con valori uguali alle registrazioni della mappa di colore.
Nel secondo passo assoceremo questo shader al layer raster:
renderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1, shader)
rlayer.setRenderer(renderer)
Il numero 1
nel codice precedente è il numero di banda (le bande raster sono indicizzate a partire da uno).
Infine dobbiamo usare il metodo triggerRepaint()
per vedere i risultati:
rlayer.triggerRepaint()
5.2.2. Raster Multi Banda
Per impostazione predefinita, QGIS mappa le prime tre bande in rosso, verde e blu per creare un’immagine a colori (questo è lo stile di disegno MultiBandColor
). In alcuni casi puoi sovrascrivere queste impostazioni. Il codice seguente scambia la banda rossa (1) con quella verde (2):
rlayer_multi = QgsProject.instance().mapLayersByName('multiband')[0]
rlayer_multi.renderer().setGreenBand(1)
rlayer_multi.renderer().setRedBand(2)
Nel caso in cui sia necessaria una sola banda per la visualizzazione del raster, puoi scegliere un disegno a banda singola, con livelli di grigio o pseudocolore.
Dobbiamo usare triggerRepaint()
per aggiornare la mappa e vedere il risultato:
rlayer_multi.triggerRepaint()
5.3. Valori dell’interrogazione
I valori raster possono essere interrogati utilizzando il metodo sample()
della classe QgsRasterDataProvider
. Devi specificare un QgsPointXY
e il numero di banda del layer raster che vuoi interrogare. Il metodo restituisce una tupla con il valore e True
o False
a seconda dei risultati:
val, res = rlayer.dataProvider().sample(QgsPointXY(20.50, -34), 1)
Un altro metodo per interrogare i valori raster è il metodo identify()
che restituisce un oggetto QgsRasterIdentifyResult
.
ident = rlayer.dataProvider().identify(QgsPointXY(20.5, -34), QgsRaster.IdentifyFormatValue)
if ident.isValid():
print(ident.results())
{1: 323.0}
In questo caso, il metodo results()
restituisce un dizionario, con gli indici di banda come chiavi e i valori di banda come valori. Per esempio, qualcosa come {1: 323.0}
5.4. Modificare dati raster
Puoi creare un layer raster usando la classe QgsRasterBlock
. Ad esempio, per creare un blocco raster 2x2 con un byte per pixel:
block = QgsRasterBlock(Qgis.Byte, 2, 2)
block.setData(b'\xaa\xbb\xcc\xdd')
I pixel raster possono essere sovrascritti grazie al metodo writeBlock()
. Per sovrascrivere i dati raster esistenti nella posizione 0,0 con un blocco 2x2:
provider = rlayer.dataProvider()
provider.setEditable(True)
provider.writeBlock(block, 1, 0, 0)
provider.setEditable(False)