Beispiel #1
0
def create_road_network(root, smopy_map):
    def get_boundary(root):
        for child in root:
            if child.tag == "location":
                convBoundary = list(
                    map(float, child.attrib["convBoundary"].split(",")))
                origBoundary = list(
                    map(float, child.attrib["origBoundary"].split(",")))
            return convBoundary, origBoundary

    def calculate_coordinates(convBoundary, origBoundary, node_x, node_y):
        orig_per_conv_X = abs(origBoundary[0] -
                              origBoundary[2]) / abs(convBoundary[0] -
                                                     convBoundary[2])
        orig_per_conv_Y = abs(origBoundary[1] -
                              origBoundary[3]) / abs(convBoundary[1] -
                                                     convBoundary[3])

        node_x = origBoundary[0] + (node_x * orig_per_conv_X)
        node_y = origBoundary[1] + (node_y * orig_per_conv_Y)
        return node_x, node_y

    def is_not_roadway(child):
        childs = str(child.attrib).split(",")
        for ch in childs:
            if "railway" in ch:
                return True
            if "highway.cycleway" in ch:
                return True
            if "highway.footway" in ch:
                return True
            if "highway.living_street" in ch:
                return True
            if "highway.path" in ch:
                return True
            if "highway.pedestrian" in ch:
                return True
            if "highway.step" in ch:
                return True
        return False

    lane_dic = {}
    lane_dic2 = {}
    x_y_dic = {}
    edge_length_dic = {}
    lane_node_dic = {}
    l_n_dic = {}
    node_id = 0
    lane_id = 0
    DG = nx.DiGraph()
    edge_lanes_list = []

    convBoundary, origBoundary = get_boundary(root)

    top = origBoundary[3]
    bottom = origBoundary[1]
    leftmost = origBoundary[0]
    rightmost = origBoundary[2]
    x_of_divided_area = abs(leftmost - rightmost) / num_of_division
    y_of_divided_area = abs(top - bottom) / num_of_division

    node_id_to_index = {}
    index_to_node_id = {}
    node_id_to_coordinate = {}

    for child in root:
        if child.tag == "edge":
            if is_not_roadway(child):
                continue

            lane = Lane()

            if "from" in child.attrib and "to" in child.attrib:
                lane.add_from_to(child.attrib["from"], child.attrib["to"])

            for child2 in child:

                try:
                    data_list = child2.attrib["shape"].split(" ")
                except:  # except param
                    continue

                node_id_list = []
                node_x_list = []
                node_y_list = []
                distance_list = []
                data_counter = 0

                for data in data_list:
                    node_lon, node_lat = calculate_coordinates(
                        convBoundary, origBoundary, float(data.split(",")[0]),
                        float(data.split(",")[1]))

                    node_x, node_y = smopy_map.to_pixels(node_lat, node_lon)

                    index_x = int(
                        abs(leftmost - node_lon) // x_of_divided_area)
                    index_y = int(abs(top - node_lat) // y_of_divided_area)

                    #緯度経度(xml,geojson)の誤差?によりindex==num_of_divisionとなる場合があるため、エリア内に収まるように調整する
                    if not 0 <= index_x < num_of_division:
                        if index_x >= num_of_division:
                            index_x = num_of_division - 1
                        else:
                            index_x = 0
                    if not 0 <= index_y < num_of_division:
                        if index_y >= num_of_division:
                            index_y = num_of_division - 1
                        else:
                            index_y = 0

                    node_id_to_index[node_id] = (index_x, index_y)
                    if (index_x, index_y) not in index_to_node_id.keys():
                        index_to_node_id[(index_x, index_y)] = [node_id]
                    else:
                        index_to_node_id[(index_x, index_y)].append(node_id)

                    node_id_to_coordinate[node_id] = {
                        "longitude": node_lon,
                        "latitude": node_lat
                    }

                    node_x_list.append(node_x)
                    node_y_list.append(node_y)

                    if (node_x, node_y) not in x_y_dic.keys():
                        node_id_list.append(node_id)
                        DG.add_node(node_id, pos=(node_x, node_y))
                        x_y_dic[(node_x, node_y)] = node_id
                        node_id += 1

                    else:
                        node_id_list.append(x_y_dic[(node_x, node_y)])

                    if data_counter >= 1:
                        distance_list.append(
                            np.sqrt((node_x - old_node_x)**2 +
                                    (node_y - old_node_y)**2))
                    old_node_x = node_x
                    old_node_y = node_y
                    data_counter += 1
                for i in range(len(node_id_list) - 1):
                    DG.add_edge(
                        node_id_list[i],
                        node_id_list[i + 1],
                        weight=distance_list[i],
                        color="black",
                        speed=float(
                            child2.attrib["speed"]))  # calculate weight here

                if "from" in child.attrib and "to" in child.attrib:
                    lane.set_others(float(child2.attrib["speed"]),
                                    node_id_list, node_x_list, node_y_list)
                    edge_lanes_list.append(lane)  # to modify here
                    lane_dic[lane] = lane_id
                    lane_dic2[lane_id] = lane
                    edge_length_dic[lane_id] = float(child2.attrib["length"])
                    for i in range(len(node_x_list)):
                        l_n_dic[(x_y_dic[node_x_list[i],
                                         node_y_list[i]])] = lane_id
                    lane_id += 1

    scc = nx.strongly_connected_components(DG)
    largest_scc = True
    for c in sorted(scc, key=len, reverse=True):
        if largest_scc == True:
            largest_scc = False
        else:
            c_list = list(c)
            for i in range(len(c_list)):
                DG.remove_node(c_list[i])
                for lane in edge_lanes_list:
                    if lane.node_id_list[0] == int(
                            c_list[i]) or lane.node_id_list[1] == int(
                                c_list[i]):
                        edge_lanes_list.remove(lane)

    lane_id = 0
    for lane in edge_lanes_list:
        for k, v in l_n_dic.items():
            if v == lane_dic[lane]:
                lane_node_dic[k] = lane_id
        lane_id += 1

    return x_y_dic, DG, edge_lanes_list, node_id_to_index, index_to_node_id, node_id_to_coordinate, edge_length_dic, lane_node_dic, lane_dic2
def create_road_network(root):
    # read edge tagged data for reading the road network
    # create data structure of road network using NetworkX
    x_y_dic = {}  # input: node's x,y pos, output: node id
    lane_dic = {}
    edge_length_dic = {}
    node_id = 0
    lane_id = 0

    DG = nx.DiGraph()  # Directed graph of road network
    edge_lanes_list = []  # list of lane instances
    for child in root:
        if child.tag == "edge":
            lane = Lane()
            if "from" in child.attrib and "to" in child.attrib:
                lane.add_from_to(child.attrib["from"], child.attrib["to"])

            for child2 in child:
                data_list = child2.attrib["shape"].split(" ")
                node_id_list = []
                node_x_list = []
                node_y_list = []
                distance_list = []
                data_counter = 0

                for data in data_list:
                    node_x_list.append(float(data.split(",")[0]))
                    node_y_list.append(float(data.split(",")[1]))
                    if (float(data.split(",")[0]),
                            float(data.split(",")[1])) not in x_y_dic.keys():
                        node_id_list.append(node_id)
                        DG.add_node(node_id,
                                    pos=(float(data.split(",")[0]),
                                         float(data.split(",")[1])))
                        x_y_dic[(float(data.split(",")[0]),
                                 float(data.split(",")[1]))] = node_id
                        node_id += 1

                    else:
                        node_id_list.append(x_y_dic[(float(
                            data.split(",")[0]), float(data.split(",")[1]))])

                    if data_counter >= 1:
                        distance_list.append(
                            np.sqrt(
                                (float(data.split(",")[0]) - old_node_x)**2 +
                                (float(data.split(",")[1]) - old_node_y)**2))
                    old_node_x = float(data.split(",")[0])
                    old_node_y = float(data.split(",")[1])
                    data_counter += 1
                for i in range(len(node_id_list) - 1):
                    DG.add_edge(
                        node_id_list[i],
                        node_id_list[i + 1],
                        weight=distance_list[i],
                        color="black",
                        speed=float(
                            child2.attrib["speed"]))  # calculate weight here
                if "from" in child.attrib and "to" in child.attrib:
                    #print("エッジ長とレーン番号の組",float(child2.attrib["length"]), lane_id)
                    edge_length_dic[lane_id] = float(child2.attrib["length"])
                    for i in range(len(node_x_list)):
                        lane_dic[(x_y_dic[node_x_list[i],
                                          node_y_list[i]])] = lane_id
                    lane_id += 1
                    lane.set_others(float(child2.attrib["speed"]),
                                    node_id_list, node_x_list, node_y_list)
                    edge_lanes_list.append(lane)  # to modify here

    return x_y_dic, lane_dic, edge_length_dic, DG, edge_lanes_list