11

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.

jazzurro
  • 23,179
  • 35
  • 66
  • 76
Michał
  • 273
  • 1
  • 3
  • 13
  • Have you tried adding `+ coord_equal()` to the end of your map plot? – Phil May 21 '15 at 08:07
  • Yes, but I think that then it is not reliable in terms of distance – Michał May 21 '15 at 08:21
  • Plus the output is different e.g from the output obtained in this website: http://www.freemaptools.com/radius-around-point.htm – Michał May 21 '15 at 08:37
  • 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](http://gis.stackexchange.com/questions/8650/measuring-accuracy-of-latitude-and-longitude/8674#8674) you can generate a set of lat long pairs that should generate a circle at the given size regardless of zoom – Travis Gaddie Jan 24 '17 at 22:59

2 Answers2

1

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)
sebdalgarno
  • 2,929
  • 12
  • 28
0

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).

mitchus
  • 4,677
  • 3
  • 35
  • 70
  • 2
    Care to demonstrate what "accordingly" means in this case? – Roman Luštrik Sep 05 '15 at 10:42
  • Doesn't 'accordingly' just involve linking the circle size parameter to the variable that is getting dropped in? So for example, if your location lat and lon are 37.8 and 122.4 respectively, your corners for the delta.y might be 37.9[ur] - 37.7[ll] - but you will have to build the calculation on to your references to get the circles the size you want them for every coordinate you feed it. – leerssej Jun 15 '16 at 16:28