Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cache maps using ggmap

I'm plotting maps using the ggmap package. To download a map over the internet, I can use this code:

library(ggmap)
get_map(location = c(-1.81, 55.655), zoom = 12, maptype = "hybrid")

Is there a way to avoid downloading maps over the internet, and instead import a .png file from a local folder? Or in other words, download maps once, cache the .png and thereafter import the .png from a local folder? My connection is rather slow, I constantly redownloading the same base map is wasting valuable time.

like image 408
luciano Avatar asked May 29 '14 13:05

luciano


2 Answers

As get_map returns an R object, you can save that to disk and reuse later if you wish:

> x <- get_map(location = c(-1.81, 55.655), zoom = 12, maptype = "hybrid")
Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=55.655,-1.81&zoom=12&size=%20640x640&scale=%202&maptype=hybrid&sensor=false
Google Maps API Terms of Service : http://developers.google.com/maps/terms
> str(x)
 chr [1:1280, 1:1280] "#122C38" "#122C38" "#122C38" "#122C38" ...
 - attr(*, "class")= chr [1:2] "ggmap" "raster"
 - attr(*, "bb")='data.frame':  1 obs. of  4 variables:
  ..$ ll.lat: num 55.6
  ..$ ll.lon: num -1.92
  ..$ ur.lat: num 55.7
  ..$ ur.lon: num -1.7

So simply write x to your disk with saveRDS, and load that via readRDS even from another R session. POC demo:

> t <- tempfile()
> saveRDS(x, file = t)
> x <- readRDS(t)
> ggmap(x)
like image 114
daroczig Avatar answered Oct 02 '22 14:10

daroczig


In the 2+ years that have passed since the question was asked, new releases of ggmap have come out. The package now directly supports caching of downloads. However, when caching Google Maps, there are some conditions one should be aware of; a link to the terms of service appears when ggmap is attached.

The general get_map function doesn't have an option for saving the downloaded Google Map tiles, but it can be done with the dedicated get_googlemap function, by setting archiving = TRUE. The manual has a note about the user having to accept the Google Maps terms of service (ToS) in this case (too). In my view, the most obvious limitation in the ToS (September 21, 2015) is that the map content must not be stored for more than 30 days. If you accept that, the following code should work.

library(ggmap)
## get_map() as in the question
foo1 <- get_map(location = c(-1.81, 55.655), zoom = 12, maptype = "hybrid")

## This will store map tiles locally, used by any repeated calls
foo2 <- get_googlemap(center = c(-1.81, 55.655), zoom = 12,
                      maptype = "hybrid", archiving = TRUE, force = FALSE)

identical(foo1, foo2) # TRUE

Other map sources may have more permissive terms or licenses. For example, to use Stamen Maps:

## Get roughly the same area as in the Google map
bbox <- c(left=-1.88, bottom=55.625, right=-1.74, top=55.685)
## Broken in ggmap 2.6.1, try GitHub version (which may have other problems)
foo3 <- get_map(location = bbox, zoom = 13, crop = FALSE,
                source = "stamen", maptype = "terrain", force = FALSE)

## Compare the two map sources / types
dev.new()
print(ggmap(foo2))
dev.new()
print(ggmap(foo3))
like image 45
mvkorpel Avatar answered Oct 02 '22 13:10

mvkorpel