<jupyter_start><jupyter_text>import packages<jupyter_code>import math
import geopy.distance<jupyter_output><empty_output><jupyter_text>define dict mapped from angle to quadrant<jupyter_code>dict_quadrant = {}
for i in range(8):
    dict_quadrant[(45 * i, 45 * (i + 1))] = i + 1<jupyter_output><empty_output><jupyter_text>calculate the distance of two geo points<jupyter_code>def get_distance(origin_point,new_point):
    dist = geopy.distance.distance(origin_point,new_point).km
    return dist<jupyter_output><empty_output><jupyter_text>mapped from an angle to quadrant<jupyter_code>def get_quadrant(table, angle):
    """
    get the quadrant according to the table
    :param table: dict, mapped angle to quadrant
    :param angle: int
    :return: int, quadant
    """
    if angle < 0 or angle > 360:
        print("angle not legal.")
        raise LookupError
    for key in table:
        if key[0] <= angle < key[1]:
            return table[key]<jupyter_output><empty_output><jupyter_text>calculate degree based on spherial coordinate<jupyter_code>def angleFromCoordinate(origin_point, new_point):
    """
    :param origin_point: tuple or list, composed of lat1, long1
    :param new_point: tuple or list, composed of lat2, long2
    :return: int, degree
    """
    lat1, long1 = origin_point[0], origin_point[1]
    lat2, long2 = new_point[0], new_point[1]
    dLon = (long2 - long1)

    y = math.sin(dLon) * math.cos(lat2)
    x = math.cos(lat1) * math.sin(lat2) - math.sin(lat1) * math.cos(lat2) * math.cos(dLon)

    brng = math.atan2(y, x)

    brng = math.degrees(brng)
    if brng<0:
        brng = 360+brng

    return brng<jupyter_output><empty_output><jupyter_text>calculate quadrant based on spherial coordinate<jupyter_code>def quadrantFromCoordinate(origin_point, new_point):
    """
    :param origin_point: tuple or list, composed of lat1, long1
    :param new_point: tuple or list, composed of lat2, long2
    :return: int, quadrant
    """
    degree = angleFromCoordinate(origin_point, new_point)
    return get_quadrant(dict_quadrant, degree)<jupyter_output><empty_output><jupyter_text>calculate degree of lines that is composed of multiple nodes, do not consider direction, north direction is default<jupyter_code>def degree_multilines_nodirection(nodes):
    """
    take the weighted degree of multi degreed lines
    :param nodes: list, composed of list or tuple of lat and lon
    :return: int, quadrant
    """
    degrees = []
    lengths = []
    for i in range(len(nodes) - 1):
        degrees.append(angleFromCoordinate(nodes[i], nodes[i + 1]))
        lengths.append(get_distance(nodes[i], nodes[i + 1]))
    degree_ave = sum(m * n for m, n in zip(degrees, lengths)) / sum(lengths)
    return get_quadrant(dict_quadrant, degree_ave)<jupyter_output><empty_output><jupyter_text>test as a concreate example:     wayid = "392752203"  node id="3959362688" lat="30.1660598" lon="120.2085375"/>  nodeid="3959362689" lat="30.1676474" lon="120.2074530"/><jupyter_code>nodes = [(30.1660598,120.2085375), (30.1676474,120.2074530)]
degree_multilines_nodirection(nodes)<jupyter_output><empty_output><jupyter_text>take another example,  way id="489071249">nd ref="4813517486"/>nd ref="5269370867"/>nd ref="4813517487"/>nd ref="4813517488"/>nd ref="4813517504"/><jupyter_code>nodes2 = [(30.1737755,120.1406690),(30.1755130,120.1401495),(30.1775893,120.1394624)]
degree_multilines_nodirection(nodes2)<jupyter_output>/usr/local/lib/python3.5/dist-packages/ipykernel_launcher.py:2: DeprecationWarning: Vincenty is deprecated and is going to be removed in geopy 2.0. Use `geopy.distance.geodesic` (or the default `geopy.distance.distance`) instead, which is more accurate and always converges.<jupyter_text>calculate degree of lines that is composed of multiple nodes, also consider direction based on the center point<jupyter_code>def degree_multilines(origin_point, nodes):
    """
    take the weighted degree of multi degreed lines
    :param direction: bool
    :param nodes: list
    :param origin_point: tuple, the base point
    :return: int, weighted degree
    """

    if get_distance(origin_point, nodes[-1]) < get_distance(origin_point, nodes[0]):
        nodes = nodes[::-1]
    degrees = []
    lengths = []
    for i in range(len(nodes) - 1):
        degrees.append(angleFromCoordinate(nodes[i], nodes[i + 1]))
        lengths.append(get_distance(nodes[i], nodes[i + 1]))
    degree_ave = sum(m * n for m, n in zip(degrees, lengths)) / sum(lengths)
    return get_quadrant(dict_quadrant, degree_ave)<jupyter_output><empty_output><jupyter_text>suppose center point is 30.173793, 120.140693, and onther point is  30.178613, 120.139168, one is closer to the end of one lane, and the other is the opposit direction, let's check the result<jupyter_code>center_point1 = (30.173793, 120.140693)
center_point2 = (30.178613, 120.139168)
degree_multilines(center_point1,nodes2)
degree_multilines(center_point2,nodes2)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11434887459807073, 'fraction_numerical': 0.0707395498392283, 'mean_word_length': 4.780487804878049, 'pattern_counts': {'":': 0, '<': 49, '<?xml version=': 0, '>': 53, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '11', 'dir': 'jupyter-structured-clean-dedup', 'id': '97487', 'license': 'MIT', 'n_tokens_mistral': 1915, 'n_tokens_neox': 1699, 'n_words': 409, 'path': 'geo-bearing-direction/geo_bearing.ipynb', 'repo_name': 'sunmengnan/city_brain', 'size': '4976'}