windspeed.py 7.2 KB

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