43 KiB
InSAR 自动化管理与智能评估系统 - 部署与使用说明
本文件为本项目主中文文档,整合了产品说明、技术架构、业务流程、部署与启动、数据库与授权等内容。
补充专题文档见:docs/TODO.md、docs/RADAR_PREVIEW_SCHEME_B.md。
1. 产品概述
本系统是一套深度集成 IDL/ENVI SARscape 的专业级 InSAR 数据管理与智能分析平台,聚焦地质灾害监测领域,解决大规模雷达影像处理流程繁琐、数据关联困难、结果解译依赖人工等问题。
通过“Web 化管理 + 自动化引擎 + AI 智能诊断”的三位一体架构,实现从原始 SAR 影像入库到生成形变诊断报告的全生命周期自动化管理。
2. 核心优势
- 核心流程自动化:覆盖数据监控、精轨关联、干涉配对、自动化处理引导与结果发布(当前扫描调度默认手动触发)。
- 高精度空间引擎:凸包算法 + 仿射变换,支持亚像素级 Footprint 提取与空间关联。
- AI 辅助决策:集成随机森林质量评估模型与 VLM 视觉大模型,给出专家级解译建议。
- 工业级稳定性:针对 Windows Server 环境优化,支持 GB 级超大影像处理。
3. 技术架构
- 管理层 (Web Interface):React + Vite + Leaflet(支持离线多级细节加载)
- 逻辑层 (Service Layer):FastAPI 异步框架,集成 PostgreSQL + PostGIS
- 空间引擎 (Spatial Engine):PostGIS 原生计算 + GeoAlchemy2 + Rasterio
- AI 引擎 (Intelligence):Scikit-learn + 本地 Ollama VLM
- 计算引擎 (Compute):IDL 8.8 / ENVI 5.6(SARscape 5.6+)
4. 业务流程指南
4.1 数据资产监控
当前系统默认采用 Manual-only(手动触发) 扫描模式,不启用后台定时守护任务。
可通过前端“立即扫描”或接口 POST /api/monitor/run-now 触发扫描;扫描内部仍采用增量策略以降低系统负载。
D-InSAR 结果扫描说明(重要):
当前 D-InSAR 结果扫描为全量遍历 + 仅新增入库。
即:每次扫描都会遍历所有 .hdr 文件,但数据库只写入“新发现”的结果记录,以保证准确性和稳定性。
扫描任务的进度条基于实际遍历数量与处理数量计算,前端显示为真实进度。
数据列表已支持“影像信息”按钮,可查看影像基础元数据(卫星/日期/模式/极化/精轨等)。
影像元数据解析已扩展:优先从 XML 获取成像模式/极化/轨道方向,并补充卫星模式、接收站代号、圈号、景中心经纬度、采集时间、产品类型/级别、唯一标识等字段用于展示。
源数据预览缓存接口:GET /api/radar-data/{data_id}/thumb(首次请求若无缓存会自动生成)。
源影像预览(Scheme B:后端预纠正缓存)
系统已接入双层缓存:
backend/image_cache/radar_geo/:地理纠正后的主缓存(前端优先使用)backend/image_cache/radar_raw/:原图 WebP 回退缓存
D-InSAR 结果缓存(标准目录)
backend/image_cache/dinsar/:D-InSAR 结果可视化缓存目录- 文件命名:
ID_{id}_{name}.webp - 清单文件:
backend/image_cache/dinsar/cache_manifest.json
一致性检测(统计面板)
GET /api/statistics已新增一致性字段,用于校验“数据库记录 vs 实际缓存文件 vs XML 读取结果”。- 重点包含:
- D-InSAR:
db_cached_but_file_missing_count、db_uncached_but_file_exists_count、manifest_missing_file_count - 源影像预览:
db_ready_but_cache_missing_count、preview_missing_count - XML:
xml_detected_but_unparsed_count、xml_missing_count
- D-InSAR:
- 前端「数据统计仪表盘」会直接显示异常数量并高亮提示,便于运维快速定位问题。
新增接口:
GET /api/radar-data/{id}/preview-status:查询单条源影像预览缓存状态POST /api/radar-data/{id}/rebuild-preview-cache:管理员强制重建该影像预览缓存GET /api/radar-data?limit=500&offset=0:分页获取源数据列表(单次最多 2000 条)POST /api/radar-data/search:源数据分页检索(支持详情字段筛选 + 行政区/上传SHP空间筛选)GET /api/radar-data/search/options:获取源数据检索下拉选项(来自数据库去重值)GET /api/dinsar-results?limit=500&offset=0:分页获取 D-InSAR 结果列表(单次最多 2000 条)GET /api/radar-data/imaging-dates:获取所有可用成像日期(用于配对起始日期下拉框)GET /api/statistics:默认返回缓存快照;管理员可用GET /api/statistics?fresh=true强制重算
/api/radar-data/search 说明:
- 权限:管理员与只读账号均可调用(只读安全查询接口)。
- 筛选字段:可按卫星、成像时间范围、模式/极化/产品元数据等详情字段检索。
- 空间筛选:支持
region_tree_id(复用行政区)或上传 AOI 文件(.shp/GeoJSON)。 - 分页性能:首次 AOI 查询会返回
aoi_token,后续翻页可仅携带 token,无需重复上传文件。 - 前端交互:检索字段采用“全下拉可选”,避免手工输入导致的筛选误差。
分页接口响应结构(/api/radar-data 与 /api/dinsar-results 一致):
{
"items": [],
"total": 12345,
"limit": 200,
"offset": 0,
"has_more": true
}
前端分页说明:
- 「数据列表」与「D-InSAR 结果」均支持上一页/下一页、每页条数切换(50/100/200/500)与页码跳转。
- 前端默认每页 200 条,避免一次性加载全量数据导致页面和地图卡顿。
- 「数据列表」改为“先检索后展示”:系统启动后不自动加载源数据,需点击“搜索”或“搜索全部源数据”后才显示列表与分页结果。
- 当检索条件变更并再次执行搜索时,前端会先清空旧结果再渲染新结果,避免“旧页数据残留”造成误判。
- 异常/堆栈文本默认不参与界面翻译(e.g.
NoneType object is not callable、Traceback),保持原始语言以避免日志或异常信息被误替换。
新增环境变量(可选):
RADAR_GEO_CACHE_WORKERS=2
RADAR_GEO_CACHE_VERSION=b1
RADAR_GEO_CACHE_QUALITY=84
RADAR_PREVIEW_BUILD_ON_DEMAND=true
说明:
thumb接口优先返回radar_geo,失败时自动回退radar_raw。- 扫描任务会增量构建
radar_geo,并维护radar_raw作为兜底。 - 如纠正逻辑升级,提升
RADAR_GEO_CACHE_VERSION可触发重建。 - 纠正方向判定优先使用 XML 的
sceneCornerCoord/refRow/refColumn建立“像素角 ↔ 地理角”映射,可显著减少左右/上下方向错误。
4.2 任务分发与处理
系统生成处理清单对接 IDL 自动化脚本,用户可在 Web 端一键启动本地 IDL 工作站,实现“云端规划,本地计算”。
4.3 智能诊断报告
AI 模块结合影像范围内的已知灾害点生成 Markdown 报告,涵盖:活动性评估、隐患搜寻、风险评级与处置建议。
5. 核心算法与机制概览
为保持文档完整性,以下为算法专题的简要说明(不再拆分子文档):
- 智能任务规划与贪心优化:多维约束模型、覆盖多样性惩罚与任务筛选策略。
- 空间几何与极速 Footprint:降采样探测 + 凸包生成,结合拓扑简化提升效率。
- AI 诊断与图像处理:百分比截断拉伸、质量评估特征与自动裁剪策略。
6. 环境与依赖
- OS:Windows Server 2019+(推荐)
- 数据库:PostgreSQL 14+ + PostGIS
- Python:推荐 Conda 环境(本项目 environment.yml 已固定为 Python 3.10)
- Nginx:用于前端静态资源与反向代理(推荐)
- Node.js:仅构建前端时需要
- IDL/ENVI:仅启用 IDL 自动化时需要
7. 离线 Python 环境(推荐:conda-pack)
7.1 开发机(有外网)
conda env create -f environment.yml
conda activate InSAR
如需授权功能,请确保安装 cryptography:
pip install cryptography
如需打包授权 GUI:
pip install pyinstaller
打包环境:
conda install -n base conda-pack
conda pack -n InSAR -o insar_env.tar.gz
将 insar_env.tar.gz 拷贝到服务器。
7.2 服务器(离线)
解压到目标目录(示例:C:\envs\InSAR):
mkdir C:\envs\InSAR
tar -xzf insar_env.tar.gz -C C:\envs\InSAR
C:\envs\InSAR\Scripts\conda-unpack.exe
如果没有 tar,可使用 7-Zip 解压。
在 .env 中配置:
PYTHON_PATH=C:\envs\InSAR\python.exe
PYTHON_PATH 也支持命令名(如 python),scripts/start_app.ps1 会通过 Get-Command 解析真实可执行文件路径。
若使用 Conda,建议先激活 InSAR 环境后再启动,或直接填入该环境的 python.exe 绝对路径。
也可使用 Conda 原生模式(推荐):
CONDA_EXE=D:\anaconda3\Scripts\conda.exe
CONDA_ENV_NAME=InSAR
当 CONDA_ENV_NAME 非空时,scripts/start_app.ps1 会优先使用
CONDA_EXE 定位目标环境并解析其 python.exe,随后使用该解释器执行数据库检查、初始化、后端与 Worker 启动流程(避免并发 conda run 稳定性问题)。
不建议直接复制 venv,二进制依赖容易失效。
8. 数据库准备
8.1 创建数据库
psql -U postgres -h localhost -p 5432
CREATE DATABASE insar_management;
\q
8.2 启用 PostGIS
psql -U postgres -h localhost -p 5432 -d insar_management
CREATE EXTENSION IF NOT EXISTS postgis;
\q
8.3 配置连接并检测
在 .env 中设置:
DATABASE_URL=postgresql+asyncpg://user:pass@host:5432/insar_management
手动检查连接:
D:\anaconda3\Scripts\conda.exe run -n InSAR python scripts/check_db_connection.py
9. 授权(离线)
启动授权管理工具:
D:\anaconda3\Scripts\conda.exe run -n InSAR python scripts/license_manager_gui.py
使用流程:
- 选择
.env路径 - 输入到期时间(UTC,格式:
YYYY-MM-DD HH:MM:SS,留空默认 1 年) - 点击“生成/续期授权”
- 自动写入
.env中的LICENSE_SECRET/LICENSE_PUBLIC_KEY - 生成
backend\license\license.lic与license_private_key.txt
说明:
license_private_key.txt请妥善保存(用于续期)。- 服务器只需要公钥与授权文件,不要部署私钥。
- 建议仅在离线管理机保存私钥文件,避免在业务服务器落盘或备份私钥。
- 离线授权属于本地合规校验机制:可显著提高误用门槛,但不等同于“对拥有服务器管理员权限场景”的绝对防篡改。
授权相关接口:
/api/license/status
/api/license/upload (仅管理员可调用)
/api/license/refresh (仅管理员可调用)
返回约束(安全脱敏):
GET /api/license/status默认仅返回ok、reason、expires_at。- 当请求携带管理员会话时,
GET /api/license/status会额外返回调试字段(如fingerprint、license_path)。
10. 关键配置(.env)
常用参数示例:
# 服务显示地址(用于启动日志与前端展示)
SERVER_HOST=192.168.1.100
# 后端端口(示例使用 18000,避免与常见本机服务冲突)
PORT=18000
# 前端开发模式代理目标(仅 npm run dev 使用)
VITE_BACKEND_TARGET=http://localhost:18000
# Python / Nginx 路径
PYTHON_PATH=C:\envs\InSAR\python.exe
CONDA_EXE=D:\anaconda3\Scripts\conda.exe
CONDA_ENV_NAME=InSAR
NGINX_PATH=C:\nginx-1.29.4\nginx.exe
# IDL / ENVI 路径与 worker 管理目录
IDL_EXECUTABLE=C:\Program Files\Harris\ENVI56\IDL88\bin\bin.x86_64\idl.exe
IDL_WORKBENCH_PATH=C:\Program Files\Harris\ENVI56\IDL88\bin\bin.x86_64\idlde.exe
IDL_WORKER_SCRIPT_SOURCE_DIR=<项目根目录>\IDL\origin
IDL_WORKER_SCRIPT_DIR=<项目根目录>\IDL\worker_managed
IDL_WORKER_RUNTIME_DIR=<项目根目录>\backend\runtime\idl_worker
IDL_WORKER_DEFAULT_TIMEOUT_SECONDS=14400
IDL_WORKER_MAX_TIMEOUT_SECONDS=43200
IDL_WORKER_TEMP_DIRECTORY=D:\Sarscape_IDL_Area
# IDL worker 默认任务参数(可被 API 请求体覆盖)
IDL_IMPORT_ROOT_DIR=
IDL_IMPORT_NUM_TO_PROCESS=0
IDL_DINSAR_ROOT_DIR=
IDL_DINSAR_DEM_BASE_FILE=
IDL_DINSAR_NUM_TO_PROCESS=0
IDL_DINSAR_TARGET_GROUND_RESOLUTION_M=10.0
IDL_DINSAR_FILTER_METHOD=GOLDSTEIN
IDL_DINSAR_UNWRAP_COH_THRESHOLD=0.05
IDL_DINSAR_GCP_COH_THRESHOLD=0.7
IDL_DINSAR_GCP_NUMBER=100
IDL_DINSAR_GEOCODING_COH_THRESHOLD=0.0
IDL_DINSAR_GEOCODING_PIXEL_SIZE_M=10.0
# 授权
LICENSE_SECRET=...
LICENSE_PUBLIC_KEY=...
LICENSE_PATH=...\backend\license\license.lic
LICENSE_STATE_PATH=...\backend\license\license_state.json
MAX_LICENSE_UPLOAD_BYTES=1048576
# 鉴权(Session + Cookie)
INIT_ADMIN_USERNAME=admin
INIT_ADMIN_PASSWORD=<REQUIRED_STRONG_PASSWORD>
INIT_ADMIN_RESET_PASSWORD=false
SESSION_TTL_HOURS=12
AUTH_SESSION_COOKIE_NAME=ims_session
AUTH_COOKIE_SAMESITE=Lax
AUTH_COOKIE_SECURE=false
AUTH_LOGIN_MAX_FAILURES=5
AUTH_LOGIN_WINDOW_SECONDS=900
AUTH_LOGIN_LOCK_SECONDS=900
AUTH_LOGIN_CLEANUP_INTERVAL_SECONDS=300
# AOI 上传限流
AOI_UPLOAD_MAX_FILES=10
AOI_UPLOAD_MAX_SINGLE_FILE_BYTES=20971520
AOI_UPLOAD_MAX_TOTAL_BYTES=104857600
# 扫描请求边界
MAX_SCAN_DIRECTORY_COUNT=64
MAX_SCAN_PATH_LENGTH=2048
# 高频列表查询边界与超时
LIST_QUERY_MAX_LIMIT=2000
LIST_QUERY_MAX_OFFSET=200000
LIST_QUERY_MAX_WINDOW=202000
LIST_QUERY_TIMEOUT_MS=20000
RADAR_SEARCH_OPTIONS_MAX_VALUES=5000
RADAR_IMAGING_DATES_MAX_VALUES=5000
# 队列入队边界(防止异常大 payload 冲击数据库)
JOB_QUEUE_MAX_PAYLOAD_BYTES=524288
JOB_QUEUE_MAX_ATTEMPTS=10
JOB_QUEUE_MAX_PRIORITY_ABS=1000
JOB_QUEUE_MAX_ID_LENGTH=128
JOB_QUEUE_MAX_TYPE_LENGTH=64
# 任务/日志查询边界(防止单次查询放大)
TASK_ACTIVE_DEFAULT_LIMIT=100
TASK_ACTIVE_MAX_LIMIT=500
TASK_LOG_DEFAULT_LIMIT=100
TASK_LOG_MAX_LIMIT=1000
TASK_QUERY_MAX_OFFSET=500000
MONITOR_LOG_DEFAULT_LIMIT=50
MONITOR_LOG_MAX_LIMIT=200
MONITOR_LOG_MAX_OFFSET=500000
# 批次与复制请求边界
TASK_BATCH_MAX_ITEMS=5000
TASK_BATCH_TEXT_MAX_LENGTH=256
TASK_BATCH_REMARK_MAX_LENGTH=2000
TASK_BATCH_LIST_DEFAULT_LIMIT=200
TASK_BATCH_LIST_MAX_LIMIT=1000
TASK_BATCH_LIST_MAX_OFFSET=500000
COPY_BATCH_TEXT_MAX_LENGTH=2048
COPY_BATCH_MAX_STATUS_COUNT=8
# 工作流请求边界
WORKFLOW_MAX_STEPS=200
WORKFLOW_MAX_DEPENDS=32
WORKFLOW_TEXT_MAX_LENGTH=128
# AI 地图分析请求边界
AI_ANALYZE_MAP_MAX_IMAGES=4
AI_ANALYZE_MAP_MAX_IMAGE_BASE64_CHARS=12582912
AI_ANALYZE_MAP_PROMPT_MAX_CHARS=8000
# 生产环境请使用白名单,不建议 *
CORS_ORIGINS=http://192.168.1.100
CORS_ALLOW_CREDENTIALS=true
CORS_STRICT_MODE=false
# 统计缓存(秒)
STATS_CACHE_TTL_SECONDS=120
# 预览缓存(可选)
RADAR_THUMBNAIL_MAX_SIZE=1600
RADAR_CACHE_WORKERS=2
# 灾害点数据源
HAZARD_POINTS_DIR=Z:\Code\Insar_management_system_v2\backend\Point
HAZARD_POINTS_FILENAME=Point.shp
鉴权说明:
- 系统不提供公开注册入口。
- 首次启动或重置管理员密码时,
INIT_ADMIN_PASSWORD为必填项(不再提供默认密码回退)。 scripts/init_db.py会检查管理员账号;若不存在则按INIT_ADMIN_*自动创建。- 如需强制重置管理员密码:将
INIT_ADMIN_RESET_PASSWORD=true(仅重置当次生效,完成后建议改回false)。 - 内网 HTTP 部署请保持
AUTH_COOKIE_SECURE=false;若启用 HTTPS,请改为true。 - 登录防爆破参数:
AUTH_LOGIN_MAX_FAILURES(窗口内失败阈值)、AUTH_LOGIN_WINDOW_SECONDS(失败统计窗口)、AUTH_LOGIN_LOCK_SECONDS(触发后锁定时长)、AUTH_LOGIN_CLEANUP_INTERVAL_SECONDS(限流状态表后台清理间隔,秒)。 - AOI 上传限流参数:
AOI_UPLOAD_MAX_FILES(上传文件数量上限)、AOI_UPLOAD_MAX_SINGLE_FILE_BYTES(单文件字节上限)、AOI_UPLOAD_MAX_TOTAL_BYTES(同次请求总字节上限)。超限时接口返回HTTP 400。 - 扫描请求边界参数:
MAX_SCAN_DIRECTORY_COUNT(单次扫描请求目录数量上限)、MAX_SCAN_PATH_LENGTH(单路径字符串长度上限)。 - 高频列表查询边界参数:
LIST_QUERY_MAX_LIMIT(单页最大返回条数)、LIST_QUERY_MAX_OFFSET(最大偏移)、LIST_QUERY_MAX_WINDOW(limit+offset窗口上限),LIST_QUERY_TIMEOUT_MS(PostgreSQL 列表查询超时,毫秒);RADAR_SEARCH_OPTIONS_MAX_VALUES/RADAR_IMAGING_DATES_MAX_VALUES用于限制雷达检索选项和成像日期去重结果规模。 - 队列入队边界参数:
JOB_QUEUE_MAX_PAYLOAD_BYTES(单任务 payload 字节上限)、JOB_QUEUE_MAX_ATTEMPTS(重试次数上限)、JOB_QUEUE_MAX_PRIORITY_ABS(优先级绝对值上限)、JOB_QUEUE_MAX_ID_LENGTH(关联 ID 字符上限)、JOB_QUEUE_MAX_TYPE_LENGTH(任务类型字符串上限)。 - 任务/日志查询边界参数:
TASK_ACTIVE_DEFAULT_LIMIT、TASK_ACTIVE_MAX_LIMIT(GET /api/tasks/active分页上限),TASK_LOG_DEFAULT_LIMIT、TASK_LOG_MAX_LIMIT、TASK_QUERY_MAX_OFFSET(任务日志分页上限),MONITOR_LOG_DEFAULT_LIMIT、MONITOR_LOG_MAX_LIMIT、MONITOR_LOG_MAX_OFFSET(GET /api/monitor/logs分页与偏移上限)。 - 批次与复制请求边界参数:
TASK_BATCH_MAX_ITEMS(单批次条目数上限)、TASK_BATCH_TEXT_MAX_LENGTH(批次名称/方向长度上限)、TASK_BATCH_REMARK_MAX_LENGTH(条目备注长度上限)、TASK_BATCH_LIST_DEFAULT_LIMIT/TASK_BATCH_LIST_MAX_LIMIT/TASK_BATCH_LIST_MAX_OFFSET(批次列表与明细分页上限)、COPY_BATCH_TEXT_MAX_LENGTH(复制接口batch_id/dest_dir长度上限)、COPY_BATCH_MAX_STATUS_COUNT(复制状态列表数量上限)。 - 工作流请求边界参数:
WORKFLOW_MAX_STEPS(单工作流步骤上限)、WORKFLOW_MAX_DEPENDS(单步骤依赖数上限)、WORKFLOW_TEXT_MAX_LENGTH(工作流文本字段长度上限)。 - AI 地图分析请求边界参数:
AI_ANALYZE_MAP_MAX_IMAGES(单次请求图片数上限)、AI_ANALYZE_MAP_MAX_IMAGE_BASE64_CHARS(单图 Base64 长度上限)、AI_ANALYZE_MAP_PROMPT_MAX_CHARS(prompt 长度上限)。 - 授权上传默认采用“先校验后替换”的原子更新流程;无效授权不会覆盖当前在用授权文件。
MAX_LICENSE_UPLOAD_BYTES用于限制授权上传文件大小(默认 1MB)。CORS_ORIGINS建议配置为明确白名单;生产环境不建议使用*。- 当
CORS_STRICT_MODE=true时,若CORS_ORIGINS包含*且CORS_ALLOW_CREDENTIALS=true,服务将拒绝启动。 - 严禁将包含真实
DATABASE_URL、LICENSE_SECRET的.env提交到代码仓库或共享目录。 - 管理员可通过
GET /api/auth/audit-logs?limit=200查看最近审计日志(仅 admin 可访问)。 - 许可文件上传与刷新接口(
POST /api/license/upload、POST /api/license/refresh)仅允许管理员会话访问。 - 前端入口:左侧「运行维护」分组下新增「用户管理」「审计日志」两个管理员面板。
源影像缓存说明:
- 系统在扫描雷达源数据时,会尝试在每个场景目录中查找预览图(jpg/jpeg/png/webp/bmp/tif/tiff)并生成 WebP 缓存。
- 雷达缓存目录:
backend/image_cache/radar_geo/(主)与backend/image_cache/radar_raw/(回退)。 - D-InSAR 缓存目录:
backend/image_cache/dinsar/(统一使用ID_{id}_{name}.webp)。 - 前端「数据列表」支持源影像单条显示/隐藏与“一键显示/一键隐藏”。
- 长期稳定方案(后端预纠正缓存,B 方案)设计见:
docs/RADAR_PREVIEW_SCHEME_B.md。
11. 启动方式
11.1 一键启动(推荐)
双击:
start_system.bat
或命令行:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts\start_app.ps1
说明:
- 启动链路保持不变:
start_system.bat->scripts/start_app.ps1->check_db_connection.py->init_db.py。 scripts/start_app.ps1中PYTHON_PATH支持“绝对路径”或“命令名”(例如python);脚本会先解析为可执行文件再调用。init_db.py会在“建库/校验修复”后执行鉴权初始化(自动补齐管理员账号)。- 扫描调度默认 Manual-only,不会后台定时自动触发;需通过前端或
/api/monitor/run-now手动触发扫描。 - 默认不执行破坏性重建;若确需重建,请显式设置
DB_SCHEMA_RESET_ON_MISMATCH=true。
11.2 仅启动后端(无 Nginx)
D:\anaconda3\Scripts\conda.exe run -n InSAR python run_backend.py
说明:后端默认绑定 127.0.0.1,仅本机访问。
11.3 后台队列 Worker(必需)
系统后台任务已改为“入队执行”,必须启动 Worker 才会真正执行扫描、AI、解包、复制等任务。
启动方式:
D:\anaconda3\Scripts\conda.exe run -n InSAR python run_worker.py
说明:
start_system.bat已包含 Worker 启动。- 若只运行
run_backend.py,请手动启动run_worker.py。 - 数据分发/复制任务仅从“批次”读取,不再支持 Excel。
POST /api/monitor/run-now的target仅支持:radar、orbit、dinsar(留空表示全部)。
Worker 可选环境变量:
JOB_WORKER_POLL_INTERVAL=1.0 # 轮询间隔(秒)
JOB_WORKER_CONCURRENCY=1 # 并发执行数
JOB_WORKER_JOB_HEARTBEAT_INTERVAL=5 # 运行中作业心跳上报间隔(秒)
JOB_WORKER_STALE_RECOVER_INTERVAL=15 # 僵尸 RUNNING 作业回收检查间隔(秒)
JOB_WORKER_STALE_RUNNING_SECONDS=300 # 判定作业僵尸的超时阈值(秒)
IDL_JOB_MAX_ATTEMPTS=6 # IDL 队列任务最大重试次数
ENVI/SARscape 集成(envipyengine):
- 执行引擎:
envipyengine(pip 包)→taskengine.exe子进程 - 工作流在独立 Python 子进程中执行,隔离 FastAPI 主进程
- D-InSAR 工作流自动检测未导入数据,先执行 Import 再处理 D-InSAR(智能串联)
- DEM 路径为系统级配置,存储在
.env的IDL_DINSAR_DEM_BASE_FILE - 运行日志目录:
backend/runtime/idl_worker/
ENVI 关键环境变量:
IDL_EXECUTABLE=... # IDL 可执行路径
IDL_WORKBENCH_PATH=... # IDL Workbench 路径
IDL_WORKER_RUNTIME_DIR=... # 运行日志目录
IDL_WORKER_DEFAULT_TIMEOUT_SECONDS=14400 # 单任务执行超时(秒)
IDL_WORKER_MAX_TIMEOUT_SECONDS=43200 # 单任务允许最大超时(秒)
IDL_DINSAR_DEM_BASE_FILE=... # DEM 路径(D-InSAR 必需)
API 端点(管理员):
GET /api/idl/status — 系统状态(含 DEM 路径和可用性)
POST /api/idl/launch-workbench — 启动 IDL Workbench
POST /api/idl/inspect/import — Import 预检查
POST /api/idl/inspect/dinsar — D-InSAR 预检查(含 Import 状态检测)
POST /api/idl/jobs/import — 提交 Import 任务
POST /api/idl/jobs/dinsar — 提交 D-InSAR 任务
GET /api/idl/jobs/recent — 最近运行记录
提交任务请求体示例:
{
"root_dir": "Z:/Test_data/Test_IDL_1",
"num_to_process": 0,
"timeout_seconds": 14400
}
说明:
- 提交后会创建系统任务并入队,由
run_worker.py消费执行。 - D-InSAR 工作流自动检测未导入数据,先执行 Import 再处理(智能串联)。
- DEM 路径从
.env读取,不需要在请求中传递。 - Worker 在执行时会周期性更新作业心跳;若进程崩溃导致作业长期停留
RUNNING,会自动回收。 - 运行日志保存在
IDL_WORKER_RUNTIME_DIR/下。
11.4 前端构建(仅构建时需要)
cd frontend
npm install
npm run build
说明:
- 前端日期控件已统一为
flatpickr(原生实例接入),无需浏览器原生input[type=date]。 - 若采用“本地构建后上传
frontend/dist”部署方式,服务器端无需额外安装前端依赖包。
11.5 离线切片底图切换
前端从 frontend/public/tiles/ 读取离线切片,当前支持三套(统一 webp):
tiles/google_image/{z}/{x}/{y}.webptiles/gaode_image/{z}/{x}/{y}.webptiles/gaode_shp/{z}/{x}/{y}.webp
地图右上角「底图」按钮可在三套底图间切换(默认 gaode_shp,便于仅下载高德矢量时直接可用)。
缩放级别已放开到 0-16;如需调整默认底图或级别,请修改 frontend/src/App.jsx 中的 TILE_LAYER_DEFAULT_KEY 与 TILE_LAYER_OPTIONS。
行政区边界叠加图层(地图参考边界)默认读取:
frontend/public/geojson/全国行政区.geojson
建议使用 UTF-8 无 BOM 编码,且文件体积较大时优先通过 public/ 静态加载(不要直接放入 frontend/src 参与打包)。
地图左上角新增「区域定位」按钮(可折叠),复用行政区二级级联(省/市):
- 可只选择到省级或市级进行定位。
- 定位时会调用后端
/api/aoi/regions/{tree_id}/geometry获取边界并自动缩放到该区域。 - 定位成功后,面板会显示“当前定位”行政区名称,方便与当前视角对照。
- 面板支持「清除定位高亮」,可一键移除地图上的定位边界高亮。
- 依赖
backend/geojson/层级映射.json与backend/geojson/全国行政区.geojson的行政区数据。
12. 访问与验证
- 前端:
http://SERVER_HOST - 后端(内部):
http://127.0.0.1:8000 - 接口文档(内部):
http://127.0.0.1:8000/docs
前端语言切换:
- 顶部状态栏新增
中文 / EN切换按钮。 - 切换结果会保存在浏览器本地(
localStorage),刷新页面后保持上次语言选择。 - 站内文案翻译映射位于
frontend/src/i18n/translations.js,新增界面文案时需同步补充映射,避免中英文混杂。 - 第二轮已补齐高频业务模块(批次/分发、运维自检、用户管理、审计日志、IDL 自动化、统计面板)常用文案映射。
- 第三轮已支持运行日志双语展示:右侧日志栏、数据监控日志、数据分发任务日志会随语言切换进行前端翻译。
- 当前词典已覆盖常见后端运行日志模板(扫描、拷贝、解包、任务生命周期);若新增日志模板,建议同步补充词典条目。
- 收口说明:当前前端可见业务文案已基本完成双语覆盖,剩余英文主要为样式类名/技术标识(不面向客户显示)。
13. 常用脚本说明
start_system.bat:一键启动入口(调用 PowerShell 启动脚本)scripts/start_app.ps1:启动后端 + Nginx,并执行数据库检查run_backend.py:仅启动后端服务run_worker.py:后台任务 Worker(队列执行)scripts/check_db_connection.py:数据库连接检查scripts/init_db.py:数据库结构检查与初始化scripts/license_manager_gui.py:授权文件生成与续期scripts/get_fingerprint.py:机器指纹获取scripts/unpack_archives.py:解包与数据整理(支持 tar.gz)scripts/pack_environment.bat:打包 Conda 环境(如使用)scripts/auth_smoke_check.py:鉴权冒烟检查(401/403/200 核心链路)
14. 常见问题
-
Python executable not found
检查.env中PYTHON_PATH是否正确;可使用绝对路径,或在已激活 Conda 环境后填写python。
如启用 Conda 原生模式,还需确认CONDA_EXE与CONDA_ENV_NAME配置正确。 -
数据库连接失败
确认 PostgreSQL 服务已启动、DATABASE_URL正确,并运行scripts/check_db_connection.py测试。 -
授权无效/过期
使用授权工具续期,检查系统时间是否回退过多。 -
前端打不开但后端正常
确认 Nginx 已启动、NGINX_PATH正确、前端已构建。
若启动时报no "events" section in configuration,请检查nginx/nginx.conf是否为空或损坏,需恢复包含events {}与http {}的完整配置。 -
后端端口被占用(Address already in use / Access denied)
scripts/start_app.ps1启动前会检查PORT对应监听占用;若被占用会直接报错并终止。
请停止占用该端口的进程,或在.env中修改PORT后重试。
脚本会在启动时自动把nginx/nginx.conf中的proxy_pass同步到该PORT,无需手动改 Nginx 反向代理端口。 -
后端或 Worker 启动后立即退出
scripts/start_app.ps1会在拉起后端与 Worker 后做快速存活检查;若进程秒退,脚本会立即报错并退出。
请优先检查终端输出与后端日志,常见原因包括端口冲突、依赖缺失、环境变量配置错误。
最小可用 nginx.conf 模板(按需替换路径,proxy_pass 端口需与 .env 的 PORT 一致):
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
root "G:/Code/Insar_management_system_v2/frontend/dist";
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://127.0.0.1:18000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /image_cache/ {
alias "G:/Code/Insar_management_system_v2/backend/image_cache/";
}
}
}
14.1 鉴权与登录排查
GET /api/auth/me返回401:未登录状态下这是正常现象,前端应显示登录页。POST /api/auth/login返回401:用户名或密码错误,先核对.env中INIT_ADMIN_USERNAME/INIT_ADMIN_PASSWORD;若为首次启动且INIT_ADMIN_PASSWORD为空,初始化会直接报错。POST /api/auth/login返回429:触发登录限流/锁定,等待Retry-After秒后重试,或调整AUTH_LOGIN_MAX_FAILURES / AUTH_LOGIN_WINDOW_SECONDS / AUTH_LOGIN_LOCK_SECONDS。- 登录后接口仍持续
401:检查浏览器是否携带 Cookie(请求需withCredentials=true),并确认反向代理没有丢弃Set-Cookie头。 - 需要重置管理员密码:设置
INIT_ADMIN_RESET_PASSWORD=true,重启一次系统完成重置后再改回false。 - Cookie 在内网 HTTP 不生效:确认
AUTH_COOKIE_SECURE=false;只有 HTTPS 场景才应设置为true。 - 需要核查谁触发了高风险写操作:使用
GET /api/auth/audit-logs?limit=200(管理员会话)。 - 需要快速回归鉴权链路:后端启动后运行
D:\anaconda3\Scripts\conda.exe run -n InSAR python scripts/auth_smoke_check.py --base-url http://127.0.0.1:8000。
- 任务一直处于“执行中”
确认run_worker.py已启动(或使用start_system.bat一键启动)。
- 若期望系统自动周期扫描:当前默认是手动模式(Manual-only),请使用前端“立即扫描”或调用
POST /api/monitor/run-now。
- 配对结果异常或为空
- 影像日期需为
YYYYMMDD格式(系统从文件夹名解析)。 - AOI 支持 SHP 上传 与 GeoJSON 传参(
aoi_geojson)两种模式。 - AOI Shapefile 建议使用 EPSG:4326(WGS84),否则需先进行投影转换。
- 若使用“行政区选择”,请准备标准 GeoJSON(见 17.7),并确保
features[*].properties.treeID与backend/geojson/层级映射.json对应。
- 灾害点导入为 0 条
请确保 Shapefile 中存在唯一标识字段(优先TYBH),并具备经纬度或点几何:
- 必填:
TYBH(唯一编号) - 推荐:
hazard_type/hazard_name/city/county/township - 坐标:点几何优先;若无几何,则读取经度/纬度字段
数据源路径:.env中HAZARD_POINTS_DIR+HAZARD_POINTS_FILENAME(默认backend/Point/Point.shp)。
-
Excel 功能找不到了
Excel 导入/导出已移除,请使用“任务批次 + 数据分发”流程完成复制与人工状态管理。 -
日志出现 “got Future attached to a different loop”
该错误通常由子线程内创建事件循环并复用 asyncpg 连接引起,多发生在自建asyncio.run(...)的耗时任务里。
处理方式:
-
确保所有耗时任务由 Worker 执行(统一事件循环),避免在线程内自行
asyncio.run。 -
重启后端与 Worker 以释放异常连接。
-
如仍复现,请检查是否有自定义脚本在子线程内直接调用数据库。
15. 数据库结构自动对齐(重要)
系统每次启动会进行数据库结构检查:
- 首次启动:自动创建表结构。
- 后续启动:校验表/列/类型/可空性。
- 不一致(默认):不做破坏性重建,仅补齐缺失结构并输出告警。
- 不一致(显式开启):仅当
DB_SCHEMA_RESET_ON_MISMATCH=true时执行 drop/recreate 重建。
推荐在生产/内网环境保持如下默认值(保留历史数据):
DB_SCHEMA_RESET_ON_MISMATCH=false
15.1 SQL 函数更新说明
若修改了 backend/migrations/002_spatial_functions.sql(例如配对函数 find_dinsar_pairs),需要执行一次:
- 重新启动系统(
start_system.bat会自动调用scripts/init_db.py) - 或手动运行
D:\anaconda3\Scripts\conda.exe run -n InSAR python scripts/init_db.py
15.2 空间函数迁移(必需)
启动时会自动执行以下迁移文件(用于空间函数、视图与日志表):
backend/migrations/001_st_intersection_agg.sqlbackend/migrations/002_spatial_functions.sql
如需手工修改,请保证 SQL 语法正确且使用 UTF-8 编码。
16. 工作流与任务队列(新增)
后台任务已改为队列执行(DB Job Queue):
- 复制、解包、扫描、AI 训练/预测/诊断等任务都会入队。
- Worker 执行任务并更新状态,前端可查看任务进度。
- 所有耗时任务在 Worker 的事件循环中执行,避免跨事件循环导致的 asyncpg 连接异常。
工作流 API:
POST /api/workflow/runs创建工作流实例GET /api/workflow/runs/{run_id}查询运行状态与步骤
任务查询 API(新增分页参数):
GET /api/tasks/active?limit=100&offset=0GET /api/tasks/{task_id}GET /api/tasks/{task_id}/logs?limit=100&offset=0GET /api/monitor/logs?limit=50&offset=0
17. 任务批次管理(替代 Excel)
为适配 IDL 线下生产流程,D-InSAR 与 PS-InSAR 任务改为“批次”形式存储在数据库:
- 前端创建批次(不再使用 Excel 导入/导出)。
- 可按批次查看明细、手动标记完成、添加备注。
- 数据分发从批次中读取任务条目并复制到目标目录。
- Excel 导入/导出接口已移除。
相关 API:
POST /api/task-batches/dinsarGET /api/task-batches/dinsar?limit=200&offset=0GET /api/task-batches/dinsar/{batch_id}/items?limit=200&offset=0PATCH /api/task-batches/dinsar/{batch_id}/complete-allPATCH /api/task-batches/dinsar/items/{item_id}POST /api/task-batches/psGET /api/task-batches/ps?limit=200&offset=0GET /api/task-batches/ps/{batch_id}/items?limit=200&offset=0PATCH /api/task-batches/ps/{batch_id}/complete-allPATCH /api/task-batches/ps/items/{item_id}
数据分发 API:
POST /api/tools/copy-ps-stack(body:batch_id,dest_dir,copy_statuses?)POST /api/tools/copy-dinsar-pairs(body:batch_id,dest_dir,copy_statuses?)GET /api/tools/copy-status/{task_id}?limit=100&offset=0
17.1 前端操作流程(推荐)
-
生成候选列表
- D-InSAR:左侧“干涉对配对”生成 pairs。
- PS-InSAR:左侧“PS 时序栈”生成 stack。
-
保存为批次
- 点击“保存批次”,系统将当前列表写入数据库。
- 批次会自动生成
batch_id,支持自定义名称。 - 保存成功后前端会自动切换到“任务批次”并定位到新建批次。
-
批次管理与人工标注
- 在右侧“任务批次”面板选择 D-InSAR 或 PS。
- 进入某批次后:
- 修改每条任务状态(PENDING / IN_PROGRESS / COMPLETED / FAILED)
- 接口仅接受上述四种状态值(大小写不敏感,非法值会返回
400) - 为每条任务添加备注(如:文件损坏、未完成原因)
- 支持“一键全部完成”
-
数据分发(复制)
- 进入“数据分发”面板选择批次与目标目录后启动复制。
- 可按任务状态筛选复制(默认仅复制
COMPLETED)。 - 复制任务由 Worker 执行,进度可在前端日志中查看。
- 若出现部分文件复制失败,任务最终会标记为
FAILED(不再误报成功)。
17.2 批次数据结构(数据库)
系统会创建以下表:
dinsar_task_batches/dinsar_task_itemsps_task_batches/ps_task_items
每条 item 包含:
status(人工状态)remark(备注)- 任务路径与元数据(用于复制与后续追踪)
17.3 数据分发复制规则
PS-InSAR:
- 复制源优先使用
{original_path}_envi_import(若存在) - 否则使用原始路径
D-InSAR:
- 为每个任务创建子目录:
<dest>/<task_name>/master<dest>/<task_name>/slave
- 若源目录内存在
envi_import且非空,优先复制envi_import
17.4 Excel 迁移说明
历史流程若依赖 Excel:
- 现在请在系统中生成批次并使用“数据分发”复制。
- 复制任务仅接收
batch_id,不再接收 Excel 文件。
17.5 API 示例(简化)
创建 D-InSAR 批次:
POST /api/task-batches/dinsar
{
"name": "DINSAR_20260208",
"pairs": [
{
"task_name": "T001",
"master": {"file_path": "D:/data/master1", "...": "..."},
"slave": {"file_path": "D:/data/slave1", "...": "..."},
"time_baseline_days": 12,
"spatial_baseline_meters": 1234.5
}
]
}
复制 D-InSAR 批次:
POST /api/tools/copy-dinsar-pairs
{
"batch_id": "xxxx-xxxx-xxxx",
"dest_dir": "D:/IDL/tasks/dinsar",
"copy_statuses": ["COMPLETED"]
}
17.6 配对参数说明(新增)
/api/find-pairs 支持以下可选参数(表单提交):
require_same_imaging_mode:是否要求主/辅影像成像模式一致(默认true,空值视为不匹配)require_same_polarization:是否要求主/辅影像极化一致(默认true,空值视为不匹配)aoi_overlap_threshold:AOI 覆盖比例阈值,计算方式为Area(image ∩ AOI) / Area(AOI),需主/辅影像同时满足aoi_geojson:可选,标准 GeoJSON 字符串(与files二选一或都不传)
系统会在候选配对数超过 3000 时返回提示信息。若数据库配对函数不可用,仅在影像数量 ≤1500 时允许回退计算,并返回强提醒。
前端已提供“成像模式一致 / 极化一致 / AOI 覆盖率阈值”的开关与输入框,默认关闭/0(不额外限制)。
17.7 行政区选择(SHP/行政区二选一)
生产规划弹窗中,AOI 来源支持:
- 上传
SHP(兼容旧流程) - 行政区选择(省/市二级联动)
后端新增接口:
GET /api/aoi/regions/children?parent_tree_id=1GET /api/aoi/regions/{tree_id}/geometry
相关环境变量(后端 .env):
AOI_REGION_INDEX_FILE=backend/geojson/层级映射.json
AOI_REGION_GEOJSON_FILE=backend/geojson/全国行政区.geojson
17.8 行政区 GeoJSON 数据规范(需提前准备)
建议提供一个标准 FeatureCollection 文件(UTF-8),示例:
{
"type": "FeatureCollection",
"features": [
{
"type": "Feature",
"properties": {
"treeID": "1-23-4",
"name": "示例地市",
"level": "city"
},
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[ [116.0, 39.0], [116.2, 39.0], [116.2, 39.2], [116.0, 39.2], [116.0, 39.0] ]]]
}
}
]
}
字段要求:
- 必填:
properties.treeID(与层级映射.json一致) - 可选:
properties.name、properties.level geometry建议使用 EPSG:4326(经纬度)
说明:
- 当前前端行政区选择为省/市二级,不提供区县单独选择入口。
- 若仅提供区县级数据,系统会在省/市选择时自动合并其下级边界。
- 若仅提供到市级数据,前端可直接按市级选择,后端会在必要时回退到最近可用上级边界(市→省)。
- 若
treeID不匹配或缺失,行政区选择将无法返回 AOI 边界。
18. 运维自检(新增)
系统提供运维自检接口与前端面板,用于快速判断关键服务状态。
后端接口:
GET /api/health
返回约束(安全脱敏):
- 未登录或只读会话:返回最小健康摘要(
ok/timestamp+ 各子系统布尔状态与基础计数)。 - 管理员会话:返回完整诊断信息(包含错误详情、Worker 列表、外部服务状态细节)。
检查内容:
- 数据库连接 / PostGIS 扩展 / 关键表结构
- 关键表覆盖包含:任务与队列(
system_tasks/task_logs/system_jobs/scan_states)、工作流(workflow_defs/workflow_runs/workflow_steps/workflow_artifacts)、鉴权(auth_users/auth_sessions/auth_audit_logs/auth_rate_limits)等核心表
- 关键表覆盖包含:任务与队列(
- Worker 心跳
- IDL/ENVI 状态
- Ollama 连通性
- Nginx 连通性
- 一致性异常汇总(来自
GET /api/statistics):- D-InSAR 缓存:数据库标记与实际缓存文件是否一致
- 源影像预览缓存:
READY状态与radar_geo/radar_raw文件是否一致 - XML 读取:是否检测到 XML 以及关键字段是否成功入库
相关环境变量:
JOB_WORKER_HEARTBEAT_INTERVAL=5 # Worker 心跳上报间隔(秒)
JOB_WORKER_HEALTH_TIMEOUT=60 # 运维自检判定 Worker 离线的阈值(秒)
前端入口:
- 左侧「系统工具」->「运维自检」
- 顶部状态栏可一键刷新自检状态
- 运维自检面板新增「一致性检测」卡片,显示异常总数、严重/一般异常,并列出具体异常项
19. 一致性统计接口(新增)
用于检查“数据库记录、缓存文件、XML读取结果”是否一致。
后端接口:
GET /api/statistics
新增返回字段(关键):
dinsar_cache_consistencydb_cached_but_file_missing_count:数据库标记已缓存,但缓存文件不存在db_uncached_but_file_exists_count:数据库标记未缓存,但缓存文件已存在manifest_missing_file_count:cache_manifest.json记录的缓存文件缺失
source_preview_consistencypreview_missing_count:源影像预览缓存缺失(radar_geo和radar_raw均不存在)db_ready_but_cache_missing_count:数据库READY,但预览缓存实际缺失
source_xml_consistencyxml_missing_count:未检测到 XMLxml_detected_but_unparsed_count:检测到 XML 但关键字段未成功入库
前端展示位置:
- 「数据统计仪表盘」:新增一致性图表与异常高亮
- 「运维自检」:新增一致性异常汇总卡片(总数 / 严重 / 一般)
建议运维动作:
- 出现
db_cached_but_file_missing_count或db_ready_but_cache_missing_count:执行一次重扫重建缓存 - 出现
xml_detected_but_unparsed_count:检查对应场景 XML 格式与解析字段 - 出现
xml_missing_count:检查场景目录是否包含 XML 元数据文件
© 2026 InSAR Management System - 致力于更高效、更智能的雷达遥感监测