Files
insar-management-system-v2/docs/archive/HOTFIX_PROJ_CONFLICT_2026-03-05.md
T

5.6 KiB
Raw Blame History

PROJ 数据库版本冲突问题修复(2026-03-05)

问题描述

在扫描 D-InSAR 结果时出现 PROJ 错误:

PROJ: proj_identify: C:\Program Files\PostgreSQL\17\share\contrib\postgis-3.6\proj\proj.db
contains DATABASE.LAYOUT.VERSION.MINOR = 2 whereas a number >= 3 is expected.
It comes from another PROJ installation.

根本原因

  1. PROJ 版本冲突

    • PostgreSQL 17 自带的 PostGIS 3.6 包含旧版 PROJ 数据库(版本 2)
    • GDAL/rasterio 期望 PROJ 数据库版本 >= 3
    • 系统在坐标转换时(Transformer.from_crs)触发此警告
  2. 环境变量优先级

    • Windows 系统可能将 PostgreSQL 的 PROJ 路径添加到 PATH
    • GDAL 默认搜索 PATH 中的 PROJ 数据库
    • 找到了 PostgreSQL 的旧版本而非 GDAL 自带的新版本

影响

  • 🟡 中等:不会导致程序崩溃,但会产生大量警告日志
  • 坐标转换仍然可以工作(PROJ 会回退到兼容模式)
  • 日志污染,影响问题排查

解决方案

方案 1:设置 PROJ_LIB 环境变量(已实施)

文件run_backend.py

修改内容

def main() -> None:
    # Load environment variables
    load_dotenv()

    # Fix PROJ database version conflict
    # PostgreSQL's PROJ database is outdated, use GDAL's bundled PROJ data
    # This prevents "DATABASE.LAYOUT.VERSION.MINOR = 2 whereas >= 3 is expected" error
    if "PROJ_LIB" not in os.environ:
        # Try to find GDAL's PROJ data directory
        try:
            from osgeo import gdal
            gdal_data = gdal.GetConfigOption("GDAL_DATA")
            if gdal_data:
                proj_lib = os.path.join(os.path.dirname(gdal_data), "proj")
                if os.path.exists(proj_lib):
                    os.environ["PROJ_LIB"] = proj_lib
                    print(f"[*] Set PROJ_LIB to: {proj_lib}")
        except Exception as e:
            print(f"[WARN] Could not auto-configure PROJ_LIB: {e}")

    port = int(os.getenv("PORT", 8000))
    # ... rest of the code

工作原理

  1. 在启动时检查 PROJ_LIB 环境变量是否已设置
  2. 如果未设置,尝试从 GDAL 配置中获取 PROJ 数据目录
  3. 设置 PROJ_LIB 指向 GDAL 自带的 PROJ 数据库

方案 2:手动设置环境变量(备选)

如果方案 1 不生效,可以在 .env 文件中手动设置:

# 找到 GDAL 的 PROJ 数据目录
python -c "from osgeo import gdal; import os; print(os.path.join(os.path.dirname(gdal.GetConfigOption('GDAL_DATA')), 'proj'))"

# 将输出路径添加到 .env
PROJ_LIB=C:\path\to\gdal\proj

或者在 PowerShell 启动脚本中设置:

# scripts/start_app.ps1
$env:PROJ_LIB = "C:\path\to\gdal\proj"

方案 3:抑制 GDAL 警告(不推荐)

如果只是想隐藏警告而不解决根本问题:

# 在 run_backend.py 中添加
from osgeo import gdal
gdal.SetConfigOption('CPL_LOG', 'OFF')  # 关闭所有 GDAL 日志

不推荐原因

  • 会隐藏所有 GDAL 错误和警告
  • 不解决根本问题
  • 可能掩盖其他重要错误

验证

1. 检查 PROJ_LIB 是否生效

启动后端后,查看日志:

[*] Set PROJ_LIB to: C:\Users\...\site-packages\osgeo\data\proj

2. 运行扫描任务

在前端触发 D-InSAR 结果扫描,观察日志:

  • 应该不再出现 PROJ 警告
  • Footprint 提取正常完成

3. 验证坐标转换

from pyproj import Transformer
transformer = Transformer.from_crs("EPSG:32650", "EPSG:4326", always_xy=True)
x, y = transformer.transform(500000, 3000000)
print(f"Transformed: {x}, {y}")
# 应该不产生警告

前端锁定问题

问题:扫描任务运行时前端没有锁定

可能原因

  1. 扫描任务执行太快(< 3 秒),前端轮询间隔(3 秒)来不及捕获
  2. 任务状态更新有延迟

解决方案

方案 A:增加最小锁定时间(推荐)

在扫描任务开始时立即锁定,结束时延迟解锁:

# job_handlers.py
async def _handle_scan_dinsar(job: SystemJobORM) -> None:
    if not job.task_id:
        raise ValueError("SCAN_DINSAR requires task_id for progress tracking.")

    await task_service.start_task(job.task_id, message="正在扫描 D-InSAR 结果...")

    # 确保任务至少运行 2 秒,让前端有时间捕获
    start_time = time.time()

    # ... 执行扫描 ...

    # 确保最小执行时间
    elapsed = time.time() - start_time
    if elapsed < 2.0:
        await asyncio.sleep(2.0 - elapsed)

    await task_service.complete_task(job.task_id, message="扫描完成")

方案 B:前端立即锁定(更好)

在提交扫描任务后立即锁定前端,不等待轮询:

// DataManagementPanel.jsx
const handleScanDinsarResults = async () => {
  try {
    // 立即锁定前端
    onJobQueued?.(null, 'SCAN_DINSAR');

    const response = await scanDinsarResults(selectedDirs);
    const taskId = response.data.task_id;

    // 更新任务 ID
    onJobQueued?.(taskId, 'SCAN_DINSAR');

    addLog('info', `D-InSAR 结果扫描任务已提交: ${taskId}`);
  } catch (error) {
    // 解锁前端
    setIsGlobalLocked(false);
    addLog('error', `扫描失败: ${error.message}`);
  }
};

状态

  • PROJ 环境变量修复已实施
  • 等待测试验证
  • 前端锁定问题待确认是否需要修复

下一步

  1. 重启后端服务
  2. 运行 D-InSAR 结果扫描
  3. 观察日志,确认 PROJ 警告消失
  4. 如果前端仍未锁定,实施方案 B

相关文档

  • SECURITY_FIX_PROGRESS.md - 安全修复进度
  • HOTFIX_NGINX_BOM_2026-03-04.md - Nginx BOM 修复