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

205 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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`
**修改内容**
```python
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` 文件中手动设置:
```bash
# 找到 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 启动脚本中设置:
```powershell
# scripts/start_app.ps1
$env:PROJ_LIB = "C:\path\to\gdal\proj"
```
### 方案 3:抑制 GDAL 警告(不推荐)
如果只是想隐藏警告而不解决根本问题:
```python
# 在 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. 验证坐标转换
```python
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:增加最小锁定时间(推荐)
在扫描任务开始时立即锁定,结束时延迟解锁:
```python
# 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:前端立即锁定(更好)
在提交扫描任务后立即锁定前端,不等待轮询:
```javascript
// 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 修复