fix: 增强 PROJ/GDAL 环境检测 — 多级回退搜索策略
问题: sys.prefix 指向 test_env,该环境不含 GDAL/PROJ 数据文件, 导致 _find_and_set_gdal_env() 找不到 proj.db。 修复: 按优先级扩展搜索路径: 1. CONDA_PREFIX 环境变量(当前激活的 Conda 环境) 2. sys.prefix(Python 安装前缀) 3. CONDA_ROOT / MAMBA_ROOT_PREFIX 4. 从 PATH 推断 conda 安装根目录 5. 硬编码回退(WQ_GUI 路径 + 常见目录 ProgramData) 每个前缀尝试 Windows (Library/share/...) 和 Linux (share/...) 子目录。 找不到时打印已搜索前缀数量供用户诊断。
This commit is contained in:
@ -25,33 +25,90 @@ import sys
|
||||
# ═══════════════════════════════════════════════════════════════
|
||||
|
||||
def _find_and_set_gdal_env():
|
||||
"""根据 sys.prefix 自动推断并强设 PROJ_LIB 和 GDAL_DATA 环境变量"""
|
||||
# sys.prefix 在 Conda 环境下通常为:
|
||||
# D:\...\anconda\envs\WQ_GUI
|
||||
# PROJ 和 GDAL 的数据文件位于:
|
||||
# {sys.prefix}\Library\share\proj (含 proj.db)
|
||||
# {sys.prefix}\Library\share\gdal
|
||||
prefix = sys.prefix
|
||||
candidates_proj = [
|
||||
os.path.join(prefix, "Library", "share", "proj"), # Windows Conda
|
||||
os.path.join(prefix, "share", "proj"), # Linux/Mac Conda
|
||||
]
|
||||
candidates_gdal = [
|
||||
os.path.join(prefix, "Library", "share", "gdal"),
|
||||
os.path.join(prefix, "share", "gdal"),
|
||||
]
|
||||
"""动态推断并强设 PROJ_LIB 和 GDAL_DATA 环境变量
|
||||
|
||||
proj_lib = None
|
||||
for path in candidates_proj:
|
||||
按优先级搜索 proj.db 和 GDAL data 目录:
|
||||
1. CONDA_PREFIX 环境变量(当前激活的 Conda 环境)
|
||||
2. sys.prefix(Python 安装前缀)
|
||||
3. CONDA_ROOT / CONDA_BASE(base 环境)
|
||||
4. 常见 Conda 安装目录
|
||||
5. 硬编码回退路径(WQ_GUI 环境)
|
||||
"""
|
||||
def _check_proj(path):
|
||||
"""检查路径下是否含有效的 proj.db"""
|
||||
proj_db = os.path.join(path, "proj.db")
|
||||
if os.path.isfile(proj_db):
|
||||
proj_lib = path
|
||||
break
|
||||
return path
|
||||
return None
|
||||
|
||||
def _check_gdal(path):
|
||||
"""检查路径下是否含 GDAL 数据文件(以 gdalvrt.xsd 或 pcs.csv 为准)"""
|
||||
for marker in ("gdalvrt.xsd", "pcs.csv", "gcs.csv"):
|
||||
if os.path.isfile(os.path.join(path, marker)):
|
||||
return path
|
||||
return None
|
||||
|
||||
# --- 构建搜索前缀列表 ---
|
||||
prefixes = []
|
||||
|
||||
# 1) CONDA_PREFIX(当前激活环境,最优先)
|
||||
conda_prefix = os.environ.get("CONDA_PREFIX", "")
|
||||
if conda_prefix:
|
||||
prefixes.append(conda_prefix)
|
||||
|
||||
# 2) sys.prefix(Python 运行环境)
|
||||
if sys.prefix and sys.prefix not in prefixes:
|
||||
prefixes.append(sys.prefix)
|
||||
|
||||
# 3) CONDA_ROOT / 其他 conda 线索
|
||||
for key in ("CONDA_ROOT", "MAMBA_ROOT_PREFIX"):
|
||||
val = os.environ.get(key, "")
|
||||
if val and val not in prefixes:
|
||||
prefixes.append(val)
|
||||
|
||||
# 4) 从 PATH 推断 conda 安装根目录
|
||||
for path_dir in os.environ.get("PATH", "").split(os.pathsep):
|
||||
lower = path_dir.lower()
|
||||
if "anaconda" in lower or "miniconda" in lower or "anconda" in lower:
|
||||
# 提取 conda 根目录: .../anconda/ 或 .../anconda/envs/xxx
|
||||
if os.path.basename(path_dir).lower() == "condabin":
|
||||
root = os.path.dirname(path_dir)
|
||||
elif lower.endswith("scripts") or lower.endswith("bin"):
|
||||
root = os.path.dirname(path_dir)
|
||||
else:
|
||||
root = path_dir
|
||||
if root and root not in prefixes:
|
||||
prefixes.append(root)
|
||||
|
||||
# 5) 硬编码回退(用户已知的 WQ_GUI 路径 + 常见目录)
|
||||
hardcoded = [
|
||||
r"D:\111\changyongruanjian\anconda\envs\WQ_GUI",
|
||||
r"D:\111\changyongruanjian\anconda",
|
||||
r"C:\ProgramData\anaconda3",
|
||||
r"C:\ProgramData\miniconda3",
|
||||
]
|
||||
for p in hardcoded:
|
||||
if os.path.isdir(p) and p not in prefixes:
|
||||
prefixes.append(p)
|
||||
|
||||
# --- 对每个前缀尝试 Windows + Linux 子目录 ---
|
||||
proj_lib = None
|
||||
gdal_data = None
|
||||
for path in candidates_gdal:
|
||||
if os.path.isdir(path):
|
||||
gdal_data = path
|
||||
|
||||
for prefix in prefixes:
|
||||
if not proj_lib:
|
||||
for sub in ("Library/share/proj", "share/proj", "Library\\share\\proj", "share\\proj"):
|
||||
path = os.path.join(prefix, sub)
|
||||
proj_lib = _check_proj(path)
|
||||
if proj_lib:
|
||||
break
|
||||
if not gdal_data:
|
||||
for sub in ("Library/share/gdal", "share/gdal", "Library\\share\\gdal", "share\\gdal"):
|
||||
path = os.path.join(prefix, sub)
|
||||
gdal_data = _check_gdal(path)
|
||||
if gdal_data:
|
||||
break
|
||||
if proj_lib and gdal_data:
|
||||
break
|
||||
|
||||
if proj_lib:
|
||||
@ -59,12 +116,14 @@ def _find_and_set_gdal_env():
|
||||
print(f"[ENV] PROJ_LIB → {proj_lib}")
|
||||
else:
|
||||
print("[ENV] ⚠ 未找到 proj.db,PROJ_LIB 保持系统默认,可能影响坐标转换")
|
||||
print(f"[ENV] (已搜索 {len(prefixes)} 个前缀: {prefixes[:3]}...)")
|
||||
|
||||
if gdal_data:
|
||||
os.environ["GDAL_DATA"] = gdal_data
|
||||
print(f"[ENV] GDAL_DATA → {gdal_data}")
|
||||
else:
|
||||
print("[ENV] ⚠ 未找到 GDAL data 目录,GDAL_DATA 保持系统默认")
|
||||
print(f"[ENV] (已搜索 {len(prefixes)} 个前缀: {prefixes[:3]}...)")
|
||||
|
||||
_find_and_set_gdal_env()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user