playback_shp.py 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import pandas as pd
  2. import numpy as np
  3. import matplotlib.pyplot as plt
  4. import matplotlib.patches as patches
  5. from matplotlib.animation import FuncAnimation
  6. import os
  7. import geopandas as gpd
  8. # 位置偏移常量
  9. # X_OFFSET = 258109.4239876
  10. # Y_OFFSET = 4149969.964821
  11. X_OFFSET = 0
  12. Y_OFFSET = 0
  13. # 读取数据
  14. csv_data_path = "/home/kevin/kevin/zhaoyuan/sqlite3_demo/docker_build/preprocess_run/data/V2I_CSAE53-2020_RedLightViolationW_LST_01-01/"
  15. # lane_map_df = pd.read_csv(os.path.join(csv_data_path, 'LaneMap.csv'))
  16. car_df = pd.read_csv(os.path.join(csv_data_path, "ObjState.csv"))
  17. # 创建颜色映射
  18. # unique_vehicle_ids = car_df['playerId'].unique()
  19. unique_vehicle_ids = (
  20. car_df["playerId"].unique()
  21. if "playerId" in car_df.columns
  22. else car_df.assign(playerId=1)["playerId"].unique()
  23. )
  24. colors = [
  25. "red",
  26. "blue",
  27. "green",
  28. "orange",
  29. "purple",
  30. "cyan",
  31. "magenta",
  32. "yellow",
  33. "black",
  34. "brown",
  35. ]
  36. vehicle_colors = {
  37. vehicle_id: colors[i] for i, vehicle_id in enumerate(unique_vehicle_ids)
  38. }
  39. # 依据时间分组车辆数据,按 simTime 进行分组
  40. grouped_car_data = car_df.groupby("simTime")
  41. # 加载地图数据
  42. gdfs = []
  43. folder_path = (
  44. "/home/kevin/kevin/zhaoyuan/zhaoyuan_0227_v0.3/zhaoyuan/modules/map/data/shp"
  45. )
  46. file_names = [
  47. "hd_arrow.shp",
  48. "hd_lane_change.shp",
  49. "hd_link_change.shp",
  50. "hd_parkingspace.shp",
  51. "hd_boundary_change.shp",
  52. "hd_crosswalk.shp",
  53. "hd_intersection.shp",
  54. "hd_link_boundary.shp",
  55. "hd_noparkingarea.shp",
  56. "hd_trafficlight.shp",
  57. "hd_stopline.shp",
  58. "hd_lane.shp",
  59. ]
  60. for file_name in file_names:
  61. gdf = gpd.read_file(f"{folder_path}/{file_name}")
  62. gdfs.append(gdf)
  63. gdfs = [gdf for gdf in gdfs if not gdf.empty]
  64. all_gdf = gpd.GeoDataFrame(pd.concat(gdfs, ignore_index=True))
  65. lane_gdf = gdfs[file_names.index("hd_lane.shp")]
  66. lane_gdf["geometry"] = lane_gdf.apply(
  67. lambda row: row["geometry"].buffer(row["lane_width"] / 2), axis=1
  68. )
  69. # 设置画布
  70. fig, ax = plt.subplots(figsize=(12, 8))
  71. lane_gdf.plot(ax=ax, color="gray", edgecolor="black", alpha=0.7)
  72. all_gdf.plot(ax=ax, edgecolor="black", alpha=0.5, linestyle="--")
  73. # 查找车辆位置的极值
  74. min_x = car_df["posX"].min() + X_OFFSET
  75. max_x = car_df["posX"].max() + X_OFFSET
  76. min_y = car_df["posY"].min() + Y_OFFSET
  77. max_y = car_df["posY"].max() + Y_OFFSET
  78. # 添加缓冲区
  79. buffer_x = 50 # 可以根据需要修改
  80. buffer_y = 50 # 可以根据需要修改
  81. # 设置适当的 x 和 y 轴范围
  82. x_min, x_max = min_x - buffer_x, max_x + buffer_x
  83. y_min, y_max = min_y - buffer_y, max_y + buffer_y
  84. ax.set_xlim(x_min, x_max)
  85. ax.set_ylim(y_min, y_max)
  86. # 动态绘制车辆
  87. def update(frame):
  88. # 清除之前的矩形
  89. for patch in ax.patches:
  90. patch.remove()
  91. for text in ax.texts:
  92. text.remove()
  93. current_time = list(grouped_car_data.groups.keys())[frame]
  94. current_data = grouped_car_data.get_group(current_time)
  95. for index, row in current_data.iterrows():
  96. posX = row["posX"] + X_OFFSET
  97. posY = row["posY"] + Y_OFFSET
  98. print(f"row[posH]: {row['posH']}")
  99. print(f"row['speedH']: {row['speedH']}")
  100. # posH =np.pi/ 2 - math.radians(row["posH"])
  101. posH =np.pi/ 2 -np.deg2rad(row["posH"])
  102. # posH = np.pi/ 2
  103. print(f"posH: {posH}")
  104. # dimX = row['dimX']np.deg2rad(degrees)
  105. # dimY = row['dimY']
  106. dimX = 5.99
  107. dimY = 2.065
  108. corners = np.array(
  109. [
  110. [-dimX / 2, -dimY / 2],
  111. [dimX / 2, -dimY / 2],
  112. [dimX / 2, dimY / 2],
  113. [-dimX / 2, dimY / 2],
  114. ]
  115. )
  116. # rotation_matrix = np.array(
  117. # [[np.cos(posH), -np.sin(posH)], [np.sin(posH), np.cos(posH)]]
  118. # )
  119. # rotated_corners = corners.dot(rotation_matrix) + np.array([posX, posY])
  120. # # 更安全的坐标转换
  121. # rotated_corners = np.dot(corners, rotation_matrix) + np.array([[posX], [posY]])
  122. rotation_matrix = np.array(
  123. [[np.cos(posH), np.sin(posH)], [-np.sin(posH), np.cos(posH)]]
  124. )
  125. # 关键修复:使用广播机制自动对齐形状
  126. rotated_corners = np.dot(corners, rotation_matrix) + [posX, posY]
  127. vehicle_color = vehicle_colors[row["playerId"]]
  128. vehicle = patches.Polygon(
  129. rotated_corners,
  130. closed=True,
  131. fill=True,
  132. color=vehicle_color,
  133. alpha=0.5,
  134. edgecolor="black",
  135. )
  136. ax.add_patch(vehicle)
  137. # 添加文本标注,显示坐标值
  138. ax.text(
  139. posX,
  140. posY,
  141. f"({posX:.1f}, {posY:.1f})",
  142. fontsize=8,
  143. ha="center",
  144. va="center",
  145. color="black",
  146. )
  147. # 添加黑色圆点,显示车辆坐标位置
  148. # ax.dot(posX, posY, 'o', color='black', markersize=1) # 你可以调整markersize来改变圆点大小
  149. plt.title(f"Time: {current_time:.5f}s")
  150. # 设置动画,frames为时间段的数量
  151. ani = FuncAnimation(
  152. fig, update, frames=len(grouped_car_data.groups), repeat=True, interval=0.1
  153. )
  154. # 添加标题并显示地图
  155. plt.title("Map Visualization with Vehicle Animation", fontsize=15)
  156. plt.show()