新增查询指定日期范围和典型时段巡检路口数据的详情数据导出接口
This commit is contained in:
parent
5d3c40988e
commit
73f3970319
|
|
@ -85,6 +85,12 @@ def cross_problems_detail_api():
|
|||
def update_cross_examine_record_state_api():
|
||||
return update_cross_examine_record_state(request.json)
|
||||
|
||||
|
||||
@app.route('/api/explode_cross_problem_detail', methods=['GET'])
|
||||
def explode_cross_problem_detail_api():
|
||||
return explode_cross_problem_detail(dict(request.args))
|
||||
|
||||
|
||||
from app.user_views import *
|
||||
from app.views_task import *
|
||||
from app.views_workstation import *
|
||||
|
|
|
|||
|
|
@ -450,3 +450,51 @@ def update_cross_examine_record_state(params):
|
|||
return json.dumps(make_common_res(0, 'ok'))
|
||||
return json.dumps(make_common_res(11, '修改失败,请检查后重试'))
|
||||
|
||||
|
||||
# 离线导出巡检路口指标明细表
|
||||
def explode_cross_problem_detail(params):
|
||||
nodeid = check_param(params, 'nodeid')
|
||||
if not nodeid:
|
||||
return json.dumps(make_common_res(2, '缺少城市信息, 请刷新后重试'))
|
||||
area_id = check_param(params, 'area_id')
|
||||
if not area_id:
|
||||
return json.dumps(make_common_res(3, '缺少辖区信息, 请刷新后重试'))
|
||||
time_range = check_param(params, 'time_range')
|
||||
if not time_range:
|
||||
return json.dumps(make_common_res(4, '缺少时间范围信息, 请刷新后重试'))
|
||||
start_date = check_param(params, 'start_date')
|
||||
if not start_date:
|
||||
return json.dumps(make_common_res(5, '缺少开始时间, 请选择开始时间'))
|
||||
end_date = check_param(params, 'end_date')
|
||||
if not end_date:
|
||||
return json.dumps(make_common_res(6, '缺少结束时间, 请选择结束时间'))
|
||||
excel = check_param(params, 'excel')
|
||||
if not excel:
|
||||
excel = 0
|
||||
excel = int(excel)
|
||||
|
||||
routing_crosses = db_tmnet.query_routing_crosses(nodeid, area_id)
|
||||
routing_crosses_dict = {item['crossid']: item for item in routing_crosses}
|
||||
cross_roads_dir_dict = gen_crossids_roads_dir_dict_by_mysql([item['crossid'] for item in routing_crosses], nodeid)
|
||||
for crossid in routing_crosses_dict.keys():
|
||||
routing_crosses_dict[crossid]['roads_dir_dict'] = cross_roads_dir_dict[crossid]
|
||||
|
||||
tp_start = 't' + str(int(str(time_range.split('-')[0]).split(':')[0]) * 100 + int(str(time_range.split('-')[0]).split(':')[1]))
|
||||
tp_end = int(str(time_range.split('-')[1]).split(':')[0]) * 100 + int(str(time_range.split('-')[1]).split(':')[1])
|
||||
|
||||
date_list = generate_date_range(start_date, end_date)
|
||||
all_cross_data = []
|
||||
for crossid in routing_crosses_dict.keys():
|
||||
days_data = db_cross.query_cross_delay_info(crossid, nodeid, date_list, tp_start)
|
||||
days_pb_list = parse_data2pb(days_data)
|
||||
cross_data_list = parse_cross_delay_detail_list(routing_crosses_dict[crossid], days_pb_list, time_range)
|
||||
all_cross_data.extend(cross_data_list)
|
||||
|
||||
if excel == 1:
|
||||
return export_excel(all_cross_data)
|
||||
|
||||
res = make_common_res(0, 'ok')
|
||||
res['data'] = all_cross_data
|
||||
return json.dumps(clean_dict_nan(res, '-'), ensure_ascii=False)
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import random
|
|||
|
||||
from openpyxl import Workbook
|
||||
from openpyxl.styles import Alignment
|
||||
from openpyxl.utils import get_column_letter
|
||||
|
||||
import proto.xlcomm_pb2 as pb
|
||||
from app.common_worker import *
|
||||
|
|
@ -2372,3 +2373,172 @@ def query_cross_delay_info_controller_export_excel(road_flow_delay_infos, road_f
|
|||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
as_attachment=True,
|
||||
download_name=f"路口诊断指标.xlsx")
|
||||
|
||||
|
||||
def parse_cross_delay_detail_list(cross_info, delay_info_list, time_range):
|
||||
cross_id = cross_info['crossid']
|
||||
cross_name = cross_info['name']
|
||||
weekday_str = '全周'
|
||||
max_car_num = 0
|
||||
for item in delay_info_list:
|
||||
if item['data'].delay_info.car_num > max_car_num:
|
||||
max_car_num = item['data'].delay_info.car_num
|
||||
data_list = []
|
||||
for item in delay_info_list:
|
||||
relative_flow_rate = round(item['data'].delay_info.car_num / max_car_num, 2) if max_car_num > 0 else 0
|
||||
item_dict = {
|
||||
'cross_id': cross_id,
|
||||
'cross_name': cross_name,
|
||||
'weekday': weekday_str,
|
||||
'time_range': time_range,
|
||||
'day': item['day'],
|
||||
'service_level': calc_service_level(item['data'].delay_info.delay_time, item['data'].delay_info.stop_times) if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'stop_times': round(item['data'].delay_info.stop_times, 2) if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'high_park_percent': item['data'].delay_info.high_park_percent if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'park_time': item['data'].delay_info.park_time if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'delay_time': item['data'].delay_info.delay_time if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'speed': round(item['data'].delay_info.speed / 100, 2) if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'move_speed': round(item['data'].delay_info.move_speed / 100, 2) if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'relative_flow_rate': relative_flow_rate if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'flow': item['data'].delay_info.car_num,
|
||||
'jam_index': round(item['data'].delay_info.jam_index, 2) if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'imbalance_index': round(item['data'].delay_info.imbalance_index, 2) if item['data'].delay_info.car_num >= 10 else '-',
|
||||
'service_level_color': 0,
|
||||
'stop_times_color': 0,
|
||||
'high_park_percent_color': 0,
|
||||
'park_time_color': 0,
|
||||
'delay_time_color': 0,
|
||||
'speed_color': 0,
|
||||
'move_speed_color': 0,
|
||||
'relative_flow_rate_color': 0,
|
||||
'flow_color': 0,
|
||||
'jam_index_color': 0,
|
||||
'imbalance_index_color': 0,
|
||||
'stop_times_rate': 0,
|
||||
'high_park_percent_rate': 0,
|
||||
'park_time_rate': 0,
|
||||
'delay_time_rate': 0,
|
||||
'speed_rate': 0,
|
||||
'move_speed_rate': 0,
|
||||
'relative_flow_rate_rate': 0,
|
||||
'flow_rate': 0,
|
||||
'jam_index_rate': 0,
|
||||
'imbalance_index_rate': 0,
|
||||
}
|
||||
data_list.append(item_dict)
|
||||
|
||||
for i in range(len(data_list)-1, -1, -1):
|
||||
if i != 0:
|
||||
item_data = data_list[i]
|
||||
prev_data = data_list[i-1]
|
||||
if item_data['service_level'] != '-' and prev_data['service_level'] != '-':
|
||||
if item_data['service_level'] < prev_data['service_level']:
|
||||
item_data['service_level_color'] = 2
|
||||
elif item_data['service_level'] > prev_data['service_level']:
|
||||
item_data['service_level_color'] = 1
|
||||
for key in ('delay_time', 'stop_times', 'high_park_percent', 'park_time', 'relative_flow_rate', 'flow', 'jam_index', 'imbalance_index'):
|
||||
if item_data[key] == '-' or prev_data[key] == '-':
|
||||
continue
|
||||
if prev_data[key] != 0:
|
||||
rate = round((item_data[key] - prev_data[key]) / prev_data[key] * 100, 2)
|
||||
item_data[key + '_rate'] = rate
|
||||
if rate > 20:
|
||||
item_data[key + '_color'] = 1
|
||||
elif rate < -20:
|
||||
item_data[key + '_color'] = 2
|
||||
for key in ('speed', 'move_speed'):
|
||||
if item_data[key] == '-' or prev_data[key] == '-':
|
||||
continue
|
||||
if prev_data[key] != 0:
|
||||
rate = round((item_data[key] - prev_data[key]) / prev_data[key] * 100, 2)
|
||||
item_data[key + '_rate'] = rate
|
||||
if rate > 20:
|
||||
item_data[key + '_color'] = 2
|
||||
elif rate < -20:
|
||||
item_data[key + '_color'] = 1
|
||||
return data_list
|
||||
|
||||
|
||||
def export_excel(all_cross_data):
|
||||
wb = Workbook()
|
||||
sheet1 = wb.active
|
||||
table_header = [
|
||||
{'A1': '路口ID'},
|
||||
{'B1': '路口名称'},
|
||||
{'C1': '运行日期'},
|
||||
{'D1': '时段'},
|
||||
{'E1': '停车次数'},
|
||||
{'F1': '停车次数变化率'},
|
||||
{'G1': '多次停车率%'},
|
||||
{'H1': '多次停车率变化率'},
|
||||
{'I1': '停车时间(秒)'},
|
||||
{'J1': '停车时间变化率'},
|
||||
{'K1': '延迟时间(秒)'},
|
||||
{'L1': '延迟时间变化率'},
|
||||
{'M1': '平均速度(KM/H)'},
|
||||
{'N1': '平均速度变化率'},
|
||||
{'O1': '不停车速度(KM/H)'},
|
||||
{'P1': '不停车速度变化率'},
|
||||
{'Q1': '相对流量'},
|
||||
{'R1': '相对流量变化率'},
|
||||
{'S1': '拥堵指数'},
|
||||
{'T1': '拥堵指数变化率'},
|
||||
{'U1': '路口失衡指数'},
|
||||
{'V1': '路口失衡指数变化率'},
|
||||
{'W1': '服务水平'},
|
||||
{'X1': '服务水平变化情况'}
|
||||
]
|
||||
for item in table_header:
|
||||
for k, v in item.items():
|
||||
sheet1[k] = v
|
||||
sheet1[k].alignment = Alignment(horizontal='center', vertical='center')
|
||||
# 自动调整列宽
|
||||
for col_idx, header in enumerate(table_header, 1):
|
||||
# 计算列宽:可以根据字体大小适当调整这个公式
|
||||
# 通常一个中文字符占2个单位宽度,英文字符占1个单位宽度
|
||||
column_width = len(list(header.values())[0].encode('utf-8')) * 1.2 # 粗略估算
|
||||
adjusted_width = min(max(column_width, 10), 50) # 设置最小和最大宽度限制
|
||||
sheet1.column_dimensions[get_column_letter(col_idx)].width = adjusted_width
|
||||
|
||||
for item in all_cross_data:
|
||||
service_level_color = '-'
|
||||
if item['service_level_color'] == 1:
|
||||
service_level_color = '恶化'
|
||||
elif item['service_level_color'] == 2:
|
||||
service_level_color = '优化'
|
||||
item_data = [
|
||||
item['cross_id'],
|
||||
item['cross_name'],
|
||||
item['weekday'],
|
||||
item['time_range'],
|
||||
item['stop_times'],
|
||||
item['stop_times_rate'],
|
||||
item['high_park_percent'],
|
||||
item['high_park_percent_rate'],
|
||||
item['park_time'],
|
||||
item['park_time_rate'],
|
||||
item['delay_time'],
|
||||
item['delay_time_rate'],
|
||||
item['speed'],
|
||||
item['speed_rate'],
|
||||
item['move_speed'],
|
||||
item['move_speed_rate'],
|
||||
item['relative_flow_rate'],
|
||||
item['relative_flow_rate_rate'],
|
||||
item['jam_index'],
|
||||
item['jam_index_rate'],
|
||||
item['imbalance_index'],
|
||||
item['imbalance_index_rate'],
|
||||
item['service_level'],
|
||||
service_level_color
|
||||
]
|
||||
sheet1.append(item_data)
|
||||
|
||||
file_stream = io.BytesIO()
|
||||
wb.save(file_stream)
|
||||
file_stream.seek(0) # 将指针移到文件开头
|
||||
return send_file(
|
||||
file_stream,
|
||||
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
||||
as_attachment=True,
|
||||
download_name=f"路口信息明细指标.xlsx")
|
||||
|
|
|
|||
Loading…
Reference in New Issue