diff --git a/README.md b/README.md index 8158f1a..875584e 100644 --- a/README.md +++ b/README.md @@ -1 +1,540 @@ -# 西安项目算法相关代码 +# 西安项目算法服务 + +## 核心功能 + +### 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、Linux(Ubuntu 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//` +2. **定义图结构**: 创建 `_dbn_graph.yaml` +3. **定义条件概率表**: 创建 `_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) 文件。 +