|
@@ -1,6 +1,9 @@
|
|
|
+# ... 保留原有导入和常量定义 ...
|
|
|
import math
|
|
|
+import operator
|
|
|
import numpy as np
|
|
|
import pandas as pd
|
|
|
+from typing import Dict, Any, List, Optional
|
|
|
from modules.lib import log_manager
|
|
|
from modules.lib.score import Score
|
|
|
from modules.lib.log_manager import LogManager
|
|
@@ -58,62 +61,296 @@ TRFFICSIGN_INFO = [
|
|
|
"sign_x",
|
|
|
"sign_y",
|
|
|
]
|
|
|
-
|
|
|
-
|
|
|
-def overtake_when_passing_car(data_processed):
|
|
|
+# 修改指标函数名称为 calculate_xxx 格式
|
|
|
+def calculate_overtake_when_passing_car(data_processed):
|
|
|
+ """计算会车时超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_when_passing_car_count = overtakingviolation.calculate_overtake_when_passing_car_count()
|
|
|
return {"overtake_when_passing_car": overtake_when_passing_car_count}
|
|
|
|
|
|
|
|
|
-def overtake_on_right(data_processed):
|
|
|
+def calculate_overtake_on_right(data_processed):
|
|
|
+ """计算右侧超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_on_right_count = overtakingviolation.calculate_overtake_on_right_count()
|
|
|
return {"overtake_on_right": overtake_on_right_count}
|
|
|
|
|
|
|
|
|
-def overtake_when_turn_around(data_processed):
|
|
|
+def calculate_overtake_when_turn_around(data_processed):
|
|
|
+ """计算掉头时超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_when_turn_around_count = overtakingviolation.calculate_overtake_when_turn_around_count()
|
|
|
return {"overtake_when_turn_around": overtake_when_turn_around_count}
|
|
|
|
|
|
|
|
|
-def overtake_in_forbid_lane(data_processed):
|
|
|
+def calculate_overtake_in_forbid_lane(data_processed):
|
|
|
+ """计算在禁止车道超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_in_forbid_lane_count = overtakingviolation.calculate_overtake_in_forbid_lane_count()
|
|
|
return {"overtake_in_forbid_lane": overtake_in_forbid_lane_count}
|
|
|
|
|
|
|
|
|
-def overtake_in_ramp(data_processed):
|
|
|
+def calculate_overtake_in_ramp(data_processed):
|
|
|
+ """计算在匝道超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_in_ramp_area_count = overtakingviolation.calculate_overtake_in_ramp_area_count()
|
|
|
return {"overtake_in_ramp": overtake_in_ramp_area_count}
|
|
|
|
|
|
|
|
|
-def overtake_in_tunnel(data_processed):
|
|
|
+def calculate_overtake_in_tunnel(data_processed):
|
|
|
+ """计算在隧道超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_in_tunnel_area_count = overtakingviolation.calculate_overtake_in_tunnel_area_count()
|
|
|
return {"overtake_in_tunnel": overtake_in_tunnel_area_count}
|
|
|
|
|
|
|
|
|
-def overtake_on_accelerate_lane(data_processed):
|
|
|
+def calculate_overtake_on_accelerate_lane(data_processed):
|
|
|
+ """计算在加速车道超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_on_accelerate_lane_count = overtakingviolation.calculate_overtake_on_accelerate_lane_count()
|
|
|
return {"overtake_on_accelerate_lane": overtake_on_accelerate_lane_count}
|
|
|
|
|
|
|
|
|
-def overtake_on_decelerate_lane(data_processed):
|
|
|
+def calculate_overtake_on_decelerate_lane(data_processed):
|
|
|
+ """计算在减速车道超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_on_decelerate_lane_count = overtakingviolation.calculate_overtake_on_decelerate_lane_count()
|
|
|
return {"overtake_on_decelerate_lane": overtake_on_decelerate_lane_count}
|
|
|
|
|
|
|
|
|
-def overtake_in_different_senerios(data_processed):
|
|
|
+def calculate_overtake_in_different_senerios(data_processed):
|
|
|
+ """计算在不同场景超车指标"""
|
|
|
overtakingviolation = OvertakingViolation(data_processed)
|
|
|
overtake_in_different_senerios_count = overtakingviolation.calculate_overtake_in_different_senerios_count()
|
|
|
return {"overtake_in_different_senerios": overtake_in_different_senerios_count}
|
|
|
|
|
|
|
|
|
+def calculate_slow_down_in_crosswalk(data_processed):
|
|
|
+ """计算在人行横道减速指标"""
|
|
|
+ slowdownviolation = SlowdownViolation(data_processed)
|
|
|
+ slow_down_in_crosswalk_count = slowdownviolation.calculate_slow_down_in_crosswalk_count()
|
|
|
+ return {"slowdown_down_in_crosswalk": slow_down_in_crosswalk_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_avoid_pedestrian_in_crosswalk(data_processed):
|
|
|
+ """计算在人行横道避让行人指标"""
|
|
|
+ avoidpedestrianincrosswalk = SlowdownViolation(data_processed)
|
|
|
+ avoid_pedestrian_in_crosswalk_count = avoidpedestrianincrosswalk.calculate_avoid_pedestrian_in_the_crosswalk_count()
|
|
|
+ return {"avoid_pedestrian_in_crosswalk": avoid_pedestrian_in_crosswalk_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_avoid_pedestrian_in_the_road(data_processed):
|
|
|
+ """计算在道路上避让行人指标"""
|
|
|
+ avoidpedestrianintheroad = SlowdownViolation(data_processed)
|
|
|
+ avoid_pedestrian_in_the_road_count = avoidpedestrianintheroad.calculate_avoid_pedestrian_in_the_road_count()
|
|
|
+ return {"avoid_pedestrian_in_the_road": avoid_pedestrian_in_the_road_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_avoid_pedestrian_when_turning(data_processed):
|
|
|
+ """计算转弯时避让行人指标"""
|
|
|
+ avoidpedestrianwhenturning = SlowdownViolation(data_processed)
|
|
|
+ avoid_pedestrian_when_turning_count = avoidpedestrianwhenturning.calculate_avoid_pedestrian_when_turning_count()
|
|
|
+ return {"avoid_pedestrian_when_turning_count": avoid_pedestrian_when_turning_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_turn_in_forbiden_turn_left_sign(data_processed):
|
|
|
+ """计算在禁止左转标志处左转指标"""
|
|
|
+ turnaroundviolation = TurnaroundViolation(data_processed)
|
|
|
+ turn_in_forbiden_turn_left_sign_count = turnaroundviolation.calculate_turn_in_forbiden_turn_left_sign_count()
|
|
|
+ return {"turn_in_forbiden_turn_left_sign": turn_in_forbiden_turn_left_sign_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_turn_in_forbiden_turn_back_sign(data_processed):
|
|
|
+ """计算在禁止掉头标志处掉头指标"""
|
|
|
+ turnaroundviolation = TurnaroundViolation(data_processed)
|
|
|
+ turn_in_forbiden_turn_back_sign_count = turnaroundviolation.calculate_turn_in_forbiden_turn_back_sign_count()
|
|
|
+ return {"turn_in_forbiden_turn_back_sign": turn_in_forbiden_turn_back_sign_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_avoid_pedestrian_when_turn_back(data_processed):
|
|
|
+ """计算掉头时避让行人指标"""
|
|
|
+ turnaroundviolation = TurnaroundViolation(data_processed)
|
|
|
+ avoid_pedestrian_when_turn_back_count = turnaroundviolation.calaulate_avoid_pedestrian_when_turn_back_count()
|
|
|
+ return {"avoid_pedestrian_when_turn_back": avoid_pedestrian_when_turn_back_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayorhighwaydrivinglanestopped(data_processed):
|
|
|
+ """计算城市快速路或高速公路行车道停车指标"""
|
|
|
+ wrongwayviolation = WrongWayViolation(data_processed)
|
|
|
+ urbanExpresswayOrHighwayDrivingLaneStopped_count = wrongwayviolation.calculate_urbanExpresswayOrHighwayDrivingLaneStopped_count()
|
|
|
+ return {"urbanExpresswayOrHighwayDrivingLaneStopped": urbanExpresswayOrHighwayDrivingLaneStopped_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayorhighwayemergencylanestopped(data_processed):
|
|
|
+ """计算城市快速路或高速公路应急车道停车指标"""
|
|
|
+ wrongwayviolation = WrongWayViolation(data_processed)
|
|
|
+ urbanExpresswayOrHighwayEmergencyLaneStopped_count = wrongwayviolation.calculate_urbanExpresswayOrHighwayDrivingLaneStopped_count()
|
|
|
+ return {"urbanExpresswayOrHighwayEmergencyLaneStopped": urbanExpresswayOrHighwayEmergencyLaneStopped_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayemergencylanedriving(data_processed):
|
|
|
+ """计算城市快速路应急车道行驶指标"""
|
|
|
+ wrongwayviolation = WrongWayViolation(data_processed)
|
|
|
+ urbanExpresswayEmergencyLaneDriving_count = wrongwayviolation.calculate_urbanExpresswayEmergencyLaneDriving()
|
|
|
+ return {"urbanExpresswayEmergencyLaneDriving": urbanExpresswayEmergencyLaneDriving_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayorhighwayspeedoverlimit50(data_processed):
|
|
|
+ """计算城市快速路或高速公路超速50%以上指标"""
|
|
|
+ speedingviolation = SpeedingViolation(data_processed)
|
|
|
+ urbanExpresswayOrHighwaySpeedOverLimit50_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedOverLimit50_count()
|
|
|
+ return {"urbanExpresswayOrHighwaySpeedOverLimit50": urbanExpresswayOrHighwaySpeedOverLimit50_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayorhighwayspeedoverlimit20to50(data_processed):
|
|
|
+ """计算城市快速路或高速公路超速20%-50%指标"""
|
|
|
+ speedingviolation = SpeedingViolation(data_processed)
|
|
|
+ urbanExpresswayOrHighwaySpeedOverLimit20to50_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedOverLimit20to50_count()
|
|
|
+ return {"urbanExpresswayOrHighwaySpeedOverLimit20to50": urbanExpresswayOrHighwaySpeedOverLimit20to50_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayorhighwayspeedoverlimit0to20(data_processed):
|
|
|
+ """计算城市快速路或高速公路超速0-20%指标"""
|
|
|
+ speedingviolation = SpeedingViolation(data_processed)
|
|
|
+ urbanExpresswayOrHighwaySpeedOverLimit0to20_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedOverLimit0to20_count()
|
|
|
+ return {"urbanExpresswayOrHighwaySpeedOverLimit0to20": urbanExpresswayOrHighwaySpeedOverLimit0to20_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayorhighwayspeedunderlimit(data_processed):
|
|
|
+ """计算城市快速路或高速公路低于最低限速指标"""
|
|
|
+ speedingviolation = SpeedingViolation(data_processed)
|
|
|
+ urbanExpresswayOrHighwaySpeedUnderLimit_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedUnderLimit_count()
|
|
|
+ return {"urbanExpresswayOrHighwaySpeedUnderLimit": urbanExpresswayOrHighwaySpeedUnderLimit_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_generalroadspeedoverlimit50(data_processed):
|
|
|
+ """计算一般道路超速50%以上指标"""
|
|
|
+ speedingviolation = SpeedingViolation(data_processed)
|
|
|
+ generalRoadSpeedOverLimit50_count = speedingviolation.calculate_generalRoadSpeedOverLimit50()
|
|
|
+ return {"generalRoadSpeedOverLimit50": generalRoadSpeedOverLimit50_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_generalroadspeedoverlimit20to50(data_processed):
|
|
|
+ """计算一般道路超速20%-50%指标"""
|
|
|
+ speedingviolation = SpeedingViolation(data_processed)
|
|
|
+ generalRoadSpeedOverLimit20to50_count = speedingviolation.calculate_generalRoadSpeedOverLimit20to50_count()
|
|
|
+ return {"generalRoadSpeedOverLimit20to50": generalRoadSpeedOverLimit20to50_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_trafficsignalviolation(data_processed):
|
|
|
+ """计算交通信号违规指标"""
|
|
|
+ trafficlightviolation = TrafficLightViolation(data_processed)
|
|
|
+ trafficSignalViolation_count = trafficlightviolation.calculate_trafficSignalViolation_count()
|
|
|
+ return {"trafficSignalViolation": trafficSignalViolation_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_illegaldrivingorparkingatcrossroads(data_processed):
|
|
|
+ """计算交叉路口违法行驶或停车指标"""
|
|
|
+ trafficlightviolation = TrafficLightViolation(data_processed)
|
|
|
+ illegalDrivingOrParkingAtCrossroads_count = trafficlightviolation.calculate_illegalDrivingOrParkingAtCrossroads()
|
|
|
+ return {"illegalDrivingOrParkingAtCrossroads": illegalDrivingOrParkingAtCrossroads_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_generalroadirregularlaneuse(data_processed):
|
|
|
+ """计算一般道路不按规定车道行驶指标"""
|
|
|
+ warningviolation = WarningViolation(data_processed)
|
|
|
+ generalRoadIrregularLaneUse_count = warningviolation.calculate_generalRoadIrregularLaneUse_count()
|
|
|
+ return {"generalRoadIrregularLaneUse": generalRoadIrregularLaneUse_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_urbanexpresswayorhighwayridelanedivider(data_processed):
|
|
|
+ """计算城市快速路或高速公路骑车道线行驶指标"""
|
|
|
+ warningviolation = WarningViolation(data_processed)
|
|
|
+ urbanExpresswayOrHighwayRideLaneDivider_count = warningviolation.calculate_urbanExpresswayOrHighwayRideLaneDivider()
|
|
|
+ return {"urbanExpresswayOrHighwayRideLaneDivider": urbanExpresswayOrHighwayRideLaneDivider_count}
|
|
|
+
|
|
|
+def calculate_nostraightthrough(data_processed):
|
|
|
+ """计算禁止直行标志牌处直行指标"""
|
|
|
+ trafficsignviolation = TrafficSignViolation(data_processed)
|
|
|
+ noStraightThrough_count = trafficsignviolation.calculate_NoStraightThrough_count()
|
|
|
+ return {"NoStraightThrough": noStraightThrough_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_speedlimitviolation(data_processed):
|
|
|
+ """计算违反限速规定指标"""
|
|
|
+ trafficsignviolation = TrafficSignViolation(data_processed)
|
|
|
+ SpeedLimitViolation_count = trafficsignviolation.calculate_SpeedLimitViolation_count()
|
|
|
+ return {"SpeedLimitViolation": SpeedLimitViolation_count}
|
|
|
+
|
|
|
+
|
|
|
+def calculate_minimumspeedlimitviolation(data_processed):
|
|
|
+ """计算违反最低限速规定指标"""
|
|
|
+ trafficsignviolation = TrafficSignViolation(data_processed)
|
|
|
+ calculate_MinimumSpeedLimitViolation_count = trafficsignviolation.calculate_MinimumSpeedLimitViolation_count()
|
|
|
+ return {"MinimumSpeedLimitViolation": calculate_MinimumSpeedLimitViolation_count}
|
|
|
+# ... 保留原有类定义 ...
|
|
|
+
|
|
|
+# 修改 TrafficRegistry 类的 _build_registry 方法
|
|
|
+class TrafficRegistry:
|
|
|
+ """交通违规指标注册器"""
|
|
|
+
|
|
|
+ def __init__(self, data_processed):
|
|
|
+ self.logger = LogManager().get_logger()
|
|
|
+ self.data = data_processed
|
|
|
+ self.traffic_config = data_processed.traffic_config["traffic"]
|
|
|
+ self.metrics = self._extract_metrics(self.traffic_config)
|
|
|
+ self._registry = self._build_registry()
|
|
|
+
|
|
|
+ def _extract_metrics(self, config_node: dict) -> list:
|
|
|
+ """从配置中提取指标名称"""
|
|
|
+ metrics = []
|
|
|
+ def _recurse(node):
|
|
|
+ if isinstance(node, dict):
|
|
|
+ if 'name' in node and not any(isinstance(v, dict) for v in node.values()):
|
|
|
+ metrics.append(node['name'])
|
|
|
+ for v in node.values():
|
|
|
+ _recurse(v)
|
|
|
+ _recurse(config_node)
|
|
|
+ self.logger.info(f'评比的交通违规指标列表:{metrics}')
|
|
|
+ return metrics
|
|
|
+
|
|
|
+ def _build_registry(self) -> dict:
|
|
|
+ """构建指标函数注册表"""
|
|
|
+ registry = {}
|
|
|
+ for metric_name in self.metrics:
|
|
|
+ func_name = f"calculate_{metric_name.lower()}"
|
|
|
+ try:
|
|
|
+ registry[metric_name] = globals()[func_name]
|
|
|
+ except KeyError:
|
|
|
+ self.logger.error(f"未实现交通违规指标函数: {func_name}")
|
|
|
+ return registry
|
|
|
+
|
|
|
+ def batch_execute(self) -> dict:
|
|
|
+ """批量执行指标计算"""
|
|
|
+ results = {}
|
|
|
+ for name, func in self._registry.items():
|
|
|
+ try:
|
|
|
+ result = func(self.data)
|
|
|
+ results.update(result)
|
|
|
+ # 新增:将每个指标的结果写入日志
|
|
|
+ self.logger.info(f'交通违规指标[{name}]计算结果: {result}')
|
|
|
+ except Exception as e:
|
|
|
+ self.logger.error(f"{name} 执行失败: {str(e)}", exc_info=True)
|
|
|
+ results[name] = None
|
|
|
+ self.logger.info(f'交通违规指标计算结果:{results}')
|
|
|
+ return results
|
|
|
+
|
|
|
+
|
|
|
+class TrafficManager:
|
|
|
+ """交通违规指标管理类"""
|
|
|
+
|
|
|
+ def __init__(self, data_processed):
|
|
|
+ self.data = data_processed
|
|
|
+ self.logger = LogManager().get_logger()
|
|
|
+ self.registry = TrafficRegistry(self.data)
|
|
|
+
|
|
|
+ def report_statistic(self):
|
|
|
+ """计算并报告交通违规指标结果"""
|
|
|
+ traffic_result = self.registry.batch_execute()
|
|
|
+ return traffic_result
|
|
|
+
|
|
|
+# ... 保留原有类定义和实现 ...
|
|
|
+
|
|
|
class OvertakingViolation(object):
|
|
|
"""超车违规类"""
|
|
|
|
|
@@ -397,7 +634,6 @@ class OvertakingViolation(object):
|
|
|
)
|
|
|
else:
|
|
|
pass
|
|
|
-
|
|
|
def calculate_overtake_when_passing_car_count(self):
|
|
|
self.illegal_overtake_with_car_detector()
|
|
|
return self.overtake_when_passing_car_count
|
|
@@ -435,29 +671,6 @@ class OvertakingViolation(object):
|
|
|
return self.overtake_in_different_senerios_count
|
|
|
|
|
|
|
|
|
-def slow_down_in_crosswalk(data_processed):
|
|
|
- slowdownviolation = SlowdownViolation(data_processed)
|
|
|
- slow_down_in_crosswalk_count = slowdownviolation.calculate_slow_down_in_crosswalk_count()
|
|
|
- return {"slowdown_down_in_crosswalk": slow_down_in_crosswalk_count}
|
|
|
-
|
|
|
-
|
|
|
-def avoid_pedestrian_in_crosswalk(data_processed):
|
|
|
- avoidpedestrianincrosswalk = SlowdownViolation(data_processed)
|
|
|
- avoid_pedestrian_in_crosswalk_count = avoidpedestrianincrosswalk.calculate_avoid_pedestrian_in_the_crosswalk_count()
|
|
|
- return {"avoid_pedestrian_in_crosswalk": avoid_pedestrian_in_crosswalk_count}
|
|
|
-
|
|
|
-
|
|
|
-def avoid_pedestrian_in_the_road(data_processed):
|
|
|
- avoidpedestrianintheroad = SlowdownViolation(data_processed)
|
|
|
- avoid_pedestrian_in_the_road_count = avoidpedestrianintheroad.calculate_avoid_pedestrian_in_the_road_count()
|
|
|
- return {"avoid_pedestrian_in_the_road": avoid_pedestrian_in_the_road_count}
|
|
|
-
|
|
|
-
|
|
|
-def aviod_pedestrian_when_turning(data_processed):
|
|
|
- avoidpedestrianwhenturning = SlowdownViolation(data_processed)
|
|
|
- avoid_pedestrian_when_turning_count = avoidpedestrianwhenturning.calculate_avoid_pedestrian_when_turning_count()
|
|
|
- return {"avoid_pedestrian_when_turning_count": avoid_pedestrian_when_turning_count}
|
|
|
-
|
|
|
|
|
|
class SlowdownViolation(object):
|
|
|
"""减速让行违规类"""
|
|
@@ -656,24 +869,6 @@ class SlowdownViolation(object):
|
|
|
return self.aviod_pedestrian_when_turning_count
|
|
|
|
|
|
|
|
|
-def turn_in_forbiden_turn_left_sign(data_processed):
|
|
|
- turnaroundviolation = TurnaroundViolation(data_processed)
|
|
|
- turn_in_forbiden_turn_left_sign_count = turnaroundviolation.calculate_turn_in_forbiden_turn_left_sign_count()
|
|
|
- return turn_in_forbiden_turn_left_sign_count
|
|
|
-
|
|
|
-
|
|
|
-def turn_in_forbiden_turn_back_sign(data_processed):
|
|
|
- turnaroundviolation = TurnaroundViolation(data_processed)
|
|
|
- turn_in_forbiden_turn_back_sign_count = turnaroundviolation.calculate_turn_in_forbiden_turn_back_sign_count()
|
|
|
- return turn_in_forbiden_turn_back_sign_count
|
|
|
-
|
|
|
-
|
|
|
-def avoid_pedestrian_when_turn_back(data_processed):
|
|
|
- turnaroundviolation = TurnaroundViolation(data_processed)
|
|
|
- avoid_pedestrian_when_turn_back_count = turnaroundviolation.calaulate_avoid_pedestrian_when_turn_back_count()
|
|
|
- return avoid_pedestrian_when_turn_back_count
|
|
|
-
|
|
|
-
|
|
|
class TurnaroundViolation(object):
|
|
|
|
|
|
def __init__(self, df_data):
|
|
@@ -827,24 +1022,6 @@ class TurnaroundViolation(object):
|
|
|
return self.avoid_pedestrian_when_turn_back_count
|
|
|
|
|
|
|
|
|
-def urbanExpresswayOrHighwayDrivingLaneStopped(data_processed):
|
|
|
- wrongwayviolation = WrongWayViolation(data_processed)
|
|
|
- urbanExpresswayOrHighwayDrivingLaneStopped_count = wrongwayviolation.calculate_urbanExpresswayOrHighwayDrivingLaneStopped_count()
|
|
|
- return {"urbanExpresswayOrHighwayDrivingLaneStopped": urbanExpresswayOrHighwayDrivingLaneStopped_count}
|
|
|
-
|
|
|
-
|
|
|
-def urbanExpresswayOrHighwayEmergencyLaneStopped(data_processed):
|
|
|
- wrongwayviolation = WrongWayViolation(data_processed)
|
|
|
- urbanExpresswayOrHighwayEmergencyLaneStopped_count = wrongwayviolation.calculate_urbanExpresswayOrHighwayDrivingLaneStopped_count()
|
|
|
- return {"urbanExpresswayOrHighwayEmergencyLaneStopped": urbanExpresswayOrHighwayEmergencyLaneStopped_count}
|
|
|
-
|
|
|
-
|
|
|
-def urbanExpresswayEmergencyLaneDriving(data_processed):
|
|
|
- wrongwayviolation = WrongWayViolation(data_processed)
|
|
|
- urbanExpresswayEmergencyLaneDriving_count = wrongwayviolation.calculate_urbanExpresswayEmergencyLaneDriving()
|
|
|
- return {"urbanExpresswayEmergencyLaneDriving": urbanExpresswayEmergencyLaneDriving_count}
|
|
|
-
|
|
|
-
|
|
|
class WrongWayViolation:
|
|
|
"""停车违规类"""
|
|
|
|
|
@@ -917,43 +1094,6 @@ class WrongWayViolation:
|
|
|
self.process_violations()
|
|
|
return self.violation_count["urbanExpresswayEmergencyLaneDriving"]
|
|
|
|
|
|
-
|
|
|
-def urbanExpresswayOrHighwaySpeedOverLimit50(data_processed):
|
|
|
- speedingviolation = SpeedingViolation(data_processed)
|
|
|
- urbanExpresswayOrHighwaySpeedOverLimit50_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedOverLimit50_count()
|
|
|
- return {"urbanExpresswayOrHighwaySpeedOverLimit50": urbanExpresswayOrHighwaySpeedOverLimit50_count}
|
|
|
-
|
|
|
-
|
|
|
-def urbanExpresswayOrHighwaySpeedOverLimit20to50(data_processed):
|
|
|
- speedingviolation = SpeedingViolation(data_processed)
|
|
|
- urbanExpresswayOrHighwaySpeedOverLimit20to50_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedOverLimit20to50_count()
|
|
|
- return {"urbanExpresswayOrHighwaySpeedOverLimit20to50": urbanExpresswayOrHighwaySpeedOverLimit20to50_count}
|
|
|
-
|
|
|
-
|
|
|
-def urbanExpresswayOrHighwaySpeedOverLimit0to20(data_processed):
|
|
|
- speedingviolation = SpeedingViolation(data_processed)
|
|
|
- urbanExpresswayOrHighwaySpeedOverLimit0to20_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedOverLimit0to20_count()
|
|
|
- return {"urbanExpresswayOrHighwaySpeedOverLimit0to20": urbanExpresswayOrHighwaySpeedOverLimit0to20_count}
|
|
|
-
|
|
|
-
|
|
|
-def urbanExpresswayOrHighwaySpeedUnderLimit(data_processed):
|
|
|
- speedingviolation = SpeedingViolation(data_processed)
|
|
|
- urbanExpresswayOrHighwaySpeedUnderLimit_count = speedingviolation.calculate_urbanExpresswayOrHighwaySpeedUnderLimit_count()
|
|
|
- return {"urbanExpresswayOrHighwaySpeedUnderLimit": urbanExpresswayOrHighwaySpeedUnderLimit_count}
|
|
|
-
|
|
|
-
|
|
|
-def generalRoadSpeedOverLimit50(data_processed):
|
|
|
- speedingviolation = SpeedingViolation(data_processed)
|
|
|
- generalRoadSpeedOverLimit50_count = speedingviolation.calculate_generalRoadSpeedOverLimit50()
|
|
|
- return {"generalRoadSpeedOverLimit50": generalRoadSpeedOverLimit50_count}
|
|
|
-
|
|
|
-
|
|
|
-def generalRoadSpeedOverLimit20to50(data_processed):
|
|
|
- speedingviolation = SpeedingViolation(data_processed)
|
|
|
- generalRoadSpeedOverLimit20to50_count = speedingviolation.calculate_generalRoadSpeedOverLimit20to50_count()
|
|
|
- return {"generalRoadSpeedOverLimit20to50": generalRoadSpeedOverLimit20to50_count}
|
|
|
-
|
|
|
-
|
|
|
class SpeedingViolation(object):
|
|
|
"""超速违规类"""
|
|
|
|
|
@@ -1060,19 +1200,6 @@ class SpeedingViolation(object):
|
|
|
return self.violation_counts["generalRoadSpeedOverLimit20to50"] if self.violation_counts.get(
|
|
|
"generalRoadSpeedOverLimit20to50") else 0
|
|
|
|
|
|
-
|
|
|
-def trafficSignalViolation(data_processed):
|
|
|
- trafficlightviolation = TrafficLightViolation(data_processed)
|
|
|
- trafficSignalViolation_count = trafficlightviolation.calculate_trafficSignalViolation_count()
|
|
|
- return {"trafficSignalViolation": trafficSignalViolation_count}
|
|
|
-
|
|
|
-
|
|
|
-def illegalDrivingOrParkingAtCrossroads(data_processed):
|
|
|
- trafficlightviolation = TrafficLightViolation(data_processed)
|
|
|
- illegalDrivingOrParkingAtCrossroads_count = trafficlightviolation.calculate_illegalDrivingOrParkingAtCrossroads()
|
|
|
- return {"illegalDrivingOrParkingAtCrossroads": illegalDrivingOrParkingAtCrossroads_count}
|
|
|
-
|
|
|
-
|
|
|
class TrafficLightViolation(object):
|
|
|
"""违反交通灯类"""
|
|
|
|
|
@@ -1234,19 +1361,6 @@ class TrafficLightViolation(object):
|
|
|
self.process_violations()
|
|
|
return self.violation_counts["illegalDrivingOrParkingAtCrossroads"]
|
|
|
|
|
|
-
|
|
|
-def generalRoadIrregularLaneUse(data_processed):
|
|
|
- warningviolation = WarningViolation(data_processed)
|
|
|
- generalRoadIrregularLaneUse_count = warningviolation.calculate_generalRoadIrregularLaneUse_count()
|
|
|
- return {"generalRoadIrregularLaneUse": generalRoadIrregularLaneUse_count}
|
|
|
-
|
|
|
-
|
|
|
-def urbanExpresswayOrHighwayRideLaneDivider(data_processed):
|
|
|
- warningviolation = WarningViolation(data_processed)
|
|
|
- urbanExpresswayOrHighwayRideLaneDivider_count = warningviolation.calculate_urbanExpresswayOrHighwayRideLaneDivider()
|
|
|
- return {"urbanExpresswayOrHighwayRideLaneDivider": urbanExpresswayOrHighwayRideLaneDivider_count}
|
|
|
-
|
|
|
-
|
|
|
class WarningViolation(object):
|
|
|
"""警告性违规类"""
|
|
|
|
|
@@ -1334,183 +1448,99 @@ class WarningViolation(object):
|
|
|
return self.violation_counts["urbanExpresswayOrHighwayRideLaneDivider"]
|
|
|
|
|
|
|
|
|
-class TrafficSignViolation(object):
|
|
|
+class TrafficSignViolation:
|
|
|
"""交通标志违规类"""
|
|
|
+
|
|
|
+ PROHIBITED_STRAIGHT_THRESHOLD = 5
|
|
|
+ SIGN_TYPE_STRAIGHT_PROHIBITED = 7
|
|
|
+ SIGN_TYPE_SPEED_LIMIT = 12
|
|
|
+ SIGN_TYPE_MIN_SPEED_LIMIT = 13
|
|
|
|
|
|
def __init__(self, df_data):
|
|
|
self.traffic_violations_type = "交通标志违规类"
|
|
|
- print("交通标志违规类 类初始化中...")
|
|
|
- self.data_ego = df_data.obj_data[1]
|
|
|
- self.ego_data = (
|
|
|
- self.data_ego[TRFFICSIGN_INFO].copy().reset_index(drop=True)
|
|
|
- )
|
|
|
- self.data_ego = self.data_ego.copy() # 避免修改原始 DataFrame
|
|
|
- self.violation_counts = {
|
|
|
- "NoStraightThrough": 0, # 禁止直行标志地方直行
|
|
|
- "SpeedLimitViolation": 0, # 违反限速规定
|
|
|
- "MinimumSpeedLimitViolation": 0, # 违反最低限速规定
|
|
|
+ print("交通标志违规类 初始化中...")
|
|
|
+
|
|
|
+ # 数据预处理
|
|
|
+ self._raw_data = df_data.obj_data[1].copy()
|
|
|
+ self.data_ego = self._raw_data.sort_values('simTime').reset_index(drop=True)
|
|
|
+
|
|
|
+ # 延迟计算标志
|
|
|
+ self._calculated = False
|
|
|
+ self._violation_counts = {
|
|
|
+ "NoStraightThrough": 0,
|
|
|
+ "SpeedLimitViolation": 0,
|
|
|
+ "MinimumSpeedLimitViolation": 0
|
|
|
}
|
|
|
|
|
|
- # def checkForProhibitionViolation(self):
|
|
|
-
|
|
|
- # """禁令标志判断违规:7 禁止直行,12:限制速度"""
|
|
|
- # # 筛选出sign_type1为7(禁止直行)
|
|
|
- # violation_straight_df = self.data_ego[self.data_ego["sign_type1"] == 7]
|
|
|
- # violation_speed_limit_df = self.data_ego[self.data_ego["sign_type1"] == 12]
|
|
|
-
|
|
|
- def checkForProhibitionViolation(self):
|
|
|
- """禁令标志判断违规:7 禁止直行,12:限制速度"""
|
|
|
- # 筛选出 sign_type1 为7(禁止直行)的数据
|
|
|
- violation_straight_df = self.data_ego[self.data_ego["sign_type1"] == 7].copy()
|
|
|
-
|
|
|
- # 判断车辆是否在禁止直行路段直行
|
|
|
- if not violation_straight_df.empty:
|
|
|
- # 按时间戳排序(假设数据按时间顺序处理)
|
|
|
- violation_straight_df = violation_straight_df.sort_values('simTime')
|
|
|
-
|
|
|
- # 计算航向角变化(前后时间点的差值绝对值)
|
|
|
- violation_straight_df['posH_diff'] = violation_straight_df['posH'].diff().abs()
|
|
|
-
|
|
|
- # 筛选条件:航向角变化小于阈值(例如5度)且速度不为0
|
|
|
- threshold = 5 # 单位:度(根据场景调整)
|
|
|
- mask = (violation_straight_df['posH_diff'] <= threshold) & (violation_straight_df['v'] > 0)
|
|
|
- straight_violations = violation_straight_df[mask]
|
|
|
-
|
|
|
- # 统计违规次数或记录违规数据
|
|
|
- self.violation_counts["prohibition_straight"] = len(straight_violations)
|
|
|
-
|
|
|
- # 限制速度判断(原代码)
|
|
|
- violation_speed_limit_df = self.data_ego[self.data_ego["sign_type1"] == 12]
|
|
|
- if violation_speed_limit_df.empty:
|
|
|
- mask = self.data_ego["v"] > self.data_ego["sign_speed"]
|
|
|
- self.violation_counts["SpeedLimitViolation"] = len(self.data_ego[mask])
|
|
|
-
|
|
|
- def checkForInstructionViolation(self):
|
|
|
- """限速标志属于指示性标志:13:最低限速"""
|
|
|
- violation_minimum_speed_limit_df = self.data_ego[self.data_ego["sign_type1"] == 13]
|
|
|
- if violation_minimum_speed_limit_df.empty:
|
|
|
- mask = self.data_ego["v"] < self.data_ego["sign_speed"]
|
|
|
- self.violation_counts["MinimumSpeedLimitViolation"] = len(self.data_ego[mask])
|
|
|
-
|
|
|
- def statistic(self):
|
|
|
- self.checkForProhibitionViolation()
|
|
|
- self.checkForInstructionViolation()
|
|
|
- # self.logger.info(f"交通标志违规类指标统计完成,统计结果:{self.violation_counts}")
|
|
|
- return self.violation_counts
|
|
|
-
|
|
|
-
|
|
|
-class TrafficRegistry:
|
|
|
- """舒适性指标注册器"""
|
|
|
-
|
|
|
- def __init__(self, data_processed):
|
|
|
- self.logger = LogManager().get_logger() # 获取全局日志实例
|
|
|
- self.data = data_processed
|
|
|
- self.traffic_config = data_processed.traffic_config["traffic"]
|
|
|
- self.metrics = self._extract_metrics(self.traffic_config)
|
|
|
- self._registry = self._build_registry()
|
|
|
-
|
|
|
- def _extract_metrics(self, config_node: dict) -> list:
|
|
|
- """DFS遍历提取指标"""
|
|
|
- metrics = []
|
|
|
-
|
|
|
- def _recurse(node):
|
|
|
- if isinstance(node, dict):
|
|
|
- if 'name' in node and not any(isinstance(v, dict) for v in node.values()):
|
|
|
- metrics.append(node['name'])
|
|
|
- for v in node.values():
|
|
|
- _recurse(v)
|
|
|
-
|
|
|
- _recurse(config_node)
|
|
|
- self.logger.info(f'评比的合规性指标列表:{metrics}')
|
|
|
- return metrics
|
|
|
-
|
|
|
- def _build_registry(self) -> dict:
|
|
|
- """自动注册指标函数"""
|
|
|
- registry = {}
|
|
|
- for metric_name in self.metrics:
|
|
|
- try:
|
|
|
- registry[metric_name] = globals()[metric_name]
|
|
|
- except KeyError:
|
|
|
- self.logger.error(f"未实现指标函数: {metric_name}")
|
|
|
- return registry
|
|
|
-
|
|
|
- def batch_execute(self) -> dict:
|
|
|
- """批量执行指标计算"""
|
|
|
- results = {}
|
|
|
- for name, func in self._registry.items():
|
|
|
- try:
|
|
|
- result = func(self.data)
|
|
|
- results.update(result)
|
|
|
- except Exception as e:
|
|
|
- self.logger.error(f"{name} 执行失败: {str(e)}", exc_info=True)
|
|
|
- results[name] = None
|
|
|
- self.logger.info(f'合规性指标计算结果:{results}')
|
|
|
- return results
|
|
|
-
|
|
|
-
|
|
|
-class TrafficManager:
|
|
|
- """合规性指标计算主类"""
|
|
|
-
|
|
|
- def __init__(self, data_processed):
|
|
|
- self.data = data_processed
|
|
|
- self.logger = LogManager().get_logger()
|
|
|
- self.registry = TrafficRegistry(self.data)
|
|
|
-
|
|
|
- def report_statistic(self):
|
|
|
- """生成合规性评分报告"""
|
|
|
- traffic_result = self.registry.batch_execute()
|
|
|
- return traffic_result
|
|
|
+ def _ensure_calculated(self):
|
|
|
+ """保证计算只执行一次"""
|
|
|
+ if not self._calculated:
|
|
|
+ self._check_prohibition_violations()
|
|
|
+ self._check_instruction_violations()
|
|
|
+ self._calculated = True
|
|
|
+
|
|
|
+ def calculate_NoStraightThrough_count(self):
|
|
|
+ """计算禁止直行违规次数"""
|
|
|
+ self._ensure_calculated()
|
|
|
+ return self._violation_counts["NoStraightThrough"]
|
|
|
+
|
|
|
+ def calculate_SpeedLimitViolation_count(self):
|
|
|
+ """计算超速违规次数"""
|
|
|
+ self._ensure_calculated()
|
|
|
+ return self._violation_counts["SpeedLimitViolation"]
|
|
|
+
|
|
|
+ def calculate_MinimumSpeedLimitViolation_count(self):
|
|
|
+ """计算最低限速违规次数"""
|
|
|
+ self._ensure_calculated()
|
|
|
+ return self._violation_counts["MinimumSpeedLimitViolation"]
|
|
|
+
|
|
|
+ def _check_prohibition_violations(self):
|
|
|
+ """处理禁令标志违规(禁止直行和限速)"""
|
|
|
+ self._check_straight_violation()
|
|
|
+ self._check_speed_violation(
|
|
|
+ self.SIGN_TYPE_SPEED_LIMIT,
|
|
|
+ operator.gt,
|
|
|
+ "SpeedLimitViolation"
|
|
|
+ )
|
|
|
|
|
|
+ def _check_instruction_violations(self):
|
|
|
+ """处理指示标志违规(最低限速)"""
|
|
|
+ self._check_speed_violation(
|
|
|
+ self.SIGN_TYPE_MIN_SPEED_LIMIT,
|
|
|
+ operator.lt,
|
|
|
+ "MinimumSpeedLimitViolation"
|
|
|
+ )
|
|
|
|
|
|
-'''
|
|
|
-class ViolationManager:
|
|
|
- """违规管理类,用于管理所有违规行为"""
|
|
|
+ def _check_straight_violation(self):
|
|
|
+ """检查禁止直行违规"""
|
|
|
+ straight_df = self.data_ego[self.data_ego["sign_type1"] == self.SIGN_TYPE_STRAIGHT_PROHIBITED]
|
|
|
+
|
|
|
+ if not straight_df.empty:
|
|
|
+ # 计算航向角变化并填充缺失值
|
|
|
+ straight_df = straight_df.copy()
|
|
|
+ straight_df['posH_diff'] = straight_df['posH'].diff().abs().fillna(0)
|
|
|
+
|
|
|
+ # 创建筛选条件
|
|
|
+ mask = (
|
|
|
+ (straight_df['posH_diff'] <= self.PROHIBITED_STRAIGHT_THRESHOLD) &
|
|
|
+ (straight_df['v'] > 0)
|
|
|
+ )
|
|
|
+
|
|
|
+ self.violation_counts["NoStraightThrough"] = mask.sum()
|
|
|
|
|
|
- def __init__(self, data_processed):
|
|
|
+ def _check_speed_violation(self, sign_type, compare_op, count_key):
|
|
|
+ """通用速度违规检查方法"""
|
|
|
+ violation_df = self.data_ego[self.data_ego["sign_type1"] == sign_type]
|
|
|
+
|
|
|
+ if not violation_df.empty:
|
|
|
+ mask = compare_op(violation_df['v'], violation_df['sign_speed'])
|
|
|
+ self.violation_counts[count_key] = mask.sum()
|
|
|
|
|
|
- self.violations = []
|
|
|
- self.data = data_processed
|
|
|
- self.config = data_processed.traffic_config
|
|
|
|
|
|
- self.over_take_violation = OvertakingViolation(self.data)
|
|
|
- self.slow_down_violation = SlowdownViolation(self.data)
|
|
|
- self.wrong_way_violation = WrongWayViolation(self.data)
|
|
|
- self.speeding_violation = SpeedingViolation(self.data)
|
|
|
- self.traffic_light_violation = TrafficLightViolation(self.data)
|
|
|
- self.warning_violation = WarningViolation(self.data)
|
|
|
|
|
|
- # self.report_statistic()
|
|
|
|
|
|
- def report_statistic(self):
|
|
|
|
|
|
- traffic_result = self.over_take_violation.statistic()
|
|
|
- traffic_result.update(self.slow_down_violation.statistic())
|
|
|
- traffic_result.update(self.traffic_light_violation.statistic())
|
|
|
- traffic_result.update(self.wrong_way_violation.statistic())
|
|
|
- traffic_result.update(self.speeding_violation.statistic())
|
|
|
- traffic_result.update(self.warning_violation.statistic())
|
|
|
|
|
|
|
|
|
- # evaluator = Score(self.config)
|
|
|
- # result = evaluator.evaluate(traffic_result)
|
|
|
|
|
|
- # print("\n[交规类表现及得分情况]")
|
|
|
- # # self.logger.info(f"Traffic Result:{traffic_result}")
|
|
|
- # return result
|
|
|
- return traffic_result
|
|
|
-'''
|
|
|
-
|
|
|
-# 示例使用
|
|
|
-if __name__ == "__main__":
|
|
|
- case_name = 'D:\Cicv\招远\V2V_CSAE53-2020_ForwardCollision_LST_02-03'
|
|
|
- mode_label = 'D:\Cicv\招远\zhaoyuan0410\config\metrics_config.yaml'
|
|
|
-
|
|
|
- data = data_process.DataPreprocessing(case_name, mode_label)
|
|
|
- traffic_instance = TrafficManager(data)
|
|
|
-
|
|
|
- try:
|
|
|
- traffic_result = traffic_instance.report_statistic()
|
|
|
- result = {'traffic': traffic_result}
|
|
|
- print(result)
|
|
|
- except Exception as e:
|
|
|
- print(f"An error occurred in Traffict.report_statistic: {e}")
|
|
|
+
|