def center_one_merge(road0, road1): """ 单向连接道路 :param road0: 待延长的道路 :param road1: 目标道路 :return: """ r0_bp, r0_ep = road0.point_list[0], road0.point_list[-1] r1_bp, r1_ep = road1.point_list[0], road1.point_list[-1] if get_dist(r0_ep, r1_bp) < 200: road0.add_point(r1_bp) road0.gene_segment() elif get_dist(r0_ep, r1_ep) < 200: road0.add_point(r1_ep) road0.gene_segment() elif get_dist(r0_bp, r1_bp) < 200: new_point_list = [r1_bp] for pt in road0.point_list: new_point_list.append(pt) road0.set_point_list(new_point_list) road0.gene_segment() elif get_dist(r0_bp, r1_ep) < 200: new_point_list = [r1_ep] for pt in road0.point_list: new_point_list.append(pt) road0.set_point_list(new_point_list) road0.gene_segment()
def center_divide(road0, road1): bp0, ep0, bp1, ep1 = road0.point_list[0], road0.point_list[ -1], road1.point_list[0], road1.point_list[-1] if bp0 == bp1 or bp0 == ep1 or ep0 == bp1 or ep0 == ep1: return for i, seg0 in enumerate(road0.seg_list): for j, seg1 in enumerate(road1.seg_list): if calc_include_angle2( seg0, seg1) < math.sqrt(3) / 2 and is_segment_cross( seg0, seg1): _, px, py = get_cross_point(seg0, seg1) if px is None: print 'None' cr0 = Point(px, py) cr0.cross, cr0.cross_name, cr0.cross_other_seg = 1, road1.name, j cr0.cross_seg = i bp, ep = seg0.begin_point, seg0.end_point w0, w1 = get_dist(cr0, bp), get_dist(cr0, ep) if w0 > 1e-5 and w1 > 1e-5: road0.cross_list.append(cr0) cr1 = Point(px, py) cr1.cross, cr1.cross_name, cr1.cross_other_seg = 1, road0.name, i cr1.cross_seg = j bp, ep = seg1.begin_point, seg1.end_point w0, w1 = get_dist(cr1, bp), get_dist(cr1, ep) if w0 > 1e-5 and w1 > 1e-5: road1.cross_list.append(cr1) return
def center_merge(road0, road1): """ 检查端点是否重合 :return: """ MERGE_DIST = 1000 r0s0, r0s1 = road0.seg_list[0], road0.seg_list[-1] r1s0, r1s1 = road1.seg_list[0], road1.seg_list[-1] r0_bp, r0_ep = road0.point_list[0], road0.point_list[-1] r1_bp, r1_ep = road1.point_list[0], road1.point_list[-1] if get_dist(r0_bp, r1_ep) < MERGE_DIST and calc_include_angle2(r0s0, r1s1) > 0.8: # 头尾相接,并且平行,说明是在同一条道路里面 road1.add_point(r0_bp) road1.gene_segment() road1.es, road0.bs = 1, 1 elif get_dist(r1_bp, r0_ep) < MERGE_DIST and calc_include_angle2( r1s0, r0s1) > 0.8: road0.add_point(r1_bp) road0.gene_segment() road0.es, road1.bs = 1, 1 elif get_dist(r0_bp, r1_bp) < MERGE_DIST and calc_include_angle2( r0s0, r1s0) > 0.8: # 有时遇到单芯线 new_point_list = [r1_bp] for pt in road0.point_list: new_point_list.append(pt) road0.set_point_list(new_point_list) road0.gene_segment() road0.bs, road1.es = 1, 1 elif get_dist(r0_ep, r1_ep) < MERGE_DIST and calc_include_angle2( r0s1, r1s1) > 0.8: road0.add_point(r1_ep) road0.gene_segment() road0.es, road1.bs = 1, 1
def par_divide(road0, road1): """ as center divide, divide cross point for each other :param road0: :param road1: :return: """ bp0, ep0, bp1, ep1 = road0.point_list[0], road0.point_list[ -1], road1.point_list[0], road1.point_list[-1] if bp0 == bp1: road0.bs, road1.bs = 1, 1 return elif bp0 == ep1: road0.bs, road1.es = 1, 1 return elif ep0 == bp1: road0.es, road1.bs = 1, 1 return elif ep0 == ep1: road0.es, road1.es = 1, 1 return for i, seg0 in enumerate(road0.seg_list): for j, seg1 in enumerate(road1.seg_list): if calc_include_angle2(seg0, seg1) > 0.8: # 平行 continue if is_segment_cross(seg0, seg1): _, px, py = get_cross_point(seg0, seg1) cr0 = Point(px, py) cr0.cross, cr0.cross_name, cr0.cross_other_seg = 1, road1.rid, j cr0.cross_seg = i bp, ep = seg0.begin_point, seg0.end_point w0, w1 = get_dist(cr0, bp), get_dist(cr0, ep) if w0 > 1e-5 and w1 > 1e-5: road0.cross_list.append(cr0) cr1 = Point(px, py) cr1.cross, cr1.cross_name, cr1.cross_other_seg = 1, road0.rid, i cr1.cross_seg = j bp, ep = seg1.begin_point, seg1.end_point w0, w1 = get_dist(cr1, bp), get_dist(cr1, ep) if w0 > 1e-5 and w1 > 1e-5: road1.cross_list.append(cr1) return
def center_insert_cross(road): pt_list = [] # split for i, pt in enumerate(road.point_list): pt_list.append(pt) last_cr = None insert_list = [] for j, cr in enumerate(road.cross_list): # 相同的线段内可能有几个cross点 if cr.cross_seg == i: if last_cr is None or get_dist(cr, last_cr) > 1e-5: # pt_list.append(cr) # 排序后再插入 dist = get_dist(pt, cr) insert_list.append((dist, cr)) last_cr = cr for d, cr in sorted(insert_list): pt_list.append(cr) road.set_point_list(pt_list) road.gene_segment()
def center_offset(road0, road1): """ 起点和终点偏移到路上 :param road0: Road 目标道路 :param road1: Road 待偏移到的道路 :return: """ # 当端点接近某路口时,需要偏移该端点,修正为路口 OFFSET_DIST = 1000 bp, ep = road0.point_list[0], road0.point_list[-1] for pt in road1.cross_list: dist = get_dist(pt, bp) if 1e-5 < dist < OFFSET_DIST: pt.cross = 0 if pt.cross_name == road0.name: # 说明与road0相交 pos = pt.cross_other_seg + 1 else: pos = 0 pt_list = [Point(pt.px, pt.py)] pt_list.extend(road0.point_list[pos:]) road0.set_point_list(pt_list) road0.gene_segment() return for pt in road1.cross_list: dist = get_dist(pt, ep) if 1e-5 < dist < OFFSET_DIST: pt.cross = 0 if pt.cross_name == road0.name: # 说明与road0相交 pos = pt.cross_other_seg + 1 else: pos = len(road0.point_list) pt_list = road0.point_list[:pos] pt_list.append(Point(pt.px, pt.py)) road0.set_point_list(pt_list) road0.gene_segment() # print road0.name, "end point fix to ", road1.name, pt.px, pt.py return
def par_simplify(road): last_pt = None pt_list = [] # 先除去重复点 for pt in road.point_list: if last_pt is not None: dist = get_dist(last_pt, pt) if dist > 1e-5: pt_list.append(pt) else: pt_list.append(pt) last_pt = pt pts = road.point_list # 然后用doglas简化算法 xy_list = [] for pt in pts: xy_list.append([pt.px, pt.py]) xy_list = dog_last(xy_list) road.point_list = [] for xy in xy_list: pt = Point(xy[0], xy[1]) road.add_point(pt) road.gene_segment()
def par_check(road): for i, pt in enumerate(road.point_list): for j, pt0 in enumerate(road.point_list): if i < j: try: if pt == pt0: print road.rid, "error" return except TypeError: print road.rid, road.name, 'check type error' return last_pt = None sel = -1 for i, pt in enumerate(road.point_list): if last_pt is not None: dist = get_dist(last_pt, pt) if dist > 2000: print road.rid, road.name, 'dist', dist, i sel = i break last_pt = pt if sel != -1: del (road.point_list[sel]) flag = 0
def par_offset(road0, road1): """ 边缘点的起点或终点从路中央偏移到路上 一定偏移到偶数序号的道路(中心线右手边) :param road0: Road 待修正的道路道路 :param road1: Road 偏移到的(与road0垂直)道路 :return: """ OFFSET = 80 if road1.rid & 1: return # 当端点接近某道路且该道路没有路口交点时,需要偏移该端点,延长至下一个道路 # 端点必须没有和其他线段相交 bp, ep = road0.point_list[0], road0.point_list[-1] # 首先是起点 min_dist = 1e10 sel_seg = None for seg in road1.seg_list: dist = point2segment2(bp, seg) if dist < min_dist: min_dist, sel_seg = dist, seg # 寻找延长至的道路线段 if min_dist < OFFSET: if road0.bs == 1: return min_dist = 1e10 for pt in road1.cross_list: dist = get_dist(pt, bp) min_dist = min(dist, min_dist) if min_dist > OFFSET: _, px, py = get_cross_point(sel_seg, road0.seg_list[0]) cr = Point(px, py) # 该延长线应落在预计道路sel_seg上 # 不然与其余道路有可能偏离在50米内 extended_segment = Segment(cr, bp) if not is_segment_cross(extended_segment, sel_seg): return pt_list = [cr] pt_list.extend(road0.point_list[:]) road0.set_point_list(pt_list) road0.gene_segment() return min_dist = 1e10 sel_seg = None for seg in road1.seg_list: dist = point2segment2(ep, seg) if dist < min_dist: min_dist, sel_seg = dist, seg if min_dist < OFFSET: if road0.es == 1: return min_dist = 1e10 for pt in road1.cross_list: dist = get_dist(pt, ep) min_dist = min(dist, min_dist) if min_dist > OFFSET: _, px, py = get_cross_point(sel_seg, road0.seg_list[-1]) cr = Point(px, py) extended_segment = Segment(cr, bp) if not is_segment_cross(extended_segment, sel_seg): return road0.point_list.append(cr) road0.gene_segment() return
def par_merge(road0, road1): """ 一条线段的起点与另一条(平行线段)的终点相接 :param road0: :param road1: :return: road0, road1重新生成道路 """ THREAD = 10 bp0, ep0, bp1, ep1 = road0.point_list[0], road0.point_list[ -1], road1.point_list[0], road1.point_list[-1] try: if bp0 == ep1 or bp1 == ep0: return except TypeError: print 'par merge', road0.rid, road1.rid, 'TypeError' return # 在生成平行线后两条道路之间必然(除非是一直线上)有空隙或者交叉 # 这个THREAD值不能太大,否则和对向车道也能查找到一起 if get_dist(bp0, ep1) < THREAD: begin_seg, end_seg = road0.seg_list[0], road1.seg_list[-1] # 首先是平行 if calc_include_angle2(begin_seg, end_seg) <= 0.8: return if is_segment_cross(begin_seg, end_seg): # 相交时cut _, px, py = get_cross_point(begin_seg, end_seg) cr = Point(px, py) road0.point_list[0] = cr road1.point_list[-1] = cr road0.gene_segment() road1.gene_segment() else: # 不相交时延长 _, px, py = get_cross_point(begin_seg, end_seg) cr = Point(px, py) pt_list = [cr] pt_list.extend(road0.point_list) road0.point_list = pt_list road1.point_list.append(cr) road0.gene_segment() road1.gene_segment() elif get_dist(bp1, ep0) < THREAD: begin_seg, end_seg = road1.seg_list[0], road0.seg_list[-1] # 首先是平行 if calc_include_angle2(begin_seg, end_seg) <= 0.8: return if is_segment_cross(begin_seg, end_seg): # 相交时cut _, px, py = get_cross_point(begin_seg, end_seg) cr = Point(px, py) road1.point_list[0] = cr road0.point_list[-1] = cr road0.gene_segment() road1.gene_segment() else: # 不相交时延长 _, px, py = get_cross_point(begin_seg, end_seg) cr = Point(px, py) pt_list = [cr] pt_list.extend(road1.point_list) road1.point_list = pt_list road0.point_list.append(cr) road0.gene_segment() road1.gene_segment()