5. Rasterlagen gebruiken
Hint
De codesnippers op deze pagina hebben de volgende import nodig als u buiten de console van PyQGIS bent:
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. Details laag
Een rasterlaag bestaat uit één of meer rasterbanden — verwezen als een enkelbands en een multibands raster. Een band vertegenwoordigt een matrix van waarden. Een kleurenafbeelding (bijv. luchtfoto) is een raster bestaande uit rode, blauwe en groene banden. Rasters met één enkele band vertegenwoordigen meestal ofwel doorlopende variabelen (bijv. hoogte) of afzonderlijke variabelen (bijv. landgebruik). In sommige gevallen heeft een rasterlaag een palet en verwijzen waarden in het raster naar de kleuren die zijn opgeslagen in het palet:
De volgende code gaat er van uit dat rlayer
een object QgsRasterLayer
is.
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. Renderer
Wanneer een raster wordt geladen krijgt het een standaard renderer om te tekenen, gebaseerd op zijn type. Die kan worden gewijzigd, ofwel in de eigenschappen van de laag of programmatisch.
De huidige renderer bevragen:
print(rlayer.renderer())
<qgis._core.QgsSingleBandGrayRenderer object at 0x7f471c1da8a0>
print(rlayer.renderer().type())
singlebandgray
Gebruik de methode setRenderer()
van QgsRasterLayer
om een renderer in te stellen. Er zijn verscheidene klassen voor renderer beschikbaar (afgeleid van QgsRasterRenderer
):
Enkelbands rasterlagen kunnen worden getekend ofwel in grijze kleuren (lage waarden = zwart, hoge waarden = wit) of met een algoritme voor pseudokleur dat kleuren toewijst aan de waarden. Enkelbands rasters met een palet kunnen ook worden getekend met het palet. Multiband-lagen worden gewoonlijk getekend door de banden in kaart te brengen als RGB-kleuren. Een andere mogelijkheid is om slechts één band voor het tekenen te gebruiken.
5.2.1. Enkelbands rasters
Laten we zeggen dat we een enkelbands rasterlaag willen renderen met kleuren die variëren van groen naar geel (overeenkomende met pixelwaarden van 0 tot en met 255). In de eerste stap zullen we een object QgsRasterShader
voorbereiden en de functie shader daarvan configureren:
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)
De shader plaats de kleuren op de kaart zoals ze zijn gespecificeerd door zijn kleurenkaart. De kleurenkaart wordt verschaft als een lijst met pixelwaarden en geassocieerde kleuren. Er zijn drie modi voor interpolatie:
linear (
Interpolated
): de kleur wordt lineair geïnterpoleerd uit de items van de kleurenkaart boven en onder de pixelwaardediscrete (
Discrete
): de kleur wordt genomen uit het dichtstbijzijnde item voor de kleurenkaart met gelijke of hogere waardeexact (
Exact
): de kleur wordt niet geïnterpoleerd, alleen pixels met waarden gelijk aan die van de kleurenkaart zullen worden getekend
In de tweede stap zullen we deze shader associeren met de rasterlaag:
renderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1, shader)
rlayer.setRenderer(renderer)
Het getal 1
in de code hierboven is het nummer van de band (rasterbanden worden geïndexeerd vanaf één).
Tenslotte moeten we de methode triggerRepaint()
gebruiken om de resultaten te kunnen zien:
rlayer.triggerRepaint()
5.2.2. Multiband rasters
Standaard brengt QGIS de eerste drie banden naar rood, groen en blauw om een kleurenafbeelding te maken (dit is de tekenstijl MultiBandColor
). In sommig gevallen zou u deze instelling willen overschrijven. De volgende code verwisselt de rode band (1) en groene band (2):
rlayer_multi = QgsProject.instance().mapLayersByName('multiband')[0]
rlayer_multi.renderer().setGreenBand(1)
rlayer_multi.renderer().setRedBand(2)
In het geval dat slechts één band nodig is voor de visualisatie van het raster, kan het tekenen van een enkele band worden gekozen, ofwel grijswaarden of pseudokleur.
We moeten de methode triggerRepaint()
gebruiken om de kaart bij te werken en de resultaten te zien:
rlayer_multi.triggerRepaint()
5.3. Waarden bevragen
Rasterwaarden kunnen worden bevraagd met de methode sample()
van de klasse QgsRasterDataProvider
. U dient een QgsPointXY
te specificeren en het bandnummer van de rasterlaag die u wilt bevragen. De methode geeft een tuple terug met de waarde en True
of False
, afhankelijk van de resultaten:
val, res = rlayer.dataProvider().sample(QgsPointXY(20.50, -34), 1)
Een andere methode om rasterwaarden te bevragen is met de methode identify()
die een object QgsRasterIdentifyResult
teruggeeft.
ident = rlayer.dataProvider().identify(QgsPointXY(20.5, -34), QgsRaster.IdentifyFormatValue)
if ident.isValid():
print(ident.results())
{1: 323.0}
In dit geval geeft de methode results()
een woordenboek terug, met indices van banden als sleutels, en bandwaarden als waarden. Bijvoorbeeld iets als {1: 323.0}
5.4. Bewerken van rastergegevens
U kunt een rasterlaag maken met de klasse QgsRasterBlock
. Bijvoorbeeld om een rasterblok van 2x2 met één byte per pixel te maken:
block = QgsRasterBlock(Qgis.Byte, 2, 2)
block.setData(b'\xaa\xbb\xcc\xdd')
Rasterpixels kunnen worden overschreven dankzij de methode writeBlock()
. Om bestaande rastergegevens te overschrijven op positie 0,0 van het 2x2-blok:
provider = rlayer.dataProvider()
provider.setEditable(True)
provider.writeBlock(block, 1, 0, 0)
provider.setEditable(False)