将 ggmap crs 与 geom_sf 对齐并使用 coord_sf 应用地图限制时出现问题

Posted

技术标签:

【中文标题】将 ggmap crs 与 geom_sf 对齐并使用 coord_sf 应用地图限制时出现问题【英文标题】:Problems aligning ggmap crs with geom_sf and applying map limits using coord_sf 【发布时间】:2021-12-07 17:06:03 【问题描述】:

我正在尝试创建一个在顶部绘制空间数据的地图。我正在使用 ggmap 跟踪示例,然后使用 geom_sf 添加新西兰海岸线。我有两个问题:

    map_data(nz) 的投影与 ggmap 的投影不匹配,因此海岸线未与地图对齐,即使两者都在 WGS84 经纬度。 当我尝试将 coord_sf(xlim, ylim) 应用于绘图时,出现 st_cast.POINT 错误:

恐怕reprex 需要一个谷歌密钥。 this post doesn't work for me中的方法

library(sf)
library(dplyr)
library(ggmap)

nz <- map_data("nz") %>%
  st_as_sf(coords = c("long", "lat"), remove = FALSE, crs = st_crs(4326)) %>%
  group_by(group) %>%
  summarise(
    region = region[1],
    do_union = FALSE
  ) %>%
  st_cast("LINESTRING") %>%
  ungroup()

gkey <- readLines("sjrw_google_key.dat")
register_google(key = gkey)
basemap <- get_map(location = c(lon = 175.5, lat = -38),
                   zoom = 8,
                   maptype = 'terrain-background',
                   source = 'stamen')

attr(basemap, "bb")
#>           ll.lat   ll.lon  ur.lat   ur.lon
#> bottom -39.37417 173.7449 -36.604 177.2606

ggmap(basemap) +
  geom_sf(data = nz, inherit.aes = FALSE) +
  coord_sf(crs = st_crs(4326)) +
  coord_sf(xlim = c(174.5, 176.5), ylim = c(-39.2, -36.6))
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
# Error in st_cast.POINT(x[[1]], to, ...) : 
#  cannot create MULTILINESTRING from POINT

由reprex package (v2.0.1) 于 2021 年 10 月 21 日创建

【问题讨论】:

看起来您正在使用st_as_sf(coords = c("long", "lat"), remove = FALSE, crs = st_crs(4326)) 执行坐标转换,您对CRS 4326 坐标系绝对肯定吗?这里的问题可能是稍微不同的坐标系? 您是否 100% 确定这两个图层确实对齐?显然,理论上新西兰的海岸线应该与陆地区域的轮廓相匹配,但看起来您正在从不同的来源检索海岸线和陆地区域。如果不运行您的示例,我想知道它们是否只是不同的分辨率/质量数据,实际上无论如何都不能完全对齐(黑线在您的地图中看起来很粗糙)。也许您可以分享一个指向您正在使用的示例的链接? 谢谢。一切都在 reprex 中。 根据警告消息,我会尝试将两条 coord_sf() 行合并为开始 - 听起来第一条无论如何都被第二条取代了。我通过“分享您的示例”在想什么 - 您所遵循的示例是否显示底图和海岸线相互匹配?你是从哪里来的例子? 好的,那么代码是生成示例中的图像还是返回错误?如果它产生图像,那就太好了。如果您想将图像完全裁剪到您提供的限制,请将expand = FALSE 添加到coord_sf(),否则它将添加一个小缓冲区。见ggplot2.tidyverse.org/reference/ggsf.html。我不知道数据是否都需要相同的crs,但是您可以尝试在ggplot()之外设置nz的crs,然后再进行绘制? 【参考方案1】:

这有点棘手,因为我无法在没有 API 的情况下重新创建示例。我自己不使用ggmap,所以我不确定,但听起来coord_sf()(或它的限制)不喜欢ggmap

您如何准确地通过在获取底图时提供限制来检索要绘制的区域,例如在此示例中R: cropping/zooming a map

或者这个例子描述了下载特定区域作为底图https://gis.stackexchange.com/questions/155334/ggmap-clip-a-map

此外,coord_sf() 不应有两行单独的行;第二个将覆盖第一个,您也可能没有第一个。可能是因为 crs 被覆盖/忽略,限制与数据坐标不匹配?将这些组合成一行,看看会发生什么。或者,不要将 crs 设置在 coord_sf() 中;尝试在 geom_sf() 中改用 data = nz %&gt;% st_transform(4326)

【讨论】:

以上是关于将 ggmap crs 与 geom_sf 对齐并使用 coord_sf 应用地图限制时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

图例标题对齐 (ggmap)

在 sf 对象下绘制静态底图

使用 ggmap 和 ggplotly

在 ggplot/ggmap 中绘制多个数据框并创建统一图例的问题

在 R 中是不是可以在 ggplot + geom_sf 图表中包含组定义的圆圈?

ggmap 与 geom_map 叠加