You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将terra包的SpatRaster对象转换为ggmap可用的底图

转换后全绿的根因

你之前转换的问题出在操作逻辑上:

  • maptiles::get_tiles()返回的是3层RGB结构的SpatRaster,每一层对应一个颜色通道的像素值(取值0-255)
  • 你用raster::raster()转换时只会取SpatRaster的第一层数值,后续raster::as.raster()把这层数值按默认色板映射成图形,根本没有把三个颜色通道拼成真实的像素颜色,最后就出了全绿的渲染效果
  • 手动写的bbox参数还容易因为边界值不准导致地图范围和实际错位
可直接复用的可靠转换流程
  1. 从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)
    
  2. 为对象附加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"
    
  3. 直接调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 10:36:04