ggmap in R - keep google copyright information on cropped map
Although seemingly simple, this is actually a quite complex issue. I did some research and found out that you can achieve this by tweaking both size
and scale
arguments. However, if you are using ggmap
v3.0.0 as I do, you will find that specifying non-square dimensions just gives you a "noisy image" as follows:
base_map <- ggmap::get_googlemap(center = c(lon= -2.325278, lat=54.6000000), zoom = 5, size = c(331, 367), style = 'element:labels|visibility:off', color= "bw")
ggmap(base_map, extent = "panel")
This involves a known bug in the ggmap
package. It has not yet been resolved. Although there exists a solution as mentioned here, that only partially solves the problem because the solution has failed for some cases mentioned in this post. Hence, I'd suggest rewriting that function to make it work in a robust way. Luckily, after investigating the source code, I found the problem not so hard to deal with. The problem results from some image-processing failure in the get_goolemap
function. Therefore, outsourcing the image processing in that function to a dedicated package is a simple workaround.
Consider this get_googlemap2
(to make it simple, I have ignored all those argument checkings in the original get_goolemap
, so be careful with your inputs)
require(RgoogleMaps)
require(httr)
require(magick)
require(urltools)
require(tibble)
get_googlemap2 <- function(
api_key = "Your API Key",
center = c(lon = -95.3632715, lat = 29.7632836),
zoom = 10, size = c(640, 640), scale = 2,
maptype = c("terrain", "satellite", "roadmap", "hybrid"),
grayscale = FALSE, style
) {
maptype <- match.arg(maptype)
params <- c(
center = paste0(center[c(2L, 1L)], collapse = ","),
zoom = zoom,
size = paste0(size, collapse = "x"),
scale = scale,
maptype = maptype,
style = style,
key = api_key
)
url <- "https://maps.googleapis.com/maps/api/staticmap"
urltools::parameters(url) <- paste(names(params), params, sep = "=", collapse = "&")
url <- URLencode(url)
message("Souce: ", url)
img <- magick::image_read(httr::content(httr::GET(url)))
if (grayscale) img <- magick::image_quantize(img, colorspace = "gray")
ll <- RgoogleMaps::XY2LatLon(
list(lat = center[2], lon = center[1], zoom = zoom),
-size[1]/2 + 0.5, -size[2]/2 - 0.5
)
ur <- RgoogleMaps::XY2LatLon(
list(lat = center[2], lon = center[1], zoom = zoom),
size[1]/2 + 0.5, size[2]/2 - 0.5
)
structure(
as.raster(img), class = c("ggmap", "raster"),
source = "google", maptype = maptype, zoom = zoom,
bb = tibble::tibble(ll.lat = ll[1], ll.lon = ll[2], ur.lat = ur[1], ur.lon = ur[2])
)
}
I tried some specifications of size
and scale
with this new function and found out that the following specifications render the best map possible.
base_map <- get_googlemap2(
"Your API Key",
center = c(lon = -2.325278, lat = 54.6000000), zoom = 5, size = c(330, 380), scale = 2, style = 'element:labels|visibility:off', grayscale = TRUE
)
ggmap(base_map, extent = "panel")
Output
I hope this is what you want. I call this the best-possible result because if you attempt to further narrow the width, for example, down to 250, the attribution text will overlap with the logo.
base_map <- get_googlemap2(
"Your API Key",
center = c(lon = -2.325278, lat = 54.6000000), zoom = 5, size = c(250, 380), scale = 2, style = 'element:labels|visibility:off', grayscale = TRUE
)
ggmap(base_map, extent = "panel")
As far as I can tell, this is Google's problem, not ggmap
's. I have no way to solve it. Another workaround would be removing the attribution text from the image but reintroducing it as plain text within the content, as mentioned in Google's attribution guidlines. However, as Google's logo still needs to be there, you then have to figure out how to paste that onto the map. IMO, using plain text gives you greater flexibility in page layouts, and thus might be a better way to go.
I used a lot ggmap, and this type of problem I could not solve then in an elegant way. But there is a way to achieve something like what you want (doing kind of manually). With geom_rect
making the lightbox, and with geom_text
writing the copyright information.
ggmap(base_map, extent = "panel")+
scale_x_continuous(limits = c(-7, 3), expand = c(0, 0)) +
scale_y_continuous(limits = c(49.5, 59), expand = c(0, 0)) +
geom_rect(ymin = 49.5,ymax = 49.7, fill = 'white', alpha = 0.1, xmin = -3.35, xmax = 3) +
geom_text(y = 49.6, x = -0.2, size = 2.5,
label = 'Map data ©2020 GeoBasis-DE/BKG (©2009), Google, Inst. Geogr Nacional')
ggsave('Map.jpg', width = 7, height = 9, units = 'in')
The size and limits of geom_rect
and geom_text
must be edited manually according to the size of the save file. In this example, I provide the ggsave
I used for it and plot in a nice way.