Пример #1
0
def shorten_border_for_crosswalk(input_border,
                                 street_name,
                                 lanes,
                                 crosswalk_width=10,
                                 destination='from_intersection',
                                 exclude_links=True,
                                 exclude_parallel=True):
    """
    Remove the portion of the input border overlapping with any crosswalk crossing the input border.
    Scan all lanes with street names other than the street the input border belongs to,
    and identify crosswalks related to each lane.
    :param input_border: list of coordinates
    :param street_name: string
    :param lanes: list of dictionaries
    :param crosswalk_width: float
    :param destination: string
    :param exclude_links: True if exclude links, False otherwise
    :return: list of coordinates
    """
    border = copy.deepcopy(input_border)
    if destination == 'from_intersection':
        multi_string_index = -1
    else:
        multi_string_index = 0

    for l in lanes:
        if l['name'] == 'no_name' or l['name'] == street_name:
            continue
        if exclude_links and 'link' in l['name']:
            continue
        if 'median' in l:
            border_type = 'median'
        else:
            border_type = 'left_border'

        bearing_delta = abs(
            get_angle_between_bearings(
                get_compass(l[border_type][-2], l[border_type][-1]),
                get_compass(input_border[0], input_border[-1])))
        if bearing_delta > 90.0:
            bearing_delta = (180.0 - bearing_delta) % 180.0
        if bearing_delta < 30.0:
            if exclude_parallel:
                logger.debug(
                    "Processing %s, excluding %s for shortening: almost parallel %r"
                    % (street_name, l['name'], bearing_delta))
                continue

        lb, rb = add_space_for_crosswalk(l, crosswalk_width=crosswalk_width)
        coord = lb + rb[::-1]
        polygon = geom.Polygon(coord)
        temp = cut_border_by_polygon(border, polygon, multi_string_index)
        if temp is not None:
            border = temp
            border = drop_small_edges(border)

    return border
Пример #2
0
def construct_turn_arc_with_initial_angle(origin_border,
                                          destination_border,
                                          initial_angle=15.0,
                                          number_of_points=12,
                                          turn_direction=-1.0):
    intersection_point, vector1, vector2 = get_turn_angle(
        origin_border, destination_border)

    if intersection_point is None:
        return None

    from_origin_to_intersection = great_circle_vec_check_for_nan(
        intersection_point[1], intersection_point[0], vector1[1][1],
        vector1[1][0])
    from_destination_to_intersection = great_circle_vec_check_for_nan(
        intersection_point[1], intersection_point[0], vector2[1][1],
        vector2[1][0])

    bearing1 = get_compass(vector1[1], vector1[0])
    bearing2 = get_compass(vector2[0], vector2[1])
    angle = ((turn_direction * (bearing2 - bearing1) + 360) % 360)
    sin1 = math.sin(to_rad(180.0 - angle))

    l_dest = from_destination_to_intersection
    z = l_dest * sin1 / (sin1 + math.sin(to_rad(initial_angle)))
    l_origin = z * math.cos(to_rad(initial_angle)) + (l_dest - z) * math.cos(
        to_rad(180.0 - angle))

    if from_origin_to_intersection > l_origin:
        #  Drive along the origin vector past the intersection
        last_origin_point = extend_vector(vector1,
                                          length=l_origin,
                                          backward=False,
                                          relative=False)[1]
    else:
        # Start turning immediately
        last_origin_point = vector1[1]

    azimuth = (get_compass(intersection_point, last_origin_point) -
               initial_angle + 360) % 360
    point = nv_frame.GeoPoint(latitude=last_origin_point[1],
                              longitude=last_origin_point[0],
                              degrees=True)
    result, _azimuthb = point.geo_point(distance=100.0,
                                        azimuth=azimuth,
                                        degrees=True)
    first_orin_point = (result.longitude_deg, result.latitude_deg)
    angled_origin_border = [first_orin_point, last_origin_point]

    return construct_turn_arc(angled_origin_border,
                              destination_border,
                              number_of_points=number_of_points,
                              turn_direction=turn_direction)
