fix: 多项稳定性修复与打包优化

- PyInstaller: runtime hook 预加载 osgeo DLL 避免 Qt5 符号冲突;
  spec 纳入 osgeo .py 文件 + 运行时 DLL 依赖 (ffi/lzma/bz2/expat/sqlite3);
  移除 DLL 双副本防止 segfault
- GDAL 环境: 新增 _MEIPASS/osgeo/data/gdal 路径搜索,改善打包后 GDAL_DATA 检测
- 预览生成器: 掩膜与底图同分辨率时跳过 Warp 加速读取
- 专题图: ConvexHull 坐标中心化修复 UTM 大坐标精度退化;
  边界采样兜底防止外扩点为空;
  TIFF 已含 NaN 掩膜时跳过矢量擦除;
  形态学闭运算填充掩膜小孔洞
- NDWI: int16→float32 防止减法溢出
- 面板注册表: 步骤模块分组重构 (模块一/二/三/四重划分)
This commit is contained in:
duxin
2026-07-26 20:35:50 +08:00
parent 0bd54d5fdd
commit b609a64811
7 changed files with 177 additions and 46 deletions

View File

@ -78,9 +78,12 @@ def _find_and_set_gdal_env():
return None
def _find_gdal_in_prefix(prefix):
"""在指定前缀下查找 Library/share/gdal"""
"""在指定前缀下查找 GDAL data 目录(Library/share/gdal 或 osgeo/data/gdal)"""
# Conda 路径:Library/share/gdal
# pip wheel / PyInstaller 打包后:osgeo/data/gdal
for sub in ("Library/share/gdal", "share/gdal",
"Library\\share\\gdal", "share\\gdal"):
"Library\\share\\gdal", "share\\gdal",
"osgeo/data/gdal", "osgeo\\data\\gdal"):
path = os.path.join(prefix, sub)
if os.path.isdir(path):
for marker in ("gdalvrt.xsd", "pcs.csv", "gcs.csv"):
@ -110,6 +113,12 @@ def _find_and_set_gdal_env():
except Exception:
pass
# 2b) PyInstaller 打包后的解包目录 (_MEIPASS)
# sys.prefix 在 PyInstaller 中已指向 _MEIPASS,但显式加入确保不被遗漏
_meipass = getattr(sys, '_MEIPASS', None)
if _meipass and _meipass not in prefixes:
prefixes.insert(0, _meipass)
# 3) 从 sys.path 中 site-packages 位置回推所有可能的 conda/env 前缀
try:
for sp in sys.path:
@ -236,10 +245,10 @@ def _find_and_set_gdal_env():
# 不设置的话 Fiona 会使用自带的旧版 proj.db (VERSION.MINOR=2),
# 导致投影解析错误 → 矢量图层错位 → 水体被错误擦除 → 有效像元为 0
os.environ["PROJ_DATA"] = proj_lib
print(f"[ENV] PROJ_LIB → {proj_lib}")
print(f"[ENV] PROJ_DATA → {proj_lib}")
print(f"[ENV] PROJ_LIB -> {proj_lib}")
print(f"[ENV] PROJ_DATA -> {proj_lib}")
else:
print("[ENV] ⚠ 未找到兼容的 proj.db (需要 PROJ v6+),PROJ_LIB/PROJ_DATA 保持系统默认")
print("[ENV] [WARN] 未找到兼容的 proj.db (需要 PROJ v6+),PROJ_LIB/PROJ_DATA 保持系统默认")
print(f"[ENV] (已搜索 {len(prefixes)} 个前缀: {[os.path.basename(p) for p in prefixes[:5]]}...)")
print("[ENV] 如果 step11 地图渲染报 PROJ 版本错误,")
print("[ENV] 请手动设置: set PROJ_LIB=<conda环境>\\Library\\share\\proj")
@ -247,9 +256,9 @@ def _find_and_set_gdal_env():
if gdal_data:
os.environ["GDAL_DATA"] = gdal_data
print(f"[ENV] GDAL_DATA → {gdal_data}")
print(f"[ENV] GDAL_DATA -> {gdal_data}")
else:
print("[ENV] ⚠ 未找到 GDAL data 目录,GDAL_DATA 保持系统默认")
print("[ENV] [WARN] 未找到 GDAL data 目录,GDAL_DATA 保持系统默认")
print(f"[ENV] (已搜索 {len(prefixes)} 个前缀)")
# ── 屏蔽 Fiona 内部旧版 PROJ 路径 ──
@ -260,7 +269,7 @@ def _find_and_set_gdal_env():
if "PROJ_DATA" in os.environ:
print("[ENV] 已屏蔽 Fiona 内部旧版 PROJ 数据库,全进程统一使用上述 proj.db")
if _fiona_v2_path:
print(f"[ENV] ⚠ 检测到 Fiona 自带的旧版 proj.db (v2) 位于:")
print(f"[ENV] [WARN] 检测到 Fiona 自带的旧版 proj.db (v2) 位于:")
print(f" {_fiona_v2_path}")
print(f" PROJ_DATA 已指向 v6+ 版本,此旧版将被忽略")
if proj_lib: