49_通过 Python 运行 QGIS3 处理算法
原文链接: https://www.qgistutorials.com/en/docs/3/processing_algorithms_pyqgis.html
通过 Python 运行处理算法 (QGIS3)¶
QGIS 中的“处理工具箱”包含一个不断增长的地理处理工具集。该工具箱提供了一个便捷的批量处理界面,可以对大量输入数据运行任何算法。请参阅使用处理框架进行批量处理 (QGIS3)。但在某些情况下,您需要在批量处理中加入一些自定义逻辑。由于所有处理算法都可以通过 Python API 以编程方式运行,因此您可以通过 Python 控制台来运行它们。本教程展示了如何通过 Python 控制台运行处理算法,仅用几行代码即可执行自定义的地理处理任务。请先查看Python 编程入门 (QGIS3)教程,以熟悉 QGIS 中 Python 脚本环境的基础知识。
任务概述¶
我们将使用代表一年中每个月的12个格网化栅格图层,并计算西雅图地区所有邮政编码的月平均降水量。
您将学到的其他技能¶
- 从 Python 控制台访问所有图层(栅格和矢量)并打印其名称。
- 使用 Python 脚本将不同图层合并为单个图层。
获取数据¶
PRISM 气候小组收集气候观测数据,并为美国本土提供历史和当前的气候数据。请访问近年数据页面,下载2017年 BIL 格式的月降水量数据。

