如何基于Pandas数据集在Folium地图中为员工添加道路路线及计算距离
解决方法
一、按员工生成沿道路的行驶路线
folium本身不具备路径规划能力,要生成沿道路的路线,可借助开源的**OSRM(Open Source Routing Machine)**服务——它能返回两点间的道路导航路径坐标,无需申请API密钥。具体步骤如下:
分组并排序员工点位
确保数据集包含记录点位时间的列(比如timestamp),先按员工姓名分组,再对每个员工的点位按时间排序,保证路线匹配员工的实际行动顺序。调用OSRM获取道路路径并绘制
对每个员工的连续点位对,调用OSRM的route接口获取路径坐标集合,再用folium.PolyLine连接这些坐标,同时使用员工对应的Hex颜色区分路线。整合后的代码示例
import folium import webbrowser import pandas as pd import requests from itertools import pairwise # 假设数据集含timestamp列,先转换时间格式并分组排序 GeoSpatial1dec['timestamp'] = pd.to_datetime(GeoSpatial1dec['timestamp']) grouped = GeoSpatial1dec.groupby('employee') # 初始化地图 my_map = folium.Map( location=[GeoSpatial1dec['latitude'].mean(), GeoSpatial1dec['longitude'].mean()], zoom_start=12 ) # 遍历每个员工的点位数据 for emp_name, group in grouped: sorted_points = group.sort_values('timestamp') emp_color = sorted_points['Hex'].iloc[0] # 保留原有的点位标记(修正fill参数让颜色生效) for _, row in sorted_points.iterrows(): folium.CircleMarker( [row['latitude'], row['longitude']], radius=10, popup=emp_name, fill=True, fill_color=row['Hex'], color=row['Hex'], fill_opacity=1 ).add_to(my_map) # 生成连续点位的道路路线 if len(sorted_points) >= 2: for point1, point2 in pairwise(sorted_points.itertuples()): # 调用OSRM API获取路径 url = f"http://router.project-osrm.org/route/v1/driving/{point1.longitude},{point1.latitude};{point2.longitude},{point2.latitude}?geometries=geojson" response = requests.get(url) if response.status_code == 200: route_data = response.json() # 转换OSRM返回的lon/lat格式为folium需要的lat/lon route_coords = [(coord[1], coord[0]) for coord in route_data['routes'][0]['geometry']['coordinates']] # 绘制路线 folium.PolyLine( locations=route_coords, color=emp_color, weight=3, opacity=0.8 ).add_to(my_map) my_map.save("map.html") webbrowser.open("map.html")
二、计算点位间的行驶距离
直接从OSRM的响应结果中提取行驶距离(单位:米),可统计单段距离或员工当日总行驶距离:
提取单段距离
在处理每对点位的代码中,加入距离提取逻辑:# 提取当前路段的行驶距离(米) segment_distance = route_data['routes'][0]['distance'] print(f"{emp_name} 该段行驶距离:{segment_distance/1000:.2f} 公里")统计员工总行驶距离
初始化字典存储总距离,遍历过程中累加:total_distances = {} # 在员工循环内累加距离 total_distances[emp_name] = total_distances.get(emp_name, 0) + segment_distance # 遍历结束后打印总距离 for emp, dist in total_distances.items(): print(f"{emp} 当日总行驶距离:{dist/1000:.2f} 公里")
关键说明
- 若需离线使用,可自行部署OSRM服务,避免公共API的速率限制。
- 必须保证点位的时间顺序正确,否则路线会出现逻辑错误。
- 之前用
Polygon无效是因为它用于绘制多边形区域,路线绘制需用PolyLine。
内容的提问来源于stack exchange,提问作者EB_10
相关产品推荐
相关产品推荐

