diff --git a/src/gui/water_quality_gui_v2.py b/src/gui/water_quality_gui_v2.py index d0b68b4..dae12e7 100644 --- a/src/gui/water_quality_gui_v2.py +++ b/src/gui/water_quality_gui_v2.py @@ -172,39 +172,62 @@ def _find_and_set_gdal_env(): pass prefixes.extend(_extra_prefixes) - # 6) pip wheel GDAL: {site-packages}/osgeo/data/proj/proj.db - # (conda-forge GDAL wheel on Windows 有时把 proj.db 放这里) + # 6) pip wheel GDAL / Fiona: {site-packages}/*/proj.db 直接搜索 + # pip 安装的 GDAL ≥3.5 把 proj.db 放在 site-packages/osgeo/data/proj/ + # Fiona 打包的旧版 proj.db 在 site-packages/fiona/proj_data/ + # 优先使用 GDAL 的 v6+,忽略 Fiona 的 v2 + _site_proj = None # site-packages 中找到的 v6+ proj.db + _site_gdal = None + _fiona_v2_path = None # 记录 Fiona 的旧版供警告 try: import site as _site for _sp in _site.getsitepackages(): - pip_proj = os.path.join(_sp, "osgeo", "data", "proj") - if os.path.isfile(os.path.join(pip_proj, "proj.db")): - pip_gdal = os.path.join(_sp, "osgeo", "data", "gdal") - if _sp not in prefixes: - prefixes.append(_sp) + # GDAL wheel: osgeo/data/proj/proj.db + for _sub in ("osgeo/data/proj", "osgeo\\data\\proj", + "osgeo/proj_data", "osgeo\\proj_data"): + _db = os.path.join(_sp, _sub, "proj.db") + if os.path.isfile(_db): + _ver = _check_proj_db_version(_db) + if _ver >= 6 and not _site_proj: + _site_proj = os.path.join(_sp, _sub) + _gd = os.path.join(_sp, "osgeo", "data", "gdal") + if os.path.isdir(_gd): + _site_gdal = _gd + # Fiona 打包的旧版 → 记录供警告 + for _sub in ("fiona/proj_data", "fiona\\proj_data"): + _fdb = os.path.join(_sp, _sub, "proj.db") + if os.path.isfile(_fdb) and not _fiona_v2_path: + _fiona_v2_path = _fdb except Exception: pass - proj_lib = None - gdal_data = None - for prefix in prefixes: - if not proj_lib: - # 先尝试标准子目录(快速路径) - for sub in ("Library/share/proj", "share/proj", - "Library\\share\\proj", "share\\proj"): - db_path = os.path.join(prefix, sub, "proj.db") - if os.path.isfile(db_path) and _check_proj_db_version(db_path) >= 6: - proj_lib = os.path.join(prefix, sub) - break - # 标准路径未找到 → 递归搜索(仅对 conda 环境前缀) - if not proj_lib and ( - os.path.basename(prefix) not in ("", "share", "bin", "Scripts") - ): - proj_lib = _find_proj_in_prefix(prefix) - if not gdal_data: - gdal_data = _find_gdal_in_prefix(prefix) - if proj_lib and gdal_data: - break + # 直接使用 site-packages 中找到的 v6+ proj.db(优先级最高: + # 它和当前 Python 进程中的 GDAL/PROJ 库版本匹配) + if _site_proj: + proj_lib = _site_proj + gdal_data = _site_gdal if _site_gdal else None + else: + proj_lib = None + gdal_data = None + + # site-packages 没找到 → 回退到前缀搜索 + if not proj_lib: + for prefix in prefixes: + if not proj_lib: + for sub in ("Library/share/proj", "share/proj", + "Library\\share\\proj", "share\\proj"): + db_path = os.path.join(prefix, sub, "proj.db") + if os.path.isfile(db_path) and _check_proj_db_version(db_path) >= 6: + proj_lib = os.path.join(prefix, sub) + break + if not proj_lib and ( + os.path.basename(prefix) not in ("", "share", "bin", "Scripts") + ): + proj_lib = _find_proj_in_prefix(prefix) + if not gdal_data: + gdal_data = _find_gdal_in_prefix(prefix) + if proj_lib and gdal_data: + break # ── 应用环境变量 ── if proj_lib: @@ -232,13 +255,16 @@ def _find_and_set_gdal_env(): # ── 屏蔽 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") + if _fiona_v2_path: + print(f"[ENV] ⚠ 检测到 Fiona 自带的旧版 proj.db (v2) 位于:") + print(f" {_fiona_v2_path}") + print(f" PROJ_DATA 已指向 v6+ 版本,此旧版将被忽略") + if proj_lib: + print(f" 确认全进程 PROJ 来源: {proj_lib}") _find_and_set_gdal_env()