123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191 |
- import pandas as pd
- import numpy as np
- import matplotlib.pyplot as plt
- import matplotlib.patches as patches
- from matplotlib.animation import FuncAnimation
- import os
- import geopandas as gpd
- # 位置偏移常量
- # X_OFFSET = 258109.4239876
- # Y_OFFSET = 4149969.964821
- X_OFFSET = 0
- Y_OFFSET = 0
- # 读取数据
- csv_data_path = "/home/kevin/kevin/zhaoyuan/sqlite3_demo/docker_build/preprocess_run/dataPreProcess/output/V2I_CSAE53-2020_RedLightViolationW_LST_01-01/"
- # lane_map_df = pd.read_csv(os.path.join(csv_data_path, 'LaneMap.csv'))
- car_df = pd.read_csv(os.path.join(csv_data_path, "ObjState.csv"))
- # 创建颜色映射
- # unique_vehicle_ids = car_df['playerId'].unique()
- unique_vehicle_ids = (
- car_df["playerId"].unique()
- if "playerId" in car_df.columns
- else car_df.assign(playerId=1)["playerId"].unique()
- )
- colors = [
- "red",
- "blue",
- "green",
- "orange",
- "purple",
- "cyan",
- "magenta",
- "yellow",
- "black",
- "brown",
- ]
- vehicle_colors = {
- vehicle_id: colors[i] for i, vehicle_id in enumerate(unique_vehicle_ids)
- }
- # 依据时间分组车辆数据,按 simTime 进行分组
- grouped_car_data = car_df.groupby("simTime")
- # 加载地图数据
- gdfs = []
- folder_path = (
- "/home/kevin/kevin/zhaoyuan/zhaoyuan_0227_v0.3/zhaoyuan/modules/map/data/shp"
- )
- file_names = [
- "hd_arrow.shp",
- "hd_lane_change.shp",
- "hd_link_change.shp",
- "hd_parkingspace.shp",
- "hd_boundary_change.shp",
- "hd_crosswalk.shp",
- "hd_intersection.shp",
- "hd_link_boundary.shp",
- "hd_noparkingarea.shp",
- "hd_trafficlight.shp",
- "hd_stopline.shp",
- "hd_lane.shp",
- ]
- for file_name in file_names:
- gdf = gpd.read_file(f"{folder_path}/{file_name}")
- gdfs.append(gdf)
- gdfs = [gdf for gdf in gdfs if not gdf.empty]
- all_gdf = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True))
- lane_gdf = gdfs[file_names.index("hd_lane.shp")]
- lane_gdf["geometry"] = lane_gdf.apply(
- lambda row: row["geometry"].buffer(row["lane_width"] / 2), axis=1
- )
- # 设置画布
- fig, ax = plt.subplots(figsize=(12, 8))
- lane_gdf.plot(ax=ax, color="gray", edgecolor="black", alpha=0.7)
- all_gdf.plot(ax=ax, edgecolor="black", alpha=0.5, linestyle="--")
- # 查找车辆位置的极值
- min_x = car_df["posX"].min() + X_OFFSET
- max_x = car_df["posX"].max() + X_OFFSET
- min_y = car_df["posY"].min() + Y_OFFSET
- max_y = car_df["posY"].max() + Y_OFFSET
- # 添加缓冲区
- buffer_x = 50 # 可以根据需要修改
- buffer_y = 50 # 可以根据需要修改
- # 设置适当的 x 和 y 轴范围
- x_min, x_max = min_x - buffer_x, max_x + buffer_x
- y_min, y_max = min_y - buffer_y, max_y + buffer_y
- ax.set_xlim(x_min, x_max)
- ax.set_ylim(y_min, y_max)
- # 动态绘制车辆
- def update(frame):
- # 清除之前的矩形
- for patch in ax.patches:
- patch.remove()
- for text in ax.texts:
- text.remove()
- current_time = list(grouped_car_data.groups.keys())[frame]
- current_data = grouped_car_data.get_group(current_time)
- for index, row in current_data.iterrows():
- posX = row["posX"] + X_OFFSET
- posY = row["posY"] + Y_OFFSET
- print(f"row[posH]: {row['posH']}")
- print(f"row['speedH']: {row['speedH']}")
- # posH =np.pi/ 2 - math.radians(row["posH"])
- posH =np.pi/ 2 -np.deg2rad(row["posH"])
- # posH = np.pi/ 2
- print(f"posH: {posH}")
- # dimX = row['dimX']np.deg2rad(degrees)
- # dimY = row['dimY']
- dimX = 5.99
- dimY = 2.065
- corners = np.array(
- [
- [-dimX / 2, -dimY / 2],
- [dimX / 2, -dimY / 2],
- [dimX / 2, dimY / 2],
- [-dimX / 2, dimY / 2],
- ]
- )
-
- # rotation_matrix = np.array(
- # [[np.cos(posH), -np.sin(posH)], [np.sin(posH), np.cos(posH)]]
- # )
- # rotated_corners = corners.dot(rotation_matrix) + np.array([posX, posY])
-
- # # 更安全的坐标转换
- # rotated_corners = np.dot(corners, rotation_matrix) + np.array([[posX], [posY]])
- rotation_matrix = np.array(
- [[np.cos(posH), np.sin(posH)], [-np.sin(posH), np.cos(posH)]]
- )
-
- # 关键修复:使用广播机制自动对齐形状
- rotated_corners = np.dot(corners, rotation_matrix) + [posX, posY]
- vehicle_color = vehicle_colors[row["playerId"]]
- vehicle = patches.Polygon(
- rotated_corners,
- closed=True,
- fill=True,
- color=vehicle_color,
- alpha=0.5,
- edgecolor="black",
- )
- ax.add_patch(vehicle)
- # 添加文本标注,显示坐标值
- ax.text(
- posX,
- posY,
- f"({posX:.1f}, {posY:.1f})",
- fontsize=8,
- ha="center",
- va="center",
- color="black",
- )
- # 添加黑色圆点,显示车辆坐标位置
- # ax.dot(posX, posY, 'o', color='black', markersize=1) # 你可以调整markersize来改变圆点大小
- plt.title(f"Time: {current_time:.5f}s")
- # 设置动画,frames为时间段的数量
- ani = FuncAnimation(
- fig, update, frames=len(grouped_car_data.groups), repeat=True, interval=0.1
- )
- # 添加标题并显示地图
- plt.title("Map Visualization with Vehicle Animation", fontsize=15)
- plt.show()
|