宁波一日游(调用高德开放平台)

本文通过R语言调用高德地图API,计算宁波主要景点之间的驾驶距离和时间,旨在找到游览宁波的最优顺序。首先获取各景点和起点的地理坐标,然后计算所有可能的行驶路线,最终找出驾驶时长最短和距离最短的旅游顺序。这种方法也可应用于解决如何在限定时间内游览最多景点以及选择最佳住宿地点的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

旅行中总有需要优化的地方

  1. 按照什么顺序游玩在路上乘车的时间最短?
  2. 如何在固定的时间时长内浏览最多的景点?
  3. 晚上在哪住宿比较合适?(如果要住宿)

本文使用R语言调用高德开放平台模拟各种方案给出一个解决方案。

获取高德开放平台调用权限

我的应用 | 高德控制台

登陆自己的高德账号,创建新应用(随意选择类型),添加新的服务(选择Web服务即可),添加完成即可获得自己的【key】,该【key】会在之后用到。

获取旅游景点地理坐标

简单罗列几个宁波主城区观赏游玩的景点:月湖公园(包括天一阁、鼓楼)、宁波博物馆、南塘老街、东钱湖、宁波老外滩、樱花公园。

获取景点对应的地理坐标,可使用两种方式,一种是在高德地图API逐个查找,优点是坐标不会出错(尤其是出现重名地点或者地图软件地名模糊查询查出多个地点的时候);另一种是直接调用API获得坐标,优点是快速(尤其在有大量地点需要查询的时候)。

本文使用后者来查询地址坐标。API参数可参考地理/逆地理编码-API文档

参考示例构建所需的API,默认返回的是JSON数据格式,可使用 jsonlite 包中的 fromJSON 函数获取。

library(tidyverse)
library(jsonlite) # fromJSON 用于获取JSON格式的数据
key <- your_key # 使用在前文提到的key
# 要游玩的景点(地点前加入宁波两个字可以提高准确性)
visit_address <- c("宁波天一阁", "宁波博物馆", "宁波南塘老街", "宁波东钱湖", "宁波老外滩", "宁波樱花公园")
# 出发地点
start_address <- c("宁波火车站")

# 获取地点对应坐标函数,输入地点向量,输出坐标向量
get_location <- function(address){
  location_vector <- vector(length = length(address), mode = "character")
  for (i in seq_along(address)) {
    url<- str_c("https://restapi.amap.com/v3/geocode/geo?key=", key, "&address=", address[i]) 
    location <- fromJSON(url) %>% 
      as.data.frame() %>% 
      select(geocodes.location)
    location_vector[i] <- location[1,1]
  }
  return(location_vector)
}

visit_location <- get_location(visit_address) # 旅游地点坐标
start_location <- get_location(start_address) # 开始地点坐标

计算两个位置之间的距离与各种交通方式所需的时间

参考路径规划-API文档-开发指南-Web服务 API | 高德地图API可以调用步行、公交、驾车等交通方式,本文使用驾驶这种交通方式。

dt_location <- data.frame(地点 = c(start_address, visit_address), 坐标 = c(start_location, visit_location))

addressA_to_B <- data.frame(出发点 = dt_location$地点, 结束点 = dt_location$地点) %>% 
  expand.grid() %>%
  left_join(dt_location, by=c("出发点" = "地点")) %>%
  rename(出发点坐标 = 坐标) %>%
  left_join(dt_location, by=c("结束点" = "地点")) %>% 
  rename(结束点坐标 = 坐标) %>%
  filter(出发点 != 结束点)

# 构建计算行车距离与行车时长的函数
get_distance_and_duration <- function(origin, destination){
  driving_distance <- vector(length = length(origin), mode = "numeric")
  driving_duration <- vector(length = length(origin), mode = "numeric")
  for(i in seq_along(origin)){
    url<- str_c("https://restapi.amap.com/v3/direction/driving?origin=", origin[i], "&destination=", destination[i], "&key=", key)
    driving_distance_and_duration <- fromJSON(url) %>% 
                   as.data.frame() %>% 
                   select(route.paths.distance, route.paths.duration)
    driving_distance[i] <- driving_distance_and_duration$route.paths.distance[1]
    driving_duration[i] <- driving_distance_and_duration$route.paths.duration[1]
  }
  return(data.frame(driving_distance, driving_duration))
}


