跳转至

5 使用栅格图层⚓︎

此页面上的代码段需要导入以下模块:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
from qgis.core import (
    Qgis,
    QgsRasterLayer,
    QgsProject,
    QgsPointXY,
    QgsRaster,
    QgsRasterBlock,
    QgsRasterShader,
    QgsColorRampShader,
    QgsSingleBandPseudoColorRenderer,
    QgsSingleBandColorDataRenderer,
    QgsSingleBandGrayRenderer,
)

from qgis.PyQt.QtGui import (
    QColor,
)

5.1 图层细节⚓︎

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

以下代码假定rlayer是一个 QgsRasterLayer对象。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
rlayer = QgsProject.instance().mapLayersByName('srtm')[0]
# 获取图层分辨率
rlayer.width(), rlayer.height()
(919, 619)
# 获取图层范围,返回QgsRectangle对象
rlayer.extent()
# <QgsRectangle: 20.06856808199999875 -34.27001076999999896, 20.83945284300000012,-33.75077500700000144>
# 获取图层范围并转换为字符串
rlayer.extent().toString()
# '20.0685680819999988,-34.2700107699999990 : 20.8394528430000001,-33.7507750070000014'
# 获取栅格类型: 0 = 灰度值(单波段), 1 = 调色板(单波段), 2 = 多波段
rlayer.rasterType()
# 0
# 获取波段个数
rlayer.bandCount()
# 1
# 获取第一个波段名称
print(rlayer.bandName(1))
# Band 1: Height
# 获取所有可用的元数据,返回QgsLayerMetadata对象
rlayer.metadata()
# '<qgis._core.QgsLayerMetadata object at 0x13711d558>'

5.2 渲染⚓︎

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

查询当前渲染器:

1
2
3
4
rlayer.renderer()
# <qgis._core.QgsSingleBandGrayRenderer object at 0x7f471c1da8a0>
rlayer.renderer().type()
# 'singlebandgray'

设置渲染器,使用QgsRasterLayersetRenderer 方法。下面有许多渲染器类(派生自QgsRasterRenderer):

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

5.2.1 单波段栅格⚓︎

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

1
2
3
4
5
6
fcn = QgsColorRampShader()
fcn.setColorRampType(QgsColorRampShader.Interpolated)
lst = [ QgsColorRampShader.ColorRampItem(0, QColor(0,255,0)),QgsColorRampShader.ColorRampItem(255, QColor(255,255,0)) ]
fcn.setColorRampItemList(lst)
shader = QgsRasterShader()
shader.setRasterShaderFunction(fcn)

着色器按其颜色映射指定的颜色。彩色地图被提供为具有相关颜色的像素值列表。插值有三种模式:

  • 线性(Interpolated):从像素值上方和下方的颜色表条带中线性插值颜色
  • 离散(Discrete):颜色取自具有相同或更高值的最接近的颜色表条带
  • 精确(Exact):不插值颜色,只绘制值等于颜色表条带的像素

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

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

上面代码中数值1是波段号(栅格波段的一个索引)。

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

1
rlayer.triggerRepaint()

5.2.2 多波段栅格⚓︎

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

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

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

我们必须使用triggerRepaint 更新地图并查看结果:

1
rlayer.triggerRepaint()

5.3 查询值⚓︎

查询栅格值的第一种方法是使用 QgsRasterDataProvidersample()方法查询。你必须指定栅格图层的QgsPointXY的和波段号。该方法返回一个value和result(true或false):

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

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

1
2
3
4
5
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栅格块:

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

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

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