fix: 修复 pip wheel GDAL 的 proj.db 未被找到的 bug
根因: pip 安装的 GDAL ≥3.5 把 proj.db 放在
{site-packages}/osgeo/data/proj/proj.db
而之前的代码将其加入 prefixes 列表后,搜索循环只查找
{prefix}/Library/share/proj/ 子目录,
导致 site-packages 中的 v6+ proj.db 被漏掉。
修复:
1. 新增独立搜索步骤:直接扫描 site-packages 下
osgeo/data/proj/ 和 osgeo/proj_data/ 目录
2. 找到 v6+ 版本后直接设为 proj_lib,
不再经过前缀子目录搜索(优先级最高)
3. 同时扫描 site-packages/fiona/proj_data/,
找到旧版时打印明确路径警告,
确认 PROJ_DATA 已覆盖该旧版
4. 仅 site-packages 未找到时回退到前缀搜索
This commit is contained in:
@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user