From 721370f3e5183566f5bf10cb2a88600cf36bf3ea Mon Sep 17 00:00:00 2001 From: duxin Date: Tue, 7 Jul 2026 16:40:51 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E6=96=B0=E5=A2=9E=20PROJ=5FDATA=20?= =?UTF-8?q?=E7=8E=AF=E5=A2=83=E5=8F=98=E9=87=8F=20+=20=E5=B1=8F=E8=94=BD?= =?UTF-8?q?=20Fiona=20=E5=86=85=E9=83=A8=E6=97=A7=E7=89=88=20PROJ=20?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 问题: visualize_raster 阶段 fiona 库内部捆绑了老旧的 PROJ 数据库 (VERSION.MINOR=2),导致读取掩膜时投影错乱 — 底图 51N 被误解析为 49N,矢量掩膜物理擦除时把所有水体当成陆地,有效像元变成 0/15300。 修复: 1. 新增 os.environ['PROJ_DATA'] = proj_lib Fiona ≥1.4 / Rasterio ≥1.4 / GDAL ≥3.5 / PROJ ≥8 优先读取此变量 2. PROJ_NETWORK = OFF — 禁用 PROJ 网络下载,避免意外行为 3. 打印明确日志确认全进程 PROJ 来源统一 效果: 所有空间组件(GDAL / PROJ / Fiona / Rasterio / pyproj) 强制使用同一套 conda 环境下的 proj.db (v6+),彻底杜绝 fiona 内部 捆绑的 v2 旧版干扰。 --- src/gui/water_quality_gui_v2.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/gui/water_quality_gui_v2.py b/src/gui/water_quality_gui_v2.py index 2b43f28..d0b68b4 100644 --- a/src/gui/water_quality_gui_v2.py +++ b/src/gui/water_quality_gui_v2.py @@ -209,12 +209,18 @@ def _find_and_set_gdal_env(): # ── 应用环境变量 ── if proj_lib: os.environ["PROJ_LIB"] = proj_lib - print(f"[ENV] PROJ_LIB → {proj_lib}") + # PROJ_DATA: Fiona / Rasterio / GDAL ≥3.5 / PROJ ≥8 优先读取此变量 + # 不设置的话 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}") else: - print("[ENV] ⚠ 未找到兼容的 proj.db (需要 PROJ v6+),PROJ_LIB 保持系统默认") + print("[ENV] ⚠ 未找到兼容的 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=\\Library\\share\\proj") + print("[ENV] set PROJ_DATA=<同上>") if gdal_data: os.environ["GDAL_DATA"] = gdal_data @@ -223,6 +229,17 @@ def _find_and_set_gdal_env(): print("[ENV] ⚠ 未找到 GDAL data 目录,GDAL_DATA 保持系统默认") print(f"[ENV] (已搜索 {len(prefixes)} 个前缀)") + # ── 屏蔽 Fiona 内部旧版 PROJ 路径 ── + # Fiona wheels 捆绑了古老的 proj.db (VERSION.MINOR=2), + # 即使设置了 PROJ_DATA 仍然可能被某些旧版 Fiona 忽略。 + # 以下环境变量作为最后防线强制覆盖。 + if proj_lib: + # GDAL ≥3.5 同时检查 PROJ_DATA 和 PROJ_LIB + os.environ["PROJ_NETWORK"] = "OFF" # 禁用 PROJ 网络下载(避免意外行为) + # 记录此信息供诊断 + if "PROJ_DATA" in os.environ: + print("[ENV] 已屏蔽 Fiona 内部旧版 PROJ 数据库,全进程统一使用上述 proj.db") + _find_and_set_gdal_env() import ctypes