windspeed.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168
  1. #!/usr/bin/env python3
  2. # -*- coding: utf-8 -*-
  3. from fastapi import APIRouter, Request, Depends, Query, HTTPException, status
  4. from fastapi.responses import JSONResponse,StreamingResponse
  5. from common.db import db_czrz
  6. from common.security import valid_access_token
  7. from sqlalchemy.orm import Session
  8. from sqlalchemy.sql import func
  9. from common.auth_user import *
  10. from sqlalchemy import text
  11. from pydantic import BaseModel
  12. from common.BigDataCenterAPI import *
  13. from database import get_db
  14. from typing import List
  15. from models import *
  16. from utils import *
  17. from utils.spatial import *
  18. import json
  19. import traceback
  20. from datetime import datetime,timedelta
  21. router = APIRouter()
  22. @router.get('/get_windspeed_range/export')
  23. async def get_inspection_task_list(
  24. request: Request,
  25. sort: str = Query('desc'),
  26. timeOption: str = Query('24'),
  27. area: str = Query(''),
  28. township: str = Query(''),
  29. db: Session = Depends(get_db),
  30. auth_user: AuthUser = Depends(find_auth_user),
  31. user_id = Depends(valid_access_token)
  32. ):
  33. try:
  34. sql=f"""SELECT row_number() OVER (PARTITION BY cn ORDER BY `T1`.`create_time` {sort} ) as `序号`,T2.area as `区县`,T2.township as `镇街`,T2.address as `站点地址`,T1.windspeed as `风速`,T1.windlevel as `风速等级`,T2.longitude as `站点经度`,T2.latitude as `站点纬度`,T1.`code` as `站点编号`,T1.create_time as `测速时间` FROM (SELECT *,row_number() OVER (PARTITION BY `govdata_wind_speed_data_info`.`code` ORDER BY `govdata_wind_speed_data_info`.`windspeed` {sort} )as cn FROM sharedb.`govdata_wind_speed_data_info`
  35. where create_time>= NOW() - INTERVAL {timeOption} HOUR and IF('{area}'='',1=1,area_name='{area}') )T1 LEFT JOIN sharedb.govdata_wind_stand_address T2 on T1.`code`=T2.`code` and IF('{township}'='',1=1,T2.township='{township}') ORDER BY `T1`.`create_time` {sort}"""
  36. da = db.execute(sql).fetchall()
  37. outlist = [dict(row) for row in da]
  38. # 返回结果
  39. import pandas as pd
  40. from io import BytesIO
  41. # 将查询结果转换为 DataFrame
  42. df = pd.DataFrame(outlist)
  43. # 将 DataFrame 导出为 Excel 文件
  44. output = BytesIO()
  45. with pd.ExcelWriter(output, engine='openpyxl') as writer:
  46. df.to_excel(writer, index=False)
  47. # 设置响应头
  48. output.seek(0)
  49. from urllib.parse import quote
  50. encoded_filename = f'风速监测导出{datetime.now().strftime("%Y%m%d%H%mi%s")}.xlsx'
  51. encoded_filename = quote(encoded_filename, encoding='utf-8')
  52. headers = {
  53. 'Content-Disposition': f'attachment; filename*=UTF-8\'\'{encoded_filename}',
  54. 'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  55. }
  56. db_czrz.log(db, auth_user, "大风监测", f"风速导出数据成功", request.client.host)
  57. # 返回文件流
  58. return StreamingResponse(output, headers=headers)
  59. except Exception as e:
  60. # 处理异常
  61. traceback.print_exc()
  62. return JSONResponse(status_code=500, content={"code": 500, "msg": f"Internal server error: {str(e)}"})
  63. def get_windspeed_data(db,timeOption):
  64. sql = f"""WITH ranked AS (
  65. SELECT
  66. A.windlevel,
  67. A.windspeed,
  68. B.`address`,
  69. ROW_NUMBER() OVER (PARTITION BY A.windlevel ORDER BY A.windspeed DESC) AS rn
  70. FROM sharedb.govdata_wind_speed_data_info A JOIN sharedb.govdata_wind_stand_address B on A.`code`=B.`code` where A.create_time >= NOW() - INTERVAL {timeOption} HOUR
  71. ),
  72. max_per_level AS (
  73. SELECT windlevel, windspeed AS maxspeed, address AS maxspeed_standaddress
  74. FROM ranked
  75. WHERE rn = 1
  76. ),
  77. summary AS (
  78. SELECT
  79. windlevel,
  80. COUNT(*) AS cnt,
  81. ROUND(COUNT(*) * 100 / SUM(COUNT(*)) OVER (), 2) AS ratio
  82. FROM sharedb.govdata_wind_speed_data_info
  83. GROUP BY windlevel
  84. )
  85. SELECT
  86. s.windlevel,
  87. s.cnt,
  88. s.ratio,
  89. CASE
  90. WHEN s.ratio < 10 THEN '个别'
  91. WHEN s.ratio < 40 THEN '部分'
  92. WHEN s.ratio < 90 THEN '大范围'
  93. ELSE '全市'
  94. END AS fugaifanwei,
  95. m.maxspeed,
  96. m.maxspeed_standaddress
  97. FROM summary s
  98. JOIN max_per_level m ON s.windlevel = m.windlevel
  99. ORDER BY s.windlevel DESC;"""
  100. result = []
  101. sqlresult = db.execute(sql)
  102. for i in sqlresult:
  103. print(i)
  104. result.append({
  105. 'windlevel': i[0],
  106. 'cnt': i[1],
  107. 'ratio': i[2],
  108. 'fugaifanwei': i[3],
  109. 'maxspeed': i[4],
  110. 'maxspeed_standaddress': i[5]
  111. })
  112. return result
  113. @router.get('/windspeed_warrning')
  114. async def mine(request: Request,
  115. timeOption: int = Query(24),body = Depends(remove_xss_json),db: Session = Depends(get_db)):
  116. try:
  117. # timeOption = 24
  118. # start_time = "8月19日20时"
  119. # end_time = "8月20日20时"
  120. end_dt = datetime.now() # 当前时间
  121. start_dt = end_dt - timedelta(hours=timeOption)
  122. fmt = "%-m月%-d日%-H时" # Windows 用 %#m %#d %#H
  123. start_time = start_dt.strftime(fmt)
  124. end_time = end_dt.strftime(fmt)
  125. windspeed_data = get_windspeed_data(db, timeOption)
  126. if windspeed_data:
  127. result = f"局气象监测,{start_time}至{end_time},"
  128. fugaifanwei = windspeed_data[0]['fugaifanwei']
  129. max_speed_level = windspeed_data[0]['windlevel']
  130. address=windspeed_data[0]['maxspeed_standaddress']
  131. max_speed =windspeed_data[0]['maxspeed']
  132. result += f'{fugaifanwei}站点出现{max_speed_level}级短时大风。'
  133. if len(windspeed_data)>1:
  134. fugaifanwei2 =windspeed_data[1]['fugaifanwei']
  135. max_speed_level2 = windspeed_data[1]['windlevel']
  136. if fugaifanwei!=fugaifanwei2:
  137. result = result[:-1] + f",{fugaifanwei2}站点出现{max_speed_level2}级短时大风。"
  138. result += f'其中,{address}录得最大阵风{max_speed}米/秒({max_speed_level}级)。'
  139. for info in windspeed_data:
  140. stand_count = info['cnt']
  141. stand_pres = info['ratio']
  142. speed_level = info['windlevel']
  143. result += f'有{stand_count}个监测站(占总数的{stand_pres}%)录得{speed_level}级以上阵风;'
  144. result = result[:-1] + "。"
  145. else:
  146. result = f"{start_time}至{end_time},暂无风速数据。"
  147. return {
  148. "code": 200,
  149. "msg": "成功",
  150. "data":
  151. {"result":result}
  152. }
  153. except Exception as e:
  154. db.rollback()
  155. traceback.print_exc()
  156. raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")