基于R语言使用OSM可视化CN塔与多伦多机场驾车路径问题
优化OSM地图细节并生成多伦多两点间驾车路径解决方案
一、优化地图细节的核心调整
你的代码存在两个关键问题:一是错误将waterway、natural这类非道路特征放到highway的value参数中,导致无法正确获取这类要素;二是所有道路用同一样式渲染,缺乏层次。以下是修正方案:
关键调整点
- 拆分要素获取:分别获取道路、建筑、水体、绿地等不同类型的OSM数据
- 道路分层渲染:根据道路等级(motorway/primary/residential等)设置不同的颜色和线宽,提升可读性
- 扩展边界范围:适当放大bbox,避免地图内容过于拥挤
优化后的地图绘制代码
library(ggplot2) library(sf) library(osmdata) # 修正坐标:CN Tower(-79.38705, 43.64257),多伦多皮尔逊机场(-79.62683, 43.67772) pt1 <- st_point(c(-79.38705, 43.64257)) # CN Tower 正确坐标 pt2 <- st_point(c(-79.62683, 43.67772)) # Toronto Airport pts <- st_sfc(pt1, pt2, crs = 4326) # 适当扩展边界,避免内容拥挤 bbox <- st_bbox(pts) bbox_expanded <- bbox + c(-0.05, -0.03, 0.05, 0.03) # 上下左右各扩展一段距离 # 获取不同类型的OSM数据 # 道路数据:按等级分类 osm_motorway <- opq(bbox = bbox_expanded) %>% add_osm_feature(key = 'highway', value = 'motorway') %>% osmdata_sf() osm_primary <- opq(bbox = bbox_expanded) %>% add_osm_feature(key = 'highway', value = 'primary') %>% osmdata_sf() osm_secondary <- opq(bbox = bbox_expanded) %>% add_osm_feature(key = 'highway', value = 'secondary') %>% osmdata_sf() osm_residential <- opq(bbox = bbox_expanded) %>% add_osm_feature(key = 'highway', value = 'residential') %>% osmdata_sf() # 其他地理要素 osm_buildings <- opq(bbox = bbox_expanded) %>% add_osm_feature(key = 'building') %>% osmdata_sf() osm_water <- opq(bbox = bbox_expanded) %>% add_osm_feature(key = 'natural', value = 'water') %>% osmdata_sf() osm_green <- opq(bbox = bbox_expanded) %>% add_osm_feature(key = 'landuse', value = 'grass') %>% osmdata_sf() # 分层绘制地图 ggplot() + # 基础层:绿地和水体 geom_sf(data = osm_green$osm_polygons, fill = '#e6f7e6') + geom_sf(data = osm_water$osm_polygons, fill = '#cceeff') + # 建筑层 geom_sf(data = osm_buildings$osm_polygons, fill = '#cccccc', alpha = 0.7) + # 道路层:从高等级到低等级叠加 geom_sf(data = osm_motorway$osm_lines, color = '#0066cc', size = 1.2) + geom_sf(data = osm_primary$osm_lines, color = '#3399ff', size = 0.8) + geom_sf(data = osm_secondary$osm_lines, color = '#66b3ff', size = 0.6) + geom_sf(data = osm_residential$osm_lines, color = '#999999', size = 0.4) + # 标记起点终点 geom_sf(data = pts, color = '#ff3333', size = 4, shape = 18) + # 设置坐标范围 coord_sf(xlim = c(bbox_expanded$xmin, bbox_expanded$xmax), ylim = c(bbox_expanded$ymin, bbox_expanded$ymax), crs = 4326) + theme_minimal() + theme(panel.grid = element_blank())
二、生成两点间驾车路径
使用osrm包可以直接基于OSM数据计算驾车最短路径,步骤如下:
注意事项
- 需要先安装
osrm包,该包依赖OSRM后端服务,默认使用公共API - 确保坐标为WGS84(EPSG:4326)格式
完整路径生成与叠加代码
# 安装并加载osrm包(首次使用需要安装) # install.packages("osrm") library(osrm) # 转换起点终点为sf数据框 pts_df <- st_sf(id = c(1,2), geometry = pts) # 获取驾车路径 route <- osrmRoute(src = pts_df[1,], dst = pts_df[2,], overview = "full", returnclass = "sf") # 在优化后的地图上叠加路径 ggplot() + geom_sf(data = osm_green$osm_polygons, fill = '#e6f7e6') + geom_sf(data = osm_water$osm_polygons, fill = '#cceeff') + geom_sf(data = osm_buildings$osm_polygons, fill = '#cccccc', alpha = 0.7) + geom_sf(data = osm_motorway$osm_lines, color = '#0066cc', size = 1.2) + geom_sf(data = osm_primary$osm_lines, color = '#3399ff', size = 0.8) + geom_sf(data = osm_secondary$osm_lines, color = '#66b3ff', size = 0.6) + geom_sf(data = osm_residential$osm_lines, color = '#999999', size = 0.4) + # 叠加驾车路径(红色粗线) geom_sf(data = route, color = '#ff0000', size = 1.5, alpha = 0.8) + geom_sf(data = pts, color = '#ff3333', size = 4, shape = 18) + coord_sf(xlim = c(bbox_expanded$xmin, bbox_expanded$xmax), ylim = c(bbox_expanded$ymin, bbox_expanded$ymax), crs = 4326) + theme_minimal() + theme(panel.grid = element_blank())
内容的提问来源于stack exchange,提问作者stats_noob
相关产品推荐
相关产品推荐

