修复多步运行时参数传递及文件读取问题
This commit is contained in:
@ -81,8 +81,14 @@ except ImportError:
|
|||||||
print("警告: scipy未安装,0值像素插值功能可能无法正常工作")
|
print("警告: scipy未安装,0值像素插值功能可能无法正常工作")
|
||||||
# 导入GDAL用于影像读写
|
# 导入GDAL用于影像读写
|
||||||
try:
|
try:
|
||||||
from osgeo import gdal
|
from osgeo import gdal, ogr
|
||||||
GDAL_AVAILABLE = True
|
GDAL_AVAILABLE = True
|
||||||
|
# 注册所有 GDAL/OGR 驱动,确保 ESRI Shapefile 驱动可用
|
||||||
|
gdal.AllRegister()
|
||||||
|
ogr.RegisterAll()
|
||||||
|
# 启用 GDAL/OGR 异常,使错误以 Python 异常形式抛出(而不是静默失败)
|
||||||
|
gdal.UseExceptions()
|
||||||
|
ogr.UseExceptions()
|
||||||
except ImportError:
|
except ImportError:
|
||||||
GDAL_AVAILABLE = False
|
GDAL_AVAILABLE = False
|
||||||
print("警告: GDAL未安装,新算法可能无法正常工作")
|
print("警告: GDAL未安装,新算法可能无法正常工作")
|
||||||
@ -369,7 +375,8 @@ class WaterQualityInversionPipeline:
|
|||||||
|
|
||||||
# 执行栅格化
|
# 执行栅格化
|
||||||
from src.utils.extract_water_area import rasterize_shp
|
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
|
self.water_mask_path = shp_output_path
|
||||||
step_end_time = time.time()
|
step_end_time = time.time()
|
||||||
self._record_step_time("步骤1: 生成水域mask", step_start_time, step_end_time)
|
self._record_step_time("步骤1: 生成水域mask", step_start_time, step_end_time)
|
||||||
@ -1134,8 +1141,52 @@ class WaterQualityInversionPipeline:
|
|||||||
# 从shp文件创建掩膜(这种情况应该很少,因为步骤1已经统一转换为dat)
|
# 从shp文件创建掩膜(这种情况应该很少,因为步骤1已经统一转换为dat)
|
||||||
try:
|
try:
|
||||||
from src.utils.extract_water_area import rasterize_shp
|
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")
|
temp_mask_path = str(self.water_mask_dir / f"water_mask_{shp_name}.dat")
|
||||||
|
|
||||||
# 如果文件已存在,直接使用
|
# 如果文件已存在,直接使用
|
||||||
@ -1146,7 +1197,8 @@ class WaterQualityInversionPipeline:
|
|||||||
# 需要栅格化(需要img_path)
|
# 需要栅格化(需要img_path)
|
||||||
if img_path is None:
|
if img_path is None:
|
||||||
raise ValueError("当water_mask为shp格式时,需要提供img_path参数用于栅格化")
|
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
|
water_mask = temp_mask_path
|
||||||
print(f"已将shp格式的水域掩膜栅格化为: {temp_mask_path}")
|
print(f"已将shp格式的水域掩膜栅格化为: {temp_mask_path}")
|
||||||
|
|
||||||
|
|||||||
@ -310,7 +310,7 @@ class WorkerThread(QThread):
|
|||||||
step_config.pop('prediction_csv_dir', None)
|
step_config.pop('prediction_csv_dir', None)
|
||||||
step_config.pop('recursive_csv_scan', 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)
|
step_config.pop('output_path', None)
|
||||||
|
|
||||||
if step_name == 'step8_5' and 'models_dir' in step_config:
|
if step_name == 'step8_5' and 'models_dir' in step_config:
|
||||||
|
|||||||
@ -14,17 +14,67 @@ def rasterize_envi_xml(shp_filepath):
|
|||||||
|
|
||||||
@timeit
|
@timeit
|
||||||
def rasterize_shp(shp_filepath, raster_fn_out, img_path, NoData_value=None):
|
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)
|
dataset = gdal.Open(img_path)
|
||||||
|
if dataset is None:
|
||||||
|
raise ValueError(f"无法打开参考影像文件: {img_path}")
|
||||||
im_width = dataset.RasterXSize
|
im_width = dataset.RasterXSize
|
||||||
im_height = dataset.RasterYSize
|
im_height = dataset.RasterYSize
|
||||||
geotransform = dataset.GetGeoTransform()
|
geotransform = dataset.GetGeoTransform()
|
||||||
imgdata_in = dataset.GetRasterBand(1).ReadAsArray()
|
imgdata_in = dataset.GetRasterBand(1).ReadAsArray()
|
||||||
del dataset
|
del dataset
|
||||||
|
|
||||||
# Open the data source and read in the extent
|
# ---------- 打开 SHP 文件(双重尝试获取详细错误) ----------
|
||||||
source_ds = gdal.OpenEx(shp_filepath, gdal.OF_VECTOR)
|
source_ds = gdal.OpenEx(shp_filepath, gdal.OF_VECTOR)
|
||||||
if source_ds is None:
|
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()
|
layer_count = source_ds.GetLayerCount()
|
||||||
|
|||||||
Reference in New Issue
Block a user