修复多步运行时参数传递及文件读取问题

This commit is contained in:
DXC
2026-05-08 09:27:07 +08:00
parent 742bc392a5
commit 0f36da742f
3 changed files with 111 additions and 9 deletions

View File

@ -81,8 +81,14 @@ except ImportError:
print("警告: scipy未安装0值像素插值功能可能无法正常工作")
# 导入GDAL用于影像读写
try:
from osgeo import gdal
from osgeo import gdal, ogr
GDAL_AVAILABLE = True
# 注册所有 GDAL/OGR 驱动,确保 ESRI Shapefile 驱动可用
gdal.AllRegister()
ogr.RegisterAll()
# 启用 GDAL/OGR 异常,使错误以 Python 异常形式抛出(而不是静默失败)
gdal.UseExceptions()
ogr.UseExceptions()
except ImportError:
GDAL_AVAILABLE = False
print("警告: GDAL未安装新算法可能无法正常工作")
@ -369,7 +375,8 @@ class WaterQualityInversionPipeline:
# 执行栅格化
from src.utils.extract_water_area import rasterize_shp
rasterize_shp(mask_path, shp_output_path, img_path)
safe_mask_path = os.path.abspath(mask_path).replace('\\', '/')
rasterize_shp(safe_mask_path, shp_output_path, img_path)
self.water_mask_path = shp_output_path
step_end_time = time.time()
self._record_step_time("步骤1: 生成水域mask", step_start_time, step_end_time)
@ -1134,10 +1141,54 @@ class WaterQualityInversionPipeline:
# 从shp文件创建掩膜这种情况应该很少因为步骤1已经统一转换为dat
try:
from src.utils.extract_water_area import rasterize_shp
# 路径标准化:转为绝对路径,统一正斜杠
safe_shp_path = os.path.abspath(water_mask).replace('\\', '/')
print(f"[DEBUG] 标准化后的 SHP 路径: {safe_shp_path}")
# 检查必要的伴随文件是否存在
shp_dir = os.path.dirname(safe_shp_path)
shp_base = os.path.splitext(safe_shp_path)[0]
for ext in ['.dbf', '.shx', '.prj']:
companion = shp_base + ext
if not os.path.exists(companion):
print(f"[DEBUG] 缺失伴随文件: {companion}")
# 检查 ESRI Shapefile 驱动是否可用
if GDAL_AVAILABLE:
driver = ogr.GetDriverByName("ESRI Shapefile")
if driver is None:
raise RuntimeError("系统中未找到 ESRI Shapefile 驱动!请检查 GDAL 安装。")
print(f"[DEBUG] ESRI Shapefile 驱动可用: {driver.GetName()}")
# 尝试用 ogr.Open 打开,捕获详细错误
try:
ogr_ds = ogr.Open(safe_shp_path)
if ogr_ds is None:
# 通过 gdal.OpenEx 再试一次,获取详细原因
ogr_ds2 = gdal.OpenEx(safe_shp_path, gdal.OF_VECTOR)
if ogr_ds2 is None:
raise RuntimeError(
f"ogr.Open 和 gdal.OpenEx 均无法打开 SHP 文件。\n"
f"可能原因:\n"
f" 1. 文件路径包含中文/特殊字符(当前路径: {safe_shp_path}\n"
f" 2. .dbf/.shx 等伴随文件缺失或损坏\n"
f" 3. GDAL 驱动未注册\n"
f"建议:将 SHP 文件复制到纯英文路径下重试"
)
else:
print(f"[DEBUG] ogr.Open 成功打开 SHP图层数: {ogr_ds.GetLayerCount()}")
ogr_ds = None # 仅用于诊断,不做后续处理
except Exception as ogr_err:
raise RuntimeError(
f"OGR 打开 SHP 时出错(详细原因): {str(ogr_err)}\n"
f"文件路径: {safe_shp_path}"
)
# 使用固定路径,避免重复转换
shp_name = Path(water_mask).stem
shp_name = Path(safe_shp_path).stem
temp_mask_path = str(self.water_mask_dir / f"water_mask_{shp_name}.dat")
# 如果文件已存在,直接使用
if Path(temp_mask_path).exists():
print(f"使用已存在的栅格化掩膜: {temp_mask_path}")
@ -1146,10 +1197,11 @@ class WaterQualityInversionPipeline:
# 需要栅格化需要img_path
if img_path is None:
raise ValueError("当water_mask为shp格式时需要提供img_path参数用于栅格化")
rasterize_shp(water_mask, temp_mask_path, img_path)
# 传入标准化后的路径
rasterize_shp(safe_shp_path, temp_mask_path, img_path)
water_mask = temp_mask_path
print(f"已将shp格式的水域掩膜栅格化为: {temp_mask_path}")
# 读取栅格化的掩膜
if not GDAL_AVAILABLE:
raise ImportError("GDAL未安装无法读取掩膜文件")

