|
@@ -0,0 +1,389 @@
|
|
|
+"""
|
|
|
+Cd预测模型API接口
|
|
|
+@description: 提供作物Cd和有效态Cd的预测与可视化功能
|
|
|
+"""
|
|
|
+
|
|
|
+from fastapi import APIRouter, HTTPException, BackgroundTasks
|
|
|
+from fastapi.responses import FileResponse
|
|
|
+from typing import Dict, Any
|
|
|
+import os
|
|
|
+import logging
|
|
|
+from ..services.cd_prediction_service import CdPredictionService
|
|
|
+
|
|
|
+router = APIRouter()
|
|
|
+
|
|
|
+# 设置日志
|
|
|
+logger = logging.getLogger(__name__)
|
|
|
+
|
|
|
+@router.post("/crop-cd/generate-and-get-map",
|
|
|
+ summary="一键生成并获取作物Cd预测地图",
|
|
|
+ description="执行作物Cd模型预测,生成可视化地图后直接返回图片文件")
|
|
|
+async def generate_and_get_crop_cd_map():
|
|
|
+ """
|
|
|
+ 一键生成并获取作物Cd预测地图
|
|
|
+
|
|
|
+ @returns {FileResponse} 作物Cd预测地图文件
|
|
|
+ @throws {HTTPException} 当预测过程发生错误时抛出500错误
|
|
|
+ @example
|
|
|
+ >>> response = await generate_and_get_crop_cd_map()
|
|
|
+ >>> # 直接返回图片文件,可在浏览器中查看或下载
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ logger.info("开始一键生成作物Cd预测地图")
|
|
|
+
|
|
|
+ service = CdPredictionService()
|
|
|
+ result = await service.generate_crop_cd_prediction()
|
|
|
+
|
|
|
+ if not result['map_path'] or not os.path.exists(result['map_path']):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail="地图文件生成失败"
|
|
|
+ )
|
|
|
+
|
|
|
+ logger.info(f"作物Cd预测地图生成成功,直接返回文件: {result['map_path']}")
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=result['map_path'],
|
|
|
+ filename="crop_cd_prediction_map.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"一键生成作物Cd预测地图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"一键生成作物Cd预测地图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.post("/effective-cd/generate-and-get-map",
|
|
|
+ summary="一键生成并获取有效态Cd预测地图",
|
|
|
+ description="执行有效态Cd模型预测,生成可视化地图后直接返回图片文件")
|
|
|
+async def generate_and_get_effective_cd_map():
|
|
|
+ """
|
|
|
+ 一键生成并获取有效态Cd预测地图
|
|
|
+
|
|
|
+ @returns {FileResponse} 有效态Cd预测地图文件
|
|
|
+ @throws {HTTPException} 当预测过程发生错误时抛出500错误
|
|
|
+ @example
|
|
|
+ >>> response = await generate_and_get_effective_cd_map()
|
|
|
+ >>> # 直接返回图片文件,可在浏览器中查看或下载
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ logger.info("开始一键生成有效态Cd预测地图")
|
|
|
+
|
|
|
+ service = CdPredictionService()
|
|
|
+ result = await service.generate_effective_cd_prediction()
|
|
|
+
|
|
|
+ if not result['map_path'] or not os.path.exists(result['map_path']):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail="地图文件生成失败"
|
|
|
+ )
|
|
|
+
|
|
|
+ logger.info(f"有效态Cd预测地图生成成功,直接返回文件: {result['map_path']}")
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=result['map_path'],
|
|
|
+ filename="effective_cd_prediction_map.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"一键生成有效态Cd预测地图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"一键生成有效态Cd预测地图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.post("/crop-cd/generate-and-get-histogram",
|
|
|
+ summary="一键生成并获取作物Cd预测直方图",
|
|
|
+ description="执行作物Cd模型预测,生成预测值分布直方图后直接返回图片文件")
|
|
|
+async def generate_and_get_crop_cd_histogram():
|
|
|
+ """
|
|
|
+ 一键生成并获取作物Cd预测直方图
|
|
|
+
|
|
|
+ @returns {FileResponse} 作物Cd预测直方图文件
|
|
|
+ @throws {HTTPException} 当预测过程发生错误时抛出500错误
|
|
|
+ @example
|
|
|
+ >>> response = await generate_and_get_crop_cd_histogram()
|
|
|
+ >>> # 直接返回直方图文件,可在浏览器中查看或下载
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ logger.info("开始一键生成作物Cd预测直方图")
|
|
|
+
|
|
|
+ service = CdPredictionService()
|
|
|
+ result = await service.generate_crop_cd_prediction()
|
|
|
+
|
|
|
+ if not result['histogram_path'] or not os.path.exists(result['histogram_path']):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail="直方图文件生成失败"
|
|
|
+ )
|
|
|
+
|
|
|
+ logger.info(f"作物Cd预测直方图生成成功,直接返回文件: {result['histogram_path']}")
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=result['histogram_path'],
|
|
|
+ filename="crop_cd_prediction_histogram.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"一键生成作物Cd预测直方图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"一键生成作物Cd预测直方图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.post("/effective-cd/generate-and-get-histogram",
|
|
|
+ summary="一键生成并获取有效态Cd预测直方图",
|
|
|
+ description="执行有效态Cd模型预测,生成预测值分布直方图后直接返回图片文件")
|
|
|
+async def generate_and_get_effective_cd_histogram():
|
|
|
+ """
|
|
|
+ 一键生成并获取有效态Cd预测直方图
|
|
|
+
|
|
|
+ @returns {FileResponse} 有效态Cd预测直方图文件
|
|
|
+ @throws {HTTPException} 当预测过程发生错误时抛出500错误
|
|
|
+ @example
|
|
|
+ >>> response = await generate_and_get_effective_cd_histogram()
|
|
|
+ >>> # 直接返回直方图文件,可在浏览器中查看或下载
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ logger.info("开始一键生成有效态Cd预测直方图")
|
|
|
+
|
|
|
+ service = CdPredictionService()
|
|
|
+ result = await service.generate_effective_cd_prediction()
|
|
|
+
|
|
|
+ if not result['histogram_path'] or not os.path.exists(result['histogram_path']):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail="直方图文件生成失败"
|
|
|
+ )
|
|
|
+
|
|
|
+ logger.info(f"有效态Cd预测直方图生成成功,直接返回文件: {result['histogram_path']}")
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=result['histogram_path'],
|
|
|
+ filename="effective_cd_prediction_histogram.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"一键生成有效态Cd预测直方图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"一键生成有效态Cd预测直方图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+# 分步式接口 - 先生成后下载
|
|
|
+@router.post("/crop-cd/generate-map",
|
|
|
+ summary="生成作物Cd预测地图",
|
|
|
+ description="执行作物Cd模型预测并生成可视化地图")
|
|
|
+async def generate_crop_cd_map() -> Dict[str, Any]:
|
|
|
+ """
|
|
|
+ 生成作物Cd预测地图
|
|
|
+
|
|
|
+ @returns {Dict[str, Any]} 包含地图文件路径和预测统计信息的响应
|
|
|
+ @throws {HTTPException} 当预测过程发生错误时抛出500错误
|
|
|
+ @example
|
|
|
+ >>> response = await generate_crop_cd_map()
|
|
|
+ >>> print(response['data']['map_path'])
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ logger.info("开始生成作物Cd预测地图")
|
|
|
+
|
|
|
+ service = CdPredictionService()
|
|
|
+ result = await service.generate_crop_cd_prediction()
|
|
|
+
|
|
|
+ logger.info(f"作物Cd预测地图生成成功: {result['map_path']}")
|
|
|
+
|
|
|
+ return {
|
|
|
+ "success": True,
|
|
|
+ "message": "作物Cd预测地图生成成功",
|
|
|
+ "data": {
|
|
|
+ "map_path": result['map_path'],
|
|
|
+ "histogram_path": result['histogram_path'],
|
|
|
+ "raster_path": result['raster_path'],
|
|
|
+ "prediction_stats": result.get('stats', {})
|
|
|
+ },
|
|
|
+ "error": None
|
|
|
+ }
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"生成作物Cd预测地图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"生成作物Cd预测地图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.post("/effective-cd/generate-map",
|
|
|
+ summary="生成有效态Cd预测地图",
|
|
|
+ description="执行有效态Cd模型预测并生成可视化地图")
|
|
|
+async def generate_effective_cd_map() -> Dict[str, Any]:
|
|
|
+ """
|
|
|
+ 生成有效态Cd预测地图
|
|
|
+
|
|
|
+ @returns {Dict[str, Any]} 包含地图文件路径和预测统计信息的响应
|
|
|
+ @throws {HTTPException} 当预测过程发生错误时抛出500错误
|
|
|
+ @example
|
|
|
+ >>> response = await generate_effective_cd_map()
|
|
|
+ >>> print(response['data']['map_path'])
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ logger.info("开始生成有效态Cd预测地图")
|
|
|
+
|
|
|
+ service = CdPredictionService()
|
|
|
+ result = await service.generate_effective_cd_prediction()
|
|
|
+
|
|
|
+ logger.info(f"有效态Cd预测地图生成成功: {result['map_path']}")
|
|
|
+
|
|
|
+ return {
|
|
|
+ "success": True,
|
|
|
+ "message": "有效态Cd预测地图生成成功",
|
|
|
+ "data": {
|
|
|
+ "map_path": result['map_path'],
|
|
|
+ "histogram_path": result['histogram_path'],
|
|
|
+ "raster_path": result['raster_path'],
|
|
|
+ "prediction_stats": result.get('stats', {})
|
|
|
+ },
|
|
|
+ "error": None
|
|
|
+ }
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"生成有效态Cd预测地图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"生成有效态Cd预测地图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.get("/crop-cd/download-map",
|
|
|
+ summary="下载作物Cd预测地图",
|
|
|
+ description="下载最新生成的作物Cd预测地图文件")
|
|
|
+async def download_crop_cd_map():
|
|
|
+ """
|
|
|
+ 下载作物Cd预测地图文件
|
|
|
+
|
|
|
+ @returns {FileResponse} 作物Cd预测地图文件
|
|
|
+ @throws {HTTPException} 当地图文件不存在时抛出404错误
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ service = CdPredictionService()
|
|
|
+ map_path = service.get_latest_crop_cd_map()
|
|
|
+
|
|
|
+ if not map_path or not os.path.exists(map_path):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=404,
|
|
|
+ detail="作物Cd预测地图文件不存在,请先生成地图"
|
|
|
+ )
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=map_path,
|
|
|
+ filename="crop_cd_prediction_map.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"下载作物Cd预测地图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"下载作物Cd预测地图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.get("/effective-cd/download-map",
|
|
|
+ summary="下载有效态Cd预测地图",
|
|
|
+ description="下载最新生成的有效态Cd预测地图文件")
|
|
|
+async def download_effective_cd_map():
|
|
|
+ """
|
|
|
+ 下载有效态Cd预测地图文件
|
|
|
+
|
|
|
+ @returns {FileResponse} 有效态Cd预测地图文件
|
|
|
+ @throws {HTTPException} 当地图文件不存在时抛出404错误
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ service = CdPredictionService()
|
|
|
+ map_path = service.get_latest_effective_cd_map()
|
|
|
+
|
|
|
+ if not map_path or not os.path.exists(map_path):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=404,
|
|
|
+ detail="有效态Cd预测地图文件不存在,请先生成地图"
|
|
|
+ )
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=map_path,
|
|
|
+ filename="effective_cd_prediction_map.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"下载有效态Cd预测地图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"下载有效态Cd预测地图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.get("/crop-cd/download-histogram",
|
|
|
+ summary="下载作物Cd预测直方图",
|
|
|
+ description="下载最新生成的作物Cd预测值分布直方图")
|
|
|
+async def download_crop_cd_histogram():
|
|
|
+ """
|
|
|
+ 下载作物Cd预测直方图文件
|
|
|
+
|
|
|
+ @returns {FileResponse} 作物Cd预测直方图文件
|
|
|
+ @throws {HTTPException} 当直方图文件不存在时抛出404错误
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ service = CdPredictionService()
|
|
|
+ histogram_path = service.get_latest_crop_cd_histogram()
|
|
|
+
|
|
|
+ if not histogram_path or not os.path.exists(histogram_path):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=404,
|
|
|
+ detail="作物Cd预测直方图文件不存在,请先生成图表"
|
|
|
+ )
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=histogram_path,
|
|
|
+ filename="crop_cd_prediction_histogram.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"下载作物Cd预测直方图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"下载作物Cd预测直方图失败: {str(e)}"
|
|
|
+ )
|
|
|
+
|
|
|
+@router.get("/effective-cd/download-histogram",
|
|
|
+ summary="下载有效态Cd预测直方图",
|
|
|
+ description="下载最新生成的有效态Cd预测值分布直方图")
|
|
|
+async def download_effective_cd_histogram():
|
|
|
+ """
|
|
|
+ 下载有效态Cd预测直方图文件
|
|
|
+
|
|
|
+ @returns {FileResponse} 有效态Cd预测直方图文件
|
|
|
+ @throws {HTTPException} 当直方图文件不存在时抛出404错误
|
|
|
+ """
|
|
|
+ try:
|
|
|
+ service = CdPredictionService()
|
|
|
+ histogram_path = service.get_latest_effective_cd_histogram()
|
|
|
+
|
|
|
+ if not histogram_path or not os.path.exists(histogram_path):
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=404,
|
|
|
+ detail="有效态Cd预测直方图文件不存在,请先生成图表"
|
|
|
+ )
|
|
|
+
|
|
|
+ return FileResponse(
|
|
|
+ path=histogram_path,
|
|
|
+ filename="effective_cd_prediction_histogram.jpg",
|
|
|
+ media_type="image/jpeg"
|
|
|
+ )
|
|
|
+
|
|
|
+ except Exception as e:
|
|
|
+ logger.error(f"下载有效态Cd预测直方图失败: {str(e)}")
|
|
|
+ raise HTTPException(
|
|
|
+ status_code=500,
|
|
|
+ detail=f"下载有效态Cd预测直方图失败: {str(e)}"
|
|
|
+ )
|