添加降雨量与持续时间接口
This commit is contained in:
+74
-6
@@ -7,11 +7,16 @@ from typing import List, Dict, Any, Optional
|
||||
|
||||
from fastapi import APIRouter, HTTPException
|
||||
|
||||
from app.schemas.api_schemas import RainfallPredictRequest, PredictResponse, PredictData, UpdateMonitoringTimeRequest
|
||||
from app.schemas.api_schemas import (
|
||||
RainfallPredictRequest, PredictResponse, PredictData,
|
||||
UpdateMonitoringTimeRequest, DistrictSummaryRequest, DistrictSummaryItem
|
||||
)
|
||||
from app.utils.api_deps import get_rainfall_model, get_prediction_semaphore
|
||||
from app.repositories.dbn_repository import dbn_repository
|
||||
from app.repositories.rainfall_repository import rainfall_repository as rain_repo
|
||||
from app.core.rainfall_manager import rainfall_manager
|
||||
from app.config.paths import get_logger
|
||||
from app.utils.db_helper import db_helper
|
||||
from app.utils.time_converter import TimeConverter
|
||||
|
||||
router = APIRouter(prefix="/rainfall", tags=["暴雨灾害链"])
|
||||
@@ -141,13 +146,17 @@ async def update_monitoring_time(req: UpdateMonitoringTimeRequest):
|
||||
@router.post("/predict", response_model=PredictResponse, summary="暴雨灾害链预测")
|
||||
async def predict_rainfall(req: RainfallPredictRequest):
|
||||
"""
|
||||
根据降雨量和持续时间,批量预测隐患点/风险点的灾害概率。
|
||||
批量预测隐患点/风险点的灾害概率。两种模式(二选一):
|
||||
|
||||
**自动推演模式**:rainfall、duration、region_code 全部不传
|
||||
→ 从气象表自动获取各点最近站降雨数据,不限区域
|
||||
|
||||
**指定条件模式**:rainfall、duration、region_code 全部传入
|
||||
→ 按指定降雨条件和区域预测
|
||||
|
||||
- **disaster_name**: 灾害名称
|
||||
- **point_ids**: 点位ID列表(可选,不传则查询所有点)
|
||||
- **region_code**: 行政区划代码(可选,不传则不限区域)
|
||||
- **rainfall**: 累计降雨量(mm),不传则从气象表自动获取
|
||||
- **duration**: 降雨持续时间(h),不传则从气象表自动获取
|
||||
- **point_ids**: 点位ID列表(可选)
|
||||
- **occurred_time**: 事件发生时间(可选,不传则为当前时间)
|
||||
- **operation_type**: 操作类型(如 '实时监测', '情景模拟', '应急评估')
|
||||
"""
|
||||
semaphore = get_prediction_semaphore()
|
||||
@@ -180,3 +189,62 @@ async def predict_rainfall(req: RainfallPredictRequest):
|
||||
logger.error(f"保存推理结果失败: {e}", exc_info=True)
|
||||
|
||||
return PredictResponse(code=200, message="success", data=PredictData(record_id=record_id, list=result_map_with_location))
|
||||
|
||||
|
||||
@router.post("/district-summary", summary="获取各区降雨概况")
|
||||
async def district_summary(req: DistrictSummaryRequest):
|
||||
"""
|
||||
根据推理结果ID获取各行政区的降雨概况(用于报告生成)。
|
||||
|
||||
逻辑:
|
||||
- 如果预测时传了 rainfall → 直接用 condition 中的值
|
||||
- 如果预测时没传 rainfall → 从 xian_meteorology 按区聚合实际气象数据
|
||||
|
||||
- **inference_id**: 推理结果ID
|
||||
"""
|
||||
# 1. 查推理结果
|
||||
record = dbn_repository.get_inference_result(req.inference_id)
|
||||
if not record:
|
||||
raise HTTPException(status_code=404, detail=f"推理结果不存在: {req.inference_id}")
|
||||
|
||||
condition = record.get('condition') or {}
|
||||
occurred_time = record.get('occurred_time')
|
||||
|
||||
# 2. 如果传了 rainfall → 直接用 condition 中的值
|
||||
if condition.get('rainfall') is not None:
|
||||
region_code = condition.get('region_code')
|
||||
rainfall_val = float(condition['rainfall'])
|
||||
duration_val = float(condition.get('duration', 0))
|
||||
|
||||
if region_code:
|
||||
# 查 district 名称
|
||||
district_row = db_helper.execute_query_one(
|
||||
"SELECT name FROM xian_district WHERE code = %s AND is_delete = 0", (region_code,)
|
||||
)
|
||||
district_name = district_row['name'] if district_row else region_code
|
||||
items = [{
|
||||
'district_name': district_name,
|
||||
'district_code': region_code,
|
||||
'rainfall': rainfall_val,
|
||||
'duration_hours': duration_val
|
||||
}]
|
||||
else:
|
||||
items = [{
|
||||
'district_name': '全市',
|
||||
'district_code': '',
|
||||
'rainfall': rainfall_val,
|
||||
'duration_hours': duration_val
|
||||
}]
|
||||
else:
|
||||
# 3. 自动推演模式 → 从气象表按区聚合
|
||||
items = rain_repo.get_district_rainfall_summary(occurred_time)
|
||||
|
||||
if not items:
|
||||
return {"code": 200, "message": "success", "data": []}
|
||||
|
||||
# 转换为响应格式
|
||||
result_items = [
|
||||
DistrictSummaryItem(**item).model_dump()
|
||||
for item in items
|
||||
]
|
||||
return {"code": 200, "message": "success", "data": result_items}
|
||||
|
||||
Reference in New Issue
Block a user