在R中利用道路网络文件计算两点驾驶距离及数据导入优化
基于加拿大统计局道路网络文件的驾驶距离计算与局部数据导入
一、能否用该shapefile计算驾驶距离?
可以实现,需完成以下关键步骤:
构建道路拓扑网络
原始shapefile是道路线段集合,需转换为带通行权重的拓扑网络(包含节点、边及驾驶成本)。推荐用dodgr包(专为道路网络最短路径优化设计),或igraph配合sf包处理。需注意利用数据中的道路长度、单行道标识(若有)等字段设置边的权重。地址转地理坐标
若输入是文字地址,需先转换为经纬度坐标。可使用tidygeocoder包调用OpenStreetMap免费地理编码服务,或借助加拿大统计局的地址匹配工具(有本地数据时优先)。坐标匹配到道路节点
地址坐标通常不在道路节点上,需将其匹配到最近的道路节点。dodgr::dodgr_points_to_network或stplanr::find_network_nodes可完成此操作,确保起点终点处于网络拓扑内。计算最短驾驶距离
通过dodgr_distances(基于dodgr网络)或igraph::shortest.paths计算两点间最短路径距离,结果默认单位为米,可转换为公里。
二、能否仅导入部分区域的数据?
完全可以,两种高效实现方法:
方法1:读取时直接过滤(推荐)
加拿大统计局的道路shapefile通常包含区域编码字段(如PRUID表示省份,安大略省编码为35;CMAPUID表示都会区,多伦多编码为535)。读取时通过SQL查询过滤,避免加载整个大文件:
library(sf) # 仅加载安大略省的道路数据 roads_on <- st_read("path/to/your/road_file.shp", query = "SELECT * FROM road_file WHERE PRUID = '35'")
方法2:读取后裁剪到目标区域
若需要更精细的范围(如多伦多市),先获取目标区域的官方边界(可通过cancensus包获取加拿大统计局的边界数据),再用空间交集裁剪:
library(cancensus) # 获取多伦多都会区边界 toronto_boundary <- get_census(dataset = "CA16", regions = list(CMA = "535"), level = "CMA", geo_format = "sf") # 裁剪道路数据到多伦多范围 roads_toronto <- st_intersection(roads_on, toronto_boundary)
完整示例代码
# 加载依赖包 library(sf) library(dodgr) library(tidygeocoder) # 1. 加载安大略省道路数据 roads <- st_read("path/to/road_shapefile.shp", query = "SELECT * FROM road_shapefile WHERE PRUID = '35'") # 2. 构建驾驶权重网络 net <- weight_streetnet(roads, wt_profile = "motorcar") # 3. 地址转坐标 addresses <- tibble( address = c("290 Bremner Blvd, Toronto, ON M5V 3L9", "6301 Silver Dart Dr, Mississauga, ON L5P 1B2") ) coords <- addresses %>% geocode(address = address, method = "osm") %>% select(lon, lat) # 4. 匹配坐标到网络节点 points <- dodgr_points_to_network(net, coords) # 5. 计算驾驶距离(转换为公里) distance_km <- dodgr_distances(net, from = points$from_id, to = points$to_id) / 1000 cat("驾驶距离:", round(distance_km, 2), "公里\n")
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

