def gene_center_express(exp_list, ln_list): mp0, mp1 = [], [] for i, lid in enumerate(exp_list[0]): line = ln_list[lid] if i == 0: for pt in line.point_list: mod_pt = ModPoint(pt=pt) mp0.append(mod_pt) else: for pt in line.point_list[1:]: mod_pt = ModPoint(pt=pt) mp0.append(mod_pt) for i, lid in enumerate(exp_list[1]): line = ln_list[lid] if i == 0: for pt in line.point_list: mod_pt = ModPoint(pt=pt) mp1.append(mod_pt) else: for pt in line.point_list[1:]: mod_pt = ModPoint(pt=pt) mp1.append(mod_pt) # 同序 mp1 = mp1[::-1] # 插值 new_mp0, new_mp1 = insert_points(mp0), insert_points(mp1) center_list = get_center_points(new_mp0, new_mp1) return new_mp0, new_mp1, center_list
def modify_line(line, ln_list): """ 变窄的地方画的漂亮一点 :param line: :param ln_list: :return: """ last_dist = 0 for i, dist in enumerate(line.dist_list): if last_dist and (dist == 60 and last_dist == 20 or dist == 20 and last_dist == 60): # print "mod", line.org_lid org_line = ln_list[line.org_lid] if last_dist == 20 and dist == 60: if line.left == 0: # right # print "add right" pt = point_on_segment(org_line.point_list[i], org_line.point_list[i - 1], 20) _, _, p0, p1 = get_parallel(org_line.point_list[i], pt, 20) # add point p1 mp = ModPoint(pt=p1) line.point_list.insert(i, mp) else: # print "add left", i seq = len(org_line.point_list) - 1 - i pt = point_on_segment(org_line.point_list[seq], org_line.point_list[seq + 1], 20) _, _, p0, p1 = get_parallel(org_line.point_list[seq], pt, 20) mp = ModPoint(pt=p1) line.point_list.insert(i, mp) else: if line.left == 0: # print "add right", i pt = point_on_segment(org_line.point_list[i - 1], org_line.point_list[i], 20) p0, p1, _, _ = get_parallel(org_line.point_list[i - 1], pt, 20) mp = ModPoint(pt=p1) line.point_list.insert(i, mp) else: # print "add left", i seq = len(org_line.point_list) - 1 - i pt = point_on_segment(org_line.point_list[seq + 1], org_line.point_list[seq], 20) p0, p1, _, _ = get_parallel(org_line.point_list[seq + 1], pt, 20) mp = ModPoint(pt=p1) line.point_list.insert(i, mp) last_dist = dist
def get_center_points(pts0, pts1): ret = [] i, j = 0, 0 while i < len(pts0) - 1 and j < len(pts1) - 1: x, y = (pts0[i].x + pts1[j].x) / 2, (pts0[i].y + pts1[j].y) / 2 pt = [x, y] ret.append(pt) distij = calc_point_dist(pts0[i], pts1[j]) if distij < 20: i, j = i + 1, j + 1 continue ni, nj = i + 1, j + 1 disti, distj = calc_point_dist(pts0[ni], pts1[j]), calc_point_dist( pts0[i], pts1[nj]) if disti <= distj: i = ni else: j = nj if i == len(pts0) - 1: while j < len(pts1): x, y = (pts0[i].x + pts1[j].x) / 2, (pts0[i].y + pts1[j].y) / 2 ret.append([x, y]) j += 1 else: while i < len(pts0): x, y = (pts0[i].x + pts1[j].x) / 2, (pts0[i].y + pts1[j].y) / 2 ret.append([x, y]) i += 1 mod_ret = dog_last(ret, 2) ret = [] for pt in mod_ret: mp = ModPoint(x=pt[0], y=pt[1]) ret.append(mp) return ret
def gene_endpoint(pt, line_list, info): lid, seq = info[0] line = line_list[lid] if line.surface: road_width = 60 else: road_width = 20 pt0, pt1 = line.point_list[seq], line.point_list[seq + 1] sw = False if seq == 0 and pt.pid == pt0.pid: begin_pt = True else: begin_pt = False if pt.pid == pt1.pid: pt0, pt1 = pt1, pt0 sw = True dp0, dp1, _dp0, _dp1 = get_parallel(pt0, pt1, road_width) ep0, ep1 = ModPoint(dp0), ModPoint(_dp0) left = False if sw: left = not left if not left: fwd = begin_pt else: fwd = not begin_pt pli = PointLineInfo(lid, seq, left, fwd, road_width) ep0.pli_list.append(pli) left = True if sw: left = not left if not left: fwd = begin_pt else: fwd = not begin_pt pli1 = PointLineInfo(lid, seq, left, fwd, road_width) ep1.pli_list.append(pli1) temp = [ep0, ep1] return temp
def cutting(line, mod_line): gene_line = ModLine() gene_line.point_list = [] gene_line.org_lid = line.lid gene_line.lid = line.lid * 2 gene_line.left = 0 # 单向路都为同向 for pt in line.point_list: min_dist, pa, pb = 1e10, None, None for i, p0 in enumerate(mod_line.point_list[:-1]): p1 = mod_line.point_list[i + 1] dist = pt2segment(pt, p0, p1) if dist < min_dist: min_dist, pa, pb = dist, p0, p1 x, y = pt_project(pt, pa, pb) pj = ModPoint(x=x, y=y) gene_line.point_list.append(pj) return gene_line
def gene_express_line(center_line, info, line_list): """ :param center_line: 中间线 :param info: 见调用函数处 :param line_list: 所有道路 :return: """ gene_line0 = ModLine() # 右手侧 gene_line0.point_list = [] n = len(center_line.point_list) for i, pt in enumerate(center_line.point_list): if i == 0: s0p0, s0p1 = center_line.point_list[i], center_line.point_list[i + 1] dstp0, dstp1, _dstp0, _dstp1 = get_parallel(s0p0, s0p1, 20) mp = ModPoint(pt=dstp0) gene_line0.point_list.append(mp) elif i == n - 1: s0p0, s0p1 = center_line.point_list[i - 1], center_line.point_list[i] dstp0, dstp1, _dstp0, _dstp1 = get_parallel(s0p0, s0p1, 20) mp = ModPoint(pt=dstp1) gene_line0.point_list.append(mp) else: s0p0, s0p1, s0p2 = center_line.point_list[i - 1:i + 2] dstp0, dstp1, _dstp0, _dstp1 = get_parallel(s0p0, s0p1, 20) dstp2, dstp3, _dstp2, _dstp3 = get_parallel(s0p1, s0p2, 20) mp = ModPoint(x=(dstp0.x + dstp2.x) / 2, y=(dstp0.y + dstp2.y) / 2) gene_line0.point_list.append(mp) gene_line1 = ModLine() gene_line1.point_list = [] pt_list = center_line.point_list[::-1] for i, pt in enumerate(pt_list): if i == 0: s0p0, s0p1 = pt_list[i], pt_list[i + 1] dstp0, dstp1, _dstp0, _dstp1 = get_parallel(s0p0, s0p1, 20) mp = ModPoint(pt=dstp0) gene_line1.point_list.append(mp) elif i == n - 1: s0p0, s0p1 = pt_list[i - 1], pt_list[i] dstp0, dstp1, _dstp0, _dstp1 = get_parallel(s0p0, s0p1, 20) mp = ModPoint(pt=dstp1) gene_line1.point_list.append(mp) else: s0p0, s0p1, s0p2 = pt_list[i - 1:i + 2] dstp0, dstp1, _dstp0, _dstp1 = get_parallel(s0p0, s0p1, 20) dstp2, dstp3, _dstp2, _dstp3 = get_parallel(s0p1, s0p2, 20) mp = ModPoint(x=(dstp0.x + dstp2.x) / 2, y=(dstp0.y + dstp2.y) / 2) gene_line1.point_list.append(mp) check_info_orient(center_line, info, line_list) gene_list = [] for idx in info[0]: line = line_list[idx] gene_list.append(cutting(line, gene_line0)) for idx in info[1]: line = line_list[idx] gene_list.append(cutting(line, gene_line1)) return gene_list
def gene_cross_point(pt, line_list, info_list, idx): buf_list = [] temp = [] for info in info_list: lid, seq = info line = line_list[lid] pt0, pt1 = line.point_list[seq], line.point_list[seq + 1] if pt.pid == pt1.pid: pt0, pt1 = pt1, pt0 swap = True else: swap = False theta = get_vector_angle(pt0, pt1) buf = LineInfo(lid, seq, theta, swap) buf_list.append(buf) buf_list.sort(key=lambda x: x.theta) deg = len(buf_list) for i in range(deg): lid0, seq0 = buf_list[i].lid, buf_list[i].seq j = i + 1 if j == deg: j = 0 lid1, seq1 = buf_list[j].lid, buf_list[j].seq del_theta = math.fabs(buf_list[i].theta - buf_list[j].theta) cross_flag = True off_flag = False if del_theta > math.pi * 2: del_theta -= math.pi * 2 if math.pi - 0.01 < del_theta < math.pi + 0.01: off_flag = True if del_theta < math.pi / 8: print "del theta", del_theta, lid0, seq0, lid1, seq1 cross_flag = False sw0, sw1 = buf_list[i].swap, buf_list[j].swap line0, line1 = line_list[lid0], line_list[lid1] s0p0, s0p1 = line0.point_list[seq0], line0.point_list[seq0 + 1] s1p0, s1p1 = line1.point_list[seq1], line1.point_list[seq1 + 1] if sw0: s0p0, s0p1 = s0p1, s0p0 if sw1: s1p0, s1p1 = s1p1, s1p0 surface = line0.surface or line1.surface d0, d1 = 20, 20 if deg == 2 and surface: d0, d1 = 60, 60 elif deg > 2: if line0.surface: d0 = 60 if line1.surface: d1 = 60 dstp0, dstp1, _dstp0, _dstp1 = get_parallel(s0p0, s0p1, d0) dstp2, dstp3, _dstp2, _dstp3 = get_parallel(s1p0, s1p1, d1) if off_flag: # 由于计算交点会有精度误差,直接采用两个点的中间点作为新点 px, py = (_dstp0.x + dstp2.x) / 2, (_dstp0.y + dstp2.y) / 2 cr_pt = ModPoint(x=px, y=py) left = True if sw0: left = not left fwd = not sw0 lid, seq = lid0, seq0 cr_pt.pli_list.append(PointLineInfo(lid, seq, left, fwd, d0)) left = False if sw1: left = not left fwd = not sw1 lid, seq = lid1, seq1 cr_pt.pli_list.append(PointLineInfo(lid, seq, left, fwd, d1)) temp.append(cr_pt) elif cross_flag: _, px, py = get_cross_point(_dstp0, _dstp1, dstp2, dstp3) cr_pt = ModPoint(x=px, y=py) left = True if sw0: left = not left fwd = not sw0 lid, seq = lid0, seq0 cr_pt.pli_list.append(PointLineInfo(lid, seq, left, fwd, d0)) left = False if sw1: left = not left fwd = not sw1 lid, seq = lid1, seq1 cr_pt.pli_list.append(PointLineInfo(lid, seq, left, fwd, d1)) temp.append(cr_pt) else: # left cr_pt0 = ModPoint(pt=_dstp0) lid, seq = lid0, seq0 pt0 = line_list[lid].point_list[seq] if pt.pid == pt0.pid: begin_pt = True else: begin_pt = False left = True if sw0: left = not left if not left: fwd = begin_pt else: fwd = not begin_pt cr_pt0.pli_list.append(PointLineInfo(lid, seq, left, fwd, d0)) # right _cr_pt0 = ModPoint(pt=dstp0) left = False if sw0: left = not left if not left: fwd = begin_pt else: fwd = not begin_pt _cr_pt0.pli_list.append(PointLineInfo(lid, seq, left, fwd, d0)) # another line lid, seq = lid1, seq1 pt0 = line_list[lid].point_list[seq] if pt.pid == pt0.pid: begin_pt = True else: begin_pt = False cr_pt1 = ModPoint(pt=_dstp2) left = True if sw1: left = not left if not left: fwd = begin_pt else: fwd = not begin_pt cr_pt1.pli_list.append(PointLineInfo(lid, seq, left, fwd, d1)) _cr_pt1 = ModPoint(pt=dstp2) left = False if sw1: left = not left if not left: fwd = begin_pt else: fwd = not begin_pt _cr_pt1.pli_list.append(PointLineInfo(lid, seq, left, fwd, d1)) temp = [cr_pt0, _cr_pt0, cr_pt1, _cr_pt1] return temp
def get_point_offset_on_segment(x0, y0, x1, y1, offset): dx, dy = x1 - x0, y1 - y0 l = math.sqrt(dx**2 + dy**2) x, y = x0 + offset / l * dx, y0 + offset / l * dy dst_pt = ModPoint(x=x, y=y) return dst_pt