Viktigt

Översättning är en gemenskapsinsats du kan gå med i. Den här sidan är för närvarande översatt till 100.00%.

5. Använda Raster-lager

Råd

Kodsnuttarna på den här sidan behöver följande import om du befinner dig utanför pyqgis-konsolen:

 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. Detaljer om lagret

Ett rasterlager består av ett eller flera rasterband — kallas single band och multi band rasters. Ett band representerar en matris av värden. En färgbild (t.ex. ett flygfoto) är ett raster som består av röda, blå och gröna band. Enbandsraster representerar vanligtvis antingen kontinuerliga variabler (t.ex. höjd) eller diskreta variabler (t.ex. markanvändning). I vissa fall levereras ett rasterlager med en palett och rastervärdena hänvisar till de färger som finns lagrade i paletten.

Följande kod förutsätter att rlayer är ett QgsRasterLayer-objekt.

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. Renderare

När ett rasterlager laddas får det en standardrenderare baserad på dess typ. Den kan ändras antingen i skiktets egenskaper eller programmatiskt.

För att fråga efter den aktuella renderingen:

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

För att ställa in en rendering använder du metoden setRenderer() i QgsRasterLayer. Det finns ett antal renderingsklasser (härledda från QgsRasterRenderer):

Rasterlager med enstaka band kan ritas antingen i gråa färger (låga värden = svart, höga värden = vitt) eller med en pseudocolor-algoritm som tilldelar värdena färger. Enkelbandsraster med en palett kan också ritas med hjälp av paletten. Flerbandsskikt ritas vanligtvis genom att mappa banden till RGB-färger. En annan möjlighet är att bara använda ett band för ritning.

5.2.1. Raster för enstaka band

Låt oss säga att vi vill rendera ett rasterlager med ett enda band med färger som sträcker sig från grönt till gult (motsvarande pixelvärden från 0 till 255). I det första steget kommer vi att förbereda ett QgsRasterShader-objekt och konfigurera dess shader-funktion:

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)

Shadern mappar färgerna enligt vad som anges i dess färgkarta. Färgkartan tillhandahålls som en lista över pixelvärden med associerade färger. Det finns tre lägen för interpolering:

  • linjär (Interpolerad): färgen interpoleras linjärt från färgkartans poster över och under pixelvärdet

  • diskret (Discrete): färgen hämtas från den närmaste färgkartposten med samma eller högre värde

  • exakt (Exact): färgen interpoleras inte, endast pixlar med värden som är lika med färgkartans poster ritas

I det andra steget kommer vi att associera denna shader med rasterlagret:

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

Siffran 1 i koden ovan är bandnumret (rasterband indexeras från ett).

Slutligen måste vi använda metoden triggerRepaint() för att se resultatet:

rlayer.triggerRepaint()

5.2.2. Multi Band Rasters

Som standard mappar QGIS de tre första banden till rött, grönt och blått för att skapa en färgbild (detta är ritningsstilen MultiBandColor). I vissa fall kanske du vill åsidosätta dessa inställningar. Följande kod växlar mellan rött band (1) och grönt band (2):

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

Om endast ett band behövs för att visualisera rastret kan man välja att rita ett band, antingen i gråtoner eller pseudofärg.

Vi måste använda triggerRepaint() för att uppdatera kartan och se resultatet:

rlayer_multi.triggerRepaint()

5.3. Fråga värden

Rastervärden kan efterfrågas med hjälp av metoden sample() i klassen QgsRasterDataProvider. Du måste ange en QgsPointXY och bandnumret för det rasterlager som du vill fråga. Metoden returnerar en tupel med värdet och True eller False beroende på resultatet:

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

En annan metod för att fråga efter rastervärden är att använda metoden identify() som returnerar ett QgsRasterIdentifyResult-objekt.

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

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

I det här fallet returnerar metoden results() en ordbok med bandindex som nycklar och bandvärden som värden. Till exempel något i stil med {1: 323.0}

5.4. Redigering av rasterdata

Du kan skapa ett rasterlager med hjälp av klassen QgsRasterBlock. Så här skapar du till exempel ett 2x2 rasterblock med en byte per pixel:

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

Rasterpixlar kan skrivas över tack vare metoden writeBlock(). För att skriva över befintliga rasterdata på position 0,0 med 2x2-blocket:

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