GeoMaster 技能中的 GIS 软件集成指南:QGIS、ArcGIS、GRASS 与 SAGA 的 Python 工作流
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
GeoMaster 是 scientific-agent-skills 仓库中的综合性地理空间科学技能,覆盖遥感、GIS、空间分析与地球观测机器学习等主题,并提供了 500+ 跨 8 种编程语言的代码示例(参见 skills/geomaster/SKILL.md)。本文聚焦该技能参考文档中的 GIS 软件集成 章节,系统讲解如何通过 Python 与四大主流 GIS 平台——QGIS(PyQGIS)、ArcGIS(ArcPy)、GRASS GIS 和 SAGA GIS——进行深度集成,涵盖脚本运行、算法开发、插件编写、地理处理流水线与跨平台数据互通。读者阅读后将掌握在这些平台间无缝搬运分析任务、批量处理空间数据并构建可复用自动化流程的完整实战方案。
一、GIS 软件集成在 GeoMaster 技能体系中的定位
在 SKILL.md 的"Detailed Documentation"索引中,gis-software.md与坐标系(coordinate-systems.md)、核心库(core-libraries.md)、遥感(remote-sensing.md)等参考文档并列,专门回答一个问题:当分析任务需要进入 QGIS、ArcGIS、GRASS 或 SAGA 等专业桌面 GIS 环境时,如何用统一的 Python 语言驱动它们。
围绕该主题,仓库中的依赖约束文件 tests/skill-requirements.toml 为skills.geomaster声明了完整的环境依赖,例如geopandas、shapely、pyproj、rasterio、rioxarray、xarray、osmnx、pystac-client、laspy等,其中rsgislib、pdal、open3d等因仅支持 conda-forge 或无对应轮子被标注为"conda-forge only"(见 tests/skill-requirements.toml)。这意味着本指南中的跨平台工作流环节以 Python 生态为黏合剂,而 QGIS / ArcGIS / GRASS / SAGA 则作为外部分析引擎。
二、QGIS / PyQGIS
QGIS 提供官方 Python 绑定 PyQGIS,可以在 QGIS 内置的 Python 控制台、脚本编辑器中运行,也可以编写 Processing 算法插件。
2.1 在 QGIS 中运行 Python 脚本
PyQGIS 的核心对象是QgsProject(当前工程)、QgsVectorLayer(矢量图层)和QgsRasterLayer(栅格图层)。以下脚本演示了加载两种图层并加入当前工程、随后遍历要素的完整流程:
# Processing framework script from qgis.core import (QgsProject, QgsVectorLayer, QgsRasterLayer, QgsProcessingAlgorithm, QgsProcessingParameterRasterLayer) # Load layers vector_layer = QgsVectorLayer("path/to/shapefile.shp", "layer_name", "ogr") raster_layer = QgsRasterLayer("path/to/raster.tif", "raster_name", "gdal") # Add to project QgsProject.instance().addMapLayer(vector_layer) QgsProject.instance().addMapLayer(raster_layer) # Access features for feature in vector_layer.getFeatures(): geom = feature.geometry() attrs = feature.attributes()要点说明:
QgsVectorLayer的第三个参数是数据提供者(data provider)标识:"ogr"用于读取 OGR 支持的所有矢量格式(Shapefile、GeoPackage、GeoJSON 等),"gdal"对应栅格驱动。addMapLayer将图层注册到当前工程,此后图层会出现在 QGIS 图层面板中。getFeatures()返回要素迭代器,feature.geometry()获取几何对象,feature.attributes()返回属性值列表,顺序与图层字段定义一致。
2.2 创建 QGIS Processing 脚本
Processing(处理工具箱)脚本可以让算法出现在 QGIS 的 Processing 面板中,获得参数化界面、日志和批处理能力。下面的NDVIAlgorithm是标准的 Processing 算法骨架,以 Sentinel-2 影像为输入、输出 NDVI 栅格:
from qgis.PyQt.QtCore import QCoreApplication from qgis.core import (QgsProcessingAlgorithm, QgsProcessingParameterRasterDestination, QgsProcessingParameterRasterLayer) class NDVIAlgorithm(QgsProcessingAlgorithm): INPUT = 'INPUT' OUTPUT = 'OUTPUT' def tr(self, string): return QCoreApplication.translate('Processing', string) def createInstance(self): return NDVIAlgorithm() def name(self): return 'ndvi_calculation' def displayName(self): return self.tr('Calculate NDVI') def group(self): return self.tr('Raster') def groupId(self): return 'raster' def shortHelpString(self): return self.tr("Calculate NDVI from Sentinel-2 imagery") def initAlgorithm(self, config=None): self.addParameter(QgsProcessingParameterRasterLayer( self.INPUT, self.tr('Input Sentinel-2 Raster'))) self.addParameter(QgsProcessingParameterRasterDestination( self.OUTPUT, self.tr('Output NDVI'))) def processAlgorithm(self, parameters, context, feedback): raster = self.parameterAsRasterLayer(parameters, self.INPUT, context) # NDVI calculation # ... implementation ... return {self.OUTPUT: destination}Processing 算法各方法的作用:
name()返回算法唯一标识(不能有空格,用于命令行qgis_process调用);displayName()是工具箱中显示的名称;group()/groupId()决定算法在工具箱中的分组位置;initAlgorithm()通过addParameter声明输入输出参数——QgsProcessingParameterRasterLayer用于选择输入栅格,QgsProcessingParameterRasterDestination用于指定输出文件;processAlgorithm()是核心执行逻辑,通过parameterAsRasterLayer取出参数对象,完成计算后返回输出路径映射;feedback对象可调用feedback.pushInfo()输出进度信息。
这与 GeoMaster 在 SKILL.md 中给出的 rasterio 版 NDVI 计算(读 B04 红波段与 B08 近红外波段,按(NIR - RED) / (NIR + RED + 1e-8)计算并写回浮点单波段 GeoTIFF)互为补充:Processing 版本把同一算法包装成可复用的工具箱工具。
2.3 QGIS 插件开发
插件在 QGIS 启动时通过classFactory入口加载,核心生命周期是initGui()(创建菜单动作)与unload()(清理):
# __init__.py def classFactory(iface): from .my_plugin import MyPlugin return MyPlugin(iface) # my_plugin.py from qgis.PyQt.QtCore import QSettings from qgis.PyQt.QtWidgets import QAction from qgis.core import QgsProject class MyPlugin: def __init__(self, iface): self.iface = iface def initGui(self): self.action = QAction("My Plugin", self.iface.mainWindow()) self.action.triggered.connect(self.run) self.iface.addPluginToMenu("My Plugin", self.action) def run(self): # Plugin logic here pass def unload(self): self.iface.removePluginMenu("My Plugin", self.action)iface(QgisInterface)提供对 QGIS 主窗口、菜单、工具栏和画布的访问能力;addPluginToMenu将动作挂到插件菜单,unload中务必移除菜单项,避免重复加载。
三、ArcGIS / ArcPy
ArcPy 是 ArcGIS 的 Python 站点包,通过它可以在 Python 中调用 ArcGIS 的地理处理工具。
3.1 基本 ArcPy 操作
环境设置(arcpy.env)决定了工具执行的空间范围与输出行为:
import arcpy # Set workspace arcpy.env.workspace = "C:/data" # Set output overwrite arcpy.env.overwriteOutput = True # Set scratch workspace arcpy.env.scratchWorkspace = "C:/data/scratch" # List features feature_classes = arcpy.ListFeatureClasses() rasters = arcpy.ListRasters()workspace是工具查找输入/输出数据的默认位置;overwriteOutput = True允许同名输出覆盖已有数据;scratchWorkspace存放临时中间数据;ListFeatureClasses()/ListRasters()返回当前工作空间下的要素类和栅格列表。
3.2 地理处理工作流:地形与水文分析
ArcPy 配合 Spatial Analyst 扩展可以完成地形(slope、aspect、hillshade)、可视域(viewshed)、成本距离(cost distance)与水文(flow direction、flow accumulation、河网提取)等经典分析:
import arcpy from arcpy.sa import * # Check out Spatial Analyst extension arcpy.CheckOutExtension("Spatial") # Set environment arcpy.env.workspace = "C:/data" arcpy.env.cellSize = 10 arcpy.env.extent = "study_area" # Slope analysis out_slope = Slope("dem.tif") out_slope.save("slope.tif") # Aspect out_aspect = Aspect("dem.tif") out_aspect.save("aspect.tif") # Hillshade out_hillshade = Hillshade("dem.tif", azimuth=315, altitude=45) out_hillshade.save("hillshade.tif") # Viewshed analysis out_viewshed = Viewshed("observer_points.shp", "dem.tif", obs_elevation_field="HEIGHT") out_viewshed.save("viewshed.tif") # Cost distance cost_raster = CostDistance("source.shp", "cost.tif") cost_raster.save("cost_distance.tif") # Hydrology: Flow direction flow_dir = FlowDirection("dem.tif") flow_dir.save("flowdir.tif") # Flow accumulation flow_acc = FlowAccumulation(flow_dir) flow_acc.save("flowacc.tif") # Stream delineation stream = Con(flow_acc > 1000, 1) stream_raster = StreamOrder(stream, flow_dir)参数细节:
CheckOutExtension("Spatial")用于签出 Spatial Analyst 许可,使用from arcpy.sa import *导入其栅格算子;env.cellSize和env.extent限定输出像元大小与分析范围;Hillshade的azimuth=315(光源方位角)与altitude=45(光源高度角)对应 GeoMaster 在 SKILL.md 中自行实现的山体阴影公式所用默认参数,两者结果一致;Con(flow_acc > 1000, 1)表示对累积流量栅格做条件判断,像元累积流量超过 1000 则赋值为 1(即河网掩膜);- 每类输出都需显式调用
.save()落盘。
3.3 矢量分析
ArcPy 提供与 GeoPandas 操作(如 code-examples.md 中的 buffer、dissolve、clip、sjoin)对应的全套矢量分析工具:
# Buffer analysis arcpy.Buffer_analysis("roads.shp", "roads_buffer.shp", "100 meters") # Spatial join arcpy.SpatialJoin_analysis("points.shp", "zones.shp", "points_joined.shp", join_operation="JOIN_ONE_TO_ONE", match_option="HAVE_THEIR_CENTER_IN") # Dissolve arcpy.Dissolve_management("parcels.shp", "parcels_dissolved.shp", dissolve_field="OWNER_ID") # Intersect arcpy.Intersect_analysis(["layer1.shp", "layer2.shp"], "intersection.shp") # Clip arcpy.Clip_analysis("input.shp", "clip_boundary.shp", "output.shp") # Select by location arcpy.SelectLayerByLocation_management("points_layer", "HAVE_THEIR_CENTER_IN", "polygon_layer") # Feature to raster arcpy.FeatureToRaster_conversion("landuse.shp", "LU_CODE", "landuse.tif", 10)关键参数含义:
Buffer_analysis的距离参数"100 meters"是带单位的文本,也支持"100 Meters"、"0.1 Kilometers"等写法;SpatialJoin_analysis的join_operation="JOIN_ONE_TO_ONE"控制连接方式(一对一),match_option="HAVE_THEIR_CENTER_IN"表示"目标要素中心位于连接要素内"的空间匹配规则;Intersect_analysis接受图层列表作为第一个参数;FeatureToRaster_conversion的"LU_CODE"是用于赋值的属性字段,10为输出像元大小。
3.4 ArcGIS Pro 中的 Notebook 工作流
ArcGIS Pro 内置 Jupyter Notebook 环境,可直接访问当前工程(arcpy.mp.ArcGISProject("CURRENT")),将图层转为空间 DataFrame 后与 pandas/matplotlib 无缝衔接,还可调用地理编码工具:
# ArcGIS Pro Jupyter Notebook import arcpy import pandas as pd import matplotlib.pyplot as plt # Use current project's map aprx = arcpy.mp.ArcGISProject("CURRENT") m = aprx.listMaps()[0] # Get layer layer = m.listLayers("Parcels")[0] # Export to spatial dataframe sdf = pd.DataFrame.spatial.from_layer(layer) # Plot sdf.plot(column='VALUE', cmap='YlOrRd', legend=True) plt.show() # Geocode addresses locator = "C:/data/locators/composite.locator" results = arcpy.geocoding.GeocodeAddresses( "addresses.csv", locator, "Address Address", None, "geocoded_results.gdb" )listMaps()[0]获取当前工程的第一个地图,listLayers("Parcels")按名称筛选图层;pd.DataFrame.spatial.from_layer把图层直接导出为带空间信息的 pandas DataFrame,绘图时沿用 GeoPandas 风格的plot(column=..., cmap=...)接口(与 code-examples.md 中 GeoPandas 绘制 choropleth 的写法一致)。GeocodeAddresses的字段映射串"Address Address"表示"地址字段名 地址字段别名"的配对。
四、GRASS GIS
GRASS GIS 的 Python 接口grass.script将 GRASS 命令封装为 Python 函数,适合在 GRASS 会话中执行空间分析。
4.1 Python API 基础与会话初始化
import grass.script as gscript import grass.script.array as garray # Initialize GRASS session gscript.run_command('g.gisenv', set='GISDBASE=/grassdata') gscript.run_command('g.gisenv', set='LOCATION_NAME=nc_spm_08') gscript.run_command('g.gisenv', set='MAPSET=user1') # Import raster gscript.run_command('r.in.gdal', input='elevation.tif', output='elevation') # Import vector gscript.run_command('v.in.ogr', input='roads.shp', output='roads') # Get raster info info = gscript.raster_info('elevation') print(info)g.gisenv通过set=KEY=VALUE设置 GRASS 环境变量:GISDBASE是 GRASS 数据库根目录,LOCATION_NAME是位置(location),MAPSET是地图集,三者构成 GRASS 数据存储的三层结构;r.in.gdal/v.in.ogr分别从 GDAL/OGR 源导入栅格与矢量;raster_info()返回栅格的元数据字典(行数、列数、分辨率、范围等)。
4.2 典型分析命令
# Slope analysis gscript.run_command('r.slope.aspect', elevation='elevation', slope='slope', aspect='aspect') # Buffer gscript.run_command('v.buffer', input='roads', output='roads_buffer', distance=100) # Overlay gscript.run_command('v.overlay', ainput='zones', binput='roads', operator='and', output='zones_roads') # Calculate statistics stats = gscript.parse_command('r.univar', map='elevation', flags='g')r.slope.aspect同时输出坡度(slope)与坡向(aspect)两个栅格,对应 GeoMaster 在 SKILL.md 的terrain_metrics()中基于np.gradient的纯 Python 实现;v.buffer的distance=100以地图单位计;v.overlay的operator='and'表示矢量叠加求交集;parse_command(..., flags='g')以g(全局统计)标志运行r.univar并自动解析键值对输出为字典。
五、SAGA GIS
SAGA GIS 提供命令行工具saga_cmd,可以在 Python 中用subprocess驱动,无需 Python 绑定即可接入其丰富的地形与水文算法库。
5.1 命令行封装模式
import subprocess import os # SAGA path saga_cmd = "/usr/local/saga/saga_cmd" # Grid Calculus def saga_grid_calculus(input1, input2, output, formula): cmd = [ saga_cmd, "grid_calculus", "GridCalculator", f"-GRIDS={input1};{input2}", f"-RESULT={output}", f"-FORMULA={formula}" ] subprocess.run(cmd) # Slope analysis def saga_slope(dem, output_slope): cmd = [ saga_cmd, "ta_morphometry", "SlopeAspectCurvature", f"-ELEVATION={dem}", f"-SLOPE={output_slope}" ] subprocess.run(cmd) # Morphometric features def saga_morphometry(dem): cmd = [ saga_cmd, "ta_morphometry", "MorphometricFeatures", f"-DEM={dem}", f"-SLOPE=slope.sgrd", f"-ASPECT=aspect.sgrd", f"-CURVATURE=curvature.sgrd" ] subprocess.run(cmd) # Channel network def saga_channels(dem, threshold=1000): cmd = [ saga_cmd, "ta_channels", "ChannelNetworkAndDrainageBasins", f"-ELEVATION={dem}", f"-CHANNELS=channels.shp", f"-BASINS=basins.shp", f"-THRESHOLD={threshold}" ] subprocess.run(cmd)saga_cmd的调用结构为saga_cmd <模块库> <模块名> [参数]:
grid_calculus库的GridCalculator通过-GRIDS=...;...传入多个栅格(分号分隔),-FORMULA指定计算公式;ta_morphometry库提供SlopeAspectCurvature(坡度坡向曲率)与MorphometricFeatures(综合地形特征,一次性输出 slope、aspect、curvature 多个栅格);ta_channels库的ChannelNetworkAndDrainageBasins以-THRESHOLD(累积流量阈值)提取河道网络与流域边界,与 ArcPy 水文工具链(FlowDirection→FlowAccumulation→Con→StreamOrder)功能对应;- 每个函数通过
subprocess.run(cmd)执行,cmd列表即完整命令行,便于审计与排错。
六、跨平台工作流
6.1 从 QGIS 导出数据到 ArcGIS
不同平台间转移数据时,GeoPandas 是天然的"通用格式层"。关键是要先统一坐标系,再选择双方都能读取的容器格式:
import geopandas as gpd # Read data processed in QGIS gdf = gpd.read_file('qgis_output.geojson') # Ensure CRS gdf = gdf.to_crs('EPSG:32633') # Export for ArcGIS (File Geodatabase) gdf.to_file('arcgis_input.gpkg', driver='GPKG') # ArcGIS can read GPKG directly # Or export to shapefile gdf.to_file('arcgis_input.shp')to_crs('EPSG:32633')将数据重投影到 UTM 33N。GeoMaster 的坐标系建议(见 SKILL.md 的 "Coordinate Systems" 一节)是:存储用EPSG:4326,Web 制图用EPSG:3857,度量计算用 UTM(EPSG:326xx/327xx),并可调用gdf.estimate_utm_crs()自动探测;- 输出为 GPKG(GeoPackage)时,ArcGIS 10.4+ 可直接读取;Shapefile 则保持最大兼容性。GeoMaster 的最佳实践(SKILL.md)也强调:
GeoPackage > Shapefile,大数据量优先使用 Parquet(gdf.to_file(..., use_arrow=True))。
6.2 批处理与多平台输出
对目录下的多个 Shapefile 批量加工并同时输出给不同平台,是 Agent 或自动化流水线中最常见的场景:
import geopandas as gpd from pathlib import Path # Process multiple files input_dir = Path('input') output_dir = Path('output') for shp in input_dir.glob('*.shp'): gdf = gpd.read_file(shp) # Process gdf['area'] = gdf.geometry.area gdf['buffered'] = gdf.geometry.buffer(100) # Export for various platforms basename = shp.stem gdf.to_file(output_dir / f'{basename}_qgis.geojson') gdf.to_file(output_dir / f'{basename}_arcgis.shp')需要提醒的是:gdf.geometry.area与buffer(100)的结果依赖当前坐标系。若数据是地理坐标系(如 WGS 84),面积单位是平方度、缓冲距离是度,会产生误导性结果;正确做法是先to_crs(gdf.estimate_utm_crs())转换到投影坐标系再做度量计算——这与 SKILL.md 中 "Always check CRS before spatial operations / Use projected CRS for area/distance calculations" 的最佳实践一致。
七、总结
四大 GIS 平台的 Python 集成路径各有侧重,可按下表选择:
| 平台 | 驱动方式 | 擅长场景 | 关键技术点 |
|---|---|---|---|
| QGIS / PyQGIS | 内置 Python 控制台、Processing、插件 | 桌面交互、工具箱算法、插件开发 | QgsProcessingAlgorithm、classFactory |
| ArcGIS / ArcPy | arcpy站点包、Pro Notebook | 企业级地理处理、Spatial Analyst 栅格分析 | arcpy.env、CheckOutExtension、from arcpy.sa import * |
| GRASS GIS | grass.script | 科研级栅格/矢量分析、水文建模 | g.gisenv会话初始化、run_command |
| SAGA GIS | subprocess调用saga_cmd | 地形与水文算法库 | 模块库 + 模块名 +-PARAM=value参数传递 |
跨平台协作的通用模式是:以 GeoPandas 为统一数据交换层,先处理坐标系(统一到 UTM 投影再做度量),再用 GeoPackage/GeoJSON/Shapefile 等通用格式在不同平台间传递数据,从而把 QGIS 的制图与工具箱、ArcGIS 的企业级地理处理、GRASS 的科研算法、SAGA 的地形水文模块组合进同一条自动化流水线。
如需更多可运行示例,可继续查阅 skills/geomaster/references/code-examples.md(500+ 代码示例)、skills/geomaster/references/core-libraries.md(GDAL/Rasterio/Fiona/GeoPandas 基础库)以及 skills/geomaster/SKILL.md(安装、快速上手与最佳实践)。
【免费下载链接】scientific-agent-skillsTurn any AI agent into an AI Scientist. The #1 Agent Skills library for science, used by 190,000+ scientists worldwide. 165 ready-to-use validated skills plus 100+ scientific databases covering biology, chemistry, medicine, and drug discovery. Compatible with Cursor, Claude Code, Codex, Pi, Antigravity, and the open Agent Skills standard.项目地址: https://gitcode.com/GitHub_Trending/cl/scientific-agent-skills
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考