Files
xian_algorithm_new/README.md
T
wzy-warehouse a07c5a1107 添加readme
2026-06-12 10:13:48 +08:00

541 lines
14 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.
# 西安项目算法服务
## 核心功能
### 1. 暴雨灾害链预测
- **触发因子**:降雨强度、持续时间、累计降雨量
- **环境因子**:高程、坡度、坡向、土壤类型、岩性、土地利用、植被指数等 16 个因子
- **预测目标**:滑坡、泥石流、崩塌、城市内涝
- **数据来源**:自动从气象站获取实时降雨数据
### 2. 地震灾害链预测
- **触发因子**:震级、震中距、地震烈度
- **环境因子**:高程、坡度、坡向、土壤类型、岩性、距离断裂带距离等 14 个因子
- **预测目标**:地震触发的滑坡、泥石流、崩塌
- **空间计算**:自动计算震中距和烈度分布
### 3. 推理结果管理
- **持久化存储**:所有预测结果自动保存到数据库
- **操作类型追踪**:支持实时监测、情景模拟、应急评估等操作分类
- **历史查询**:支持按时间、事件类型、操作类型查询历史预测记录
### 4. 栅格数据生成
- **降雨栅格插值**:基于站点数据生成空间降雨分布栅格(PNG 格式)
- **Redis 缓存**:栅格元数据缓存到 Redis,提升查询性能
- **文件存储**:栅格图片存储到文件系统,支持 CDN 加速
---
## 项目结构
```
xian_algorithm_new/
├── app/ # 应用主目录
│ ├── api/ # FastAPI 路由
│ │ ├── rainfall.py # 暴雨预测接口
│ │ ├── earthquake.py # 地震预测接口
│ │ └── __init__.py
│ ├── config/ # 配置模块
│ │ ├── dbn/ # DBN 模型配置
│ │ │ ├── rainfall_dbn_graph.yaml # 暴雨图结构
│ │ │ ├── rainfall_cpt_params.yaml # 暴雨条件概率表
│ │ │ ├── earthquake_dbn_graph.yaml # 地震图结构
│ │ │ └── earthquake_cpt_params.yaml # 地震条件概率表
│ │ ├── paths.py # 路径配置
│ │ └── __init__.py
│ ├── core/ # 核心模块
│ │ ├── launcher.py # 应用启动器
│ │ ├── env_checker.py # 环境检查
│ │ ├── venv_manager.py # 虚拟环境管理
│ │ ├── dependency_manager.py # 依赖管理
│ │ ├── rainfall_manager.py # 降雨监测管理器
│ │ ├── server.py # FastAPI 服务器
│ │ └── __init__.py
│ ├── models/ # 数据模型
│ │ ├── dbn/ # DBN 模型
│ │ │ ├── rainfall/ # 暴雨模型
│ │ │ │ ├── rainfall_dbn.py
│ │ │ │ └── discretizer.py
│ │ │ └── earthquake/ # 地震模型
│ │ │ ├── earthquake_dbn.py
│ │ │ └── discretizer.py
│ │ └── __init__.py
│ ├── repositories/ # 数据访问层
│ │ ├── dbn_repository.py # DBN 数据查询
│ │ └── __init__.py
│ ├── schemas/ # Pydantic 数据模型
│ │ ├── api_schemas.py # API 请求/响应模型
│ │ └── __init__.py
│ ├── services/ # 业务逻辑层
│ │ ├── rainfall_grid_service.py # 降雨栅格服务
│ │ └── __init__.py
│ └── utils/ # 工具函数
│ ├── logger.py # 日志工具
│ ├── api_deps.py # API 依赖注入
│ ├── thread_pool_manager.py # 线程池管理
│ ├── spatial_utils.py # 空间计算工具
│ └── __init__.py
├── logs/ # 日志目录
├── scripts/ # 脚本目录
├── test/ # 测试目录
├── .venv/ # 虚拟环境(自动生成)
├── .gitignore
├── .secrets.toml # 敏感配置(不提交到 Git)
├── config.py # Dynaconf 配置入口
├── settings.toml # 环境配置文件
├── requirements.txt # Python 依赖
├── start.py # 启动脚本
└── README.md # 项目文档
```
---
## 环境要求
### 系统要求
- **操作系统**Windows 10/11、LinuxUbuntu 20.04+)、macOS 10.15+
- **Python 版本**3.10
- **内存**:至少 4GB RAM
- **磁盘空间**:至少 2GB 可用空间
### 外部依赖
- **PostgreSQL 12+**:主数据库
- **Redis 6.0+**:缓存服务
- **Git**:版本控制
---
## 快速开始
### 1. 安装依赖
```bash
# 直接运行启动脚本,会自动安装依赖
python start.py
# 或者手动安装
pip install -r requirements.txt
```
### 2. 配置环境变量
编辑 `settings.toml` 文件,修改数据库、Redis 等配置:
```toml
[development]
DB_HOST = "localhost"
DB_PORT = 5432
DB_USER = "postgres"
DB_PASSWORD = "your_password"
DB_NAME = "xian_new"
REDIS_HOST = "localhost"
REDIS_PORT = 6379
REDIS_PASSWORD = ""
```
### 3. 启动服务
```bash
python start.py
```
启动成功后会看到类似输出:
```
==================================================
步骤 1: 系统和 Python 版本检查
==================================================
✓ Python 版本: 3.10.x
==================================================
步骤 2: 虚拟环境检查
==================================================
✓ 虚拟环境已存在
==================================================
步骤 3: 依赖检查
==================================================
✓ 所有依赖已安装
==================================================
✓ 所有检查通过,准备启动应用...
==================================================
INFO: Started server process [xxxxx]
INFO: Application startup complete.
INFO: Uvicorn running on http://127.0.0.1:8082 (Press CTRL+C to quit)
```
### 4. 访问 API 文档
浏览器打开:http://127.0.0.1:8082/docs
---
## 配置说明
### 多环境配置
项目使用 **Dynaconf** 管理多环境配置,支持以下环境:
- `development`:开发环境
- `production`:生产环境
通过环境变量切换:
```bash
# Windows
set ENV_FOR_DYNACONF=production
# Linux/Mac
export ENV_FOR_DYNACONF=production
```
### 主要配置项
| 配置项 | 说明 | 示例 |
|--------|------|------|
| `DB_HOST` | PostgreSQL 主机地址 | `localhost` |
| `DB_PORT` | PostgreSQL 端口 | `5432` |
| `DB_USER` | 数据库用户名 | `postgres` |
| `DB_PASSWORD` | 数据库密码 | `password` |
| `DB_NAME` | 数据库名称 | `xian_new` |
| `API_HOST` | FastAPI 监听地址 | `127.0.0.1` |
| `API_PORT` | FastAPI 监听端口 | `8082` |
| `REDIS_HOST` | Redis 主机地址 | `localhost` |
| `REDIS_PORT` | Redis 端口 | `6379` |
| `LOG_LEVEL` | 日志级别 | `DEBUG` / `INFO` / `WARNING` |
| `FILE_STORE_DIR` | 文件存储根目录 | `G:/files` |
### 敏感配置
敏感信息(如密码、密钥)应放在 `.secrets.toml` 文件中,该文件已被 `.gitignore` 忽略:
```toml
[development]
DB_PASSWORD = "secret_password"
REDIS_PASSWORD = "redis_secret"
[production]
DB_PASSWORD = "prod_secret"
```
---
## API 接口
### 基础信息
- **Base URL**: `http://127.0.0.1:8082`
- **API 文档**: `http://127.0.0.1:8082/docs` (Swagger UI)
- **备用文档**: `http://127.0.0.1:8082/redoc` (ReDoc)
### 1. 暴雨灾害链预测
**接口**: `POST /rainfall/predict`
**请求参数**:
```json
{
"point_ids": [1, 2, 3], // 可选,点位ID列表
"region_code": "610104", // 可选,行政区划代码
"rainfall": 50.5, // 可选,累计降雨量(mm)
"duration": 2.0, // 可选,持续时间(h)
"operation_type": "实时监测" // 操作类型
}
```
**响应示例**:
```json
{
"code": 200,
"message": "success",
"data": [
{
"id": 1001,
"type": "隐患点",
"probability": 0.7523,
"level": "高"
},
{
"id": 1002,
"type": "风险点",
"probability": 0.4215,
"level": "中"
}
],
"record_id": 12345
}
```
**说明**:
- `point_ids``region_code` 二选一,都不传则查询所有点
- `rainfall``duration` 不传时,系统自动从气象表获取最新数据
- `record_id` 是保存的推理记录 ID,可用于后续查询
### 2. 地震灾害链预测
**接口**: `POST /earthquake/predict`
**请求参数**:
```json
{
"point_ids": [1, 2, 3], // 可选,点位ID列表
"region_code": "610104", // 可选,行政区划代码
"magnitude": 6.5, // 必填,震级(Richter)
"depth": 10.0, // 可选,震源深度(km),默认10
"epicenter_lon": 108.95, // 必填,震中经度
"epicenter_lat": 34.27, // 必填,震中纬度
"occurred_time": "2024-01-01T12:00:00", // 必填,地震发生时间
"operation_type": "应急评估" // 操作类型
}
```
**响应示例**:
```json
{
"code": 200,
"message": "success",
"data": [
{
"id": 2001,
"type": "隐患点",
"probability": 0.8234,
"level": "高"
}
],
"record_id": 12346
}
```
### 3. 模型状态查询
**接口**: `GET /models/status`
**响应示例**:
```json
{
"rainfall_model_loaded": true,
"earthquake_model_loaded": true
}
```
---
## 数据库设计
### 核心表结构
#### 1. xian_risk_factors(风险因子表)
存储隐患点和风险点的静态因子数据。
| 字段 | 类型 | 说明 |
|------|------|------|
| id | INTEGER | 主键(内部关联ID |
| source_id | INTEGER | 源表ID(隐患点或风险点真实ID) |
| source_type | SMALLINT | 源类型(1=隐患点,2=风险点) |
| lon | DECIMAL | 经度 |
| lat | DECIMAL | 纬度 |
| static_factors | JSONB | 静态因子数据 |
| is_delete | SMALLINT | 删除标记(0=正常,1=删除) |
**static_factors 字段示例**:
```json
{
"dem_value": 1250.5,
"slope_value": 25.3,
"aspect_value": 180.0,
"soil_type": "brown_soil",
"lithology": "acid_rock",
"landuse": "forest",
"landform": "mountain",
"vegetation_index": 0.65,
"river_distance": 500.0,
"fault_distance": 2000.0
}
```
#### 2. xian_inference_result(推理结果表)
存储预测结果记录。
| 字段 | 类型 | 说明 |
|------|------|------|
| id | SERIAL | 主键 |
| event_type | VARCHAR | 事件类型(rainfall/earthquake |
| occurred_time | TIMESTAMP | 事件发生时间 |
| operation_type | VARCHAR | 操作类型 |
| condition | JSONB | 输入条件 |
| result | JSONB | 预测结果 |
| created_at | TIMESTAMP | 创建时间 |
**result 字段示例**:
```json
[
{
"point_id": 1001,
"source_type": 1,
"lon": 108.95,
"lat": 34.27,
"disaster_probabilities": {
"landslide": 0.7523,
"debris_flow": 0.4215,
"collapse": 0.3102
},
"disaster_levels": {
"landslide": "高",
"debris_flow": "中",
"collapse": "低"
}
}
]
```
#### 3. xian_hidden_danger_spots(隐患点表)
存储隐患点基础信息。
#### 4. xian_risk_spots(风险点表)
存储风险点基础信息。
---
## 开发指南
### 添加新的 DBN 模型
1. **创建模型目录**: `app/models/dbn/<model_name>/`
2. **定义图结构**: 创建 `<model_name>_dbn_graph.yaml`
3. **定义条件概率表**: 创建 `<model_name>_cpt_params.yaml`
4. **实现模型类**: 继承基础 DBN 类,实现推理逻辑
5. **注册模型**: 在 `app/utils/api_deps.py` 中添加模型加载函数
6. **创建 API 接口**: 在 `app/api/` 下创建路由文件
### 日志规范
项目使用 Loguru 作为日志库:
```python
from app.utils.logger import get_logger
logger = get_logger()
logger.debug("调试信息")
logger.info("普通信息")
logger.warning("警告信息")
logger.error("错误信息")
```
**日志特性**:
- 按大小轮转(50 MB
- 保留 7 天
- 自动压缩旧日志
- 异步写入,避免文件锁定
### 数据库查询规范
所有 DBN 相关的数据库查询统一放在 `app/repositories/dbn_repository.py`
```python
from app.repositories.dbn_repository import dbn_repository
# 获取所有点
points = dbn_repository.get_all_points(region_code="610104")
# 根据ID获取点
point = dbn_repository.get_point_by_id(1001)
```
### 线程池使用
对于耗时操作,使用线程池管理器:
```python
from app.utils.thread_pool_manager import thread_pool_manager
def heavy_task():
# 耗时操作
pass
future = thread_pool_manager.submit(heavy_task)
result = future.result()
```
---
## 常见问题
### 1. 启动时提示 `ModuleNotFoundError`
**问题**: 缺少依赖包
**解决**:
```bash
pip install -r requirements.txt
```
### 2. 日志文件锁定错误(Windows)
**问题**: `PermissionError: [WinError 32] 另一个程序正在使用此文件`
**原因**: 多个进程同时写入日志文件
**解决**:
- 项目已配置 `enqueue=True``delay=True` 避免此问题
- 如果仍出现,删除 `logs/` 目录下的日志文件后重启
### 3. 数据库连接失败
**问题**: `could not connect to server`
**检查**:
1. PostgreSQL 服务是否启动
2. `settings.toml` 中的数据库配置是否正确
3. 网络连接是否正常
4. 防火墙是否阻止端口
### 4. 虚拟环境未激活
**问题**: 依赖安装到系统 Python 而非虚拟环境
**解决**:
```bash
# Windows
.venv\Scripts\activate
# Linux/Mac
source .venv/bin/activate
```
或者直接运行 `python start.py`,项目会自动切换到虚拟环境。
### 5. 模型加载缓慢
**原因**: DBN 模型首次加载需要初始化条件概率表
**优化**:
- 模型采用单例模式,只加载一次
- 使用 `get_rainfall_model()``get_earthquake_model()` 获取模型实例
---
## 许可证
本项目采用 MIT 许可证。详见 [LICENSE](LICENSE) 文件。