修复巡检bug

This commit is contained in:
wangxu 2025-12-04 17:27:26 +08:00
parent 48291896a6
commit 504b07cf39
3 changed files with 120 additions and 57 deletions

View File

@ -393,6 +393,7 @@ def query_cross_examine_records_detail(params):
else:
phase_type_dir_dict[int(item_type)].append(item_detail)
days_records[date] = phase_type_dir_dict
days_records = days_records[-14:]
res = make_common_res(0, 'ok')
res['data'] = {
'days_records': days_records,

View File

@ -81,7 +81,7 @@ def gen_avg_cross_delay_pb(cross_delay_data_list):
for item in cross_delay_pb_list:
# print(MessageToJson(item, indent=None, always_print_fields_with_no_presence=True))
item_delay_info = item.delay_info
item_car_num = item_delay_info.car_num
item_car_num = item_delay_info.turn_ratio_0 + item_delay_info.turn_ratio_1
if item_car_num != 0:
sum_car_num += item_car_num
delay_time += item_delay_info.delay_time * item_car_num
@ -131,18 +131,19 @@ def gen_avg_cross_delay_pb(cross_delay_data_list):
ffs, capacity = road_delay_infos[0].delay_info.ffs, road_delay_infos[0].delay_info.capacity
turn_ratio_0, turn_ratio_1, turn_ratio_2, turn_ratio_3 = 0, 0, 0, 0
for road_delay_info in road_delay_infos:
inroad_sum_car_num += road_delay_info.delay_info.car_num
inroad_delay_time += road_delay_info.delay_info.delay_time * road_delay_info.delay_info.car_num
inroad_stop_times += road_delay_info.delay_info.stop_times * road_delay_info.delay_info.car_num
inroad_queue_len += road_delay_info.delay_info.queue_len * road_delay_info.delay_info.car_num
inroad_speed += road_delay_info.delay_info.speed * road_delay_info.delay_info.car_num
inroad_jam_index += road_delay_info.delay_info.jam_index * road_delay_info.delay_info.car_num
inroad_park_time += road_delay_info.delay_info.park_time * road_delay_info.delay_info.car_num
inroad_high_park_percent += road_delay_info.delay_info.high_park_percent * road_delay_info.delay_info.car_num
inroad_truck_percent += road_delay_info.delay_info.truck_percent * road_delay_info.delay_info.car_num
inroad_park_percent += road_delay_info.delay_info.park_percent * road_delay_info.delay_info.car_num
inroad_move_speed += road_delay_info.delay_info.move_speed * road_delay_info.delay_info.car_num
inroad_travel_time += road_delay_info.delay_info.travel_time * road_delay_info.delay_info.car_num
inroad_sum_car_num += (road_delay_info.delay_info.turn_ratio_0 + road_delay_info.delay_info.turn_ratio_1)
inroad_car_num = road_delay_info.delay_info.turn_ratio_0 + road_delay_info.delay_info.turn_ratio_1
inroad_delay_time += road_delay_info.delay_info.delay_time * inroad_car_num
inroad_stop_times += road_delay_info.delay_info.stop_times * inroad_car_num
inroad_queue_len += road_delay_info.delay_info.queue_len * inroad_car_num
inroad_speed += road_delay_info.delay_info.speed * inroad_car_num
inroad_jam_index += road_delay_info.delay_info.jam_index * inroad_car_num
inroad_park_time += road_delay_info.delay_info.park_time * inroad_car_num
inroad_high_park_percent += road_delay_info.delay_info.high_park_percent * inroad_car_num
inroad_truck_percent += road_delay_info.delay_info.truck_percent * inroad_car_num
inroad_park_percent += road_delay_info.delay_info.park_percent * inroad_car_num
inroad_move_speed += road_delay_info.delay_info.move_speed * inroad_car_num
inroad_travel_time += road_delay_info.delay_info.travel_time * inroad_car_num
# inroad_imbalance_index += delay_info.imbalance_index * delay_info.car_num
inroad_std_flow += road_delay_info.delay_info.std_flow
turn_ratio_0 += road_delay_info.delay_info.turn_ratio_0
@ -157,30 +158,30 @@ def gen_avg_cross_delay_pb(cross_delay_data_list):
inroad_delay_info.delay_info.ffs = ffs
inroad_delay_info.delay_info.capacity = capacity
inroad_delay_info.delay_info.car_num = inroad_sum_car_num
inroad_delay_info.delay_info.delay_time = int(inroad_delay_time / inroad_sum_car_num)
inroad_delay_info.delay_info.stop_times = inroad_stop_times / inroad_sum_car_num
inroad_delay_info.delay_info.delay_time = int(inroad_delay_time / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.stop_times = inroad_stop_times / inroad_sum_car_num if inroad_sum_car_num > 0 else 0
if inroad_delay_info.delay_info.stop_times > max_stop_times:
max_stop_times = inroad_delay_info.delay_info.stop_times
if inroad_delay_info.delay_info.stop_times < min_stop_times:
min_stop_times = inroad_delay_info.delay_info.stop_times
inroad_delay_info.delay_info.queue_len = int(inroad_queue_len / inroad_sum_car_num)
inroad_delay_info.delay_info.speed = int(inroad_speed / inroad_sum_car_num)
inroad_delay_info.delay_info.jam_index = inroad_jam_index / inroad_sum_car_num
inroad_delay_info.delay_info.park_time = int(inroad_park_time / inroad_sum_car_num)
inroad_delay_info.delay_info.high_park_percent = int(inroad_high_park_percent / inroad_sum_car_num)
inroad_delay_info.delay_info.truck_percent = int(inroad_truck_percent / inroad_sum_car_num)
inroad_delay_info.delay_info.park_percent = int(inroad_park_percent / inroad_sum_car_num)
inroad_delay_info.delay_info.move_speed = int(inroad_move_speed / inroad_sum_car_num)
inroad_delay_info.delay_info.travel_time = int(inroad_travel_time / inroad_sum_car_num)
inroad_delay_info.delay_info.queue_len = int(inroad_queue_len / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.speed = int(inroad_speed / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.jam_index = inroad_jam_index / inroad_sum_car_num if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.park_time = int(inroad_park_time / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.high_park_percent = int(inroad_high_park_percent / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.truck_percent = int(inroad_truck_percent / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.park_percent = int(inroad_park_percent / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.move_speed = int(inroad_move_speed / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
inroad_delay_info.delay_info.travel_time = int(inroad_travel_time / inroad_sum_car_num) if inroad_sum_car_num > 0 else 0
# inroad_delay_info.delay_info.imbalance_index = inroad_imbalance_index / inroad_sum_car_num
inroad_delay_info.delay_info.std_flow = int(inroad_std_flow / len(road_delay_infos))
inroad_delay_info.delay_info.std_flow = int(inroad_std_flow / len(road_delay_infos)) if len(road_delay_infos) > 0 else 0
inroad_delay_info.delay_info.turn_ratio_0 = turn_ratio_0
inroad_delay_info.delay_info.turn_ratio_1 = turn_ratio_1
inroad_delay_info.delay_info.turn_ratio_2 = turn_ratio_2
inroad_delay_info.delay_info.turn_ratio_3 = turn_ratio_3
inroad_delay_pb_list.append(inroad_delay_info)
avg_road_stop_times = sum(item.delay_info.stop_times for item in inroad_delay_pb_list) / len(inroad_delay_pb_list) if len(inroad_delay_pb_list) > 0 else 0
cross_imbalance_index = round((round(max_stop_times, 2) - round(min_stop_times, 2)) / round(avg_road_stop_times, 2), 2) if round(avg_road_stop_times, 2) != 0 else 0
cross_imbalance_index = (max_stop_times - min_stop_times) / avg_road_stop_times if avg_road_stop_times != 0 else 0
avg_cross_delay.delay_info.imbalance_index = cross_imbalance_index
for flow_delay_info in flow_delay_list:
@ -734,11 +735,11 @@ def calc_tide_index(crossid, nodeid, date_list, roads_dir_dict, date_type=None):
Fam = max(max_am_flow, subtend_road_am_flow) / min(max_am_flow, subtend_road_am_flow)
Fpm = max(max_pm_flow, subtend_road_pm_flow) / min(max_pm_flow, subtend_road_pm_flow)
if Fam >= 1.5 and Fpm >= 1.5 and max_pm_flow_road == subtend_road_pair[max_am_flow_road]:
tide_index = round(min(Fam, Fpm) / max(Fam, Fpm), 2)
tide_index = round(Fam * Fpm, 2)
if min(Fam, Fpm) <= 0:
tide_index = 0
if max_pm_flow_road == max_am_flow_road:
tide_index = round(Fam * Fpm, 2)
tide_index = round(min(Fam, Fpm) / max(Fam, Fpm), 2)
tide_index_list.append(tide_index)
return tide_index_list
@ -1041,7 +1042,7 @@ def gen_cross_problems(crossid, nodeid, area_id, time_range, start_hm, date_list
operating_efficiency_problems = gen_operating_efficiency_problems(avg_cross_delay_info, roads_dir_dict, cross_phase, is_peak)
balanced_control_problems = gen_balanced_control_problems(crossid, nodeid, date_list, avg_cross_delay_info, roads_dir_dict, inroad_static_info_dict, cross_phase)
phase_problems = gen_phase_problems(nodeid, area_id, crossid, time_range, date_list, min(date_list), max(date_list), start_hm)
cross_channelized_problems = gen_cross_channelized_problems(avg_cross_delay_info, roads_dir_dict, inroad_static_info_dict, cross_ledger_info)
cross_channelized_problems = gen_cross_channelized_problems(avg_cross_delay_info, roads_dir_dict, inroad_static_info_dict, cross_ledger_info, time_range)
problems = {
'operating_efficiency_problems': operating_efficiency_problems,
'balanced_control_problems': balanced_control_problems,
@ -1160,14 +1161,16 @@ def gen_high_stop_time_problems(avg_cross_delay_info, is_peak):
if avg_cross_delay_info:
if avg_cross_delay_info.delay_info.stop_times > max_stop_times and avg_cross_delay_info.delay_info.car_num >= 10:
total_num = 1
detail = [{
detail = [[
{
'child_detail': [
{
'desc': desc,
'text': '车辆多次停车时长过长(' + str(round(avg_cross_delay_info.delay_info.stop_times, 2)) + '),整体运行效率不高',
}
]
}]
}
]]
suggestion = [
{
'child_detail': [
@ -1557,9 +1560,9 @@ def gen_err_phase_problems(max_date, crossid, min_date, time_range):
# 路口渠化
def gen_cross_channelized_problems(avg_cross_delay_info, roads_dir_dict, inroad_static_info_dict, cross_ledger_info):
def gen_cross_channelized_problems(avg_cross_delay_info, roads_dir_dict, inroad_static_info_dict, cross_ledger_info, time_range):
road_delay_infos = avg_cross_delay_info.inroad_delay_infos
inroad_num_detail, inroad_num_suggestion, inroad_num_err_total_num = gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir_dict)
inroad_num_detail, inroad_num_suggestion, inroad_num_err_total_num = gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir_dict, time_range, avg_cross_delay_info.delay_info.car_num)
inout_lane_num_gap_problems, inout_lane_num_gap_suggestions, inout_lane_num_gap_total_num = gen_in_out_lane_num_gap_problems(cross_ledger_info)
cross_channelized_problems = {
'item': '路口渠化',
@ -1573,7 +1576,7 @@ def gen_cross_channelized_problems(avg_cross_delay_info, roads_dir_dict, inroad_
{
'item': '车道资源不匹配',
'detail': inroad_num_detail,
'reason': '同一进口道直行或左转的流量占比大于50%且相对流量占比大于60%,且车道数量占比小于流量占比的一半多方向放行车道每个方向各算0.5',
'reason': '路口的单位小时流量大于20, 同一进口道针对直行、左转如果该流向的流量占比大于20%,且该流向的车道数量占比小于流量占比的一半多方向放行车道每个方向各算0.5',
'suggestions': inroad_num_suggestion
}
)
@ -1592,12 +1595,13 @@ def gen_cross_channelized_problems(avg_cross_delay_info, roads_dir_dict, inroad_
# 路口渠化-车道资源不匹配
def gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir_dict):
def gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir_dict, time_range, car_num):
detail = []
suggestions, err_src_dirs, total_num = [], {}, 0
road_src_dict = {v['in']: k for k, v in roads_dir_dict.items()}
max_flow_car_num = 0
# 20251204 调整计算逻辑取消相对流量占比大于60% 更换为 路口 单位小时流量大于20
hours = calculate_hours(time_range)
hour_car_num = car_num / hours
for road_delay in road_delay_infos:
inroadid = road_delay.inroadid
src_dir = road_src_dict[inroadid] if inroadid in road_src_dict else None
@ -1605,9 +1609,6 @@ def gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir
continue
lane_info = inroad_static_info_dict[inroadid]['lane_turn_info']
flow_delay_infos = road_delay.flow_delay_infos
max_car_num = max([item.delay_info.car_num for item in flow_delay_infos if item.turn_type in [0, 1]]) if flow_delay_infos else 0
if max_car_num > max_flow_car_num:
max_flow_car_num = max_car_num
road_car_num = road_delay.delay_info.car_num
turn_delay_dict = {item.turn_type: item for item in flow_delay_infos}
left_lane_num_half, straight_lane_num_half, right_lane_num_half = count_lsr_half(lane_info)
@ -1625,9 +1626,8 @@ def gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir
turn_type_str = '左转'
lane_num_rate = left_lane_num_rate
flow_car_num = turn_delay_dict[turn_type].delay_info.car_num
relative_rate = flow_car_num / max_flow_car_num
flow_rate = flow_car_num / road_car_num
if flow_rate > 0.2 and relative_rate > 0.6 and lane_num_rate < 0.5:
if flow_rate > 0.2 and hour_car_num > 20 and lane_num_rate < 50:
if src_dir in err_src_dirs.keys():
err_src_dirs[src_dir].append({
'turn_type': turn_type_str,
@ -1657,7 +1657,7 @@ def gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir
src_detail['child_detail'].append(
{
'turn_type': turn_type['turn_type'],
'text': '分流转向比过大(' + str(int(round(turn_type['flow_rate'], 2) * 100)) + '%),但分配的转向车道占比不足(' + str(int(round(turn_type['lane_num_rate'], 2) * 100)) + '%),分配车道资源不匹配'
'text': '分流转向比过大(' + str(int(round(turn_type['flow_rate'], 2) * 100)) + '%),但分配的转向车道占比不足(' + str(int(round(turn_type['lane_num_rate'], 2))) + '%),分配车道资源不匹配'
}
)
detail.append(
@ -1690,6 +1690,30 @@ def gen_inroad_num_problems(road_delay_infos, inroad_static_info_dict, roads_dir
return detail, suggestions, total_num
def calculate_hours(time_range):
"""
计算时间区间包含多少小时返回浮点数
参数:
time_range: 字符串格式为"HH:MM-HH:MM"不跨天
返回:
float: 小时数浮点数
"""
# 解析时间段
start_str, end_str = time_range.split('-')
# 将小时和分钟转换为整数
start_h, start_m = map(int, start_str.split(':'))
end_h, end_m = map(int, end_str.split(':'))
# 计算总分钟数并转换为小时
start_minutes = start_h * 60 + start_m
end_minutes = end_h * 60 + end_m
return (end_minutes - start_minutes) / 60.0
# 路口渠化-进出口道数不匹配
def gen_in_out_lane_num_gap_problems(cross_ledger_info):
detail = []
@ -1734,7 +1758,45 @@ def check_is_peak_tp(time_range, area_id, nodeid):
peak_tp = ['07:00-09:00', '17:00-19:00']
if tp_desc and len(tp_desc) > 0:
peak_tp = tp_desc[0]['peak_tp'].split(',')
return time_overlap(time_range, peak_tp)
for item_peak in peak_tp:
start_hm, end_hm = int(time_range.split('-')[0].split(':')[0]) * 100 + int(time_range.split('-')[0].split(':')[1]), int(time_range.split('-')[1].split(':')[0]) * 100 + int(time_range.split('-')[1].split(':')[1])
res = check_peak_time_range(start_hm, end_hm, item_peak)
if res:
return True
return False
def check_peak_time_range(startHm, endHm, peak_time_range):
# 将 startHm 和 endHm 转换为小时和分钟
start_hour = startHm // 100
start_minute = startHm % 100
end_hour = endHm // 100
end_minute = endHm % 100
# 解析 time_range
start_time_range, end_time_range = peak_time_range.split('-')
start_hr, start_min = map(int, start_time_range.split(':'))
end_hr, end_min = map(int, end_time_range.split(':'))
# 将所有时间转换为分钟(自午夜以来的总分钟数)
def to_minutes(hour, minute):
return hour * 60 + minute
# 转换所有时间点
start = to_minutes(start_hour, start_minute)
end = to_minutes(end_hour, end_minute)
range_start = to_minutes(start_hr, start_min)
range_end = to_minutes(end_hr, end_min)
# 计算重叠部分
overlap_start = max(start, range_start)
overlap_end = min(end, range_end)
if overlap_start < overlap_end:
overlap_duration = overlap_end - overlap_start
return overlap_duration * 2 >= (end - start) # 重叠时长大于等于60分钟返回True
else:
return False
def get_flow_phase_detail(src_dir, turn_type_list, cross_phase):

View File

@ -139,7 +139,7 @@ def gen_monitor_overview_data(cross_report_pb, date_type, routing_crosses, speci
for cross_delay_info in cross_delay_info_list:
if special_time_range != '' and not is_overlap_greater_than_one_hour(cross_delay_info.tp.start_hm, cross_delay_info.tp.end_hm, special_time_range):
continue
service_level = calc_service_level(cross_delay_info.delay_info.delay_time, stop_times)
service_level = calc_service_level(cross_delay_info.delay_info.delay_time, cross_delay_info.delay_info.stop_times)
if service_level != '-':
overview['cross_service_levels']['total'] += 1
if service_level in ('A', 'B'):
@ -1081,7 +1081,7 @@ def turn_imbalance_problems(turn_imbalance_crosses, routing_crosses, special_tim
'time_range': time_range,
'weekdays_str': weekdays_str,
'weekdays': weekdays,
'imbalance_index': ''.join(inroad_imbalance_index_list),
'imbalance_index': ''.join(list(set(inroad_imbalance_index_list))),
'detail': detail,
'is_new': is_new,
'cont_times': cont_times,
@ -1793,15 +1793,15 @@ def gen_cross_problem_detail(routing_crosses, high_park_problems, too_many_stop_
item_desc = '' + item['weekdays_str'] + '' + item['plan_info']
cross_insufficient_ped_time_list.append(item_desc)
insufficient_ped_time = cross_insufficient_ped_time_list
if crossid in inroad_turnlane_mismatch.keys():
inroad_turnlane_problems = inroad_turnlane_mismatch[crossid]
if crossid in inroad_turnlane_mismatch['problems'].keys():
inroad_turnlane_problems = inroad_turnlane_mismatch['problems'][crossid]
inroad_turnlane_mismatch_list = []
for item in inroad_turnlane_problems:
inroad_turnlane = '' + item['weekdays_str'] + ' ' + item['time_range'] + '' + item['src_info']
inroad_turnlane_mismatch_list.append(inroad_turnlane)
inroad_turnlane = inroad_turnlane_mismatch_list
if crossid in unmatch_lane_num_problem.keys():
cross_unmatch_problem = unmatch_lane_num_problem[crossid]
if crossid in unmatch_lane_num_problem['problems'].keys():
cross_unmatch_problem = unmatch_lane_num_problem['problems'][crossid]
unmatched_lane_num = [cross_unmatch_problem[0]['src_dir']]
cross_problem_detail.append({
'crossid': crossid,