Пример #3
0
def get_simulated_crosswalk(street_data, streets, width=1.8):
    """
    Construct a simulated crosswalk
    :param street_data: street dictionary
    :param streets: list of dictionaries
    :param width: float, crosswalk width in meters
    :return: crosswalk dictionary
    """
    right_border = shorten_border_for_crosswalk(street_data['right_border'],
                                                street_data['name'],
                                                streets,
                                                crosswalk_width=2,
                                                destination='to_intersection',
                                                exclude_parallel=False)
    left_border = shorten_border_for_crosswalk(street_data['left_border'],
                                               street_data['name'],
                                               streets,
                                               crosswalk_width=2,
                                               destination='to_intersection',
                                               exclude_parallel=False)

    right_border2 = shorten_border_for_crosswalk(street_data['right_border'],
                                                 street_data['name'],
                                                 streets,
                                                 crosswalk_width=2 + width,
                                                 destination='to_intersection',
                                                 exclude_parallel=False)
    left_border2 = shorten_border_for_crosswalk(street_data['left_border'],
                                                street_data['name'],
                                                streets,
                                                crosswalk_width=2 + width,
                                                destination='to_intersection',
                                                exclude_parallel=False)

    crosswalk = {
        'lane_id': '1C',
        'name': street_data['name'],
        'simulated': 'yes',
        'right_border': [right_border[-1], left_border[-1]],
        'left_border': [right_border2[-1], left_border2[-1]],
        'median': shift_vector([right_border[-1], left_border[-1]],
                               -width / 2.0),
        'path_id': 0,
        'path': [],
        'lane_type': 'crosswalk',
        'direction': 'undefined',
        'nodes': [],
        'nodes_coordinates': [],
        'width': width,
        'type': 'footway'
    }
    bearing = get_compass(crosswalk['right_border'][0],
                          crosswalk['right_border'][-1])
    crosswalk['bearing'] = bearing
    crosswalk['compass'] = get_compass_rhumb(bearing),
    crosswalk['length'] = get_border_length(crosswalk['median'])
    logger.debug('Created crosswalk for street %s %s' %
                 (street_data['name'], street_data['compass']))

    return crosswalk
Пример #4
0
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
Пример #5
0
def construct_u_turn_arc(origin_border, destination_border, number_of_points=12):
    """
    Construct a turn arc with the destination border
    :param origin_border: list of coordinates
    :param destination_border: list of coordinates
    :param number_of_points: integer
    :return: list of coordinates
    """

    bearing1 = get_compass(origin_border[-2], origin_border[-1])
    bearing2 = get_compass(destination_border[0], destination_border[1])
    angle = abs(get_angle_between_bearings(bearing1, bearing2))

    radius, landing_border = get_u_turn_radius_and_landing_border(origin_border, destination_border)
    if radius > 50:
        logger.debug('U-turn bearings %r, %r, angle %r' % (bearing1, bearing2, angle))
        logger.warning('Radius is too large %r, landing border %r' % (radius, landing_border))
        ob = cut_line_by_relative_distance(destination_border, 0.95)
        radius, landing_border = get_u_turn_radius_and_landing_border(ob, destination_border)
        logger.debug('Retry bearings %r, %r, angle %r' % (bearing1, bearing2, angle))
        logger.debug('Adjusted radius %r, landing border %r' % (radius, landing_border))
    else:
        ob = origin_border
    shift = [2.0 * radius * (math.sin(to_rad(angle / 2.0 * i / float(number_of_points)))) ** 2
             for i in range(0, number_of_points + 1)
             ]

    vec = [ob[-1], extend_vector(ob[-2:], length=30.0, backward=False, relative=True)[-1]]
    vector = [extend_vector(vec,
                            length=radius * (math.sin(to_rad(angle * i / float(number_of_points)))),
                            backward=False
                            )[1]
              for i in range(0, number_of_points + 1)
              ]

    arc = [shift_by_bearing_and_distance(vector[i], shift[i], ob[-2:], bearing_delta=-90.0)
           for i in range(0, number_of_points + 1)
           ]

    return arc[:-1] + landing_border
