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 渲染
加载栅格图层时,它会根据其类型获取默认渲染器。它可以在图层属性中更改,也可以通过编程方式更改。
查询当前渲染器:
| rlayer.renderer()
# <qgis._core.QgsSingleBandGrayRenderer object at 0x7f471c1da8a0>
rlayer.renderer().type()
# 'singlebandgray'
|
设置渲染器,使用QgsRasterLayer的setRenderer 方法。下面有许多渲染器类(派生自QgsRasterRenderer):
单波段栅格图层可以以灰色(低值=黑色,高值=白色)或使用伪彩色算法绘制,该算法为值指定颜色。也可以使用调色板绘制带调色板的单波段栅格。多波段图层通常通过将波段映射到RGB来绘制颜色。另一种可能是仅使用一个波段来绘图。
5.2.1 单波段栅格
假设我们想要渲染一个单波段栅格图层,颜色范围从绿色到黄色(对应于0到255之间的像素值)。在第一阶段,我们将准备一个:QgsRasterShader对象并配置其着色器函数:
| 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):不插值颜色,只绘制值等于颜色表条带的像素
在第二步中,我们将此着色器与栅格图层相关联:
| renderer = QgsSingleBandPseudoColorRenderer(rlayer.dataProvider(), 1, shader)
rlayer.setRenderer(renderer)
|
上面代码中数值1是波段号(栅格波段的一个索引)。
最后我们必须使用 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 更新地图并查看结果:
5.3 查询值
查询栅格值的第一种方法是使用 QgsRasterDataProvider的sample()方法查询。你必须指定栅格图层的QgsPointXY的和波段号。该方法返回一个value和result(true或false):
| 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)
|