def get_sector(point, block): """ Get visibility sector from a point to a blocking object :param point: point coordinates :param block: guideway dictionary :return: max and min azimuths and points where sector boundaries crosses the block """ max_azimuth = -1.0 min_azimuth = 361.0 for x in block['reduced_left_border'] + block['reduced_right_border']: azimuth = get_compass(point, x) if azimuth < min_azimuth: min_point = x min_azimuth = azimuth elif azimuth == min_azimuth: if get_distance_between_points( point, x) < get_distance_between_points(point, min_point): min_point = x min_azimuth = azimuth if azimuth > max_azimuth: max_point = x max_azimuth = azimuth elif azimuth == max_azimuth: if get_distance_between_points( point, x) < get_distance_between_points(point, max_point): max_point = x max_azimuth = azimuth return min_azimuth, max_azimuth, min_point, max_point
def get_public_transit_stop(lane_data, stops, max_distance=20.0): """ Get a list of public transit stops within the specified distance to the right border of a lane. Stop is a node. :param lane_data: dictionary :param stops: list of dictionaries :param max_distance: float in meters :return: list of stops (dictionaries) """ nearby_stops = set() if 'right_border' not in lane_data: return [] for stop in stops: s = get_node(stop) stop_location = (s['x'], s['y']) closest_point_on_the_border = get_closest_point( stop_location, lane_data['right_border']) distance = get_distance_between_points(stop_location, closest_point_on_the_border) if distance < max_distance: nearby_stops.add(stop['id']) return [s for s in stops if s['id'] in nearby_stops]
def get_u_turn_radius_and_landing_border(origin_border, destination_border): """ 1) Extend a perpendicular line 2) intersect with the destination border 3) calculate radius :return: """ far_away = shift_by_bearing_and_distance(origin_border[-1], 1000.0, origin_border[-2:], bearing_delta=-90.0) orthogonal = geom.LineString([origin_border[-1], far_away]) destination_line = geom.LineString(destination_border) if orthogonal.intersects(destination_line): intersection_point = orthogonal.intersection(destination_line) pt = list(intersection_point.coords)[0] cut_point = destination_line.project(intersection_point) landing_line = cut_border_by_distance(destination_line, cut_point)[-1] else: cut_point = orthogonal.project(geom.Point(destination_border[0])) line0 = cut_border_by_distance(orthogonal, cut_point)[0] pt = list(line0.coords)[-1] landing_line = geom.LineString(destination_border) return get_distance_between_points(origin_border[-1], pt) / 2.0, list( landing_line.coords)
def get_destination_lanes_for_u_turn(origin_lane, all_lanes): """ Identifying the destination lane for the u-turn. Assuming that the origin and destination lanes must have the index from left equal to zero. :param origin_lane: lane dictionary of a left turn :param all_lanes: list of dictionaries :return: list of valid lane destinations for the left turn """ if origin_lane['name'] == 'no_name': return [] return [l for l in all_lanes if l['name'] == origin_lane['name'] and l['direction'] == 'from_intersection' and get_lane_index_from_left(l) == 0 and abs(get_angle_between_bearings(origin_lane['bearing'], l['bearing'])) > 150.0 and get_distance_between_points(l['left_border'][0], origin_lane['left_border'][-1]) < 25.0 and get_distance_between_points(l['left_border'][0], l['left_border'][-1]) > 25.0 ]
def get_destination_lane(lane_data, all_lanes, min_len=21.0): """ Get destination lane for through driving :param lane_data: dictionary :param all_lanes: list of dictionaries :return: dictionary """ # Try common node first res = [l for l in all_lanes if lane_data['nodes'][-1] == l['nodes'][0] and lane_data['lane_id'] == l['lane_id'] and l['direction'] == 'from_intersection' and - 30.0 < get_angle_between_bearings(lane_data['bearing'], l['bearing']) < 30.0 and ("length" not in l or l["length"] > min_len) ] if len(res) > 0: return res[0] # Try same street name res = [l for l in all_lanes if lane_data['name'] == l['name'] and lane_data['lane_id'] == l['lane_id'] and l['direction'] == 'from_intersection' and - 60.0 < get_angle_between_bearings(lane_data['bearing'], l['bearing']) < 60.0 and get_distance_between_points(lane_data['median'][-1], l['median'][0]) < 15.0 and ("length" not in l or l["length"] > min_len) ] if len(res) > 0: return res[0] # Try all other possible options res = [l for l in all_lanes if -30.0 < get_angle_between_bearings(lane_data['bearing'], l['bearing']) < 30.0 and int(lane_data['lane_id'][0]) - 1 == get_lane_index_from_right(l) and l['direction'] == 'from_intersection' and get_distance_between_points(lane_data['median'][-1], l['median'][0]) < 10.0 and ("length" not in l or l["length"] > min_len) ] if len(res) > 0: return res[0] return None
def is_u_turn_allowed(origin_lane, x_data): """ Check if a U-turn is allowed for this lane :param origin_lane: dictionary :return: True if allowed, otherwise False """ if origin_lane['direction'] != 'to_intersection': return False if origin_lane['lane_type'] == 'cycleway' or 'rail' in origin_lane['lane_type']: return False if get_lane_index_from_left(origin_lane): return False if 'through' in origin_lane['lane_type'] and 'left' not in origin_lane['lane_type']: return False if get_distance_between_points(origin_lane['left_border'][-1], (x_data['center_x'], x_data['center_y'])) > 35.0: return False return True
def insert_distances_to_the_center(x): center = (x["center_x"], x["center_y"]) for c in x["crosswalks"]: c["distance_to_center"] = min( [get_distance_between_points(center, p) for p in c["right_border"] + c["left_border"]])