https://www.osgeo.cn/networkx/index.html
https://blog.csdn.net/weixin_45562896/article/details/134167896
https://blog.csdn.net/u013410354/article/details/121775373
https://leuvenmapmatching.readthedocs.io/en/latest/usage/introduction.html
network
import pandas as pd
import networkx as nx
# node_data = pd.read_csv('node.csv', encoding='gbk')
node_data = pd.DataFrame([{"node_id": 1, "lon": 1, "lat": 2},
{"node_id": 2, "lon": 2, "lat": 2},
{"node_id": 3, "lon": 3, "lat": 2},
{"node_id": 4, "lon": 4, "lat": 2}])
# link_data = pd.read_csv('link.csv', encoding='gbk')
link_data = pd.DataFrame([{"weight": 1, "from_node_id": 1, "to_node_id": 2},
{"weight": 2, "from_node_id": 3, "to_node_id": 2},
{"weight": 3, "from_node_id": 4, "to_node_id": 2}])
G = nx.Graph()
G.graph["crs"] = "epsg:4326"
for idx, row in node_data.iterrows():
node_id = row['node_id']
node_lon = row['lon']
node_lat = row['lat']
G.add_node(node_id, lon=node_lon, lat=node_lat)
for idx, row in link_data.iterrows():
weight = row['weight']
link_from = row['from_node_id']
link_to = row['to_node_id']
G.add_edge(link_from, link_to, weight=weight)
InMemMap
from leuvenmapmatching.map.inmem import InMemMap
# 创建一个 InMemMap 对象
#graph: Initial graph of form Dict[label, Tuple[Tuple[y,x], List[neighbor]]]]
my_map = InMemMap("my_map", use_latlon=True, use_rtree=True, index_edges=True)
for node in G.nodes:
print(node, G.nodes[node])
my_map.add_node(node, (G.nodes[node]['lon'], G.nodes[node]['lat']))
for u, v in G.edges:
print(u, v, G.get_edge_data(u, v))
my_map.add_edge(u, v)
my_map.purge()
# 将路网转换为网络
map_con = InMemMap(name='pNEUMA', use_latlon=False) # , use_rtree=True, index_edges=True)
# 构建网络
for node_id, row in nodes_p.iterrows():
map_con.add_node(node_id, (row['y'], row['x']))
for node_id_1, node_id_2, _ in G_p.edges:
map_con.add_edge(node_id_1, node_id_2)
匹配
#用transbigdata提取出行轨迹
import geopandas as gpd
tmp_gdf = data_deliver[data_deliver['ID'] == 22].sort_values(by = 'Time')
#轨迹增密
tmp_gdf = tbd.traj_densify(tmp_gdf,col = ['ID', 'Time', 'Lng', 'Lat'],timegap = 15)
#转换轨迹的坐标系为地理坐标系
tmp_gdf['geometry'] = gpd.points_from_xy(tmp_gdf['Lng'],tmp_gdf['Lat'])
tmp_gdf = gpd.GeoDataFrame(tmp_gdf)
tmp_gdf.crs = {'init':'epsg:4326'}
#tmp_gdf = tmp_gdf.to_crs(2416)
#获得轨迹点
path = list(zip(tmp_gdf.geometry.y, tmp_gdf.geometry.x))
#构建地图匹配工具
matcher = DistanceMatcher(map_con,
max_dist=500,
max_dist_init=170,
min_prob_norm=0.0001,
non_emitting_length_factor=0.95,
obs_noise=50,
obs_noise_ne=50,
dist_noise=50,
max_lattice_width=20,
non_emitting_states=True)
#进行地图匹配
states, _ = matcher.match(path, unique=False)
#绘制底图匹配结果
mmviz.plot_map(map_con, matcher=matcher,
show_labels=False, show_matching=True,#show_graph=False,
filename=None)
#获取地图匹配的路径geodataframe
pathdf = pd.DataFrame(matcher.path_pred_onlynodes,columns = ['u'])
pathdf['v'] = pathdf['u'].shift(-1)
pathdf = pathdf[-pathdf['v'].isnull()]
pathgdf = pd.merge(pathdf,edges_p.reset_index())
pathgdf = gpd.GeoDataFrame(pathgdf)
pathgdf.plot()
pathgdf.crs = {'init':'epsg:2416'}
pathgdf_4326 = pathgdf.to_crs(4326)
网友评论