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,31 +172,54 @@ def _find_and_set_gdal_env():
|
|||||||
pass
|
pass
|
||||||
prefixes.extend(_extra_prefixes)
|
prefixes.extend(_extra_prefixes)
|
||||||
|
|
||||||
# 6) pip wheel GDAL: {site-packages}/osgeo/data/proj/proj.db
|
# 6) pip wheel GDAL / Fiona: {site-packages}/*/proj.db 直接搜索
|
||||||
# (conda-forge GDAL wheel on Windows 有时把 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:
|
try:
|
||||||
import site as _site
|
import site as _site
|
||||||
for _sp in _site.getsitepackages():
|
for _sp in _site.getsitepackages():
|
||||||
pip_proj = os.path.join(_sp, "osgeo", "data", "proj")
|
# GDAL wheel: osgeo/data/proj/proj.db
|
||||||
if os.path.isfile(os.path.join(pip_proj, "proj.db")):
|
for _sub in ("osgeo/data/proj", "osgeo\\data\\proj",
|
||||||
pip_gdal = os.path.join(_sp, "osgeo", "data", "gdal")
|
"osgeo/proj_data", "osgeo\\proj_data"):
|
||||||
if _sp not in prefixes:
|
_db = os.path.join(_sp, _sub, "proj.db")
|
||||||
prefixes.append(_sp)
|
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:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
# 直接使用 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
|
proj_lib = None
|
||||||
gdal_data = None
|
gdal_data = None
|
||||||
|
|
||||||
|
# site-packages 没找到 → 回退到前缀搜索
|
||||||
|
if not proj_lib:
|
||||||
for prefix in prefixes:
|
for prefix in prefixes:
|
||||||
if not proj_lib:
|
if not proj_lib:
|
||||||
# 先尝试标准子目录(快速路径)
|
|
||||||
for sub in ("Library/share/proj", "share/proj",
|
for sub in ("Library/share/proj", "share/proj",
|
||||||
"Library\\share\\proj", "share\\proj"):
|
"Library\\share\\proj", "share\\proj"):
|
||||||
db_path = os.path.join(prefix, sub, "proj.db")
|
db_path = os.path.join(prefix, sub, "proj.db")
|
||||||
if os.path.isfile(db_path) and _check_proj_db_version(db_path) >= 6:
|
if os.path.isfile(db_path) and _check_proj_db_version(db_path) >= 6:
|
||||||
proj_lib = os.path.join(prefix, sub)
|
proj_lib = os.path.join(prefix, sub)
|
||||||
break
|
break
|
||||||
# 标准路径未找到 → 递归搜索(仅对 conda 环境前缀)
|
|
||||||
if not proj_lib and (
|
if not proj_lib and (
|
||||||
os.path.basename(prefix) not in ("", "share", "bin", "Scripts")
|
os.path.basename(prefix) not in ("", "share", "bin", "Scripts")
|
||||||
):
|
):
|
||||||
@ -232,13 +255,16 @@ def _find_and_set_gdal_env():
|
|||||||
# ── 屏蔽 Fiona 内部旧版 PROJ 路径 ──
|
# ── 屏蔽 Fiona 内部旧版 PROJ 路径 ──
|
||||||
# Fiona wheels 捆绑了古老的 proj.db (VERSION.MINOR=2),
|
# Fiona wheels 捆绑了古老的 proj.db (VERSION.MINOR=2),
|
||||||
# 即使设置了 PROJ_DATA 仍然可能被某些旧版 Fiona 忽略。
|
# 即使设置了 PROJ_DATA 仍然可能被某些旧版 Fiona 忽略。
|
||||||
# 以下环境变量作为最后防线强制覆盖。
|
|
||||||
if proj_lib:
|
if proj_lib:
|
||||||
# GDAL ≥3.5 同时检查 PROJ_DATA 和 PROJ_LIB
|
|
||||||
os.environ["PROJ_NETWORK"] = "OFF" # 禁用 PROJ 网络下载(避免意外行为)
|
os.environ["PROJ_NETWORK"] = "OFF" # 禁用 PROJ 网络下载(避免意外行为)
|
||||||
# 记录此信息供诊断
|
|
||||||
if "PROJ_DATA" in os.environ:
|
if "PROJ_DATA" in os.environ:
|
||||||
print("[ENV] 已屏蔽 Fiona 内部旧版 PROJ 数据库,全进程统一使用上述 proj.db")
|
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()
|
_find_and_set_gdal_env()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user