es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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) 
Tags:  , ,

Answer

  1. Avatar for 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ón ggmap 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ón st_transform a la llamada st_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 a st_as_sf ya que no era necesario. La función st_crs extrae el CRS del objeto basemap_3857 y lo establece para el gráfico. La función st_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.

Comments are closed.