使用coord_sf与geom_spatraster导致栅格分辨率降低的解决方案
解决tidyterra+ggplot2绘制高分辨率栅格子区域并叠加WGS84矢量的问题
核心问题在于直接用lims+coord_sf(CRS=WGS84)会触发ggplot对整个大栅格做重采样,导致分辨率损失。正确思路是先在栅格原生CRS下裁剪出目标区域(保留原分辨率),再统一坐标系后叠加图层,具体步骤如下:
步骤1:将WGS84范围转换为栅格原生CRS并裁剪栅格
先把你用经纬度定义的目标范围(比如亚利桑那州)转换为栅格的原生坐标系,再用这个范围裁剪栅格,确保裁剪后的子栅格仍保持1km分辨率。
library(tidyterra) library(ggplot2) library(terra) library(sf) # 假设你的北美栅格对象为north_america_rast,先获取其原生CRS rast_crs <- crs(north_america_rast) # 定义亚利桑那州的WGS84经纬度范围,转换为栅格原生CRS az_wgs84_bbox <- st_bbox( c(xmin = -114, xmax = -109, ymin = 31, ymax = 37), crs = st_crs(4326) ) %>% st_as_sfc() %>% st_transform(rast_crs) # 裁剪栅格,保留原分辨率 az_rast <- crop(north_america_rast, az_wgs84_bbox)
步骤2:两种绘图方案(任选其一)
方案A:将裁剪后的栅格转换为WGS84,叠加WGS84矢量
适合需要最终图用WGS84经纬度显示的场景:
# 将子栅格转换为WGS84 az_rast_wgs84 <- project(az_rast, "EPSG:4326") # 加载你的WGS84矢量数据(比如州边界) az_boundary_wgs84 <- st_read("az_boundary.shp") # 假设矢量为WGS84 ggplot() + geom_spatraster(data = az_rast_wgs84) + # 高分辨率栅格 geom_sf(data = az_boundary_wgs84, color = "darkred", fill = NA, linewidth = 1) + coord_sf(crs = st_crs(4326)) + theme_minimal()
方案B:保持栅格原生CRS,转换矢量数据(更高效)
避免栅格重采样,适合处理超大型栅格的场景,同时可以通过工具让坐标轴显示经纬度:
# 将WGS84矢量转换为栅格原生CRS az_boundary_native <- st_transform(az_boundary_wgs84, rast_crs) ggplot() + geom_spatraster(data = az_rast) + # 原生分辨率栅格,无需转换 geom_sf(data = az_boundary_native, color = "darkred", fill = NA, linewidth = 1) + coord_sf(crs = rast_crs) + # 可选:添加比例尺和指北针,让图更直观 ggspatial::annotation_scale(location = "bottomleft") + ggspatial::annotation_north_arrow(location = "topright") + theme_minimal()
关键说明
- 直接用
lims裁剪的本质是先对全栅格重采样适配WGS84视图,再截取范围,必然丢失分辨率;而先裁剪再转换是在原生分辨率下操作,完全保留1km细节。 - 若需要更精确的裁剪(比如按州边界而非矩形框),可以用
terra::mask(az_rast, az_boundary_native)替代crop。
内容的提问来源于stack exchange,提问作者Eonema
相关产品推荐
相关产品推荐

