我正在使用 ggmap
在 map 上绘制 geom
s:
Lat = 47.617736
Lon = -122.334244
map1 <- get_map(location = c(lon = Lon, lat = Lat), zoom = 12)
map2 <- get.googlemap.with.style(center=c(lon = Lon, lat = Lat), zoom=12, scale = 2, size = c(640, 640), maptype = "roadmap", color = "color", format = "png8", style = Style1)
ggmap(map1) +
geom_point()
使用 Google map api 的样式参数,我可以下载第二张 map map2,其中只有同一地区的街道和水景。
Style1 <- paste("visibility:off",
"&style=feature:road|element:geometry.fill|visibility:on|color:0x7f8080",
"&style=feature:water|element:geometry.fill|visibility:on|color:0x41567d", sep="")
map2 <- get.googlemap.with.style(center=c(lon = Lon, lat = Lat), zoom=12, scale = 2, size = c(640, 640), maptype = "roadmap", color = "color", format = "png8", style = Style1)
我希望能够像这样在
geom
之上将 map2 分层:ggmap(map1) +
geom_point() +
map2, alpha = 0.5
这个想法是在
geom
s 下方有一个 basemap ,然后能够在 geom
s(点、stat_密度、hex_bin 等)之上渲染道路和水景。我看不到将
ggmapraster
(来自 get_map
)转换为数据帧以启用基于 geom_map
的解决方案的可行方法。使用 inset_raster
,我可以在 map1 和 geom
s 之上绘制 map2 ,但似乎没有办法设置 alpha
级别,以便 map2 不会不透明地掩盖 geom
s 和 map1。我是否遗漏了一个明显的特征,或者是否有一个简单的解决方案可以在同一个图中将两张 map 分层?
根据 DWin 的评论,为了获得 map2,我需要修改 get_map 以便它接受 Google 的样式参数。下面是支持调用上面获取 map2 的代码。
get.googlemap.with.style <- function (center = c(lon = -95.3632715, lat = 29.7632836), zoom = 10, size = c(640, 640), scale = 2,
format = c("png8", "gif", "jpg", "jpg-baseline", "png32"),
maptype = c("terrain", "satellite", "roadmap", "hybrid"), language = "en-EN",
region, markers, path, visible, style, sensor = FALSE, messaging = FALSE,
urlonly = FALSE, filename = "ggmapTemp", color = c("color", "bw"), ...)
{
args <- as.list(match.call(expand.dots = TRUE)[-1])
argsgiven <- names(args)
if ("center" %in% argsgiven) {
if (!((is.numeric(center) && length(center) == 2) ||
(is.character(center) && length(center) == 1))) {
stop("center of map misspecified, see ?get_googlemap.",
call. = F)
}
if (all(is.numeric(center))) {
lon <- center[1]
lat <- center[2]
if (lon < -180 || lon > 180) {
stop("longitude of center must be between -180 and 180 degrees.",
" note ggmap uses lon/lat, not lat/lon.", call. = F)
}
if (lat < -90 || lat > 90) {
stop("latitude of center must be between -90 and 90 degrees.",
" note ggmap uses lon/lat, not lat/lon.", call. = F)
}
}
}
if ("zoom" %in% argsgiven) {
if (!(is.numeric(zoom) && zoom == round(zoom) && zoom >
0)) {
stop("zoom must be a whole number between 1 and 21",
call. = F)
}
}
if ("size" %in% argsgiven) {
stopifnot(all(is.numeric(size)) && all(size == round(size)) &&
all(size > 0))
}
if ("scale" %in% argsgiven) {
stopifnot(scale %in% c(1, 2, 4))
}
if ("markers" %in% argsgiven) {
markers_stop <- TRUE
if (is.data.frame(markers) && all(apply(markers[, 1:2],
2, is.numeric)))
markers_stop <- FALSE
if (class(markers) == "list" && all(sapply(markers, function(elem) {
is.data.frame(elem) && all(apply(elem[, 1:2], 2,
is.numeric))
})))
markers_stop <- FALSE
if (is.character(markers) && length(markers) == 1)
markers_stop <- FALSE
if (markers_stop)
stop("improper marker specification, see ?get_googlemap.",
call. = F)
}
if ("path" %in% argsgiven) {
path_stop <- TRUE
if (is.data.frame(path) && all(apply(path[, 1:2], 2,
is.numeric)))
path_stop <- FALSE
if (class(path) == "list" && all(sapply(path, function(elem) {
is.data.frame(elem) && all(apply(elem[, 1:2], 2,
is.numeric))
})))
path_stop <- FALSE
if (is.character(path) && length(path) == 1)
path_stop <- FALSE
if (path_stop)
stop("improper path specification, see ?get_googlemap.",
call. = F)
}
if ("visible" %in% argsgiven) {
message("visible argument untested.")
visible_stop <- TRUE
if (is.data.frame(visible) && all(apply(visible[, 1:2],
2, is.numeric)))
visible_stop <- FALSE
if (is.character(visible))
visible_stop <- FALSE
if (visible_stop)
stop("improper visible specification, see ?get_googlemap.",
call. = F)
}
if ("style" %in% argsgiven) {
style_stop <- TRUE
if (is.character(style) && length(style) == 1)
style_stop <- FALSE
if (style_stop)
stop("improper style specification, see ?get_googlemap.",
call. = F)
}
if ("sensor" %in% argsgiven)
stopifnot(is.logical(sensor))
if ("messaging" %in% argsgiven)
stopifnot(is.logical(messaging))
if ("urlonly" %in% argsgiven)
stopifnot(is.logical(urlonly))
if ("filename" %in% argsgiven) {
filename_stop <- TRUE
if (is.character(filename) && length(filename) == 1)
filename_stop <- FALSE
if (filename_stop)
stop("improper filename specification, see ?get_googlemap.",
call. = F)
}
if ("checkargs" %in% argsgiven) {
.Deprecated(msg = "checkargs argument deprecated, args are always checked after v2.1.")
}
format <- match.arg(format)
if (format != "png8")
stop("currently only the png format is supported.", call. = F)
maptype <- match.arg(maptype)
color <- match.arg(color)
if (!missing(markers) && class(markers) == "list")
markers <- plyr:::list_to_dataframe(markers)
if (!missing(path) && is.data.frame(path))
path <- list(path)
base_url <- "http://maps.googleapis.com/maps/api/staticmap?"
center_url <- if (all(is.numeric(center))) {
center <- round(center, digits = 6)
lon <- center[1]
lat <- center[2]
paste("center=", paste(lat, lon, sep = ","), sep = "")
}
else {
centerPlus <- gsub(" ", "+", center)
paste("center=", centerPlus, sep = "")
}
zoom_url <- paste("zoom=", zoom, sep = "")
size_url <- paste("size=", paste(size, collapse = "x"), sep = "")
scale_url <- if (!missing(scale)) {
paste("scale=", scale, sep = "")
}
else {
""
}
format_url <- if (!missing(format) && format != "png8") {
paste("format=", format, sep = "")
}
else {
""
}
maptype_url <- paste("maptype=", maptype, sep = "")
language_url <- if (!missing(language)) {
paste("language=", language, sep = "")
}
else {
""
}
region_url <- if (!missing(region)) {
paste("region=", region, sep = "")
}
else {
""
}
markers_url <- if (!missing(markers)) {
if (is.data.frame(markers)) {
paste("markers=", paste(apply(markers, 1, function(v) paste(rev(round(v,
6)), collapse = ",")), collapse = "|"), sep = "")
}
else {
paste("markers=", markers, sep = "")
}
}
else {
""
}
path_url <- if (!missing(path)) {
if (is.list(path)) {
ps <- sapply(path, function(one_path) {
paste("path=", paste(apply(one_path, 1, function(v) paste(rev(round(v,
6)), collapse = ",")), collapse = "|"), sep = "")
})
paste(ps, collapse = "&", sep = "")
}
else {
paste("path=", path, sep = "")
}
}
else {
""
}
visible_url <- if (!missing(visible)) {
if (is.data.frame(visible)) {
paste("visible=", paste(apply(visible, 1, function(v) paste(rev(round(v,
6)), collapse = ",")), collapse = "|"), sep = "")
}
else {
paste("visible=", paste(visible, collapse = "|"),
sep = "")
}
}
else {
""
}
style_url <- if (!missing(style)) {
paste("style=", style, sep = "")
}
else {
""
}
sensor_url <- paste("sensor=", tolower(as.character(sensor)),
sep = "")
post_url <- paste(center_url, zoom_url, size_url, scale_url,
format_url, maptype_url, language_url, region_url, markers_url,
path_url, visible_url, style_url, sensor_url, sep = "&")
url <- paste(base_url, post_url, sep = "")
url <- gsub("[&]+", "&", url)
if (substr(url, nchar(url), nchar(url)) == "&") {
url <- substr(url, 1, nchar(url) - 1)
}
url <- URLencode(url)
if (urlonly)
return(url)
if (nchar(url) > 2048)
stop("max url length is 2048 characters.", call. = FALSE)
destfile <- if (format %in% c("png8", "png32")) {
paste(filename, "png", sep = ".")
}
else if (format %in% c("jpg", "jpg-baseline")) {
paste(filename, "jpg", sep = ".")
}
else {
paste(filename, "gif", sep = ".")
}
download.file(url, destfile = destfile, quiet = !messaging,
mode = "wb")
print(url)
map <- readPNG(destfile)
if (color == "color") {
map <- apply(map, 2, rgb)
}
else if (color == "bw") {
mapd <- dim(map)
map <- gray(0.3 * map[, , 1] + 0.59 * map[, , 2] + 0.11 *
map[, , 3])
dim(map) <- mapd[1:2]
}
class(map) <- c("ggmap", "raster")
if (is.character(center))
center <- as.numeric(geocode(center))
ll <- XY2LatLon(list(lat = center[2], lon = center[1], zoom = zoom),
-size[1]/2 + 0.5, -size[2]/2 - 0.5)
ur <- XY2LatLon(list(lat = center[2], lon = center[1], zoom = zoom),
size[1]/2 + 0.5, size[2]/2 - 0.5)
attr(map, "bb") <- data.frame(ll.lat = ll[1], ll.lon = ll[2],
ur.lat = ur[1], ur.lon = ur[2])
t(map)
}
最佳答案
使用 ggmap 版本 2.0 inset_ggmap() 完全解决了原始问题:
require(ggmap)
map.background <- get_map(c(lon = -122, lat = 47.5), map = "toner-background")
map.lines <- get_map(c(lon = -122, lat = 47.5), map = "toner-lines")
map.labels <- get_map(c(lon = -122, lat = 47.5), map = "toner-labels")
set.seed(127)
df <- data.frame(lon = rnorm(25, mean = -122.2, sd = 0.2),
lat = rnorm(25, mean = 47.5, sd = 0.1),
size = rnorm(25, mean = 15, sd = 5))
ggmap(map.background) +
geom_point(data = df,
aes(x = lon, y = lat, size = size),
color = "blue", alpha = 0.8) +
scale_size_identity(guide = "none") +
inset_ggmap(map.lines) +
inset_ggmap(map.labels)
关于r - 使用ggplot的ggmap函数将两张 map 相互叠加,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19307896/