5. 使用栅格图层

提示

如果您在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. 层详细信息

栅格层由一个或多个栅格波段组成-称为单波段和多波段栅格。一个波段代表一个价值矩阵。彩色图像(例如航拍照片)是由红、蓝、绿三色带组成的栅格。单波段栅格通常表示连续变量(例如海拔)或离散变量(例如土地利用)。在某些情况下,栅格图层附带调色板,而栅格值指的是调色板中存储的颜色。

以下代码假定 rlayer 是一种 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. 渲染器

加载栅格图层时,它将根据其类型获取默认渲染器。它可以在层属性中更改,也可以通过编程方式更改。

要查询当前渲染器,请执行以下操作:

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

若要设置呈现器,请使用 setRenderer() 方法论 QgsRasterLayer 。有许多渲染器类(派生自 QgsRasterRenderer ):

可以用灰色(低值=黑色,高值=白色)绘制单波段栅格图层,也可以使用为这些值指定颜色的伪彩色算法绘制单波段栅格图层。也可以使用调色板绘制带有调色板的单波段栅格。多波段层通常通过将波段映射到RGB颜色来绘制。另一种可能是只使用一个乐队来绘画。

5.2.1. 单波段栅格

假设我们想要渲染一个颜色范围从绿色到黄色(对应于像素值从0到255)的单波段栅格层。在第一阶段,我们将准备一个 QgsRasterShader 对象并配置其着色器函数:

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)

着色器按照其颜色贴图指定的颜色进行贴图。颜色映射表作为具有关联颜色的像素值的列表来提供。有三种插补模式:

  • 线性 (Interpolated ):根据像素值上方和下方的色彩映射表条目对颜色进行线性内插

  • 离散的 (Discrete ):颜色取自具有相同或更高值的最近颜色映射表条目

  • 精确 (Exact ):不对颜色进行内插,仅绘制具有等于色彩映射表条目的值的像素

在第二步中,我们将该着色器与栅格层相关联:

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

数字 1 在上面的代码中是波段编号(栅格波段从1开始索引)。

最后,我们必须使用 triggerRepaint() 方法查看结果:

rlayer.triggerRepaint()

5.2.2. 多波段栅格

默认情况下,QGIS会将前三个波段映射为红色、绿色和蓝色以创建彩色图像(这是 MultiBandColor 绘画风格)。在某些情况下,您可能希望覆盖这些设置。以下代码交换红色波段(1)和绿色波段(2):

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

如果只需要一个波段来可视化栅格,则可以选择单波段绘制,或者灰度级或伪彩色。

我们必须使用 triggerRepaint() 要更新地图并查看结果,请执行以下操作:

rlayer_multi.triggerRepaint()

5.3. 查询值

栅格值可以使用 sample() 的方法。 QgsRasterDataProvider 班级。您必须指定一个 QgsPointXY 以及要查询的栅格图层的波段编号。该方法返回一个具有值的元组和 TrueFalse 根据结果:

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

查询栅格值的另一种方法是使用 identify() 方法,它返回 QgsRasterIdentifyResult 对象。

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

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

在这种情况下, results() 方法返回一个字典,其中带索引作为键,带值作为值。例如,像这样的东西 {1: 323.0}

5.4. 编辑栅格数据

您可以使用创建栅格图层 QgsRasterBlock 班级。例如,要创建一个每个像素一个字节的2x2栅格块:

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

栅格像素可以被覆盖 writeBlock() 方法。要按2x2块覆盖位置0,0处的现有栅格数据:

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