我想在放置在谷歌底图上的 geom_sf 多边形图层上使用自定义符号和注释。最初,我很难正确排列底图和多边形
所以我使用了这个 Stack Overflow 解决方案来修复它。现在底图和多边形图层对齐
但我想要使用 geom_image 的自定义符号和使用 annotate 的标签。具有自定义符号的未修改底图和注记图层有效
下面我扩展了 andyteucher 和 user1453488 的代码,并添加了我想使用的 geom_image 和 annotate 函数。
我通过使用 sf 包进行绘图尝试了替代解决方案,但我无法弄清楚如何在具有纬度和经度的绘图上使用自定义符号。我的实际数据有纬度和经度。尽管我更熟悉 ggmap,但我对替代解决方案持开放态度。
您知道如何将谷歌底图、具有精确投影的多边形图层、自定义符号(从具有地理坐标的数据框生成)和标签放在同一张地图上吗?谢谢你。
# code modified and expanded from andyteucher's solution
library(ggplot2)
library(ggmap)
library(sf)
library(ggimage)
#load shapefile with sf package
nc <- st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
# Transform nc to EPSG 3857 (Pseudo-Mercator, what Google uses)
nc_3857 <- st_transform(nc, 3857)
map <- get_map("north carolina", maptype = "satellite", zoom = 6, source = "google")
# display misaligned polygon with basemap
a <- unlist(attr(map,"bb")[1, ])
bb <- st_bbox(nc)
ggplot() +
annotation_raster(map, xmin = a[2], xmax = a[4], ymin = a[1], ymax = a[3]) +
xlim(c(bb[1], bb[3])) + ylim(c(bb[2], bb[4])) +
geom_sf(data = nc, aes(fill = AREA))
# Define a function to fix the bbox to be in EPSG:3857
ggmap_bbox <- function(map) {
if (!inherits(map, "ggmap")) stop("map must be a ggmap object")
# Extract the bounding box (in lat/lon) from the ggmap to a numeric vector,
# and set the names to what sf::st_bbox expects:
map_bbox <- setNames(unlist(attr(map, "bb")),
c("ymin", "xmin", "ymax", "xmax"))
# Coonvert the bbox to an sf polygon, transform it to 3857,
# and convert back to a bbox (convoluted, but it works)
bbox_3857 <- st_bbox(st_transform(st_as_sfc(st_bbox(map_bbox, crs = 4326)), 3857))
# Overwrite the bbox of the ggmap object with the transformed coordinates
attr(map, "bb")$ll.lat <- bbox_3857["ymin"]
attr(map, "bb")$ll.lon <- bbox_3857["xmin"]
attr(map, "bb")$ur.lat <- bbox_3857["ymax"]
attr(map, "bb")$ur.lon <- bbox_3857["xmax"]
map
}
# Use the function:
mapModified <- ggmap_bbox(map)
# display aligned polygon with basemap
ggmap(mapModified) +
coord_sf(crs = st_crs(3857)) + # force the ggplot2 map to be in 3857
geom_sf(data = nc_3857, aes(fill = AREA), inherit.aes = FALSE)
# create simple data frame for labels and symbols
name <- c("Point1", "Point2")
x <- c(-82, -78)
y <- c(35, 36)
symbol <- c("https://www.r-project.org/logo/Rlogo.png",
"https://jeroenooms.github.io/images/frink.png")
df <- data.frame(name, x, y, name, symbol)
# example symbols and label on basemap (but polygon layer misaligned)
ggplot() +
annotation_raster(map, xmin = a[2], xmax = a[4], ymin = a[1], ymax = a[3]) +
xlim(c(bb[1], bb[3])) + ylim(c(bb[2], bb[4])) +
geom_sf(data = nc, aes(fill = AREA)) +
annotate("text", -80, 36.5, label = "My text here") +
geom_image(aes(x, y, image = symbol))
# after the polygons are aligned the geom_image no longer displays
ggmap(mapModified) +
coord_sf(crs = st_crs(3857)) + # force the ggplot2 map to be in 3857
geom_sf(data = nc_3857, aes(fill = AREA), inherit.aes = FALSE) +
geom_image(aes(x, y, image = symbol))
# after the polygons are aligned the annotate is dropped from display
ggmap(mapModified) +
coord_sf(crs = st_crs(3857)) + # force the ggplot2 map to be in 3857
geom_sf(data = nc_3857, aes(fill = AREA), inherit.aes = FALSE) +
annotate("text", -80, 36.5, label = "My text here")