Commit e0c51e5d authored by xiongchao's avatar xiongchao

修复道路边缘相关的bugg

parent 95614a8c
...@@ -45,6 +45,8 @@ class ConnectMeshByMeshList: ...@@ -45,6 +45,8 @@ class ConnectMeshByMeshList:
self.mesh_box_layer.SetAttributeFilter(filter) self.mesh_box_layer.SetAttributeFilter(filter)
mesh_box_count = self.mesh_box_layer.GetFeatureCount() mesh_box_count = self.mesh_box_layer.GetFeatureCount()
if mesh_box_count != 1: if mesh_box_count != 1:
self.mesh_box_layer.SetAttributeFilter(None) # 消除属性过滤
self.mesh_box_layer.ResetReading()
return False return False
mesh_box_feature = self.mesh_box_layer.GetNextFeature() mesh_box_feature = self.mesh_box_layer.GetNextFeature()
self.mesh_box_layer.SetAttributeFilter(None) # 消除属性过滤 self.mesh_box_layer.SetAttributeFilter(None) # 消除属性过滤
...@@ -157,6 +159,7 @@ class ConnectMeshByMeshList: ...@@ -157,6 +159,7 @@ class ConnectMeshByMeshList:
output_info = "图幅号为:" + str(mesh_id1) + "的topo点" + "和图幅号为:" + \ output_info = "图幅号为:" + str(mesh_id1) + "的topo点" + "和图幅号为:" + \
str(mesh_id2) + "的topo点没有连接的关系,不需要接边\n" str(mesh_id2) + "的topo点没有连接的关系,不需要接边\n"
self.output_info3.append(output_info) self.output_info3.append(output_info)
self.topo_point_layer.SetSpatialFilter(None) # 消除空间过滤
return False, [] return False, []
filter = '"' + const.NEXT_COUNT + '" = 0 and "' + const.PREV_COUNT + '" != 0' filter = '"' + const.NEXT_COUNT + '" = 0 and "' + const.PREV_COUNT + '" != 0'
self.topo_point_layer.SetAttributeFilter(filter) self.topo_point_layer.SetAttributeFilter(filter)
...@@ -165,6 +168,8 @@ class ConnectMeshByMeshList: ...@@ -165,6 +168,8 @@ class ConnectMeshByMeshList:
output_info = "图幅号:" + str(mesh_id1) + "和图幅号:" + str(mesh_id2) + \ output_info = "图幅号:" + str(mesh_id1) + "和图幅号:" + str(mesh_id2) + \
"之间没有topo的next_count为0且prev_count不为0,不需要接边\n" "之间没有topo的next_count为0且prev_count不为0,不需要接边\n"
self.output_info3.append(output_info) self.output_info3.append(output_info)
self.topo_point_layer.SetAttributeFilter(None) # 消除属性过滤
self.topo_point_layer.SetSpatialFilter(None) # 消除空间过滤
return False, [] return False, []
topo_features = [] topo_features = []
for _ in range(topo_feature_count): for _ in range(topo_feature_count):
...@@ -267,12 +272,12 @@ class ConnectMeshByMeshList: ...@@ -267,12 +272,12 @@ class ConnectMeshByMeshList:
for mesh_id1 in self.mesh_ids: for mesh_id1 in self.mesh_ids:
try: try:
mesh_box_feature1 = self.get_box_by_meshid(mesh_id1) mesh_box_feature1 = self.get_box_by_meshid(mesh_id1)
connected_meshs[mesh_id1] = []
if mesh_box_feature1 is False: if mesh_box_feature1 is False:
output_info = "根据图幅号:" + str(mesh_id1) + \ output_info = "根据图幅号:" + str(mesh_id1) + \
"没有找到图幅框或者找到的图幅框不止一个,数据异常,请修改数据后执行接边" "没有找到图幅框或者找到的图幅框不止一个,数据异常,请修改数据后执行接边"
self.output_info1.append([str(mesh_id1), '', [output_info]]) self.output_info1.append([str(mesh_id1), '', [output_info]])
continue continue
connected_meshs[mesh_id1] = []
mesh_box_geom1 = mesh_box_feature1.GetGeometryRef() mesh_box_geom1 = mesh_box_feature1.GetGeometryRef()
mesh_box_features = self.get_waiting_connect_meshs(mesh_box_feature1, mesh_id1) mesh_box_features = self.get_waiting_connect_meshs(mesh_box_feature1, mesh_id1)
except Exception as e: except Exception as e:
...@@ -442,6 +447,7 @@ class ConnectTwoMeshByTopo: ...@@ -442,6 +447,7 @@ class ConnectTwoMeshByTopo:
if lane_edge_feature_count < 2: if lane_edge_feature_count < 2:
output_info = "gps_id: " + str(topo_feature[const.ID]) + "的topo点附近的车道宽度过大,请手动接边" output_info = "gps_id: " + str(topo_feature[const.ID]) + "的topo点附近的车道宽度过大,请手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
self.lane_edge_layer.SetSpatialFilter(None)
return [] return []
lane_edge_features = [] lane_edge_features = []
for _ in range(lane_edge_feature_count): for _ in range(lane_edge_feature_count):
...@@ -561,6 +567,7 @@ class ConnectTwoMeshByTopo: ...@@ -561,6 +567,7 @@ class ConnectTwoMeshByTopo:
if topo_count != 1: if topo_count != 1:
output_info = "根据gps_id:" + str(next_topo_id) + "搜索到的topo点不是一个,topo数据异常,请手动接边" output_info = "根据gps_id:" + str(next_topo_id) + "搜索到的topo点不是一个,topo数据异常,请手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
self.topo_point_layer.SetAttributeFilter(None) # 消除属性过滤
return False, [] return False, []
begin_topo_feature = self.topo_point_layer.GetNextFeature() begin_topo_feature = self.topo_point_layer.GetNextFeature()
self.topo_point_layer.SetAttributeFilter(None) # 消除属性过滤 self.topo_point_layer.SetAttributeFilter(None) # 消除属性过滤
...@@ -596,6 +603,7 @@ class ConnectTwoMeshByTopo: ...@@ -596,6 +603,7 @@ class ConnectTwoMeshByTopo:
output_info = "在图幅号为:" + str(mesh_id) + "中根据参考线id:" + \ output_info = "在图幅号为:" + str(mesh_id) + "中根据参考线id:" + \
str(link_id) + "搜索到的参考线不是一条,数据异常,请修改数据后手动接边" str(link_id) + "搜索到的参考线不是一条,数据异常,请修改数据后手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
self.link_layer.SetAttributeFilter(None) # 消除属性过滤
return None return None
link_feature = self.link_layer.GetNextFeature() link_feature = self.link_layer.GetNextFeature()
self.link_layer.SetAttributeFilter(None) # 消除属性过滤 self.link_layer.SetAttributeFilter(None) # 消除属性过滤
...@@ -612,6 +620,7 @@ class ConnectTwoMeshByTopo: ...@@ -612,6 +620,7 @@ class ConnectTwoMeshByTopo:
output_info = "在图幅号为:" + str(mesh_id) + "中根据参考线id:" + \ output_info = "在图幅号为:" + str(mesh_id) + "中根据参考线id:" + \
str(link_id) + "搜索到的边界线不足2条,请手动接边" str(link_id) + "搜索到的边界线不足2条,请手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
self.lane_edge_layer.SetAttributeFilter(None)
return None return None
lane_edge_features = [] lane_edge_features = []
for _ in range(lane_edge_count): for _ in range(lane_edge_count):
...@@ -623,6 +632,7 @@ class ConnectTwoMeshByTopo: ...@@ -623,6 +632,7 @@ class ConnectTwoMeshByTopo:
output_info = "在图幅号为:" + str(mesh_id) + "中根据参考线id:" + \ output_info = "在图幅号为:" + str(mesh_id) + "中根据参考线id:" + \
str(link_id) + "搜索到的边界线不足2条,请手动接边" str(link_id) + "搜索到的边界线不足2条,请手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
self.lane_edge_layer.SetAttributeFilter(None)
return None return None
self.lane_edge_layer.SetAttributeFilter(None) self.lane_edge_layer.SetAttributeFilter(None)
self.lane_edge_layer.ResetReading() self.lane_edge_layer.ResetReading()
...@@ -638,6 +648,7 @@ class ConnectTwoMeshByTopo: ...@@ -638,6 +648,7 @@ class ConnectTwoMeshByTopo:
output_info = "在图幅号为:" + str(mesh_id) + "中,根据关联的参考线id:" + \ output_info = "在图幅号为:" + str(mesh_id) + "中,根据关联的参考线id:" + \
str(link_id) + "没有搜索到中心线,数据异常,请修改数据后手动接边" str(link_id) + "没有搜索到中心线,数据异常,请修改数据后手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
self.lane_link_layer.SetAttributeFilter(None)
return None return None
lane_link_features = [] lane_link_features = []
for _ in range(lane_link_count): for _ in range(lane_link_count):
...@@ -649,61 +660,78 @@ class ConnectTwoMeshByTopo: ...@@ -649,61 +660,78 @@ class ConnectTwoMeshByTopo:
output_info = "在图幅号为:" + str(mesh_id) + "中,根据关联的参考线id:" + \ output_info = "在图幅号为:" + str(mesh_id) + "中,根据关联的参考线id:" + \
str(link_id) + "没有搜索到中心线,数据异常,请修改数据后手动接边" str(link_id) + "没有搜索到中心线,数据异常,请修改数据后手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
self.lane_link_layer.SetAttributeFilter(None)
return None return None
self.lane_link_layer.SetAttributeFilter(None) self.lane_link_layer.SetAttributeFilter(None)
self.lane_link_layer.ResetReading() self.lane_link_layer.ResetReading()
return lane_link_features return lane_link_features
def get_link_edge_by_link(self, link_feature, mesh_id): def get_link_edge_by_link(self, link_feature, mesh_id):
left_link_edge_id, right_link_edge_id = link_feature[const.LEFT_LINK_EDGE], link_feature[const.RIGHT_LINK_EDGE] left_link_edge_ids, right_link_edge_ids = link_feature[const.LEFT_LINK_EDGE], link_feature[const.RIGHT_LINK_EDGE]
if not left_link_edge_id or not right_link_edge_id: if not left_link_edge_ids or not right_link_edge_ids:
output_info = "id为:" + str(link_feature[const.LINK_ID]) + \ output_info = "id为:" + str(link_feature[const.LINK_ID]) + \
"的参考线的左道路边缘或者右道路边缘为空,数据异常,请修改收据后手动接边" "的参考线的左道路边缘或者右道路边缘为空,数据异常,请修改收据后手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
return [] return [[], []]
filter = '"' + const.LINK_EDGE_ID + '" = ' + str(left_link_edge_id) + \
' and "' + const.MESH_ID + '" = ' + "'" + str(mesh_id) + "'" left_link_edge_id_list = left_link_edge_ids.split(";")
self.link_edge_layer.SetAttributeFilter(filter) left_link_edge_features = []
link_edge_count = self.link_edge_layer.GetFeatureCount() for left_link_edge_id in left_link_edge_id_list:
if link_edge_count != 1: filter = '"' + const.LINK_EDGE_ID + '" = ' + str(left_link_edge_id) + \
output_info = "根据id:" + str(left_link_edge_id) + "搜索到的道路边缘不是一条,数据异常,请修改数据后手动接边" ' and "' + const.MESH_ID + '" = ' + "'" + str(mesh_id) + "'"
self.output_info1.append(output_info) self.link_edge_layer.SetAttributeFilter(filter)
return [] link_edge_count = self.link_edge_layer.GetFeatureCount()
left_link_edge_feature = self.link_edge_layer.GetNextFeature() if link_edge_count != 1:
self.link_edge_layer.SetAttributeFilter(None) output_info = "根据id:" + str(left_link_edge_id) + "搜索到的道路边缘不是一条,数据异常,请修改数据后手动接边"
self.output_info1.append(output_info)
self.link_edge_layer.SetAttributeFilter(None)
return [[], []]
left_link_edge_feature = self.link_edge_layer.GetNextFeature()
left_link_edge_features.append(left_link_edge_feature)
self.link_edge_layer.SetAttributeFilter(None)
self.link_edge_layer.ResetReading() self.link_edge_layer.ResetReading()
filter = '"' + const.LINK_EDGE_ID + '" = ' + str(right_link_edge_id) + \ right_link_edge_id_list = right_link_edge_ids.split(";")
' and "' + const.MESH_ID + '" = ' + "'" + str(mesh_id) + "'" right_link_edge_features = []
self.link_edge_layer.SetAttributeFilter(filter) for right_link_edge_id in right_link_edge_id_list:
link_edge_count = self.link_edge_layer.GetFeatureCount() filter = '"' + const.LINK_EDGE_ID + '" = ' + str(right_link_edge_id) + \
if link_edge_count != 1: ' and "' + const.MESH_ID + '" = ' + "'" + str(mesh_id) + "'"
output_info = "根据id:" + str(right_link_edge_id) + "搜索到的道路边缘不是一条,请修改数据后手动接边" self.link_edge_layer.SetAttributeFilter(filter)
self.output_info1.append(output_info) link_edge_count = self.link_edge_layer.GetFeatureCount()
return [] if link_edge_count != 1:
right_link_edge_feature = self.link_edge_layer.GetNextFeature() output_info = "根据id:" + str(right_link_edge_id) + "搜索到的道路边缘不是一条,请修改数据后手动接边"
self.link_edge_layer.SetAttributeFilter(None) self.output_info1.append(output_info)
self.link_edge_layer.SetAttributeFilter(None)
return [[], []]
right_link_edge_feature = self.link_edge_layer.GetNextFeature()
right_link_edge_features.append(right_link_edge_feature)
self.link_edge_layer.SetAttributeFilter(None)
self.link_edge_layer.ResetReading() self.link_edge_layer.ResetReading()
return [left_link_edge_feature, right_link_edge_feature] return [left_link_edge_features, right_link_edge_features]
def match_line(self, lines1, lines2, id): def match_line(self, lines1, lines2, line_layer_name, id):
# 对前后得线段集合进行匹配,id为参考线的主键 # 对前后得线段集合进行匹配,id为参考线的主键
# lines1和lines2都是cpt坐标系下的点
interpol_lines1 = [interpolation_dataset_3d(line, 2) for line in lines1]
interpol_lines2 = [interpolation_dataset_3d(line, 2) for line in lines2]
cal_x_mean = lambda line: np.mean([point[0] for point in line[-const.COMPARISON_NUM2:]]) cal_x_mean = lambda line: np.mean([point[0] for point in line[-const.COMPARISON_NUM2:]])
line_info1 = [[cal_x_mean(lines1[i]), i] for i in range(len(lines1))] line_info1 = [[cal_x_mean(lines1[i]), i] for i in range(len(interpol_lines1))]
line_info2 = [[cal_x_mean(lines2[j]), j] for j in range(len(lines2))] line_info2 = [[cal_x_mean(lines2[j]), j] for j in range(len(interpol_lines2))]
line_info1.sort(key=lambda x: x[0]) line_info1.sort(key=lambda x: x[0])
line_info2.sort(key=lambda x: x[0]) line_info2.sort(key=lambda x: x[0])
m1, m2 = len(line_info1), len(line_info2) m1, m2 = len(line_info1), len(line_info2)
if abs(line_info1[0][0] - line_info2[0][0]) < 1 and abs(line_info1[-1][0] - line_info2[-1][0]) < 1 and m1 != m2: if abs(line_info1[0][0] - line_info2[0][0]) < 1 and abs(line_info1[-1][0] - line_info2[-1][0]) < 1 and m1 != m2:
# 道路宽度一样,车道数不一样 # 道路宽度一样,车道数不一样
output_info = "id为:" + str(id) + "的参考线的接边处,两者的道路宽度近似,但是车道数不一样,请手动接边" output_info = "id为:" + str(id) + "的参考线的接边处,两者的道路宽度近似,但是" + \
str(line_layer_name) + "的数量不一样,请手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
return False, [] return False, []
if ((abs(line_info1[0][0] - line_info2[0][0]) < 1 and abs(line_info1[-1][0] - line_info2[-1][0]) > 2) or ( if ((abs(line_info1[0][0] - line_info2[0][0]) < 1 and abs(line_info1[-1][0] - line_info2[-1][0]) > 2) or (
abs(line_info1[-1][0] - line_info2[-1][0]) < 1 and abs( abs(line_info1[-1][0] - line_info2[-1][0]) < 1 and abs(
line_info1[0][0] - line_info2[0][0]) > 2)) and m1 == m2: line_info1[0][0] - line_info2[0][0]) > 2)) and m1 == m2:
# 车道数一样,且起始车道线一样(或者末尾车道线一样),道路宽度不一样 # 车道数一样,且起始车道线一样(或者末尾车道线一样),道路宽度不一样
output_info = "id为:" + str(id) + "的参考线的接边处,两者的车道数一样,道路宽度不一样,请手动接边" output_info = "id为:" + str(id) + "的参考线的接边处,两者的" + \
str(line_layer_name) + "数量一样,道路宽度不一样,请手动接边"
self.output_info1.append(output_info) self.output_info1.append(output_info)
return False, [] return False, []
match_list = [] match_list = []
...@@ -825,7 +853,8 @@ class ConnectTwoMeshByTopo: ...@@ -825,7 +853,8 @@ class ConnectTwoMeshByTopo:
cpt_lane_edge_lines2.append(new_cpt_lane_edge_points) cpt_lane_edge_lines2.append(new_cpt_lane_edge_points)
lane_edge_directions2.append(lane_edge_direction) lane_edge_directions2.append(lane_edge_direction)
flag, lane_edge_match_list = self.match_line(cpt_lane_edge_lines1, cpt_lane_edge_lines2, link_id1) flag, lane_edge_match_list = self.match_line(cpt_lane_edge_lines1, cpt_lane_edge_lines2,
const.HD_LANE_EDGE, link_id1)
if not flag: if not flag:
return False, [] return False, []
smoothing_count_list = [] smoothing_count_list = []
...@@ -870,7 +899,8 @@ class ConnectTwoMeshByTopo: ...@@ -870,7 +899,8 @@ class ConnectTwoMeshByTopo:
cpt_lane_link_lines2.append(new_cpt_lane_link_points) cpt_lane_link_lines2.append(new_cpt_lane_link_points)
lane_link_directions2.append(lane_link_direction) lane_link_directions2.append(lane_link_direction)
flag, lane_link_match_list = self.match_line(cpt_lane_link_lines1, cpt_lane_link_lines2, link_id1) flag, lane_link_match_list = self.match_line(cpt_lane_link_lines1, cpt_lane_link_lines2,
const.HD_LANE_LINK, link_id1)
if not flag: if not flag:
return False, [] return False, []
...@@ -887,37 +917,144 @@ class ConnectTwoMeshByTopo: ...@@ -887,37 +917,144 @@ class ConnectTwoMeshByTopo:
return True, [lane_link_features1, lane_link_features2, return True, [lane_link_features1, lane_link_features2,
lane_link_match_directions, lane_link_match_list, smoothing_count_list] lane_link_match_directions, lane_link_match_list, smoothing_count_list]
def is_connect_link_edge(self, topo_feature, link_feature1, link_feature2, def get_target_link_edge1(self, link_id, left_link_edge_features, right_link_edge_features, topo_feature, *proj_info):
mesh_id1, mesh_id2, connect_boundary, *proj_info): # 由于参考线可以关联多条道路边缘线,需要计算获取所需的道路边缘
link_edge_features1 = self.get_link_edge_by_link(link_feature1, mesh_id1) cpt_link_edge_lines = []
if not link_edge_features1: link_edge_directions = []
return False, []
link_edge_features2 = self.get_link_edge_by_link(link_feature2, mesh_id2) left_max_cpt_y = -np.inf
if not link_edge_features2: left_target_cpt_link_edge_points = []
return False, [] left_target_link_edge_direction = None
left_target_link_edge_feature = None
cpt_link_edge_lines1 = [] for left_link_edge_feature in left_link_edge_features:
link_edge_directions1 = [] link_edge_points = left_link_edge_feature.GetGeometryRef().GetPoints()
for link_edge_feature in link_edge_features1:
link_edge_points = link_edge_feature.GetGeometryRef().GetPoints()
cpt_link_edge_points = blh_to_cpt(link_edge_points, *proj_info) cpt_link_edge_points = blh_to_cpt(link_edge_points, *proj_info)
new_cpt_link_edge_points, link_edge_direction = self.cal_forward_direction(cpt_link_edge_points, new_cpt_link_edge_points, link_edge_direction = self.cal_forward_direction(cpt_link_edge_points,
topo_feature, *proj_info) topo_feature, *proj_info)
cpt_link_edge_lines1.append(new_cpt_link_edge_points) left_max_cpt_y1 = max([point[1] for point in new_cpt_link_edge_points])
link_edge_directions1.append(link_edge_direction) if left_max_cpt_y1 > left_max_cpt_y:
left_max_cpt_y = left_max_cpt_y1
cpt_link_edge_lines2 = [] left_target_cpt_link_edge_points = new_cpt_link_edge_points
link_edge_directions2 = [] left_target_link_edge_direction = link_edge_direction
for link_edge_feature in link_edge_features2: left_target_link_edge_feature = left_link_edge_feature
link_edge_points = link_edge_feature.GetGeometryRef().GetPoints() if abs(left_max_cpt_y) > 6:
output_info = "id为:" + str(link_id) + "的参考线,根据它的左边缘id找到的左边缘距离接边处太远," \
"请确认数据是否正确,之后请手动接边"
self.output_info1.append(output_info)
return False, [None, None, []]
right_max_cpt_y = -np.inf
right_target_cpt_link_edge_points = []
right_target_link_edge_direction = None
right_target_link_edge_feature = None
for right_link_edge_feature in right_link_edge_features:
link_edge_points = right_link_edge_feature.GetGeometryRef().GetPoints()
cpt_link_edge_points = blh_to_cpt(link_edge_points, *proj_info) cpt_link_edge_points = blh_to_cpt(link_edge_points, *proj_info)
new_cpt_link_edge_points, link_edge_direction = self.cal_forward_direction(cpt_link_edge_points, new_cpt_link_edge_points, link_edge_direction = self.cal_forward_direction(cpt_link_edge_points,
topo_feature, *proj_info) topo_feature, *proj_info)
cpt_link_edge_lines2.append(new_cpt_link_edge_points) right_max_cpt_y1 = max([point[1] for point in new_cpt_link_edge_points])
link_edge_directions2.append(link_edge_direction) if right_max_cpt_y1 > right_max_cpt_y:
right_max_cpt_y = right_max_cpt_y1
right_target_cpt_link_edge_points = new_cpt_link_edge_points
right_target_link_edge_direction = link_edge_direction
right_target_link_edge_feature = right_link_edge_feature
if abs(right_max_cpt_y) > 6:
output_info = "id为:" + str(link_id) + "的参考线,根据它的右边缘id找到的右边缘距离接边处太远," \
"请确认数据是否正确,之后请手动接边"
self.output_info1.append(output_info)
return False, [None, None, []]
if not left_target_cpt_link_edge_points or not right_target_cpt_link_edge_points:
output_info = "id为:" + str(link_id) + "的参考线,根据它的左边缘和右边缘id没有找到左边缘或者右边缘,请手动接边"
self.output_info1.append(output_info)
return False, [None, None, []]
else:
cpt_link_edge_lines.append(left_target_cpt_link_edge_points)
cpt_link_edge_lines.append(right_target_cpt_link_edge_points)
link_edge_directions.append(left_target_link_edge_direction)
link_edge_directions.append(right_target_link_edge_direction)
return True, [cpt_link_edge_lines, link_edge_directions,
[left_target_link_edge_feature, right_target_link_edge_feature]]
def get_target_link_edge2(self, link_id, left_link_edge_features, right_link_edge_features, topo_feature, *proj_info):
# 由于参考线可以关联多条道路边缘线,需要计算获取所需的道路边缘
cpt_link_edge_lines = []
link_edge_directions = []
left_min_cpt_y = np.inf
left_target_cpt_link_edge_points = []
left_target_link_edge_direction = None
left_target_link_edge_feature = None
for left_link_edge_feature in left_link_edge_features:
link_edge_points = left_link_edge_feature.GetGeometryRef().GetPoints()
cpt_link_edge_points = blh_to_cpt(link_edge_points, *proj_info)
new_cpt_link_edge_points, link_edge_direction = self.cal_behind_direction(cpt_link_edge_points,
topo_feature, *proj_info)
left_min_cpt_y1 = min([point[1] for point in new_cpt_link_edge_points])
if left_min_cpt_y1 < left_min_cpt_y:
left_min_cpt_y = left_min_cpt_y1
left_target_cpt_link_edge_points = new_cpt_link_edge_points
left_target_link_edge_direction = link_edge_direction
left_target_link_edge_feature = left_link_edge_feature
if abs(left_min_cpt_y) > 6:
output_info = "id为:" + str(link_id) + "的参考线,根据它的左边缘id找到的左边缘距离接边处太远," \
"请确认数据是否正确,之后请手动接边"
self.output_info1.append(output_info)
return False, [None, None, []]
right_min_cpt_y = np.inf
right_target_cpt_link_edge_points = []
right_target_link_edge_direction = None
right_target_link_edge_feature = None
for right_link_edge_feature in right_link_edge_features:
link_edge_points = right_link_edge_feature.GetGeometryRef().GetPoints()
cpt_link_edge_points = blh_to_cpt(link_edge_points, *proj_info)
new_cpt_link_edge_points, link_edge_direction = self.cal_behind_direction(cpt_link_edge_points,
topo_feature, *proj_info)
right_min_cpt_y1 = min([point[1] for point in new_cpt_link_edge_points])
if right_min_cpt_y1 < right_min_cpt_y:
right_min_cpt_y = right_min_cpt_y1
right_target_cpt_link_edge_points = new_cpt_link_edge_points
right_target_link_edge_direction = link_edge_direction
right_target_link_edge_feature = right_link_edge_feature
if abs(right_min_cpt_y) > 6:
output_info = "id为:" + str(link_id) + "的参考线,根据它的右边缘id找到的右边缘距离接边处太远," \
"请确认数据是否正确,之后请手动接边"
self.output_info1.append(output_info)
return False, [None, None, []]
if not left_target_cpt_link_edge_points or not right_target_cpt_link_edge_points:
output_info = "id为:" + str(link_id) + "的参考线,根据它的左边缘和右边缘id没有找到左边缘或者右边缘,请手动接边"
self.output_info1.append(output_info)
return False, [None, None, []]
else:
cpt_link_edge_lines.append(left_target_cpt_link_edge_points)
cpt_link_edge_lines.append(right_target_cpt_link_edge_points)
link_edge_directions.append(left_target_link_edge_direction)
link_edge_directions.append(right_target_link_edge_direction)
return True, [cpt_link_edge_lines, link_edge_directions,
[left_target_link_edge_feature, right_target_link_edge_feature]]
def is_connect_link_edge(self, topo_feature, link_feature1, link_feature2,
mesh_id1, mesh_id2, connect_boundary, *proj_info):
left_link_edge_features1, right_link_edge_features1 = self.get_link_edge_by_link(link_feature1, mesh_id1)
if not left_link_edge_features1 or not right_link_edge_features1:
return False, []
left_link_edge_features2, right_link_edge_features2 = self.get_link_edge_by_link(link_feature2, mesh_id2)
if not left_link_edge_features2 or not right_link_edge_features2:
return False, []
flag1, [cpt_link_edge_lines1, link_edge_directions1, link_edge_features1] = self.get_target_link_edge1(
link_feature1[const.LINK_ID], left_link_edge_features1, right_link_edge_features1, topo_feature, *proj_info)
if not flag1:
return False, []
flag2, [cpt_link_edge_lines2, link_edge_directions2, link_edge_features2] = self.get_target_link_edge2(
link_feature2[const.LINK_ID], left_link_edge_features2, right_link_edge_features2, topo_feature, *proj_info)
if not flag2:
return False, []
flag, link_edge_match_list = self.match_line(cpt_link_edge_lines1, cpt_link_edge_lines2, flag, link_edge_match_list = self.match_line(cpt_link_edge_lines1, cpt_link_edge_lines2,
link_feature1[const.LINK_ID]) const.HD_LINK_EDGE, link_feature1[const.LINK_ID])
if not flag: if not flag:
return False, [] return False, []
...@@ -1220,7 +1357,8 @@ class ConnectTwoMeshByTopo: ...@@ -1220,7 +1357,8 @@ class ConnectTwoMeshByTopo:
utm_require_node_point = transform_to_utm([require_node_point], source_srs)[0][0] utm_require_node_point = transform_to_utm([require_node_point], source_srs)[0][0]
utm_node_point = transform_to_utm([node_point], source_srs)[0][0] utm_node_point = transform_to_utm([node_point], source_srs)[0][0]
if is_same_point_3d(utm_node_point, utm_require_node_point): if is_same_point_3d(utm_node_point, utm_require_node_point, 0.05):
# 0.05是按照产品得要求
return True, node_feature return True, node_feature
else: else:
output_info = "节点id为:" + str(node_id) + "的" + str(layer_name) + "节点不与" + \ output_info = "节点id为:" + str(node_id) + "的" + str(layer_name) + "节点不与" + \
...@@ -1257,49 +1395,57 @@ class ConnectTwoMeshByTopo: ...@@ -1257,49 +1395,57 @@ class ConnectTwoMeshByTopo:
node_feature.Destroy() node_feature.Destroy()
return True return True
def is_intersect_by_multi_lines(self, node_layer, blh_point, mesh_id, gps_id, layer_name, source_srs): def is_intersect_by_multi_lines(self, node_layer, blh_point, mesh_id, gps_id, layer_name, ids_field, source_srs):
# 判断一个点处是否是多条线的端点,如在路口或者匝道处 # 判断一个点处是否是多条线的端点,如在路口或者匝道处
lon, lat = blh_point[:2] lon, lat = blh_point[:2]
buffer_size = 0.0000001 utm_point = transform_to_utm([blh_point], source_srs)[0][0]
buffer_size = 0.0000005 # 近似5cm
min_lon, max_lon = lon - buffer_size, lon + buffer_size min_lon, max_lon = lon - buffer_size, lon + buffer_size
min_lat, max_lat = lat - buffer_size, lat + buffer_size min_lat, max_lat = lat - buffer_size, lat + buffer_size
node_layer.SetSpatialFilterRect(min_lon, min_lat, max_lon, max_lat) node_layer.SetSpatialFilterRect(min_lon, min_lat, max_lon, max_lat)
node_count = node_layer.GetFeatureCount()
if node_count == 1:
node_layer.SetSpatialFilter(None)
return False
filter = '"' + const.MESH_ID + '" = ' + "'" + str(mesh_id) + "'" filter = '"' + const.MESH_ID + '" = ' + "'" + str(mesh_id) + "'"
node_layer.SetAttributeFilter(filter) node_layer.SetAttributeFilter(filter)
node_count = node_layer.GetFeatureCount() node_count = node_layer.GetFeatureCount()
if node_count == 1: if node_count == 0:
node_layer.SetSpatialFilter(None) # 消除空间过滤 output_info = "gps_id:" + str(gps_id) + ",mesh_id:" + str(mesh_id) + "的topo点附近的接边处," + "根据" + \
node_layer.SetAttributeFilter(None) # 消除属性过滤 str(layer_name) + "的端点坐标:" + str(blh_point) + ",在附近大约5cm范围内,没有找到节点"
return False self.output_info1.append(output_info)
node_layer.SetSpatialFilter(None)
node_layer.SetAttributeFilter(None)
return True
# node_points = [node_layer.GetNextFeature().GetGeometryRef().GetPoints()[0] for _ in range(node_count)] min_distance = np.inf
# 使用推导式会出现奇怪的错误 target_node_feature = None
node_points = []
for _ in range(node_count): for _ in range(node_count):
node_feature = node_layer.GetNextFeature() node_feature = node_layer.GetNextFeature()
if not node_feature: if not node_feature:
continue continue
node_point = node_feature.GetGeometryRef().GetPoints()[0] blh_node_point = node_feature.GetGeometryRef().GetPoints()
node_points.append(node_point) utm_node_point = transform_to_utm(blh_node_point, source_srs)[0][0]
utm_node_points = transform_to_utm(node_points, source_srs)[0] distance = two_point_distance_2d(utm_point, utm_node_point)
utm_point = transform_to_utm([blh_point], source_srs)[0][0] if distance <= min_distance:
node_layer.SetSpatialFilter(None) # 消除空间过滤 target_node_feature = node_feature
node_layer.SetAttributeFilter(None) # 消除属性过滤 min_distance = distance
if target_node_feature is None:
output_info = "gps_id:" + str(gps_id) + ",mesh_id:" + str(mesh_id) + "的topo点附近的接边处," + "根据" + \
str(layer_name) + "的端点坐标:" + str(blh_point) + ",在附近5cm范围内,没有找到节点"
self.output_info1.append(output_info)
node_layer.SetSpatialFilter(None)
node_layer.SetAttributeFilter(None)
node_layer.ResetReading()
return True
node_layer.SetSpatialFilter(None)
node_layer.SetAttributeFilter(None)
node_layer.ResetReading() node_layer.ResetReading()
same_point_num = 0 ids = target_node_feature[ids_field].split(';')
for point1 in utm_node_points: if len(ids) > 2:
if point1 and is_same_point_3d(utm_point, point1):
same_point_num += 1
if same_point_num >= 2:
output_info = "gps_id:" + str(gps_id) + ",mesh_id:" + str(mesh_id) + "的topo点附近的接边处," + \ output_info = "gps_id:" + str(gps_id) + ",mesh_id:" + str(mesh_id) + "的topo点附近的接边处," + \
str(layer_name) + "的节点坐标为:" + str(blh_point) + ",在此处有2条线共点,请修改数据再接边" str(layer_name) + "的节点坐标近似为:" + str(blh_point) + \
",此节点至少关联了两条线,请修改数据,变换接边位置"
self.output_info1.append(output_info) self.output_info1.append(output_info)
return True return True
return False
def connect_line(self, source_srs, utm_boundary, gps_id, attribute_info, connect_info): def connect_line(self, source_srs, utm_boundary, gps_id, attribute_info, connect_info):
""" """
...@@ -1313,7 +1459,7 @@ class ConnectTwoMeshByTopo: ...@@ -1313,7 +1459,7 @@ class ConnectTwoMeshByTopo:
""" """
if not attribute_info or not connect_info: if not attribute_info or not connect_info:
return False return False
line_layer, node_layer, node_fields, layer_name = attribute_info line_layer, node_layer, node_fields, layer_name, ids_field = attribute_info
features1, features2, match_directions, match_list, smoothing_count_list = connect_info features1, features2, match_directions, match_list, smoothing_count_list = connect_info
if line_layer is None: if line_layer is None:
# 没有边缘图层时,直接运行结束 # 没有边缘图层时,直接运行结束
...@@ -1344,9 +1490,9 @@ class ConnectTwoMeshByTopo: ...@@ -1344,9 +1490,9 @@ class ConnectTwoMeshByTopo:
blh_points2 = blh_points2[::-1] blh_points2 = blh_points2[::-1]
flag1 = self.is_intersect_by_multi_lines(node_layer, blh_points1[-1], feature1[const.MESH_ID], flag1 = self.is_intersect_by_multi_lines(node_layer, blh_points1[-1], feature1[const.MESH_ID],
gps_id, layer_name, source_srs) gps_id, layer_name, ids_field, source_srs)
flag2 = self.is_intersect_by_multi_lines(node_layer, blh_points2[-1], feature2[const.MESH_ID], flag2 = self.is_intersect_by_multi_lines(node_layer, blh_points2[-1], feature2[const.MESH_ID],
gps_id, layer_name, source_srs) gps_id, layer_name, ids_field, source_srs)
if flag1 or flag2: if flag1 or flag2:
return False return False
...@@ -1388,6 +1534,13 @@ class ConnectTwoMeshByTopo: ...@@ -1388,6 +1534,13 @@ class ConnectTwoMeshByTopo:
source_srs = self.link_layer.GetSpatialRef() # 获取图层的坐标系 source_srs = self.link_layer.GetSpatialRef() # 获取图层的坐标系
for topo_feature in topo_features: for topo_feature in topo_features:
try: try:
# if int(topo_feature[const.ID]) == 6602679627452:
# print("dflksjhd")
# else:
# continue
link_ids = [] # 存储已经接过边的道路参考线id,主要应用于多次同路轨迹 link_ids = [] # 存储已经接过边的道路参考线id,主要应用于多次同路轨迹
mesh_id1, mesh_id2 = self.reset_mesh_id(topo_feature, mesh_id1, mesh_id2) mesh_id1, mesh_id2 = self.reset_mesh_id(topo_feature, mesh_id1, mesh_id2)
if self.is_gap_or_big_curve(topo_feature, source_srs): if self.is_gap_or_big_curve(topo_feature, source_srs):
...@@ -1446,7 +1599,8 @@ class ConnectTwoMeshByTopo: ...@@ -1446,7 +1599,8 @@ class ConnectTwoMeshByTopo:
# 连接参考线及其节点 # 连接参考线及其节点
link_attribute_info = [self.link_layer, self.node_layer, link_attribute_info = [self.link_layer, self.node_layer,
[const.START_NODE_ID, const.END_NODE_ID, const.NODE_ID], const.HD_LINK] [const.START_NODE_ID, const.END_NODE_ID, const.NODE_ID],
const.HD_LINK, const.LINK_IDS]
link_connect_info = [[link_feature1], [link_feature2], [[link_direction1, link_direction2]], [[0, 0]], link_connect_info = [[link_feature1], [link_feature2], [[link_direction1, link_direction2]], [[0, 0]],
[link_smoothing_count]] [link_smoothing_count]]
if self.connect_line(source_srs, utm_connect_boundary, gps_id, link_attribute_info, link_connect_info): if self.connect_line(source_srs, utm_connect_boundary, gps_id, link_attribute_info, link_connect_info):
...@@ -1460,7 +1614,7 @@ class ConnectTwoMeshByTopo: ...@@ -1460,7 +1614,7 @@ class ConnectTwoMeshByTopo:
# 连接边界线及其节点 # 连接边界线及其节点
lane_edge_attribute_info = [self.lane_edge_layer, self.lane_edge_node_layer, lane_edge_attribute_info = [self.lane_edge_layer, self.lane_edge_node_layer,
[const.START_EDGE_NODE_ID, const.END_EDGE_NODE_ID, const.LANE_EDGE_NODE_ID], [const.START_EDGE_NODE_ID, const.END_EDGE_NODE_ID, const.LANE_EDGE_NODE_ID],
const.HD_LANE_EDGE] const.HD_LANE_EDGE, const.EDGE_IDS]
if self.connect_line(source_srs, utm_connect_boundary, gps_id, if self.connect_line(source_srs, utm_connect_boundary, gps_id,
lane_edge_attribute_info, lane_edge_connect_info): lane_edge_attribute_info, lane_edge_connect_info):
output_info = "gps_id为:" + str(gps_id) + "的topo的接边处,边界线接边成功" output_info = "gps_id为:" + str(gps_id) + "的topo的接边处,边界线接边成功"
...@@ -1473,7 +1627,7 @@ class ConnectTwoMeshByTopo: ...@@ -1473,7 +1627,7 @@ class ConnectTwoMeshByTopo:
# 连接中心线及其节点 # 连接中心线及其节点
lane_link_attribute_info = [self.lane_link_layer, self.lane_node_layer, lane_link_attribute_info = [self.lane_link_layer, self.lane_node_layer,
[const.START_LANE_NODE_ID, const.END_LANE_NODE_ID, const.LANE_NODE_ID], [const.START_LANE_NODE_ID, const.END_LANE_NODE_ID, const.LANE_NODE_ID],
const.HD_LANE_LINK] const.HD_LANE_LINK, const.LANE_IDS]
if self.connect_line(source_srs, utm_connect_boundary, gps_id, if self.connect_line(source_srs, utm_connect_boundary, gps_id,
lane_link_attribute_info, lane_link_connect_info): lane_link_attribute_info, lane_link_connect_info):
output_info = "gps_id为:" + str(gps_id) + "的topo的接边处,中心线接边成功" output_info = "gps_id为:" + str(gps_id) + "的topo的接边处,中心线接边成功"
...@@ -1486,7 +1640,7 @@ class ConnectTwoMeshByTopo: ...@@ -1486,7 +1640,7 @@ class ConnectTwoMeshByTopo:
# 连接道路边缘及其节点 # 连接道路边缘及其节点
link_edge_attribute_info = [self.link_edge_layer, self.link_edge_node_layer, link_edge_attribute_info = [self.link_edge_layer, self.link_edge_node_layer,
[const.START_EDGE_NODE_ID, const.END_EDGE_NODE_ID, const.LINK_EDGE_NODE_ID], [const.START_EDGE_NODE_ID, const.END_EDGE_NODE_ID, const.LINK_EDGE_NODE_ID],
const.HD_LINK_EDGE] const.HD_LINK_EDGE, const.EDGE_IDS]
if self.connect_line(source_srs, utm_connect_boundary, if self.connect_line(source_srs, utm_connect_boundary,
gps_id, link_edge_attribute_info, link_edge_connect_info): gps_id, link_edge_attribute_info, link_edge_connect_info):
output_info = "gps_id为:" + str(gps_id) + "的topo的接边处,道路边缘接边成功" output_info = "gps_id为:" + str(gps_id) + "的topo的接边处,道路边缘接边成功"
......
...@@ -128,7 +128,7 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume ...@@ -128,7 +128,7 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume
output_info1.append(output_info) output_info1.append(output_info)
write_info(output_document_path, output_info1, output_info2, output_info3) write_info(output_document_path, output_info1, output_info2, output_info3)
return return
mesh_box_data_source = ogr.Open(mesh_box_path, 0) mesh_box_data_source = ogr.Open(mesh_box_path, 1)
if mesh_box_data_source is None: if mesh_box_data_source is None:
output_info = "图幅框文件中没有任何数据,请确认后重试!" output_info = "图幅框文件中没有任何数据,请确认后重试!"
output_info1.append(output_info) output_info1.append(output_info)
...@@ -210,21 +210,23 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume ...@@ -210,21 +210,23 @@ def run(connect_postgresql, sheet_designation_path, mesh_box_path, output_docume
if __name__ == '__main__': if __name__ == '__main__':
arg1 = r"PG:dbname='test3' host='localhost' port='5432' user='postgres' password='19931018'" # arg1 = r"PG:dbname='test12' host='localhost' port='5432' user='postgres' password='19931018'"
arg2 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_ids.txt" # # arg1 = r"PG:dbname='qgis_hb_sync' host='win-1.corp.roadlinks.cn' port='5432' user='postgres' password='juefx0123'"
arg3 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_grid.gpkg" # arg2 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_ids.txt"
arg4 = r"C:\Users\熊超\Desktop\edge_match_file" # # arg3 = r"C:\Users\熊超\Desktop\edge_match_file\mesh_grid.gpkg"
run(arg1, arg2, arg3, arg4) # arg3 = r"C:\Users\熊超\Desktop\new1\gps_grids.gpkg"
# arg1, arg2, arg3, arg4 = None, None, None, None # arg4 = r"C:\Users\熊超\Desktop\edge_match_file"
# try:
# arg1 = sys.argv[1] # 数据库连接字符串
# arg2 = sys.argv[2] # 图幅号的txt文件
# arg3 = sys.argv[3] # 图幅框文件
# arg4 = sys.argv[4] # 接边报表路径
# current_path = os.path.dirname(os.path.abspath(__file__))
# gdal_data = current_path + '\\proj'
# osr.SetPROJSearchPath(gdal_data)
# except Exception as e:
# print("传入的参数有问题,程序发生异常,异常为:" + str(e))
# run(arg1, arg2, arg3, arg4) # run(arg1, arg2, arg3, arg4)
arg1, arg2, arg3, arg4 = None, None, None, None
try:
arg1 = sys.argv[1] # 数据库连接字符串
arg2 = sys.argv[2] # 图幅号的txt文件
arg3 = sys.argv[3] # 图幅框文件
arg4 = sys.argv[4] # 接边报表路径
current_path = os.path.dirname(os.path.abspath(__file__))
gdal_data = current_path + '\\proj'
osr.SetPROJSearchPath(gdal_data)
except Exception as e:
print("传入的参数有问题,程序发生异常,异常为:" + str(e))
run(arg1, arg2, arg3, arg4)
...@@ -8,7 +8,7 @@ import numpy as np ...@@ -8,7 +8,7 @@ import numpy as np
from sklearn.neighbors import KDTree from sklearn.neighbors import KDTree
DEF_ALPHA = 0.0000001 # 单位米,如果是度的话,请进行转换 DEF_ALPHA = 0.000001 # 单位米,如果是度的话,请进行转换
def two_point_distance_2d(point1, point2): def two_point_distance_2d(point1, point2):
...@@ -69,9 +69,9 @@ def is_same_point_2d(point1, point2): ...@@ -69,9 +69,9 @@ def is_same_point_2d(point1, point2):
return False return False
def is_same_point_3d(point1, point2): def is_same_point_3d(point1, point2, alpha=DEF_ALPHA):
# 判断两个点是不是一个点,选择x, y, z # 判断两个点是不是一个点,选择x, y, z
flag = np.array([np.abs(point1[i] - point2[i]) < DEF_ALPHA for i in range(len(point1))]) flag = np.array([np.abs(point1[i] - point2[i]) < alpha for i in range(len(point1))])
if flag.all(): if flag.all():
return True return True
return False return False
......
...@@ -85,5 +85,8 @@ c.CONNECT_THRESHOLD = 2 # 除了参考线之外,需要连接的两天线之 ...@@ -85,5 +85,8 @@ c.CONNECT_THRESHOLD = 2 # 除了参考线之外,需要连接的两天线之
c.LANE_EDGE_NODE_ID = "LANE_EDGE_NODE_ID" # 边界线节点的主键 c.LANE_EDGE_NODE_ID = "LANE_EDGE_NODE_ID" # 边界线节点的主键
c.LANE_NODE_ID = "LANE_NODE_ID" # 中心线节点的主键 c.LANE_NODE_ID = "LANE_NODE_ID" # 中心线节点的主键
c.LINK_EDGE_NODE_ID = "LINK_EDGE_NODE_ID" # 道路边缘节点的主键 c.LINK_EDGE_NODE_ID = "LINK_EDGE_NODE_ID" # 道路边缘节点的主键
c.LINK_IDS = "LINK_IDS" # 参考线节点关联得参考线id
c.LANE_IDS = "LANE_IDS" # 中心线节点关联的中心线id
c.EDGE_IDS = "EDGE_IDS" # 边界线/道路边缘节点关联的边界线/道路边缘的id
sys.modules[__name__] = c sys.modules[__name__] = c
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment