如何修改Python代码实现QGIS v.kernel.rast多嵌套文件夹批量处理
问题
我使用QGIS 3.40.8,需要实现跨嵌套文件夹结构的核密度计算自动化。我不懂Python,现有代码是基于GUI手动运行v.kernel.rast的QGIS日志由大语言模型生成的单文件夹运行代码。
现有可运行的单文件夹代码
import processing import os from qgis.core import QgsRasterLayer # === Inputs === point_layer = 'main_folder/manchester/2018/01/poi.shp' reference_raster = 'main_folder/manchester/2018/01/lc.tif' output_dir = 'main_folder/manchester/2018/01/' # === Bandwidths to test === bandwidths = [50, 100, 150, 200] # === Extract parameters from reference raster === print("Extracting parameters from reference raster...") ref_layer = QgsRasterLayer(reference_raster, "reference") if not ref_layer.isValid(): print(f"ERROR: Could not load reference raster: {reference_raster}") exit() # Get extent extent = ref_layer.extent() region_extent = f"{extent.xMinimum()},{extent.xMaximum()},{extent.yMinimum()},{extent.yMaximum()} [EPSG:{ref_layer.crs().postgisSrid()}]" # Get pixel size pixel_size = ref_layer.rasterUnitsPerPixelX() print(f"Extracted region extent: {region_extent}") print(f"Extracted pixel size: {pixel_size}") # === Kernel density loop === for radius in bandwidths: output_path = os.path.join(output_dir, f'kernel_bw_{radius}.tif') print(f"Processing bandwidth: {radius}...") processing.run("grass7:v.kernel.rast", { 'input': point_layer, 'radius': radius, 'kernel': 5, # Gaussian 'multiplier': 1, 'output': output_path, 'GRASS_REGION_PARAMETER': region_extent, 'GRASS_REGION_CELLSIZE_PARAMETER': pixel_size, 'GRASS_RASTER_FORMAT_OPT': 'TFW=YES,COMPRESS=LZW', 'GRASS_RASTER_FORMAT_META': '' }) print("All kernel rasters created.")
文件夹结构
main_folder/ ├── city (e.g., rome)/ │ ├── year (e.g., 2018)/ │ │ ├── month (e.g., 11)/ │ │ │ ├── poi.shp │ │ │ └── lc.tif │ │ └── 04/ │ │ ├── poi.shp │ │ └── lc.tif │ └── 2019/ │ └── 11/ │ ├── poi.shp │ └── lc.tif └── london/ └── 2021/ └── 03/ ├── poi.shp └── lc.tif
需求
- 遍历所有符合
main_folder/city/year/month/模式的月度文件夹 - 跳过不包含
poi.shp的文件夹 - 为每个有效月度文件夹运行核密度分析
- 将输出栅格保存到
poi.shp所在的月度文件夹中 - 文件命名固定为
poi.shp(点图层)和lc.tif(参考栅格)
解决方案
修改后的代码会自动遍历嵌套文件夹,处理符合要求的月度目录:
import processing import os from qgis.core import QgsRasterLayer # === 全局设置 === main_folder = 'main_folder' # 根文件夹路径 bandwidths = [50, 100, 150, 200] # 要测试的带宽值 # === 遍历嵌套文件夹 === # 遍历根文件夹下的所有城市目录 for city_name in os.listdir(main_folder): city_path = os.path.join(main_folder, city_name) if not os.path.isdir(city_path): continue # 跳过非目录文件 # 遍历城市目录下的所有年份目录 for year_name in os.listdir(city_path): year_path = os.path.join(city_path, year_name) if not os.path.isdir(year_path): continue # 遍历年份目录下的所有月份目录 for month_name in os.listdir(year_path): month_path = os.path.join(year_path, month_name) if not os.path.isdir(month_path): continue # 检查当前月份目录是否包含必要文件 poi_path = os.path.join(month_path, 'poi.shp') lc_path = os.path.join(month_path, 'lc.tif') if not os.path.exists(poi_path): print(f"跳过目录:{month_path} - 未找到poi.shp") continue if not os.path.exists(lc_path): print(f"跳过目录:{month_path} - 未找到lc.tif") continue # === 提取参考栅格参数 === print(f"正在处理目录:{month_path}") ref_layer = QgsRasterLayer(lc_path, "reference") if not ref_layer.isValid(): print(f"错误:无法加载参考栅格 {lc_path}") continue extent = ref_layer.extent() region_extent = f"{extent.xMinimum()},{extent.xMaximum()},{extent.yMinimum()},{extent.yMaximum()} [EPSG:{ref_layer.crs().postgisSrid()}]" pixel_size = ref_layer.rasterUnitsPerPixelX() print(f"提取的范围:{region_extent}") print(f"提取的像素大小:{pixel_size}") # === 运行核密度分析 === for radius in bandwidths: output_path = os.path.join(month_path, f'kernel_bw_{radius}.tif') print(f"处理带宽:{radius}...") processing.run("grass7:v.kernel.rast", { 'input': poi_path, 'radius': radius, 'kernel': 5, # 高斯核 'multiplier': 1, 'output': output_path, 'GRASS_REGION_PARAMETER': region_extent, 'GRASS_REGION_CELLSIZE_PARAMETER': pixel_size, 'GRASS_RASTER_FORMAT_OPT': 'TFW=YES,COMPRESS=LZW', 'GRASS_RASTER_FORMAT_META': '' }) print(f"{month_path} 处理完成\n") print("所有核密度栅格生成完成。")
关键修改说明
- 嵌套遍历逻辑:使用三层循环依次遍历城市、年份、月份目录,确保覆盖所有符合
main_folder/city/year/month结构的文件夹 - 有效性检查:进入每个月份目录后,先检查
poi.shp和lc.tif是否存在,不存在则直接跳过该目录 - 动态路径生成:所有文件路径(点图层、参考栅格、输出文件)都基于当前月份目录动态生成,无需手动指定单个路径
- 错误处理增强:对参考栅格加载失败的情况增加跳过逻辑,避免单个目录出错导致整个程序终止
内容的提问来源于stack exchange,提问作者Nikos
相关产品推荐
相关产品推荐