西雅图市开放数据门户为该市提供免费的开放数据。搜索并下载 shapefile 格式的邮政编码数据。
为方便起见,您可以直接通过以下链接下载这两个数据集的副本:
PRISM_ppt_stable_4kmM3_2017_all_bil.zip
数据来源 [PRISM] [CITYOFSEATTLE]
操作步骤¶
- 在 QGIS 浏览器中找到
PRISM_ppt_stable_4kmM3_2017_all_bil.zip文件夹并展开它。该文件夹包含每个月的12个独立图层。按住Ctrl键并选择所有12个月的.bil文件。选中后,将它们拖到画布上。
注意
数据以BIL 格式提供。每个图层都包含一组文件:.bil 文件包含实际数据,.hdr 文件描述数据结构,.prj 文件包含投影信息。只要其他文件存在于同一目录中,QGIS 就可以加载 .bil 文件。
- 将会出现“选择 PRISM_ppt_stable_4kmM3_2017_all_bil 的转换”对话框,保留默认选择并点击确定。
- 接下来,找到
Zip_Codes.zip文件夹并展开它。将Zip_Codes.shp文件拖到画布上。
- 右键单击
Zip_Codes图层并选择 缩放到图层。您将看到西雅图市及邻近地区的邮政编码多边形。
- 转到 处理 -> 工具箱。
- 使用矢量多边形采样栅格层的算法被称为
分区统计。在“处理工具箱”中搜索该算法。选择该算法并将鼠标悬停在上面。您将看到一个工具提示,显示文本 算法 ID:‘native:zonalstatisticsfb’。请记下此 ID,因为需要通过 Python API 调用此算法。双击分区统计算法启动它。
- 我们将对一个图层进行手动测试运行。这是一种有用的方法,可以检查算法是否按预期运行,也是在通过 Python 使用该算法时,找出如何传递相关参数的简便方法。在“分区统计”对话框中,选择
Zip_Codes作为输入图层,PRISM_ppt_stable_4kmM3_201701_bil作为栅格图层,其他参数保留默认值。点击 要计算的统计量 旁边的 … 按钮,仅选择平均值。接下来,点击 分区统计 旁边的 … 按钮,将图层另存为january_mean.gpkg。点击 运行。
- 算法完成后,切换到 日志 选项卡。记下传递给算法的输入参数。点击 关闭。
- 现在,一个新图层
january_mean将被添加到画布中。让我们检查结果,右键单击该图层并选择 打开属性表。此特定算法会原地修改输入的区域图层,并为每个选定的统计量添加一个新列。由于我们只选择了平均值,因此表中添加了一个名为_mean的新列。_是默认前缀。当我们为每个月的图层运行算法时,指定一个带有月份编号的自定义前缀将很有用,这样我们可以轻松识别每个月的平均值(例如,01_mean,02_mean 等)。在 QGIS 的批量处理界面中无法指定此自定义前缀,如果我们使用该界面运行此命令,则必须为每个图层手动输入自定义前缀。如果您要处理大量图层,这可能非常繁琐。因此,我们可以使用 Python API 添加此自定义逻辑,并在 for 循环中为每个图层运行算法。
- 回到主 QGIS 窗口,转到 插件 -> Python 控制台。
- 点击显示编辑器按钮。这将打开 Python 编辑器,您可以在其中编写一串 Python 代码,并通过一次单击按钮来执行。
- 要通过 Python 运行处理算法,我们需要访问所有图层的名称。在编辑器中输入以下代码,然后点击 运行 按钮。您将在控制台中看到所有图层的名称被打印出来。
bash root = QgsProject.instance().layerTreeRoot() for layer in root.children(): print(layer.name())
- 现在,让我们计算一个月的
平均值并创建一个输出图层。在下面的代码中,break用于在第一次执行后退出循环,通过这样我们可以计算一月份的平均值。
```bash import re
root = QgsProject.instance().layerTreeRoot()
input_layer = 'Zip_Codes' unique_field = 'OBJECTID'
Iterate through all raster layers
for layer in root.children(): if layer.name().startswith('PRISM'): # Run Zonal Stats algorithm # Extract the YYYYMM part of the layer name pattern = r'(\d+)' matches = re.findall(pattern, layer.name()) # Use the month as the prefix prefix = matches[0][-2:] params = {'INPUT_RASTER': layer.name(), 'RASTER_BAND': 1, 'INPUT': input_layer, 'COLUMN_PREFIX': prefix+'_', 'STATISTICS': [2], 'OUTPUT': 'memory:' } result = processing.run("native:zonalstatisticsfb", params)
result_layer = result['OUTPUT'] QgsProject.instance().addMapLayer(result_layer) # Breaking out of loop to demonstrate the # zonalstatistics algorithm. break```
注意
您也可以通过 Python 运行 QGIS 处理算法,使用 processing.runAndLoadResults() 函数,而不是如上所示的 processing.run() —— 这将直接把结果加载到 QGIS 画布中。
- 一个新图层
output将被添加到画布中,右键单击该图层并选择 打开属性表。01_mean 代表一月份的平均值,同样,如果不加 break 执行,上述算法将生成 12 个新图层。
- 现在让我们添加代码来合并所有月份的平均值,并从中创建单个输出图层。我们更新之前的代码,以迭代运行分区统计算法。我们定义一个新变量
result_layer,开始时将其设置为Zip_Codes,但会在每次迭代中更新为输出图层。这将允许我们使用每次迭代的结果并向其添加新列。输入以下代码,迭代所有栅格图层并创建包含所有月份平均值的单个图层。
```bash import re
root = QgsProject.instance().layerTreeRoot()
input_layer = 'Zip_Codes' result_layer = input_layer unique_field = 'OBJECTID'
Iterate through all raster layers
for layer in root.children(): if layer.name().startswith('PRISM'): # Run Zonal Stats algorithm # Extract the YYYYMM part of the layer name pattern = r'(\d+)' matches = re.findall(pattern, layer.name()) # Use the month as the prefix prefix = matches[0][-2:] params = {'INPUT_RASTER': layer.name(), 'RASTER_BAND': 1, 'INPUT': result_layer, 'COLUMN_PREFIX': prefix+'_', 'STATISTICS': [2], 'OUTPUT': 'memory:' } result = processing.run("native:zonalstatisticsfb", params)
# Update the result_layer variable # The result will be used as input for the next iteration result_layer = result['OUTPUT']QgsProject.instance().addMapLayer(result_layer) ```
- 处理完成后,一个新图层
output将被添加到画布中,右键单击该图层并选择 打开属性表。
- 您将看到表中添加了 12 个新列,这些列带有自定义前缀,并包含了从栅格图层中提取的平均降水量值。
如果您想对此教程提供反馈或分享您的经验,请在下方留言。(需要 GitHub 账户)
















