From 756e55bf0d5f9725f2e87ad31f68f4e0499ca584 Mon Sep 17 00:00:00 2001 From: wangxu <1318272526@qq.com> Date: Tue, 4 Nov 2025 11:41:29 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=B7=AF=E5=8F=A3=E5=88=86?= =?UTF-8?q?=E6=B5=81=E6=B1=87=E5=85=A5bug=EF=BC=8C=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E4=BF=AE=E9=A5=B0100=E7=9A=84=E6=83=85=E5=86=B5=EF=BC=8C?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E4=BC=98=E5=8C=96=E4=B8=8D=E5=AD=98=E5=9C=A8?= =?UTF-8?q?=E7=9A=84=E8=BF=9B=E5=8F=A3=E9=81=93=E5=B1=95=E7=A4=BA=E6=95=88?= =?UTF-8?q?=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/eva_common.py | 155 +++++++++++++++++++++++++++++++++++++------- proto/phase_grpc.py | 2 +- 2 files changed, 132 insertions(+), 25 deletions(-) diff --git a/app/eva_common.py b/app/eva_common.py index 7d827f7..f854a1a 100644 --- a/app/eva_common.py +++ b/app/eva_common.py @@ -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 + + diff --git a/proto/phase_grpc.py b/proto/phase_grpc.py index 25b59c8..a6de3f5 100644 --- a/proto/phase_grpc.py +++ b/proto/phase_grpc.py @@ -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