distance_and_duration <- get_distance_and_duration(addressA_to_B$出发点坐标, addressA_to_B$结束点坐标)

addressA_to_B_mix <- bind_cols(addressA_to_B, distance_and_duration) %>%
  mutate(驾驶时长min = as.numeric(driving_duration)/60, 驾驶距离km = as.numeric(driving_distance)/1000) %>%
  select(-driving_duration, -driving_distance)

运行后得到出发点与结束点之间的驾驶时长与驾驶距离,在文中除了计算A点到B点的驾驶距离,也计算B点到A点的驾驶距离,为了避免出现单行道等来回线路不一致的情况。

模拟各种游玩顺序,评估时长

首先构建构建旅游顺序,以宁波火车站开始,旅游玩6个景点,最后回到宁波火车站。

visit_address_copy <- data.frame(visit_address)
for (i in 1:(length(visit_address)-1)) {
  visit_address_copy <- bind_cols(visit_address_copy, visit_address)
}
order_of_visit <- expand.grid(visit_address_copy)
names(order_of_visit) <- paste("地点", 1:ncol(order_of_visit), sep = "")

duplicate_address <- apply(order_of_visit, 1, function(x) max(table(x)))

order_of_visit$出发点 <- start_address
order_of_visit$终点 <- start_address
order_of_visit$最大重复 <- duplicate_address

order_of_visit <- order_of_visit %>% filter(最大重复 == 1) %>% select(出发点, everything(), -最大重复)

计算每种路线的驾驶时长与驾驶距离。

visit_address_copy <- data.frame(visit_address)
for (i in 1:(length(visit_address)-1)) {
  visit_address_copy <- bind_cols(visit_address_copy, visit_address)
}
order_of_visit <- expand.grid(visit_address_copy)
names(order_of_visit) <- paste("地点", 1:ncol(order_of_visit), sep = "")

duplicate_address <- apply(order_of_visit, 1, function(x) max(table(x)))

order_of_visit$出发点 <- start_address
order_of_visit$终点 <- start_address
order_of_visit$最大重复 <- duplicate_address

order_of_visit <- order_of_visit %>% filter(最大重复 == 1) %>% select(出发点, everything(), -最大重复)

all_distance_duration <- data.frame(驾驶时长min = rep(0, nrow(order_of_visit)), 驾驶距离km = rep(0, nrow(order_of_visit)))
for(i in 1:(ncol(order_of_visit)-1)){
  period_visit <- order_of_visit[,i:(i+1)]
  names(period_visit) <- c("出发点", "结束点")
  period_distance_duration <- period_visit %>% 
    left_join(addressA_to_B_mix, by = c("出发点", "结束点")) %>% 
    select(驾驶时长min, 驾驶距离km)
  all_distance_duration <- all_distance_duration + period_distance_duration
}

order_of_visit_distance_duration <- bind_cols(order_of_visit, all_distance_duration)

 最终结果,驾驶时长最短的是如下方案,总共驾驶时长2个小时不到一点。

驾驶路程最短的是如下方案。两者的前后顺序相反, 是由一些微小的道路差异引起。

问题解决

按照什么顺序游玩在路上乘车的时间最短?

方案:直接模仿上文可解决。

如何在固定的时间时长内浏览最多的景点?

方案:在上文基础上匹配上各个浏览景点的预计浏览时长,计算总时长后在限制时长内挑选想要的旅游顺序。若最短的时长仍然高于限制时长,去掉一个你相对不喜欢的景点后再进行测算。或者直接在代码中调整,在所有length(visit_address) 后多减1。

晚上在哪住宿比较合适?(如果要住宿)

方案:将出发点设置为住宿的地点即可,比较多个住宿点,选出旅游所有目标景点最短乘车时间中最短的住宿点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值