def test_find_nearest(): # get graph G = ox.graph_from_point(location_point, dist=500, network_type="drive") # get nearest node nn, d = ox.get_nearest_node(G, location_point, method="euclidean", return_dist=True) # get nearest nodes: haversine, kdtree, balltree gdf_nodes = ox.graph_to_gdfs(G, edges=False) X = gdf_nodes["x"].head() Y = gdf_nodes["y"].head() nn1, dist1 = ox.get_nearest_nodes(G, X, Y, return_dist=True) nn2, dist2 = ox.get_nearest_nodes(G, X, Y, method="kdtree", return_dist=True) nn3, dist3 = ox.get_nearest_nodes(G, X, Y, method="balltree", return_dist=True) nn4 = ox.get_nearest_nodes(G, X, Y) nn5 = ox.get_nearest_nodes(G, X, Y, method="kdtree") nn6 = ox.get_nearest_nodes(G, X, Y, method="balltree") # get nearest edge u, v, k, g, d = ox.get_nearest_edge(G, location_point, return_geom=True, return_dist=True) # get nearest edges: haversine, kdtree, balltree ne1 = ox.get_nearest_edges(G, X, Y) ne2 = ox.get_nearest_edges(G, X, Y, method="kdtree") ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
def test_find_nearest(): # get graph G = ox.graph_from_point(location_point, dist=500, network_type="drive") # convert graph to node/edge GeoDataFrames and back again gdf_nodes, gdf_edges = ox.graph_to_gdfs( G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True ) assert len(gdf_nodes) == len(G) assert len(gdf_edges) == len(G.edges(keys=True)) G = ox.graph_from_gdfs(gdf_nodes, gdf_edges) assert len(gdf_nodes) == len(G) assert len(gdf_edges) == len(G.edges(keys=True)) # get nearest node nn, d = ox.get_nearest_node(G, location_point, method="euclidean", return_dist=True) # get nearest nodes: haversine, kdtree, balltree X = gdf_nodes["x"].head() Y = gdf_nodes["y"].head() nn1 = ox.get_nearest_nodes(G, X, Y) nn2 = ox.get_nearest_nodes(G, X, Y, method="kdtree") nn3 = ox.get_nearest_nodes(G, X, Y, method="balltree") # get nearest edge u, v, k, g, d = ox.get_nearest_edge(G, location_point, return_geom=True, return_dist=True) # get nearest edges: haversine, kdtree, balltree ne1 = ox.get_nearest_edges(G, X, Y) ne2 = ox.get_nearest_edges(G, X, Y, method="kdtree") ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
def test_nearest_edges(): from pyproj import Proj # test in closest edge section sheik_sayed_dubai = [25.09, 25.06, 55.16, 55.11] location_coordinates = (25.071764, 55.138978) G = ox.graph_from_bbox(*sheik_sayed_dubai, simplify=False, retain_all=True, network_type='drive') # Unprojected ne1 = ox.get_nearest_edges( G, X=[location_coordinates[1], location_coordinates[1]], Y=[location_coordinates[0], location_coordinates[0]], method='balltree', dist=0.0001) # Projected G2 = ox.project_graph(G) crs = Proj(G2.graph['crs']) projected_point = crs(location_coordinates[1], location_coordinates[0]) ne2 = ox.get_nearest_edges(G2, X=[projected_point[0], projected_point[0]], Y=[projected_point[1], projected_point[1]], method='kdtree', dist=10) assert (ne1 == ne2).all()
def test_network_saving_loading(): # save/load graph as shapefile and graphml file G = ox.graph_from_place('Piedmont, California, USA') G_projected = ox.project_graph(G) ox.save_graph_shapefile(G_projected) ox.save_graphml(G_projected) ox.save_graphml(G_projected, filename='gephi.graphml', gephi=True) G2 = ox.load_graphml('graph.graphml') G3 = ox.load_graphml('graph.graphml', node_type=str) # convert graph to node/edge GeoDataFrames and back again gdf_nodes, gdf_edges = ox.graph_to_gdfs(G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True) G4 = ox.gdfs_to_graph(gdf_nodes, gdf_edges) # find graph nodes nearest to some set of points X = gdf_nodes['x'].head() Y = gdf_nodes['y'].head() nn1 = ox.get_nearest_nodes(G, X, Y) nn2 = ox.get_nearest_nodes(G, X, Y, method='kdtree') nn3 = ox.get_nearest_nodes(G, X, Y, method='balltree') # find graph edges nearest to some set of points ne1 = ox.get_nearest_edges(G, X, Y) ne2 = ox.get_nearest_edges(G, X, Y, method='kdtree') ne3 = ox.get_nearest_edges(G, X, Y, method='kdtree', dist=50)
def test_find_nearest(): # get graph and x/y coords to search G = ox.graph_from_point(location_point, dist=500, network_type="drive") Gp = ox.project_graph(G) points = ox.utils_geo.sample_points(ox.get_undirected(Gp), 5) X = points.x Y = points.y # get nearest node nn, d = ox.get_nearest_node(Gp, location_point, method="euclidean", return_dist=True) nn = ox.get_nearest_node(Gp, location_point, method="euclidean", return_dist=False) # get nearest nodes nn1, dist1 = ox.get_nearest_nodes(G, X, Y, return_dist=True) nn2, dist2 = ox.get_nearest_nodes(Gp, X, Y, method="kdtree", return_dist=True) nn3, dist3 = ox.get_nearest_nodes(G, X, Y, method="balltree", return_dist=True) nn4 = ox.get_nearest_nodes(G, X, Y) nn5 = ox.get_nearest_nodes(Gp, X, Y, method="kdtree") nn6 = ox.get_nearest_nodes(G, X, Y, method="balltree") # get nearest edge u, v, k, g, d = ox.get_nearest_edge(Gp, location_point, return_geom=True, return_dist=True) u, v, k, g = ox.get_nearest_edge(Gp, location_point, return_geom=True) u, v, k, d = ox.get_nearest_edge(Gp, location_point, return_dist=True) u, v, k = ox.get_nearest_edge(Gp, location_point) # get nearest edges ne0 = ox.distance.nearest_edges(Gp, X, Y, interpolate=50) ne1 = ox.get_nearest_edges(Gp, X, Y) ne2 = ox.get_nearest_edges(Gp, X, Y, method="kdtree") ne3 = ox.get_nearest_edges(G, X, Y, method="balltree", dist=0.0001)
def test_network_saving_loading(): # save/load graph as shapefile and graphml file G = ox.graph_from_place('Piedmont, California, USA') G_projected = ox.project_graph(G) ox.save_graph_shapefile(G_projected) ox.save_graphml(G_projected) ox.save_graphml(G_projected, filename='gephi.graphml', gephi=True) G2 = ox.load_graphml('graph.graphml') G3 = ox.load_graphml('graph.graphml', node_type=str) # convert graph to node/edge GeoDataFrames and back again gdf_edges = ox.graph_to_gdfs(G, nodes=False, edges=True, fill_edge_geometry=False) gdf_nodes, gdf_edges = ox.graph_to_gdfs(G, nodes=True, edges=True, node_geometry=True, fill_edge_geometry=True) G4 = ox.gdfs_to_graph(gdf_nodes, gdf_edges) # find graph nodes nearest to some set of points X = gdf_nodes['x'].head() Y = gdf_nodes['y'].head() nn1 = ox.get_nearest_nodes(G, X, Y) nn2 = ox.get_nearest_nodes(G, X, Y, method='kdtree') nn3 = ox.get_nearest_nodes(G, X, Y, method='balltree') # find graph edges nearest to some set of points ne1 = ox.get_nearest_edges(G, X, Y) ne2 = ox.get_nearest_edges(G, X, Y, method='kdtree') ne3 = ox.get_nearest_edges(G, X, Y, method='kdtree', dist=50)
def find_nearest_edges_in_network__OLD(road_network, tdf, return_tdf_with_new_col=False): """Map-matching. For each point in a TrajDataFrame, it finds the nearest edge in a road network. Each edge is represented as the couple of OSM ids of its starting and ending nodes. Parameters: ---------- road_network : networkx MultiDiGraph the road network on which to map the points. tdf : TrajDataFrame the trajectories of the individuals. return_tdf_with_new_col : boolean if False (default), returns the list of the nearest edges; if True, returns a copy of the original TrajDataFrame with one more column called 'road_link'. Returns ------- list (if return_tdf_with_new_col = True) list of the nearest edges. TrajDataFrame (if return_tdf_with_new_col = False) the TrajDataFrame with 1 more column collecting the couple of OSM ids of the two nodes. """ tdf.sort_by_uid_and_datetime() # extracting arrays of lat and lng for the vehicle: vec_of_longitudes = np.array(tdf['lng']) vec_of_latitudes = np.array(tdf['lat']) # for each (lat,lon), find the nearest edge in the road network: array_of_nearest_edges = ox.get_nearest_edges(road_network, X=vec_of_longitudes, Y=vec_of_latitudes, method='balltree') ### # method (str {None, 'kdtree', 'balltree'}) – Which method to use for finding nearest node to each point. # If None, we manually find each node one at a time using osmnx.utils.get_nearest_node and haversine. # If ‘kdtree’ we use scipy.spatial.cKDTree for very fast euclidean search. # If ‘balltree’, we use sklearn.neighbors.BallTree for fast haversine search. ### list_of_nearest_edges = [] for index in range(0, array_of_nearest_edges.shape[0]): list_of_nearest_edges.append([ array_of_nearest_edges[index][0], array_of_nearest_edges[index][1] ]) if return_tdf_with_new_col: tdf_with_nearest_edges = tdf.copy() #.drop(columns=['lat', 'lng']) tdf_with_nearest_edges['road_link'] = list_of_nearest_edges return tdf_with_nearest_edges return list_of_nearest_edges
def test_nearest_edges(): from pyproj import Proj # test in closest edge section sheik_sayed_dubai = [25.09, 25.06, 55.16, 55.11] location_coordinates = (25.071764, 55.138978) G = ox.graph_from_bbox(*sheik_sayed_dubai, simplify=False, retain_all=True, network_type='drive') # Unprojected ne1 = ox.get_nearest_edges(G, X=[location_coordinates[1], location_coordinates[1]], Y=[location_coordinates[0], location_coordinates[0]], method='balltree', dist=0.0001) # Projected G2 = ox.project_graph(G) crs = Proj(G2.graph['crs']) projected_point = crs(location_coordinates[1], location_coordinates[0]) ne2 = ox.get_nearest_edges(G2, X=[projected_point[0], projected_point[0]], Y=[projected_point[1], projected_point[1]], method='kdtree', dist=10) assert (ne1 == ne2).all()
def set_up(self): def name(names): if not names: return '' elif isinstance(names, str): return names else: return ' '.join(names) tags = {'amenity': "vending_maching", "vending": "parking_tickets"} self.vending_machines_gdf = ox.geometries_from_place(self.place, tags) G = ox.graph_from_place(self.place, network_type='drive', retain_all = True, simplify=True) nearest_edges = ox.get_nearest_edges(G, self.vending_machines_gdf['geometry'].x, self.vending_machines_gdf['geometry'].y , method='balltree') self.vending_machines_gdf['street'] = [*map(lambda x: name(G.edges[(x[0], x[1], x[2])].get("name")).lower(), nearest_edges)]
def link_traffic_signals_to_edge(self): G = self.graph_latlon gdf_netw = self.network_matrix gdf_ts = self.traffic_signals lon = [j[0] for i, j in gdf_ts['coordinates'].iteritems()] lat = [j[1] for i, j in gdf_ts['coordinates'].iteritems()] nearest = ox.get_nearest_edges(G, lon, lat, method='balltree') nearest = [tuple(j) for i, j in enumerate(nearest)] gdf_ts['edge'] = nearest gdf_ts['N1'] = [j[0] for i, j in enumerate(nearest)] gdf_ts['N2'] = [j[1] for i, j in enumerate(nearest)] df_ts_e = pd.merge(gdf_netw[['N1', 'N2', 'geometry']], gdf_ts[['N1', 'N2']], how='inner', on=['N1', 'N2']) return df_ts_e
def match_nearest_edge(graph, track): """ Algorithm to match the track to the nearest edge on the Open Street Map network. This function match a track of GPS coordinates, in the (Lat, Lon) format. to a graph. It loops all over the points to match them to the closest edge of the OSM network. The GPS points are projected on the edge with an orthogonal projection. If the projected point goes outside of the edge, then it is match to one extremity (see noiseplanet.utils.oproj documentation for more details). Parameters ---------- graph : NetworkX MultiDiGraph Graph of the Open Street Map network. track : numpy 2D array A 2D matrix composed by Latitudes (first column) and Longitudes (second column) of the track. Returns ------- track_corr : numpy 2D array A 2D matrix composed by Latitudes (first column) and Longitudes (second column) of the corrected track. route : numpy 2D array Route connecting all track's points on the Open Street Map network. edgeid : numpy 2D array List of edges to which each points belongs to. Edges id are composed by two extremity nodes id. stats : Dict Statistics of the Map Matching. 'proj_length' is the length of the projection (from track's point to corrected ones), 'path_length' is the distance on the graph between two following points, 'unlinked' higlights unconnected points on the graph. Example ------- >>> import osmnx as ox >>> import numpy as np >>> from noiseplanet.matcher.model.leuven import leuven >>> place_name = "2e Arrondissement, Lyon, France" >>> distance = 1000 # meters >>> graph = ox.graph_from_address(place_name, distance) >>> track = np.array([[45.75809136, 4.83577159], [45.7580932 , 4.83576182], [45.7580929 , 4.8357634 ], [45.75809207, 4.8357678 ], [45.75809207, 4.8357678 ], [45.75809647, 4.83574439], [45.75809908, 4.83573054], [45.75809908, 4.83573054], [45.75810077, 4.83572153], [45.75810182, 4.83571596], [45.75810159, 4.83571719], [45.7581021 , 4.83571442], [45.7580448 , 4.83558152], [45.75804304, 4.83558066], [45.75804304, 4.83558066], [45.75802703, 4.83557288]]) >>> track_corr, route_corr, edgeid = match_nearest(graph, track) """ # id of the nearest edges edgeid = ox.get_nearest_edges(graph, track[:, 1], track[:, 0], method='balltree', dist=.000001) lat1, lat2, lon1, lon2 = [], [], [], [] for edge in edgeid: lon1.append(graph.nodes[edge[0]]['x']) lat1.append(graph.nodes[edge[0]]['y']) lon2.append(graph.nodes[edge[1]]['x']) lat2.append(graph.nodes[edge[1]]['y']) # Reference ellipsoid for distance # Projection of the point in the web mercator coordinate system (used by OSM) proj_init = "epsg:4326" # geographic coordinates proj_out = "epsg:3857" # web mercator coordinates # Using the class Transformer, faster for large dataset transformer = Transformer.from_proj(Proj(init=proj_init), Proj(init=proj_out)) Xt, Yt = transformer.transform(track[:, 1], track[:, 0]) # Projecting the nearest edges' nodes 1, 2 into the same coordinates system X1, Y1 = transformer.transform(lon1, lat1) X2, Y2 = transformer.transform(lon2, lat2) # With the transform function (slower since the 2.2.0 update) # Xt, Yt = transform(Proj(init=proj_init), Proj(init=proj_out), track[:,1], track[:,0]) # X1, Y1 = transform(Proj(init=proj_init), Proj(init=proj_out), lon1, lat1) # X2, Y2 = transform(Proj(init=proj_init), Proj(init=proj_out), lon2, lat2) # Need to evaluate the projection for each point distance(point, point_proj) proj_dist = np.zeros(len(track)) Xcorr, Ycorr = [], [] for i in range(len(track)): # Ortho projection x, y = Xt[i], Yt[i] xH, yH = oproj.orthoProjSegment((x, y), (X1[i], Y1[i]), (X2[i], Y2[i])) # Stack the coordinates in the web mercator coordinates system Xcorr.append(xH) Ycorr.append(yH) transformer = Transformer.from_proj(Proj(init=proj_out), Proj(init=proj_init)) lon_corr, lat_corr = transformer.transform(Xcorr, Ycorr) # With the transform function (slower since the 2.2.0 update) # lon_corr, lat_corr = transform(Proj(init=proj_out), Proj(init=proj_init), Xcorr, Ycorr) # Evaluate the distance betweeen these points # Reference ellipsoid for distance geod = Geod(ellps='WGS84') _, _, proj_dist = geod.inv(track[:, 1], track[:, 0], lon_corr, lat_corr) track_corr = np.column_stack((lat_corr, lon_corr)) route, stats_route = rt.route_from_track(graph, track_corr, edgeid=edgeid) stats = dict({"proj_length": proj_dist}, **stats_route) return track_corr, route, np.array(edgeid), stats
# Given three points off of the network, matches to the nearest edge and highlights that edge import osmnx as ox import matplotlib.pyplot as plt ox.config(use_cache=True, log_console=True) G = ox.graph_from_address('2801 Debarr Road, Anchorage, AK 99508', distance=400) fig, ax = ox.plot_graph(G, show=False, close=False) ax.scatter(-149.824945, 61.210608, c='red') ax.scatter(-149.828, 61.2078, c='blue') ax.scatter(-149.825, 61.2114, c='violet') plt.show() x = (-149.824945, -149.828, -149.825) y = (61.210608, 61.2078, 61.2114) edge = ox.get_nearest_edges(G, x, y, method='kdtree', dist=0.0001) for i in range(0, len(edge)): ec = ['orange' if (u == edge[i, 1] and v == edge[i, 0]) else 'grey' for u, v, k in G.edges(keys=True)] fig, ax = ox.plot_graph(G, node_color='w', node_edgecolor='k', node_size=30, node_zorder=3, edge_color=ec, edge_linewidth=2)
def network_dfs(self): g = self.graph_latlon if not self.strict: g = ox.simplify_graph(g, strict=self.strict) g = ox.add_edge_bearings(g, precision=1) n, e = ox.graph_to_gdfs(g) e = e.reset_index() # Method graph_to_gdfs changed to multiindex df network_edges, network_nodes_small = dbl_cleaning(ndf=n, edf=e) network_edges = network_edges.join(network_nodes_small, on='u') network_edges = network_edges.rename(columns={ 'u': 'n1', 'y': 'lat1', 'x': 'lon1' }) network_edges = network_edges.join(network_nodes_small, on='v') network_edges = network_edges.rename(columns={ 'v': 'n2', 'y': 'lat2', 'x': 'lon2' }) x1, y1 = zip( *project_point(list(zip(network_edges.lon1, network_edges.lat1)))) x2, y2 = zip( *project_point(list(zip(network_edges.lon2, network_edges.lat2)))) network_edges = network_edges.assign(x1=x1, y1=y1, x2=x2, y2=y2) network_edges['edge'] = list( zip(network_edges['n1'].values, network_edges['n2'].values)) network_edges.reset_index( inplace=True ) # From hereon the unique index of an edge is just its position in df network_edges = network_edges.rename(columns={'index': '_id'}) self.graph_latlon = g self.graph_xy = ox.project_graph(self.graph_latlon) self.network_edges = network_edges self._get_network_nodes(network_edges) # link node_tags to specific edge, osmid not unique over edges after simplification nearest = ox.get_nearest_edges(self.graph_xy, self.node_tags.x.to_list(), self.node_tags.y.to_list(), method='kdtree', dist=1) n1, n2, _ = zip(*nearest) test_b1 = network_edges[['_id', 'edge', 'bearing']][network_edges.edge.isin( list(zip(n1, n2)))].values test_b2 = network_edges[['_id', 'edge', 'bearing']][network_edges.edge.isin( list(zip(n2, n1)))].values self.node_tags['edge'] = [ij for ij in zip(n1, n2)] self.node_tags.reset_index(inplace=True) self.node_tags = self.node_tags.merge( self.network_edges[['edge', 'bearing']], on='edge', suffixes=('', '_edge')) diff_b = abs(self.node_tags['bearing'] - self.node_tags['bearing_edge']) for i, j in diff_b.iteritems(): if (j > 45) and not self.node_tags.junction[i]: self.node_tags.at[i, 'edge'] = (self.node_tags.at[i, 'edge'][1], self.node_tags.at[i, 'edge'][0]) self.node_tags.drop('bearing_edge', axis=1, inplace=True) self.node_tags = self.node_tags.merge( self.network_edges[['_id', 'edge', 'bearing']], on='edge', suffixes=('', '_edge')) diff_b2 = abs(self.node_tags['bearing'] - self.node_tags['bearing_edge']) breakpoint() # check if nearest edge is in right direction, problem with two way streets self.node_tags.set_index('index', inplace=True) self.node_tags.sort_index(inplace=True)
def map_matching_edge( move_data: Union[PandasMoveDataFrame, DaskMoveDataFrame, PandasDiscreteMoveDataFrame], inplace: Optional[bool] = True, bbox: Optional[Tuple[float, float, float, float]] = None, place: Optional[Text] = None, G: Optional[MultiDiGraph] = None ) -> Optional[DataFrame]: """ Generate Map matching using the graph edges Parameters ---------- move_data : MoveDataFrame The input trajectories data inplace: bool, optional if set to true the original dataframe will be altered, otherwise the alteration will be made in a copy, that will be returned, by default True bbox : tuple, optional The bounding box as (north, east, south, west), by default None place : string, optional The query to geocode to get place boundary polygon, by default None G : MultiDiGraph, optional The input graph, by default None Returns ------- move_data : MoveDataFrame A copy of the original dataframe or None """ if(G is None): if(bbox is None): bbox = move_data.get_bbox() G = ox.graph_from_bbox( bbox[0], bbox[2], bbox[1], bbox[3], network_type='all_private' ) elif(place is not None): G = ox.footprints_from_place(query=place, tags={'network_type': 'all_private'}) if not inplace: move_data = move_data[:] edges = ox.get_nearest_edges( G, X=move_data['lon'], Y=move_data['lat'], method='kdtree' ) gdf_edges = ox.graph_to_gdfs(G, nodes=False) geometries = [] for e in edges: df_edges = gdf_edges[ (gdf_edges.index.get_level_values('u') == e[0]) & (gdf_edges.index.get_level_values('v') == e[1]) ] geometries.append(df_edges['geometry']) move_data['edge'] = [*map(lambda x: tuple([x[0], x[1]]), edges)] move_data['geometry'] = geometries if not inplace: return move_data
def route_from_track(graph, track, edgeid=None): """ Get the route connecting points of a track projected on the Open Street Map network. Parameters ---------- graph : NetworkX MultiDiGraph Open Street Map graph where the route will be computed. track : numpy 2D array A 2D matrix composed by Latitudes (first column) and Longitudes (second column) of the track. edgeid : numpy 2D array, optional List of edges to which each points belongs to. Edges id are composed by two extremity nodes id. The default is None. Returns ------- route : numpy 2D array Route connecting all track's points. stats : Dict Statistics of the routing connection. 'path_length' is the distance on the graph between two following points, 'unlinked' higlights unconnected points on the graph. Example ------- >>> import numpy as np >>> from noiseplanet.matcher.model.route import route_from_track, graph_from_track >>> track = np.array([[45.75809136, 4.83577159], [45.7580932 , 4.83576182], [45.7580929 , 4.8357634 ], [45.75809207, 4.8357678 ], [45.75809207, 4.8357678 ], [45.75809647, 4.83574439], [45.75809908, 4.83573054], [45.75809908, 4.83573054], [45.75810077, 4.83572153], [45.75810182, 4.83571596]]) >>> graph = graph_from_track(track, network='all') >>> route_corr, stats = route_from_track(graph, track) """ # Reference ellipsoid for distance geod = Geod(ellps='WGS84') # Find closest edges for each points if edgeid is None: edgeid = np.array( ox.get_nearest_edges(graph, track[:, 1], track[:, 0], method="balltree", dist=0.00001)) edgeid = np.array(edgeid) # Deep copy of the graph, so the original is not modified # This algorithm will add edges and nodes to the graph # to compute Dijkstras shortest path graph2 = copy.deepcopy(graph) # adding the projected nodes to the copied graph for i in range(len(track)): graph2.add_node(i, y=track[i, 0], x=track[i, 1], osmid=i) _, _, distance1 = geod.inv(track[i, 1], track[i, 0], graph2.nodes[edgeid[i, 0]]['x'], graph2.nodes[edgeid[i, 0]]['y']) graph2.add_edge(edgeid[i, 0], i, osmid=2 * i, highway=graph2.edges[(edgeid[i, 0], edgeid[i, 1], 0)]["highway"], oneway=graph2.edges[(edgeid[i, 0], edgeid[i, 1], 0)]["oneway"], length=distance1) _, _, distance2 = geod.inv(track[i, 1], track[i, 0], graph2.nodes[edgeid[i, 1]]['x'], graph2.nodes[edgeid[i, 1]]['y']) graph2.add_edge(edgeid[i, 1], i, osmid=2 * i + 1, highway=graph2.edges[(edgeid[i, 0], edgeid[i, 1], 0)]["highway"], oneway=graph2.edges[(edgeid[i, 0], edgeid[i, 1], 0)]["oneway"], length=distance2) # adding edges in both directions # for edge in list(graph2.edges): # graph2.add_edge(edge[1], edge[0], # osmid=graph2.edges[(edge[0], edge[1], 0)]["osmid"]*2, # highway=graph2.edges[(edge[0], edge[1], 0)]["highway"], # oneway=graph2.edges[(edge[0], edge[1], 0)]["oneway"], # length=graph2.edges[(edge[0], edge[1], 0)]["length"]) graph2 = graph2.to_undirected() route = [] path_length = [] unlinked = [] for i in range(len(track) - 1): # If there is a changing direction (going from one edge to another, # compute Dijkstras algorithm to know what path to follow. if edgeid[i][0] != edgeid[i + 1][0] or edgeid[i][1] != edgeid[i + 1][1]: # If the two nodes are connected try: path = nx.shortest_path(graph2, i, i + 1, weight='length') distance = nx.shortest_path_length(graph2, i, i + 1, weight='length') path_length.append(distance) unlinked.append(0) for nodeid in path: route.append( [graph2.nodes[nodeid]["y"], graph2.nodes[nodeid]["x"]]) # If they are not connected, there is a mismatched except nx.NetworkXNoPath: route.append(track[i]) _, _, distance = geod.inv(track[i, 1], track[i, 0], track[i + 1, 1], track[i + 1, 0]) path_length.append(distance) unlinked.append(1) # If the route is already matched else: route.append(track[i]) _, _, distance = geod.inv(track[i, 1], track[i, 0], track[i + 1, 1], track[i + 1, 0]) path_length.append(distance) unlinked.append(0) # Let's not forget to add the last point route.append(track[-1]) unlinked.append(0) path_length.append(0) stats = { "path_length": np.array(path_length), "unlinked": np.array(unlinked) } return np.array(route), stats