Пример #6
0
def get_simulated_crosswalk(street_data, streets, width=1.8):
    """
    Construct a simulated crosswalk
    :param street_data: street dictionary
    :param streets: list of dictionaries
    :param width: float, crosswalk width in meters
    :return: crosswalk dictionary
    """
    if is_highway(street_data):
        return None
    logger.debug("Simulated crosswalk for %s" % street_data['name'])
    right_border = shorten_border_for_crosswalk(street_data['right_border'],
                                                street_data['name'],
                                                streets,
                                                crosswalk_width=3,
                                                destination='to_intersection',
                                                exclude_parallel=True,
                                                max_reduction=130.0
                                                )
    left_border = shorten_border_for_crosswalk(street_data['left_border'],
                                               street_data['name'],
                                               streets,
                                               crosswalk_width=3,
                                               destination='to_intersection',
                                               exclude_parallel=True,
                                               max_reduction=130.0
                                               )

    right_border2 = shorten_border_for_crosswalk(street_data['right_border'],
                                                 street_data['name'],
                                                 streets,
                                                 crosswalk_width=3 + width,
                                                 destination='to_intersection',
                                                 exclude_parallel=True,
                                                 max_reduction=130.0
                                                 )

    left_border2 = shorten_border_for_crosswalk(street_data['left_border'],
                                                street_data['name'],
                                                streets,
                                                crosswalk_width=3 + width,
                                                destination='to_intersection',
                                                exclude_parallel=False,
                                                max_reduction=130.0
                                                )

    vector = [right_border[-1], right_border2[-1]]
    resized_vector = extend_vector(vector, length=width, backward=False)
    vector2 = [get_closest_point(p, street_data['left_border']) for p in resized_vector]
    # logger.debug("Vector %r" % vector)
    # logger.debug("Resize %r" % resized_vector)
    # logger.debug("Vecto2 %r" % vector2)
    r_b = [right_border[-1], left_border[-1]]
    r_l = [shift_by_bearing_and_distance(r_b[0], width, [right_border[-1], right_border[-2]],
                                         bearing_delta=0.0),
           shift_by_bearing_and_distance(r_b[-1], width, [left_border[-1], left_border[-2]],
                                         bearing_delta=0.0)]
    crosswalk = {
        'lane_id': '1C',
        'name': street_data['name'],
        'simulated': 'yes',
        # 'right_border': [vector[0], vector2[0]],
        # 'left_border': [resized_vector[1], vector2[1]],
        'right_border': r_b,  # [right_border[-1], left_border[-1]],
        'left_border': r_l,  # [right_border2[-1], left_border2[-1]],
        'median': shift_vector([right_border[-1], left_border[-1]], -width / 2.0),
        'path_id': 0,
        'path': [],
        'lane_type': 'crosswalk',
        'direction': 'undefined',
        'nodes': [],
        'nodes_coordinates': [],
        'width': width,
        'type': 'footway'
    }
    bearing = get_compass(crosswalk['right_border'][0], crosswalk['right_border'][-1])
    crosswalk['bearing'] = bearing
    crosswalk['compass'] = get_compass_rhumb(bearing),
    crosswalk['length'] = get_border_length(crosswalk['median'])
    if crosswalk['length'] > 50.0:
        return None
    if "id" in street_data:
        crosswalk["street_id"] = street_data["id"]
    logger.debug(
        'Created crosswalk for street %s %s' % (street_data['name'], street_data['compass']))

    return crosswalk
Пример #7
0
def construct_turn_arc(origin_border,
                       destination_border,
                       number_of_points=12,
                       turn_direction=-1.0,
                       lane=None):
    """
    Construct a turn arc
    :param origin_border: list of coordinates
    :param destination_border: list of coordinates
    :param number_of_points: integer
    :param turn_direction: -1 if left turn otherwise 1
    :return: list of coordinates
    """

    intersection_point, vector1, vector2 = get_turn_angle(
        origin_border, destination_border)

    if intersection_point is None:
        logger.debug('Origin %r' % origin_border)
        logger.debug('Destin %r' % destination_border)
        logger.debug('Cannot find intersection point')
        return None

    from_origin_to_intersection = great_circle_vec_check_for_nan(
        intersection_point[1], intersection_point[0], vector1[1][1],
        vector1[1][0])
    from_destination_to_intersection = great_circle_vec_check_for_nan(
        intersection_point[1], intersection_point[0], vector2[1][1],
        vector2[1][0])

    #logger.debug("Vectors 1 %r" % vector1)
    #logger.debug("Vectors 2 %r" % vector2)
    if lane is not None:
        lane["left_vector"] = vector1
        lane["right_vector"] = vector2
    # logger.debug("Intersection point %r" % intersection_point)
    bearing1 = get_compass(vector1[1], vector1[0])
    bearing2 = get_compass(vector2[0], tuple(vector2[1]))
    angle = ((turn_direction * (bearing2 - bearing1) + 360) % 360)

    if from_origin_to_intersection < from_destination_to_intersection:
        distance_to_starting_point = from_origin_to_intersection
        dist_delta = 0.0
    else:
        distance_to_starting_point = from_destination_to_intersection
        dist_delta = from_origin_to_intersection - from_destination_to_intersection

    radius = distance_to_starting_point / math.tan(to_rad(angle / 2.0))
    if radius < 0.0:
        logger.error("Negative radius %r" % radius)
        logger.debug("from_origin_to_intersection %r" %
                     from_origin_to_intersection)
        logger.debug("from_destination_to_intersection %r" %
                     from_destination_to_intersection)
        return None
    else:
        logger.debug("Radius %r" % radius)

    shift = [
        turn_direction * 2.0 * radius *
        (math.sin(to_rad(angle / 2.0 * i / float(number_of_points))))**2
        for i in range(0, number_of_points + 1)
    ]

    vec = [origin_border[-1], intersection_point]
    vector = [
        extend_vector(vec,
                      length=dist_delta + radius *
                      (math.sin(to_rad(angle * i / float(number_of_points)))),
                      backward=False)[1]
        for i in range(0, number_of_points + 1)
    ]

    return [
        shift_by_bearing_and_distance(vector[i],
                                      shift[i],
                                      vec,
                                      bearing_delta=turn_direction * 90.0)
        for i in range(0, number_of_points + 1)
    ]