楚新元 | All in R

Welcome to R Square

用 R 调用高德地图实现路径规划

楚新元 / 2021-10-14


实现该功能需要先去高德开放平台注册后,创建应用添加key,然后在R工作目录下创建一个.Renviron文件,文件内容为key = '你的key'

# 编写一个根据起点、终点和出行方式生成地图的函数
route = function(start_point, end_point, by = "driving") {
  
  # 生成一个关于起点和终点的向量
  address = c(start_point, end_point)
  
  # 定义一个高德API Key
  key = Sys.getenv("key")
  
  # 将起点和终点转换为坐标形式
  df = data.frame()
  for (i in address) {
    url = paste0(
      'https://restapi.amap.com/v3/geocode/geo?key=', key, 
      '&address=', i
    ) 
    url |>
      xml2::read_html(encoding = 'utf-8') |>
      rvest::html_text() |>
      jsonlite::fromJSON() |> 
      as.data.frame(row.names = NULL) |> 
      dplyr::select(
        geocodes.city, 
        geocodes.location
      ) -> temp
    df = rbind(df, temp)
  }
  
  origin = df[1, "geocodes.location"]  # 起点坐标
  destination = df[2, "geocodes.location"]  # 终点坐标
  
  # 生成一个关于起点和终点的地址
  url = paste0(
    "https://restapi.amap.com/v3/direction/", by, 
    "?origin=", origin, 
    "&destination=", destination, 
    "&key=", key
  )
  
  # 解析地址并返回路程、耗时和关键点经纬度
  url |> 
    xml2::read_html(encoding = 'utf-8') |> 
    rvest::html_text() |> 
    jsonlite::fromJSON() -> routelist
  
  dist = routelist$route$paths$distance  # 距离(单位:米)
  duration = routelist$route$paths$duration  # 耗时(单位:秒)
  extra = data.frame(
    dist = round(as.numeric(dist) / 1000, 2), 
    duration = round(as.numeric(duration) / 60, 0)
  )
  if (by == "driving") {
    colnames(extra)[1] = "驾驶距离(单位:千米)"
  } else {
    colnames(extra)[1] = "步行距离(单位:千米)"
  }
  colnames(extra)[2] = "预计耗时(单位:分钟)"
  print(extra)
  
  routelist$route$paths$steps |>  
    as.data.frame() |> 
    dplyr::select(polyline) |>  
    tidytext::unnest_tokens(
      polyline, polyline, 
      token = stringr::str_split, 
      pattern = ";"
    ) |> 
    dplyr::distinct() |> 
    tidyr::separate(
      col = "polyline", 
      into = c("lon", "lat"), 
      sep = ","
    ) |> 
    dplyr::mutate(
      lon = as.double(lon),
      lat = as.double(lat)
    ) |>
    as.matrix() |> 
    sf::st_linestring() -> path
  
  # 根据关键点经纬度形成的path生成地图
  leaflet::leaflet(width = "100%", height = "400px") |>  
    leafletCN::amap() |> 
    leafem::addFeatures(data = path, color = "red", weight = 10) 

}

运行完上述函数后,会生成路程、用时和路径地图。下面我们来测试下该函数:

# 驾驶模式
route("乌鲁木齐市天山区政府", "新疆自治区博物馆", by = "driving")

# 步行模式
route("乌鲁木齐市天山区政府", "新疆自治区博物馆", by = "walking")