Esempio n. 1
0
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)
Esempio n. 2
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
Esempio n. 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
    """
    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
Esempio n. 4
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)
    ]