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