在RStudio中使用HERE API获取加拿大路线时单条结果全NA求助
问题描述
在RStudio中调用HERE API计算加拿大境内驾车路线,代码如下:
# Packages library("sf") library("tidyverse") library("hereR") library("stringi") library("dplyr") # Load data distancePairs <- structure(list(Origin = c("Saskatoon", "St. John's"), Lat1 = c(52.1583630506965, 47.5535718086621), Lon1 = c(-106.671978365698, -52.7486803304426 ), Destination = c("St. John's", "Calgary"), Lat2 = c(47.5535718086621, 51.0452926068494), Lon2 = c(-52.7486803304426, -114.05905562721 ), id = c(17, 18), straight.distance.meters = structure(c(3808910.50512732, 4332741.9186734), units = structure(list(numerator = "m", denominator = character(0)), class = "symbolic_units"), class = "units")), row.names = c(NA, -2L), class = c("tbl_df", "tbl", "data.frame")) # Set API key set_key(api_key = "YOUR_FREEMIUN_KEY") # Create SFDFs (points with lat-lon pairs): dist.pairs.input.1 <- dist.pairs.query %>% st_as_sf(coords = c("Lon1","Lat1"), crs = "WGS84", remove = F) dist.pairs.input.2 <- dist.pairs.query %>% st_as_sf(coords = c("Lon2", "Lat2"), crs = "WGS84", remove = F) #Calculate drive time&distance: query_result <- route(origin = dist.pairs.input.1, destination = dist.pairs.input.2, traffic = T) result_summary <- query_result %>% group_by(id) %>% summarise(new_shp = st_combine(.), departure = first(departure), arrival = last(arrival), type = mode(type), mode = mode(mode), distance_km = sum(distance)/1000, duration_min = sum(duration)/60) distancePairs$id <- 1:2 result_output<- merge(result_summary, dist.pairs.query, by = "id", all = TRUE)
运行后出现异常:第一行(萨斯卡通→圣约翰斯)返回完整的路线几何(MULTILINESTRINGZ)、距离和时长信息,但第二行(圣约翰斯→卡尔加里)所有字段为NA,几何对象显示为GEOMETRYCOLLECTION Z EMPTY。
原因分析
- 变量名引用错误:代码中加载的数据集是
distancePairs,但后续创建SF对象和合并结果时误用了未定义的dist.pairs.query,导致第二组坐标未正确传入API。 - 跨大陆路线的渡轮限制:圣约翰斯位于纽芬兰岛,到加拿大本土需乘坐渡轮,HERE API默认驾车路线不包含渡轮,无法直接计算跨岛的完整驾车路线。
- 长路线API限制:跨大陆超长路线可能触发API单次请求的计算阈值,或因实时流量数据覆盖不全导致请求失败。
- 批量请求容错机制:
hereR的route()函数批量处理时,单个请求失败会返回NA而非中断,导致第二行结果缺失。
修复方案
1. 修正变量名错误
统一使用加载的数据集名称distancePairs,替换所有误用的dist.pairs.query:
# 修正SF对象创建代码 dist.pairs.input.1 <- distancePairs %>% st_as_sf(coords = c("Lon1","Lat1"), crs = "WGS84", remove = F) dist.pairs.input.2 <- distancePairs %>% st_as_sf(coords = c("Lon2", "Lat2"), crs = "WGS84", remove = F) # 修正结果合并代码 result_output<- merge(result_summary, distancePairs, by = "id", all = TRUE)
2. 启用渡轮支持并调整请求参数
显式允许渡轮路线,同时关闭实时流量(长路线流量数据覆盖有限):
query_result <- route(origin = dist.pairs.input.1, destination = dist.pairs.input.2, traffic = FALSE, transport_mode = "car", routing_mode = "fast", allow_ferries = TRUE)
3. 拆分长路线并逐对处理
若跨大陆路线仍无法计算,将其拆分为两段(如圣约翰斯→哈利法克斯、哈利法克斯→卡尔加里),逐对请求后合并结果:
# 逐对处理路线请求,添加错误捕获 route_results <- map2(dist.pairs.input.1$geometry, dist.pairs.input.2$geometry, function(orig, dest) { tryCatch({ route(origin = orig, destination = dest, traffic = FALSE, allow_ferries = TRUE) }, error = function(e) { message(paste("路线计算失败:", dist.pairs.input.1$Origin[which(dist.pairs.input.1$geometry == orig)], "→", dist.pairs.input.2$Destination[which(dist.pairs.input.2$geometry == dest)])) return(NULL) }) }) # 合并有效结果 query_result <- bind_rows(route_results)
4. 检查API配额与权限
确认HERE API密钥拥有路线计算服务权限,且剩余配额充足——超长路线计算会消耗更多配额,若配额不足会导致请求被限制。
内容的提问来源于stack exchange,提问作者MelaniaCB
相关产品推荐
相关产品推荐

