def add_space_for_crosswalk(lane_data, crosswalk_width=1.82): """ Extend space around the lane to include a crosswalk into the space :param lane_data: dictionary :param crosswalk_width: float :return: dictionary """ left_border = extend_both_sides_of_a_border(lane_data['left_border']) right_border = extend_both_sides_of_a_border(lane_data['right_border']) return shift_list_of_nodes(left_border, [-crosswalk_width]*len(left_border)),\ shift_list_of_nodes(right_border, [crosswalk_width]*len(right_border))
def reshape_lane(lane_data, lanes): """ Reapply starting shapes to a lane :param lane_data: dictionary :param lanes: list of dictionaries :return: None """ if 'L' in lane_data['lane_id'] and '1L' not in lane_data['lane_id']: next_to_right = get_next_right_lane(lane_data, lanes) if next_to_right is not None and 'prev' in next_to_right and next_to_right[ 'prev'] is not None: right_border_with_inserted_points = add_incremental_points( lane_data['right_border'], n=lane_data['shape_points'], l=lane_data['shape_length']) delta_len = len(right_border_with_inserted_points) - len( lane_data['right_border']) shaped_widths = get_shaped_lane_width(-lane_data['width'], n=lane_data['shape_points']) width_list = shaped_widths[:delta_len] + [ -lane_data['width'] ] * len(lane_data['right_border']) lane_data['left_shaped_border'] = shift_list_of_nodes( right_border_with_inserted_points, width_list) lane_data['right_shaped_border'] = copy.deepcopy( lane_data['right_border'])
def get_crosswalk_from_path(path_data, nodes_dict, width=1.8): """ Create a crosswalk from a path. :param path_data: dictionary :param nodes_dict: dictionary :param width: float in meters :return: dictionary of crosswalk data """ if 'highway' not in path_data['tags'] or 'foot' not in path_data['tags']['highway']: return None if 'footway' not in path_data['tags'] or 'crossing' not in path_data['tags']['footway']: return None crosswalk = { 'lane_id': '1C', 'simulated': 'no', 'path_id': path_data['id'], 'bearing': path_data['bearing'], 'compass': path_data['compass'], 'path': [path_data], 'lane_type': 'crosswalk', 'direction': 'undefined', 'nodes': path_data['nodes'], 'nodes_coordinates': [(nodes_dict[n]['x'], nodes_dict[n]['y']) for n in path_data['nodes']], 'width': width, 'type': 'footway' } for x in path_data['tags']: crosswalk[x] = path_data['tags'][x] if 'name' not in path_data['tags']: crosswalk['name'] = 'no_name' if 'left_border' in path_data: crosswalk['left_border'] = path_data['left_border'] else: crosswalk['left_border'] = None if 'right_border' in path_data: crosswalk['right_border'] = path_data['right_border'] else: crosswalk['right_border'] = None if crosswalk['left_border'] is not None: crosswalk['median'] = shift_list_of_nodes(crosswalk['left_border'], [width / 2.0] * len(crosswalk['left_border'])) else: crosswalk['median'] = None add_node_tags_to_lane(crosswalk, nodes_dict) insert_referenced_nodes(crosswalk, nodes_dict) return crosswalk
def add_borders_to_path(path_data, nodes_dict, width=3.048): """ Create left and right borders for a path assuming the path nodes defines the center of the street :param path_data: dictionary :param nodes_dict: dictionary :param width: float lane width in meters :return: dictionary """ path_data = remove_nodes_without_coordinates(path_data, nodes_dict) if len(path_data['nodes']) < 2: path_data['left_border'] = None path_data['right_border'] = None return path_data num_of_left_lanes, num_of_right_lanes, num_of_trunk_lanes = count_lanes( path_data) node_coordinates = [(nodes_dict[n]['x'], nodes_dict[n]['y']) for n in path_data['nodes']] if 'left_border' not in path_data or path_data[ 'left_border'] is None or len(path_data['left_border']) < 2: path_data['right_border'] = shift_list_of_nodes( node_coordinates, [width * num_of_trunk_lanes / 2.0] * len(node_coordinates)) path_data['left_border'] = shift_list_of_nodes( node_coordinates, [-width * num_of_trunk_lanes / 2.0] * len(node_coordinates)) else: path_data['right_border'] = shift_list_of_nodes( path_data['left_border'], [width * num_of_trunk_lanes] * len(node_coordinates)) if 'name' not in path_data['tags'] and 'highway' in path_data[ 'tags'] and 'link' in path_data['tags']['highway']: path_data['tags']['name'] = path_data['tags']['highway'] for node_id in path_data['nodes']: if 'street_name' not in nodes_dict[node_id]: nodes_dict[node_id]['street_name'] = set() nodes_dict[node_id]['street_name'].add(path_data['tags']['name']) return path_data
def split_bidirectional_path(path_data, nodes_dict, space_between_direction=1.0, width=3.048): """ Split a bidirectional path to two oneway paths :param path_data: dictionary :param nodes_dict: dictionary :param space_between_direction: float in meters :param width: lane width in meters :return: a tuple of dictionaries: forward and backward paths """ if 'oneway' in path_data['tags'] and path_data['tags']['oneway'] == 'yes': path_data['tags']['split'] = 'no' return path_data, None forward_path = copy.deepcopy(path_data) forward_path['tags']['split'] = 'yes' forward_path['tags']['oneway'] = 'yes' forward_path['id'] = forward_path['id'] * 100 if 'lanes' in path_data['tags'] \ and 'lanes:forward' not in path_data['tags'] \ and 'lanes:backward' not in path_data['tags'] \ and int(path_data['tags']['lanes']) % 2 == 0: forward_path['tags']['lanes'] = int(path_data['tags']['lanes']) / 2 else: if 'turn:lanes:forward' in path_data['tags']: forward_path['tags']['turn:lanes'] = path_data['tags'][ 'turn:lanes:forward'] if 'turn:lanes:both_ways' in path_data['tags']: forward_path['tags']['turn:lanes'] = path_data['tags'][ 'turn:lanes:both_ways'] if 'lanes:forward' in path_data['tags']: forward_path['tags']['lanes'] = path_data['tags']['lanes:forward'] # process bicycle lanes if 'bicycle' not in path_data['tags'] or path_data['tags'][ 'bicycle'] == 'yes': if 'cycleway:left' in forward_path: del forward_path['cycleway:left'] if 'cycleway:both' in forward_path['tags']: forward_path['tags']['cycleway:right'] = forward_path['tags'][ 'cycleway:both'] del forward_path['tags']['cycleway:both'] backward_path = copy.deepcopy(path_data) backward_path['tags']['split'] = 'yes' backward_path['id'] = backward_path['id'] * 100 + 1 backward_path['tags']['oneway'] = 'yes' backward_path['nodes'] = backward_path['nodes'][::-1] if 'turn:lanes:backward' in path_data['tags']: backward_path['tags']['turn:lanes'] = path_data['tags'][ 'turn:lanes:backward'] if 'turn:lanes:forward' in backward_path['tags']: del backward_path['tags']['turn:lanes:forward'] if 'turn:lanes:both_ways' in path_data['tags']: backward_path['tags']['turn:lanes'] = path_data['tags'][ 'turn:lanes:both_ways'] if 'lanes' in path_data['tags'] \ and 'lanes:forward' not in path_data['tags'] \ and 'lanes:backward' not in path_data['tags'] \ and int(path_data['tags']['lanes']) % 2 == 0: backward_path['tags']['lanes'] = int(path_data['tags']['lanes']) / 2 else: if 'lanes:backward' in path_data['tags']: backward_path['tags']['lanes'] = path_data['tags'][ 'lanes:backward'] if 'lanes:forward' in backward_path['tags']: del backward_path['tags']['lanes:forward'] if 'destination:ref:backward' in path_data['tags']: backward_path['tags']['destination:ref'] = path_data['tags'][ 'destination:ref:backward'] if 'destination:ref:forward' in backward_path['tags']: del backward_path['tags']['destination:ref:forward'] if 'destination:backward' in path_data['tags']: backward_path['tags']['destination'] = path_data['tags'][ 'destination:backward'] # process bicycle lanes if 'bicycle' not in backward_path['tags'] or backward_path['tags'][ 'bicycle'] == 'yes': if 'cycleway:right' in backward_path: del backward_path['tags']['cycleway:right'] if 'cycleway:left' in backward_path: backward_path['tags']['cycleway:right'] = backward_path['tags'][ 'cycleway:left'] del backward_path['tags']['cycleway:left'] if 'cycleway:both' in backward_path['tags']: backward_path['tags']['cycleway:right'] = backward_path['tags'][ 'cycleway:both'] del backward_path['tags']['cycleway:both'] forward_left_lanes, forward_right_lanes, forward_trunk_lanes = count_lanes( forward_path) backward_left_lanes, backward_right_lanes, backward_trunk_lanes = count_lanes( backward_path) distance_to_right_border = ( (forward_left_lanes + forward_right_lanes + forward_trunk_lanes + backward_left_lanes + backward_right_lanes + backward_trunk_lanes) * width + space_between_direction) / 2.0 forward_border_offset = distance_to_right_border - ( forward_right_lanes + forward_trunk_lanes) * width forward_path['left_border'] = shift_border(forward_path, nodes_dict, forward_border_offset) offset_from_forward_left_border = space_between_direction + ( backward_left_lanes + forward_left_lanes) * width backward_path['left_border'] = shift_list_of_nodes( forward_path['left_border'][::-1], [offset_from_forward_left_border] * len(forward_path['left_border'])) return forward_path, backward_path
def create_lane(p, nodes_dict, left_border=None, right_border=None, right_shaped_border=None, lane_id='1', lane_type='', direction='undefined', width=3.048, shape_points=16, shape_length=10.0, num_of_left_lanes=0, num_of_right_lanes=0, num_of_trunk_lanes=1, crosswalk_width=1.82): """ Create a lane from a path :param p: :param nodes_dict: :param left_border: :param right_border: :param right_shaped_border: :param lane_id: :param lane_type: :param direction: :param width: :param shape_points: :param shape_length: :param num_of_left_lanes: :param num_of_right_lanes: :param num_of_trunk_lanes: :param crosswalk_width: :return: """ lane_data = { 'lane_id': str(lane_id), 'path_id': p['id'], 'path': p, 'left_border': copy.deepcopy(left_border), 'lane_type': lane_type, 'direction': direction, 'width': width, 'shape_points': shape_points, 'shape_length': shape_length, 'num_of_left_lanes': num_of_left_lanes, 'num_of_right_lanes': num_of_right_lanes, 'num_of_trunk_lanes': num_of_trunk_lanes, 'crosswalk_width': crosswalk_width } if lane_type == 'cycleway': bicycle_lane_location = get_bicycle_lane_location(p) lane_data['bicycle_forward_location'] = bicycle_lane_location[ 'bicycle_forward_location'] lane_data['bicycle_backward_location'] = bicycle_lane_location[ 'bicycle_backward_location'] for x in p['tags']: lane_data[x] = p['tags'][x] if lane_type == 'left': lane_data['lane_id'] = str(lane_id) + 'L' elif lane_type == 'right': lane_data['lane_id'] = str(lane_id) + 'R' if 'name' in p['tags']: name = p['tags']['name'] elif 'highway' in p['tags'] and 'link' in p['tags']['highway']: name = p['tags']['highway'] else: name = 'no_name' lane_data['name'] = name lane_data['nodes'] = p['nodes'] lane_data['nodes_coordinates'] = [(nodes_dict[n]['x'], nodes_dict[n]['y']) for n in lane_data['nodes']] lane_data['right_shaped_border'] = None lane_data['left_shaped_border'] = None if right_border is None: lane_data['left_border'] = copy.deepcopy(left_border) lane_data['right_border'] = shift_list_of_nodes( left_border, [width] * len(left_border)) elif left_border is None: lane_data['right_border'] = copy.deepcopy(right_border) lane_data['left_border'] = shift_list_of_nodes(right_border, [-width] * len(right_border)) if 'L' in lane_data['lane_id']: right_border_with_inserted_points = add_incremental_points( right_border, n=shape_points, l=shape_length) delta_len = len(right_border_with_inserted_points) - len( right_border) shaped_widths = get_shaped_lane_width(-width, n=shape_points) width_list = shaped_widths[:delta_len] + [-width ] * len(right_border) if lane_data['lane_id'] == '1L': lane_data['right_shaped_border'] = copy.deepcopy( lane_data['right_border']) lane_data['left_shaped_border'] = shift_list_of_nodes( right_border_with_inserted_points, width_list) elif right_shaped_border is not None: lane_data['right_shaped_border'] = copy.deepcopy( right_shaped_border) lane_data['left_shaped_border'] = shift_list_of_nodes( right_shaped_border, width_list, direction_reference=lane_data['right_border']) else: lane_data['right_border'] = copy.deepcopy(right_border) lane_data['left_border'] = copy.deepcopy(left_border) if 'L' not in lane_data['lane_id']: lane_data['right_shaped_border'] = None lane_data['left_shaped_border'] = None lane_data['median'] = shift_list_of_nodes(lane_data['left_border'], [width / 2.0] * len(lane_data['left_border'])) lane_data['length'] = get_border_length(lane_data['median']) insert_referenced_nodes(lane_data, nodes_dict) return lane_data