2

I am trying to map data onto higher resolution Google satellite imagery. I could use a lower resolution image (e.g. zoom 13 and limit the scales - as suggested here - ggmap extended zoom or boundaries) however, the resultant image is not clear enough for my purpose. So basically I would like to be able to combine 2 14 zoom into 1 ggmap:

library(ggmap)
library(gridExtra)
g1 <- get_googlemap(center =  c(-83.986927, 33.955656), maptype="satellite", zoom=14)


g2 <- get_googlemap(center =  c(-83.938079, 33.955656), maptype="satellite", zoom=14)


gmap1 <- ggmap(g1)
gmap2 <- ggmap(g2)

grid.arrange(gmap1, gmap2, ncol =2)

but have 1 ggmap object that combined gmap1 and gmap2.

1 Answers1

3

You can (and probably should) convert to raster objects. You should really use them independently from then on, like tiles, since their pixels don't seem to be on the same grid basis so mosaicing them might not be perfect. You can bodge this by adjusting the tolerance.

The objects from get_googlemap are matrices with colour values in hex ("#FF000" etc) and some attributes defining the extent. The following code converts that object to a three-band RGB raster, with the right extent and CRS:

library(raster)

ggmap2raster <- function(g){
    rgb = col2rgb(g)
    bands = apply(rgb, 1, function(band){
        raster(t(matrix(band,ncol=ncol(g), nrow=nrow(g))))
    })
    s = stack(bands)
    bb = attr(g, "bb")
    extent(s) = extent(bb$ll.lon,bb$ur.lon, bb$ll.lat, bb$ur.lat)
    crs(s) <- "+init=epsg:4326"
    s
}

To merge a bunch of them, this code uses mosaic, but because the layers don't seem to line up quite right (possibly because the data are really in web mercator rather than WGS84) you need to up the tolerance and hope:

mergegg <- function(glist){
    m = function(...){
        mosaic(...,tolerance=0.5, fun=min)
    }
    do.call(m,
            lapply(glist, function(g){
                ggmap2raster(g)
            })
            )
}

> r = mergegg(list(g1, g2))
> plotRGB(r)

enter image description here

I suspect the tolerance problem may disappear if I convert the corner coords back to Web Mercator. But that's too much bother for a Friday morning. ggmap and its handling of coordinate systems is not something I want to get into right now. You could try binding the two g1 and g2 matrix objects together but you probably would have to do the reverse transform first and to be honest given the restrictions on using Google satellite images (you have read the license conditions?) I suspect its a bad thing.

To visualise raster objects, use the tmap package instead of ggmap.

Spacedman
  • 92,590
  • 12
  • 140
  • 224
  • Thanks for suggesting tmap! I did not know about that package. It looks so far to be a million times nicer than ggmap. Thanks! – James Thomas Durant Sep 29 '17 at 16:25
  • Just so you are aware, this is technically against the terms and conditions of the Google API. Check 10.5 Intellectual Property Restrictions, point b. https://developers.google.com/maps/terms#section_10. It might be worth updating the answer to make this clear. – Michael Harper Feb 25 '18 at 21:25