trazar puntos ggmap y sf
Estoy teniendo dificultades para trazar un basemap desde ggmap con puntos (objeto sf). La solución más prometedora que encontré es esta respuesta de SO de @andyteucher. Intenté reproducirla a continuación, pero no tengo mucha suerte. Consigo que se imprima el basemap pero no los puntos.
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"))
# Convert 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')
basemap3857 <- 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(basemap3857) +
coord_sf(crs = st_crs(3857)) +
geom_sf(data = points,
inherit.aes = FALSE)
davy.ai
El código mostrado intenta trazar un mapa base desde ggmap junto con puntos de un objeto sf. Los puntos no se están trazando, pero el mapa base sí lo está. El código incluye una función personalizada llamada
ggmap_bbox
, que corrige el cuadro delimitador para que esté en EPSG:3857.Hay algunos problemas en el código que podrían estar causando que los puntos no se tracen. En primer lugar, hay un error de escritura en el marco de datos
points
donde hay una coma final después del último valor en la última fila. Esto podría causar un error o un comportamiento inesperado. Eliminar la coma debería resolver este problema.Otro posible problema es que el objeto
points
no está proyectado en EPSG:3857 antes de ser trazado. La funciónggmap
espera que todas las capas estén en el mismo CRS, por lo que es importante asegurarse de que los puntos estén proyectados en el mismo CRS que el mapa base. Agregar la funciónst_transform
a la llamadast_as_sf
y transformar los puntos a EPSG:3857 debería resolver este problema.Aquí está el código corregido:
“`{r}
library(tidyverse)
library(sf)
library(ggmap)
Definir una función para corregir el cuadro delimitador a EPSG:3857
ggmap_bbox <- function(map) {
if (!inherits(map, “ggmap”)) stop(“map must be a ggmap object”)
# Extraer el cuadro delimitador (en lat/lon) del ggmap a un vector numérico,
# y establecer los nombres que espera sf::st_bbox:
map_bbox <- setNames(unlist(attr(map, “bb”)),
c(“ymin”, “xmin”, “ymax”, “xmax”))
# Convertir el cuadro delimitador en un polígono sf, transformarlo a 3857,
# y convertirlo de nuevo a un cuadro delimitador (complicado, pero funciona)
bbox_3857 <- st_bbox(st_transform(st_as_sfc(st_bbox(map_bbox))), 3857)
# Sobrescribir el cuadro delimitador del objeto ggmap con las coordenadas transformadas
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
}
se requiere una clave de API
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(“lon”, “lat”)) %>%
st_transform(3857)
ggmap(basemap_3857) +
coord_sf() +
geom_sf(data = points, inherit.aes = FALSE)
“`
En el código corregido, eliminé el argumento
crs
de la llamada ast_as_sf
ya que no era necesario. La funciónst_crs
extrae el CRS del objetobasemap_3857
y lo establece para el gráfico. La funciónst_transform
transforma los puntos a EPSG:3857 antes de trazarlos. El gráfico resultante debería mostrar tanto el mapa base como los puntos juntos.