fix: 新增 PROJ_DATA 环境变量 + 屏蔽 Fiona 内部旧版 PROJ 数据库

问题: 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 旧版干扰。
This commit is contained in:
duxin
2026-07-07 16:40:51 +08:00
parent da773b139f
commit 721370f3e5

View File

@ -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=<conda环境>\\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