[GIS] ggmap: create circle symbol where radius represents distance (miles or km)

ggmapr

I am trying to add a circle around a given latitude and longitude point where the circle size (radius) reflects distance in miles or km.

I managed to come up with this example using ggmap, where I can add a circle. but what do I need to do to have it represent distance. I would ultimately like the bounds of the circle to represent 20 miles from the center.

Code below:

library(ggmap)
library(ggplot2)

d <- data.frame(lat=c(33.79245),
                lon=c(-84.32130))

emory <- get_map("Atlanta,Georgia", zoom=12)

p <- ggmap(emory)
p <- p + geom_point(data=d, aes(x=lon, y=lat),
                    color="red", size=20, alpha=0.5)
p

Best Answer

The actual problem is to plot a circle with 40 miles in diameter on a map with a lat/lon projection (typically EPSG:4326), because native map units are degrees. Therefore, it seems to me the simplest solution is to work with a different projection that is based on meters (that can easily be converted to miles) rather than degrees.
As an alternative to get_map, you could work with gmap from the dismo package that also allows the retrieval of Google Maps data. I have to confess that get_map results in a higher spatial resolution and is easier to handle when working with ggplot, but for demonstration purposes, gmap should do the trick as well. Anyway, retrieving the data from Google Maps works quite similar...

# Google Map of Atlanta
library(dismo)

emory <- gmap("Atlanta,Georgia", zoom = 10, scale = 2)

Next, you should transform your central location into a true spatial object by defining coordinates and projection. For subsequent buffering and plotting purposes, you need to reproject it to the coordinate reference system (CRS) of the Google Maps 'RasterLayer' object.

d <- data.frame(lat = c(33.79245), lon = c(-84.32130))

coordinates(d) <- ~ lon + lat
projection(d) <- "+init=epsg:4326"

d_mrc <- spTransform(d, CRS = CRS(projection(emory)))

Now that you transformed your lat/lon location into Google's Mercator projection that comes in metres, you could define a little helper function that converts miles to meters (or you just use an online conversion tool). Based on the thus derived distance in metres, gBuffer from the rgeos package will create a circular-shaped 'SpatialPolygons' object .

# Miles to meters conversion
mile2meter <- function(x) {
  x * 1609.344
}

# Buffer creation
d_mrc_bff <- gBuffer(d_mrc, width = mile2meter(20))

Now that you have assembled everything you need, it's finally time for plotting.

library(scales) # for `alpha()` function

plot(emory)
plot(d_mrc_bff, col = alpha("blue", .35), add = TRUE)
points(d_mrc, cex = 2, pch = 20)

enter image description here