如何将terra包的SpatRaster对象转换为ggmap可用的底图
转换后全绿的根因
你之前转换的问题出在操作逻辑上:
maptiles::get_tiles()返回的是3层RGB结构的SpatRaster,每一层对应一个颜色通道的像素值(取值0-255)- 你用
raster::raster()转换时只会取SpatRaster的第一层数值,后续raster::as.raster()把这层数值按默认色板映射成图形,根本没有把三个颜色通道拼成真实的像素颜色,最后就出了全绿的渲染效果 - 手动写的bbox参数还容易因为边界值不准导致地图范围和实际错位
可直接复用的可靠转换流程
- 从SpatRaster提取RGB值生成像素颜色矩阵
# 读取栅格的全量像素值 rgb_layer_values <- terra::values(nc_osm) # 按照RGB三通道规则拼接为标准的十六进制颜色字符 pixel_color_vec <- rgb( rgb_layer_values[, 1], rgb_layer_values[, 2], rgb_layer_values[, 3], maxColorValue = 255 ) # 按照栅格的实际行列数重塑为矩阵结构 raster_color_mat <- matrix( pixel_color_vec, nrow = terra::nrow(nc_osm), ncol = terra::ncol(nc_osm), byrow = TRUE ) # 转换为R内置的raster栅格对象 ggmap_base <- as.raster(raster_color_mat) - 为对象附加ggmap要求的标准属性,直接从SpatRaster提取空间范围,不要手动填写数值
# 从原SpatRaster提取真实空间边界 raster_extent <- terra::ext(nc_osm) # 赋值ggmap要求的类标记与元数据 class(ggmap_base) <- c("ggmap", "raster") attr(ggmap_base, "bb") <- data.frame( ll.lat = raster_extent$ymin, ll.lon = raster_extent$xmin, ur.lat = raster_extent$ymax, ur.lon = raster_extent$xmax ) attr(ggmap_base, "source") <- "maptiles" - 直接调用
ggmap()即可正常加载底图,后续叠加sf格式的多边形要素时不会占用fill美学通道:ggmap(ggmap_base) + geom_sf(data = nc, inherit.aes = FALSE, aes(fill = AREA), alpha = 0.5)
简化操作方案
如果觉得手动写转换步骤繁琐,可以通过stars包做一步中转,最终渲染效果和手动转换完全一致:
ggmap_base <- stars::st_as_stars(nc_osm) %>% stars::merge() %>% as.raster() # 补充上面的bbox属性赋值步骤即可直接使用
注意:不推荐用SpatRaster转data.frame后用geom_tile()渲染的方案,这种方式既会占用fill美学通道,也会因为高分辨率栅格生成几十万行数据,大幅拖慢ggplot的渲染速度。
内容的提问来源于stack exchange,提问作者Oliver
相关产品推荐
相关产品推荐

