11
votes

Let's assume I generate a map of London using ggmap package:

library(ggmap)
library(mapproj)

map <- get_map(location = "London", zoom = 11, maptype = "satellite")

p <- ggmap(map)+ 
     theme(legend.position = "none") 

print(p)

Now I would like to add to this plot a circle with some center coordinates(let's say: lon=-0.1, lat=52.23) and radius expressed e.g. in kilometers. I tried to use a solution from similar question(Draw a circle with ggplot2), where you can just add to the function a statement like this:

p <- p + annotate("path",
                  x = xc+r*cos(seq(0,2*pi,length.out=100)),
                  y = yc+r*sin(seq(0,2*pi,length.out=100)))

It works but the circle is not really a circle due to the different scale. Is it possible to draw it correctly? Any help would be appreciated!

EDIT: I found solution (https://gis.stackexchange.com/questions/119736/ggmap-create-circle-symbol-where-radius-represents-distance-miles-or-km) that uses different package and the output is correct. Nevertheless, if anyone knows how to do it using ggmap please share it.

2
Have you tried adding + coord_equal() to the end of your map plot?Phil
Yes, but I think that then it is not reliable in terms of distanceMichał
Plus the output is different e.g from the output obtained in this website: freemaptools.com/radius-around-point.htmMichał
the biggest problem I see with your code for creating the circle is that your center is in lat,long pairs and not distance pairs in a given mile or km pair... if you use this post link you can generate a set of lat long pairs that should generate a circle at the given size regardless of zoomTravis Gaddie

2 Answers

1
votes

Here is a solution using the sf package and ggplot::geom_sf. First, create a point from coordinates and transform to London's UTM zone (30u) with EPSG 32630 so that distance can be determined:

# dev version of ggplot2 required
library(sf)
library(ggplot2)

sf_pt <- st_point(c(-0.1, 52.23)) %>% 
  st_sfc(crs = 4326) %>%
  st_transform(32630)

then add a buffer

sf_pt %<>% st_buffer(100)

now transform back to epsg:4326 (lat/lon WGS84) and plot with ggmap

p <- ggmap(map) +
  geom_sf(data = sf_pt %>% st_transform(4326)) +
  theme(legend.position = "none") 

print(p)
0
votes

You can get the longitude and latitude span from the map object:

> m = get_map(location="london", zoom=11, maptype="satellite")
> corners = attributes(m)$bb
> delta.x = corners["ur.lon"] - corners["ll.lon"]
> delta.y = corners["ur.lat"] - corners["ll.lat"]

Then adjust your path accordingly. Notice also that the ggmap package has a function called LonLat2XY (see reference).