如何在R的Leaflet中展示TSP最终最优路径并保存
TSP最优路线的可视化与保存(R语言)
问题背景
我正在开发一个基于R语言的旅行商问题(TSP)程序,已通过osrm包计算出距离矩阵,代码如下:
distance_matrix <- matrix(NA, nrow = nrow(data), ncol = nrow(data)) for (i in 1:nrow(data)) { for (j in i:nrow(data)) { if (i != j) { route <- osrmRoute(c(data[i,]$lng,data[i,]$lat),c(data[j,]$lng,data[j,]$lat)) distance_matrix[i,j] <- route$distance distance_matrix[j,i] <- route$distance } } }
我已经能用Leaflet展示单条路径:
leaflet(route) |> addTiles() |> addPolylines(label = ~ sprintf("%d min - %d km", round(duration), round(distance)), labelOptions = labelOptions(noHide = FALSE))
但现在需要在得到TSP最优解后,展示完整的最短路线并保存该路线。
解决方案
1. 生成TSP最优路径的完整路线数据
首先用TSP算法求解得到节点访问顺序,再依次获取每段路径的几何数据并拼接成完整路线。
步骤1:求解TSP最优访问顺序
使用TSP包计算最优访问序列(示例用最近邻算法,可替换为concorde等更精准的算法):
library(TSP) # 基于距离矩阵创建TSP对象 tsp <- TSP(distance_matrix) # 求解TSP,得到最优访问顺序 tsp_solution <- solve_TSP(tsp, method = "nn") # 转换为整数型的访问索引 order <- as.integer(tsp_solution) # 若不需要闭合回路(不回到起点),移除最后一个元素 # order <- order[-length(order)]
步骤2:拼接所有路径段的几何数据
循环遍历相邻节点对,调用osrmRoute获取路径并合并:
library(dplyr) library(osrm) # 初始化空数据框存储完整路线 full_route <- data.frame() for (k in 1:(length(order)-1)) { idx_from <- order[k] idx_to <- order[k+1] # 获取两点间的路径,指定返回sf格式便于处理 segment <- osrmRoute( src = c(data[idx_from,]$lng, data[idx_from,]$lat), dst = c(data[idx_to,]$lng, data[idx_to,]$lat), returnclass = "sf" ) # 计算累计距离和时长(可选,用于标注) segment$cumulative_dist <- round(cumsum(segment$distance)[nrow(segment)], 1) segment$cumulative_time <- round(cumsum(segment$duration)[nrow(segment)], 0) # 合并到完整路线 full_route <- bind_rows(full_route, segment) }
2. 用Leaflet展示完整最优路线
基于拼接好的full_route绘制完整路线,同时标记所有节点:
library(leaflet) leaflet(full_route) |> addTiles() |> # 绘制最优路线 addPolylines( color = "#e74c3c", weight = 4, opacity = 0.8, label = ~ sprintf("累计:%s km,%s 分钟", cumulative_dist, cumulative_time), labelOptions = labelOptions(noHide = FALSE, direction = "auto") ) |> # 添加节点标记 addMarkers( data = data[order,], lng = ~lng, lat = ~lat, label = ~paste0("节点 ", row.names(data[order,])) )
3. 保存路线数据
根据需求选择不同格式保存:
- 保存为CSV文件(适合R内后续分析):
write.csv(full_route, "tsp_optimal_route.csv", row.names = FALSE)
- 保存为GeoJSON/SHP格式(适合GIS软件导入):
library(sf) # 保存为GeoJSON st_write(full_route, "tsp_optimal_route.geojson", driver = "GeoJSON") # 保存为Shapefile st_write(full_route, "tsp_optimal_route.shp")
- 保存Leaflet地图为HTML文件(可直接打开查看):
library(htmlwidgets) # 先创建地图对象 tsp_map <- leaflet(full_route) |> addTiles() |> addPolylines(color = "#e74c3c", weight = 4) |> addMarkers(data = data[order,], lng = ~lng, lat = ~lat) # 保存为HTML saveWidget(tsp_map, "tsp_optimal_route_map.html", selfcontained = TRUE)
内容的提问来源于stack exchange,提问作者Gabriela Cvečková
相关产品推荐
相关产品推荐

