在 sf 对象下绘制静态底图
Posted
技术标签:
【中文标题】在 sf 对象下绘制静态底图【英文标题】:Plotting static base map underneath a sf object 【发布时间】:2018-09-12 13:16:36 【问题描述】:我正在尝试在我的sf
对象下方绘制静态底图(用于打印)。使用ggmap
时,我首先遇到很多错误,然后我似乎无法弄清楚如何使用geom_sf
将基本地图链接到我的ggplot2
对象。
library(sf)
# devtools::install_github("tidyverse/ggplot2")
library(ggplot2)
library(ggmap)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
nc_map <- get_map(location = "North Carolina, NC", zoom = 7)
ggmap(nc_map)
nc_centers <- st_centroid(nc)
nc_centers %>%
ggplot() +
geom_sf(aes(color = SID79, size = BIR74),
show.legend = "point") +
coord_sf(datum = NA) +
theme_minimal()
我也宁愿使用source = "osm"
作为样式,但那些总是返回'400 Bad Request'
。
是否还有其他适合底图的软件包?
【问题讨论】:
leaflet
是一个很好的软件包 imo - 不知道你是否能够用它完成任务。
leaflet
用于交互式地图,对吗?我正在寻找静态打印解决方案。
您可以使用mapview::mapshot
将传单地图保存为静态文件(jpeg、png 等)。也许这适合您的需求
【参考方案1】:
您可能会考虑重新投影您的数据,但以下代码似乎对我有用。
请参阅 here 了解您为什么需要 inherit.aes = FALSE
的解释,并参阅 here 了解带有基图的替代解决方案。
library(sf)
#> Linking to GEOS 3.5.1, GDAL 2.1.3, proj.4 4.9.2
# devtools::install_github("r-lib/rlang")
library(ggplot2)
library(ggmap)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
#> Reading layer `nc' from data source `/home/gilles/R/x86_64-pc-linux-gnu-library/3.4/sf/shape/nc.shp' using driver `ESRI Shapefile'
#> Simple feature collection with 100 features and 14 fields
#> geometry type: MULTIPOLYGON
#> dimension: XY
#> bbox: xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> epsg (SRID): 4267
#> proj4string: +proj=longlat +datum=NAD27 +no_defs
nc_map <- get_map(location = "North Carolina, NC", zoom = 7)
#> Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=North+Carolina,+NC&zoom=7&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false
#> Information from URL : http://maps.googleapis.com/maps/api/geocode/json?address=North%20Carolina,%20NC&sensor=false
nc_centers <- st_centroid(nc)
#> Warning in st_centroid.sfc(st_geometry(x), of_largest_polygon =
#> of_largest_polygon): st_centroid does not give correct centroids for
#> longitude/latitude data
ggmap(nc_map) +
geom_sf(data = nc_centers,
aes(color = SID79, size = BIR74),
show.legend = "point", inherit.aes = FALSE) +
coord_sf(datum = NA) +
theme_minimal()
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.
由reprex package (v0.2.0) 于 2018 年 4 月 3 日创建。
【讨论】:
@Gilles感谢您提供出色的解决方案。能否请您也添加文本注释?我试过 geom_sf_label () 但这个解决方案似乎失败了。【参考方案2】:您也可以使用包ggspatial
,它提供了“地图瓦片”注释层。
ggplot(nc_centers) +
annotation_map_tile(zoom = 7) +
geom_sf(aes(color = SID79, size = BIR74),
show.legend = "point", inherit.aes = FALSE) +
coord_sf(datum = NA) +
theme_minimal()
【讨论】:
【参考方案3】:我最近一直在研究package,有人可能会觉得它有用。 ggmap 答案现在需要一个 API 密钥才能与谷歌地图一起使用,这增加了一些额外的麻烦。
basemapR
还允许您通过使用边界框更灵活地设置底图的范围。
#devtools::install_github('Chrisjb/basemapR')
library(basemapR)
library(sf)
library(ggplot2)
nc <- st_read(system.file("shape/nc.shp", package="sf"))
nc_centers <- st_centroid(nc)
# create bbox from our nc layer and expand it to include more area above/below
bbox <- expand_bbox(st_bbox(nc_centers), X = 0, Y = 150000)
ggplot() +
base_map(bbox, increase_zoom = 2, basemap = 'google-terrain') +
geom_sf(data = nc_centers,
aes(color = SID79, size = BIR74),
show.legend = "point", inherit.aes = FALSE) +
coord_sf(datum = NA,
xlim = c(bbox['xmin'], bbox['xmax']),
ylim = c(bbox['ymin'], bbox['ymax'])) +
theme_minimal() +
labs(caption = 'map data \uA9 2020 Google')
记得在标题或地图其他地方引用谷歌地图
【讨论】:
以上是关于在 sf 对象下绘制静态底图的主要内容,如果未能解决你的问题,请参考以下文章