修复路口分流汇入bug,新增修饰100的情况,以及优化不存在的进口道展示效果

This commit is contained in:
wangxu 2025-11-04 11:41:29 +08:00
parent c1958c1f7b
commit 756e55bf0d
2 changed files with 132 additions and 25 deletions

View File

@ -535,19 +535,39 @@ def gen_flow_turn_rate_index(avg_cross_delay_info, roads_dir_dict):
cross_sum_car_num = sum([item.delay_info.car_num for item in road_delay_infos])
cross_out_sum_car_num = sum([item.turn_info.car_num for item in outroad_infos])
road_flow_turn_rate = {}
inroadid_list = [roads_dir_dict[k]['in'] for k in roads_dir_dict.keys()]
outroadid_list = [roads_dir_dict[k]['out'] for k in roads_dir_dict.keys()]
for dir in roads_dir_dict.keys():
roadid = roads_dir_dict[dir]['in']
l_rate, s_rate, r_rate = '-', '-', '-'
out_l_rate, out_s_rate, out_r_rate = '-', '-', '-'
in_flow_rate, out_flow_rate = '-', '-'
l_rate, s_rate, r_rate = 0, 0, 0
out_l_rate, out_s_rate, out_r_rate = 0, 0, 0
in_flow_rate, out_flow_rate = 0, 0
l_num, s_num, r_num = 0, 0, 0
out_l_num, out_s_num, out_r_num = 0, 0, 0
if roadid != '-' and roadid in road_delay_dict.keys():
inroad_info = g_roadnet.query_road(roadid)
split_turns_set = set()
for outroadid in outroadid_list:
angle = g_roadnet.calc_road_turn_angle_without_abs(inroad_info, g_roadnet.query_road(outroadid))
if abs(angle) <= 30:
split_turns_set.add(0)
elif abs(angle) >= 150:
split_turns_set.add(3)
elif angle > 0:
split_turns_set.add(2)
else:
split_turns_set.add(1)
car_num = road_delay_dict[roadid].delay_info.car_num
in_flow_rate = round(car_num / cross_sum_car_num, 2) if cross_out_sum_car_num != 0 else '-'
l_rate = round(road_delay_dict[roadid].delay_info.turn_ratio_1 / car_num, 2) if car_num != 0 else '-'
s_rate = round(road_delay_dict[roadid].delay_info.turn_ratio_0 / car_num, 2) if car_num != 0 else '-'
r_rate = round(road_delay_dict[roadid].delay_info.turn_ratio_2 / car_num, 2) if car_num != 0 else '-'
in_flow_rate = round(car_num / cross_sum_car_num, 2) if cross_out_sum_car_num != 0 else 0
l_rate = round(road_delay_dict[roadid].delay_info.turn_ratio_1 / car_num, 2) * 100 if car_num != 0 else 0
s_rate = round(road_delay_dict[roadid].delay_info.turn_ratio_0 / car_num, 2) * 100 if car_num != 0 else 0
r_rate = round(road_delay_dict[roadid].delay_info.turn_ratio_2 / car_num, 2) * 100 if car_num != 0 else 0
if 0 not in split_turns_set:
s_rate = '-'
if 1 not in split_turns_set:
l_rate = '-'
if 2 not in split_turns_set:
r_rate = '-'
l_num = road_delay_dict[roadid].delay_info.turn_ratio_1
s_num = road_delay_dict[roadid].delay_info.turn_ratio_0
r_num = road_delay_dict[roadid].delay_info.turn_ratio_2
@ -555,11 +575,29 @@ def gen_flow_turn_rate_index(avg_cross_delay_info, roads_dir_dict):
l_rate, s_rate, r_rate = rate_list[0], rate_list[1], rate_list[2]
out_road_id = roads_dir_dict[dir]['out']
if out_road_id != '-' and out_road_id in outroad_info_dict.keys():
out_road_info = g_roadnet.query_road(out_road_id)
merge_turns_set = set()
for inroadid in inroadid_list:
angle = g_roadnet.calc_road_turn_angle_without_abs(out_road_info, g_roadnet.query_road(inroadid))
if abs(angle) <= 30:
merge_turns_set.add(0)
elif abs(angle) >= 150:
merge_turns_set.add(3)
elif angle > 0:
merge_turns_set.add(2)
else:
merge_turns_set.add(1)
out_car_num = outroad_info_dict[out_road_id].turn_info.car_num
out_flow_rate = round(out_car_num / cross_out_sum_car_num, 2) if cross_out_sum_car_num != 0 else '-'
out_l_rate = round(outroad_info_dict[out_road_id].turn_info.turn_ratio_1 / out_car_num, 2) if out_car_num != 0 else '-'
out_s_rate = round(outroad_info_dict[out_road_id].turn_info.turn_ratio_0 / out_car_num, 2) if out_car_num != 0 else '-'
out_r_rate = round(outroad_info_dict[out_road_id].turn_info.turn_ratio_2 / out_car_num, 2) if out_car_num != 0 else '-'
out_flow_rate = round(out_car_num / cross_out_sum_car_num, 2) if cross_out_sum_car_num != 0 else 0
out_l_rate = round(outroad_info_dict[out_road_id].turn_info.turn_ratio_1 / out_car_num, 2) * 100 if out_car_num != 0 else 0
out_s_rate = round(outroad_info_dict[out_road_id].turn_info.turn_ratio_0 / out_car_num, 2) * 100 if out_car_num != 0 else 0
out_r_rate = round(outroad_info_dict[out_road_id].turn_info.turn_ratio_2 / out_car_num, 2) * 100 if out_car_num != 0 else 0
if 0 not in merge_turns_set:
out_s_rate = '-'
if 1 not in merge_turns_set:
out_l_rate = '-'
if 2 not in merge_turns_set:
out_r_rate = '-'
out_l_num, out_s_num, out_r_num = outroad_info_dict[out_road_id].turn_info.turn_ratio_1, outroad_info_dict[out_road_id].turn_info.turn_ratio_0, outroad_info_dict[out_road_id].turn_info.turn_ratio_2
rate_list = fix_to_100(out_l_rate, out_s_rate, out_r_rate)
out_l_rate, out_s_rate, out_r_rate = rate_list[0], rate_list[1], rate_list[2]
@ -1393,7 +1431,7 @@ def gen_phase_problems(nodeid, area_id, crossid, time_range, date_list, min_date
'reason': '路口停车次数徒增或大数据计算方案与录入方案不一致',
'suggestions': phase_err_suggestions
})
total = phase_problems_detail['total'] if phase_problems_detail and len(phase_problems_detail) > 0 else 0
total = phase_problems_detail['total_num'] if phase_problems_detail and len(phase_problems_detail) > 0 else 0
phase_problems['total_num'] = total + phase_err_total_num
return phase_problems
@ -1746,7 +1784,7 @@ def gen_src_dir_phase_detail(max_src_dir, min_src_dir, cross_phase, is_tide=Fals
need2sug = False
if is_tide:
for item in cross_phase.data:
stages_info = item.tps[0].stages
stages_info = item.tps[0].stage_list
for stage in stages_info:
phases_name = stage.phases_name
if dir_str_dict[max_src_dir] + '直行' in phases_name\
@ -1829,17 +1867,86 @@ def get_next_cross(nodeid, area_id, roads_dir_dict):
def fix_to_100(a, b, c):
nums = [a, b, c]
if 100 not in nums: # 无 100走统一修复
delta = sum(nums) - 100
idx_max = max(range(3), key=nums.__getitem__)
nums[idx_max] -= delta
dash_mask = [v == '-' for v in nums]
valid_idx = [i for i, m in enumerate(dash_mask) if not m]
# ----- 全 '-' -----
if len(valid_idx) == 0:
return nums[:]
# ----- 仅 1 个有效 -----
if len(valid_idx) == 1:
vi = valid_idx[0]
nums[vi] = 100
return nums
idx_100 = nums.index(100) # 定位 100
zeros = [i for i in range(3) if nums[i] == 0]
r1 = random.randint(1, 3)
r2 = random.randint(1, 3)
nums[zeros[0]] = r1
nums[zeros[1]] = r2
nums[idx_100] = 100 - (r1 + r2) # 只动 100 位置
# ----- 2 个有效 -----
if len(valid_idx) == 2:
i0, i1 = valid_idx
v0, v1 = nums[i0], nums[i1]
# 只有出现 100 或 0 才强制随机拆分
if 100 in (v0, v1) or 0 in (v0, v1):
r1 = random.randint(1, 3)
r2 = 100 - r1
# 原 100 的下标放较大值,原 0 的下标放较小值
if v0 == 100 or v1 == 100: # 谁 100 谁拿大的
idx_100 = i0 if v0 == 100 else i1
idx_zro = i1 if v0 == 100 else i0
nums[idx_100] = max(r1, r2)
nums[idx_zro] = min(r1, r2)
else: # 谁 0 谁拿小的
idx_zro = i0 if v0 == 0 else i1
idx_nz = i1 if v0 == 0 else i0
nums[idx_zro] = min(r1, r2)
nums[idx_nz] = max(r1, r2)
return nums
# 正常值:等比缩放(下标不变)
s = v0 + v1
if s == 100:
return nums
delta = s - 100 # 正=超出,负=不足
# 从值更大的下标里扣掉 delta
idx_big = i0 if v0 >= v1 else i1
nums[idx_big] -= delta
# Rounding 可能导致差 1再微调一次仍只动同一下标
delta2 = sum(nums[i] for i in valid_idx) - 100
nums[idx_big] -= delta2
return nums
# ----- 3 个有效 -----
# 先处理 0/100只动原 100 或原 0 的下标)
if 100 in nums or 0 in nums:
# 100 存在:拆成两份 1~3只动 100 位与 0 位
if 100 in nums:
idx_100 = nums.index(100)
zeros = [i for i in range(3) if nums[i] == 0]
r1 = random.randint(1, 3)
r2 = 100 - r1
nums[zeros[0]] = r1
nums[zeros[1]] = r2
nums[idx_100] = 0 # 先清零,再走下面统一处理
# 现在只剩 0 需要修正
zeros = [i for i in range(3) if nums[i] == 0]
if len(zeros) == 1: # 单 0用 1~3 填充
nums[zeros[0]] = random.randint(1, 3)
elif len(zeros) == 2: # 双 0随机拆分 100只动 0 位
r1 = random.randint(1, 3)
r2 = 100 - r1
nums[zeros[0]] = r1
nums[zeros[1]] = r2
return nums
# 原本无 0/100等比缩放只动最大下标
s = sum(nums)
if s == 100:
return nums
for i in range(3):
nums[i] = max(1, int(round(nums[i] * 100 / s)))
delta = sum(nums) - 100
idx_max = max(range(3), key=nums.__getitem__)
nums[idx_max] -= delta
return nums

View File

@ -153,7 +153,7 @@ def QueryCrossPhaseDiagnosis(citycode: int, crossid: str, date_list: List, tp: s
data = MessageToDict(response.data, preserving_proto_field_name=True)
if len(data) > 0:
data['total'] = len(data['values'])
data['total_num'] = len(data['values'])
return data, None
except Exception as e:
return None, e