View File

@ -310,7 +310,7 @@ class WorkerThread(QThread):
step_config.pop('prediction_csv_dir', None)
step_config.pop('recursive_csv_scan', None)
if step_name in ['step2', 'step3', 'step4', 'step5', 'step7', 'step8', 'step8_5', 'step8_75']:
if step_name in ['step2', 'step3', 'step4', 'step5', 'step6', 'step7', 'step8', 'step8_5', 'step8_75']:
step_config.pop('output_path', None)
if step_name == 'step8_5' and 'models_dir' in step_config:

View File

@ -14,17 +14,67 @@ def rasterize_envi_xml(shp_filepath):
@timeit
def rasterize_shp(shp_filepath, raster_fn_out, img_path, NoData_value=None):
# ---------- 防御性处理:路径标准化 ----------
shp_filepath = os.path.abspath(shp_filepath).replace('\\', '/')
print(f"[DEBUG rasterize_shp] 标准化后的 SHP 路径: {shp_filepath}")
# 检查伴随文件完整性
shp_base = os.path.splitext(shp_filepath)[0]
for ext in ['.dbf', '.shx', '.prj']:
companion = shp_base + ext
if os.path.exists(companion):
print(f"[DEBUG rasterize_shp] 伴随文件存在: {companion}")
else:
print(f"[WARNING rasterize_shp] 伴随文件缺失: {companion}")
# 确保 GDAL/OGR 驱动已注册
gdal.AllRegister()
ogr.RegisterAll()
# 检查 ESRI Shapefile 驱动
driver = ogr.GetDriverByName("ESRI Shapefile")
if driver is None:
raise RuntimeError(
"系统中未找到 ESRI Shapefile 驱动!请检查 GDAL 是否正确安装及是否包含 Shapefile 支持。"
)
print(f"[DEBUG rasterize_shp] ESRI Shapefile 驱动: {driver.GetName()}")
# 打开参考影像获取尺寸信息
dataset = gdal.Open(img_path)
if dataset is None:
raise ValueError(f"无法打开参考影像文件: {img_path}")
im_width = dataset.RasterXSize
im_height = dataset.RasterYSize
geotransform = dataset.GetGeoTransform()
imgdata_in = dataset.GetRasterBand(1).ReadAsArray()
del dataset
# Open the data source and read in the extent
# ---------- 打开 SHP 文件(双重尝试获取详细错误) ----------
source_ds = gdal.OpenEx(shp_filepath, gdal.OF_VECTOR)
if source_ds is None:
raise ValueError(f"无法打开shapefile: {shp_filepath}")
# gdal.OpenEx 失败,尝试 ogr.Open 获取更详细的错误信息
try:
ogr_ds = ogr.Open(shp_filepath)
except Exception as ogr_err:
raise RuntimeError(
f"GDAL/OGR 无法打开 SHP 文件(详细原因):\n"
f" ogr.Open 抛出异常: {str(ogr_err)}\n"
f" 文件路径: {shp_filepath}\n"
f"常见原因:\n"
f" 1. 路径包含中文/空格/特殊字符(建议复制到纯英文路径下重试)\n"
f" 2. .dbf 或 .shx 伴随文件缺失或损坏\n"
f" 3. GDAL 未注册 ESRI Shapefile 驱动\n"
f" 4. 文件被其他程序锁定"
)
if ogr_ds is None:
raise RuntimeError(
f"ogr.Open 和 gdal.OpenEx 均返回 None无法打开 SHP 文件。\n"
f"文件路径: {shp_filepath}\n"
f"请检查:\n"
f" 1. 所有伴随文件(.dbf/.shx/.prg是否齐全\n"
f" 2. 文件是否被其他程序占用\n"
f" 3. 路径中是否存在不支持的字符"
)
# 检查图层数量,如果有多层,指定使用第一层
layer_count = source_ds.GetLayerCount()