1

I'm struggling to plot a basemap from ggmap with points (sf object). The most promising solution I came across is this SO answer from @andyteucher. I tried to reproduce it below, but I'm not having much luck. I get the basemap to print but not the points.

library(tidyverse)
library(sf)
library(ggmap)

# Define a function to fix the bbox to be in EPSG:3857
# https://stackoverflow.com/a/50844502/841405
  ggmap_bbox <- function(map) {
    if (!inherits(map, "ggmap")) stop("map must be a ggmap object")
    # Extract the bounding box (in lat/lon) from the ggmap to a numeric vector, 
    # and set the names to what sf::st_bbox expects:
    map_bbox <- setNames(unlist(attr(map, "bb")), 
                         c("ymin", "xmin", "ymax", "xmax"))
    
    # Coonvert the bbox to an sf polygon, transform it to 3857, 
    # and convert back to a bbox (convoluted, but it works)
    bbox_3857 <- st_bbox(st_transform(st_as_sfc(st_bbox(map_bbox, crs = 4326)), 3857))
    
    # Overwrite the bbox of the ggmap object with the transformed coordinates 
    attr(map, "bb")$ll.lat <- bbox_3857["ymin"]
    attr(map, "bb")$ll.lon <- bbox_3857["xmin"]
    attr(map, "bb")$ur.lat <- bbox_3857["ymax"]
    attr(map, "bb")$ur.lon <- bbox_3857["xmax"]
    map
  }
# requires API key
  basemap <- get_map(location=c(lon = 75.85199398072335, 
                                lat = 22.7176905515565), 
                     zoom=9, maptype = 'toner-hybrid', 
                     source = 'google')


  basemap_3857 <- ggmap_bbox(basemap)

  points <- tribble(
    ~name, ~lat, ~lon,
    "test1", 22.7176905515565, 75.85199398072335,
    "test2", 22.71802612842761, 75.84848927237663,
  ) %>%
    st_as_sf(coords = c("lat", "lon"),
             crs = 3857)

  ggmap(basemap_3857) + 
    coord_sf(crs = st_crs(3857)) + 
    geom_sf(data = points, 
            inherit.aes = FALSE) 
Eric Green
  • 7,385
  • 11
  • 56
  • 102
  • Hello @Eric Green. I don't use ggmap, so hard to help you. That said, it seems to me that there is a small error in your code. It seems to me that `coords = c("lat", "lon")` should be `coords = c("lon", "lat")`. Hope this helps. Cheers. – lovalery Dec 13 '21 at 17:15
  • Thanks @lovalery. It doesn't fix my initial problem, unfortunately. – Eric Green Dec 13 '21 at 17:42
  • It was just an attempt without much conviction ;-) Unfortunately I am not able to help you better as I am not a specialist of ggmap. Good luck! – lovalery Dec 13 '21 at 18:10

1 Answers1

2

I believe you had an issue with your coordinate reference systems - you seem to have used degrees in context of CRS 3857, which is defined in meters (and so several degrees of magnitude off...)

If my hunch is correct you need to first declare your sf object to be in 4326 (WGS84 = the CRS of GPS coordinates) and then - and only then - apply transformation to 3857 (from a known start).

Does this code and map fit your expectations? (I also cleaned up the get_map call somewhat, as it had mixed Google and Stamen terms; no big deal there)

# requires API key
basemap <- get_map(location=c(lon = 75.85199398072335, 
                              lat = 22.7176905515565), 
                   zoom=9, 
                   source = 'google')


basemap_3857 <- ggmap_bbox(basemap)

points <- tribble(
  ~name, ~lat, ~lon,
  "test1", 22.7176905515565, 75.85199398072335,
  "test2", 22.71802612842761, 75.84848927237663,
) %>%
  st_as_sf(coords = c("lon", "lat"),
           crs = 4326) %>% # this is important! first declare wgs84
  st_transform(3857) # and then transform to web mercator 

ggmap(basemap_3857) + 
  geom_sf(data = points,
          color = "red",
          inherit.aes = F) 

indore with red points

Jindra Lacko
  • 7,814
  • 3
  • 22
  • 44
  • 1
    Forever until the end of time I will be wrong about crs and transformations – Eric Green Dec 14 '21 at 13:27
  • 4
    @EricGreen :D it is a easy topic to be wrong about - I have developed a deep & intimate relationship with the gulf of Aden, which is where my usual area of interest (the Czech Republic) appears when rotated by 90° (= lat lon swapped). Happens to me about half of the time, i.e. entirely at random – Jindra Lacko Dec 14 '21 at 13:30