import laspy
import numpy as np
import open3d as o3d
from shapely.geometry import Polygon, LineString
from shapely.ops import nearest_points
def facade_follow_planner(las_path, target_z_levels, offset_dist=5.0):
las = laspy.read(las_path)
points = np.vstack((las.x, las.y, las.z)).transpose()
pcd = o3d.geometry.PointCloud()
pcd.points = o3d.utility.Vector3dVector(points)
labels = np.array(pcd.cluster_dbscan(eps=0.5, min_points=100))
print(labels)
target_idx = np.where(labels == 1)[0]
building_pcd = pcd.select_by_index(target_idx)
o3d.visualization.draw_geometries([building_pcd],
window_name="提取出的建筑物",
width=800,
height=600)
all_waypoints = []
for z in target_z_levels:
z_min, z_max = z - 0.1, z + 0.1
slice_idx = np.where((np.asarray(building_pcd.points)[:, 2] >= z_min) &
(np.asarray(building_pcd.points)[:, 2] <= z_max))[0]
slice_pcd = building_pcd.select_by_index(slice_idx)
if len(slice_pcd.points) < 10: continue
points_2d = np.asarray(slice_pcd.points)[:, :2]
line = LineString(points_2d)
offset_line = line.parallel_offset(offset_dist, side='left')
for pt in offset_line.coords:
p_on_wall = line.interpolate(line.project(Point(pt)))
dx = pt[0] - p_on_wall.x
dy = pt[1] - p_on_wall.y
yaw = np.degrees(np.arctan2(dy, dx))
all_waypoints.append({
'coord': (pt[0], pt[1], z),
'yaw': yaw
})
return all_waypoints
if __name__ == "__main__":
levels = np.arange(10, 50, 3)
waypoints = facade_follow_planner("input/cloud.las", levels)