You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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á

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 06:23:15