本文主要是介绍宁波一日游(调用高德开放平台),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
旅行中总有需要优化的地方
- 按照什么顺序游玩在路上乘车的时间最短?
- 如何在固定的时间时长内浏览最多的景点?
- 晚上在哪住宿比较合适?(如果要住宿)
本文使用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_addressorder_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_addressorder_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。
晚上在哪住宿比较合适?(如果要住宿)
方案:将出发点设置为住宿的地点即可,比较多个住宿点,选出旅游所有目标景点最短乘车时间中最短的住宿点。
这篇关于宁波一日游(调用高德开放平台)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!