如何在R中免费计算英国邮政编码间的距离?
英国邮政编码间距离计算的免费R解决方案
直线距离:用PostcodeioR实现
PostcodeioR可调用英国皇家邮政的免费API获取邮编对应的经纬度,搭配geosphere包就能计算球面直线距离,全程无成本。
步骤如下:
- 安装并加载依赖包:
install.packages(c("PostcodeioR", "dplyr", "geosphere")) library(PostcodeioR) library(dplyr) library(geosphere)
- 编写工具函数获取邮编经纬度:
get_coords <- function(postcode) { res <- postcode_lookup(postcode) if (!is.null(res$latitude) && !is.null(res$longitude)) { return(c(lon = res$longitude, lat = res$latitude)) } else { return(c(lon = NA, lat = NA)) } }
- 批量计算直线距离:
df <- df %>% rowwise() %>% mutate( origin_coords = list(get_coords(origin)), dest_coords = list(get_coords(dest)), straight_dist_km = distHaversine(origin_coords, dest_coords) / 1000 ) %>% ungroup()
注意:PostcodeioR调用的免费API有请求频率限制,批量处理时建议加入短暂延迟避免被限流。
驾车距离:免费替代方案
免费获取驾车距离的选项有限,以下两个方案实用性最强:
1. OSRM包(基于OpenStreetMap)
osrm包调用开源路由服务OSRM,支持驾车路线距离计算,无需API密钥,完全免费:
install.packages("osrm") library(osrm) # 结合之前的get_coords函数获取驾车距离 get_drive_dist <- function(origin_pc, dest_pc) { origin <- get_coords(origin_pc) dest <- get_coords(dest_pc) if (!any(is.na(origin)) && !any(is.na(dest))) { route <- osrmRoute(src = origin, dst = dest, returnclass = "sf") return(route$distance) # 单位:公里 } else { return(NA) } } # 批量计算 df <- df %>% rowwise() %>% mutate(drive_dist_km = get_drive_dist(origin, dest)) %>% ungroup()
注意:公共OSRM服务器有请求上限,处理大量数据建议自行搭建私有OSRM服务。
2. Mapbox免费额度(小批量场景)
Mapbox每月提供10万次免费API请求,足够小批量数据的驾车距离计算:
install.packages(c("tidygeocoder", "httr")) library(tidygeocoder) library(httr) # 先通过OpenStreetMap获取经纬度 df <- df %>% geocode(origin, method = "osm", lat = origin_lat, long = origin_lon) %>% geocode(dest, method = "osm", lat = dest_lat, long = dest_lon) # 调用Mapbox Directions API get_mapbox_drive <- function(orig_lon, orig_lat, dest_lon, dest_lat, token) { req_url <- sprintf( "https://api.mapbox.com/directions/v5/mapbox/driving/%f,%f;%f,%f?access_token=%s", orig_lon, orig_lat, dest_lon, dest_lat, token ) resp <- GET(req_url) if (status_code(resp) == 200) { route_data <- content(resp) return(route_data$routes[[1]]$distance / 1000) # 转公里 } else { return(NA) } } # 替换为你的Mapbox免费Token(注册即可获取) mapbox_token <- "your_free_token_here" df <- df %>% rowwise() %>% mutate(drive_dist_km = get_mapbox_drive(origin_lon, origin_lat, dest_lon, dest_lat, mapbox_token)) %>% ungroup()
方案选择建议
- 要免费驾车距离优先选osrm包,无需额外配置,数据基于OpenStreetMap可靠;
- 仅需直线距离用PostcodeioR,零成本且简单;
- 小批量数据需要更精准的驾车路线时,用Mapbox免费额度。
内容的提问来源于stack exchange,提问作者mda08rds
相关产品推荐
相关产品推荐

