Para facilitar la reproducción de este ejercicio en sus propios equipos, puede descargar el siguiente script de R aquí.
En este bloque de código se realiza la configuración básica del
entorno de trabajo. Para ello se utiliza el paquete pacman
,
que permite cargar múltiples paquetes de forma eficiente. Si un paquete
no está instalado, pacman::p_load()
lo instala
automáticamente antes de cargarlo.
## llamar pacman
require(pacman)
## llamar y/o instalar librerias
p_load(tidyverse, ## tidy data
rio, ## leer/escribir conjuntos de datos
sf, ## datos espaciales
mapview, ## visualizaciones
tidygeocoder, ## geocodificar
ggspatial, ## mapas base en ggplot2 (tiles OSM, Stamen, Esri)
osmdata) ## packages osm data
Cada una de estas librerías cumple un rol importante en el flujo de trabajo para análisis espacial:
tidyverse
: Facilita la manipulación, exploración y
visualización de datos.
rio
: Permite importar/exportar archivos en múltiples
formatos (como .csv, .xlsx, .sav, entre otros).
sf
: Es el estándar actual para el manejo de datos
espaciales vectoriales en R.
mapview
: Herramienta práctica para visualizar
rápidamente objetos espaciales en mapas interactivos.
tidygeocoder
: Proporciona una interfaz sencilla para
convertir direcciones en coordenadas geográficas y viceversa.
ggspatial
: Extiende las capacidades de ggplot2 para
incluir mapas base (tiles) de proveedores como OpenStreetMap, Stamen y
Esri, a través de la función annotation_map_tile(). Ideal para crear
mapas estáticos de alta calidad y superponer objetos sf con contexto
geográfico.
osmdata
: Permite descargar datos vectoriales de
OpenStreetMap, como calles, ríos, edificios, entre otros elementos
geográficos.
Esta configuración inicial asegura que contamos con todas las herramientas necesarias para realizar análisis geoespaciales y geocodificación dentro de un entorno reproducible.
El paquete tidygeocoder
permite realizar procesos de
geocodificación (obtener coordenadas geográficas a partir de
direcciones) y geocodificación inversa (obtener direcciones a partir de
coordenadas) de forma sencilla y en formato tidy
, ideal
para trabajar con dplyr
y tidyverse.
.
Aunque su función más conocida es geocode()
, el paquete
incluye otras funciones como geo()
y
reverse_geocode()
, que permiten realizar tareas similares
con menor complejidad o desde coordenadas.
A continuación se presentan los principales motores de
geocodificación disponibles en tidygeocoder
, indicando si
requieren o no una clave API:
## Warning in attr(x, "align"): 'xfun::attr()' is deprecated.
## Use 'xfun::attr2()' instead.
## See help("Deprecated")
## Warning in attr(x, "format"): 'xfun::attr()' is deprecated.
## Use 'xfun::attr2()' instead.
## See help("Deprecated")
Metodo | Motor | Requiere.API.Key |
---|---|---|
osm | OpenStreetMap Nominatim | No |
arcgis | Esri ArcGIS | No |
Google Maps | Sí | |
census | US Census Bureau | No (solo EE.UU.) |
tomtom | TomTom | Sí |
bing | Microsoft Bing Maps | Sí |
La siguiente línea utiliza la función geo()
para obtener
las coordenadas (latitud y longitud) de una dirección específica. En
este caso se utiliza el motor arcgis (de Esri), que no requiere clave
API para este tipo de consultas. La función retorna un data.frame con
las columnas address, lat y long.
## obtener las coordenadas de una dirección
geo("Universidad Icesi, Cali, Colombia" , method="arcgis")
## # A tibble: 1 × 3
## address lat long
## <chr> <dbl> <dbl>
## 1 Universidad Icesi, Cali, Colombia 3.34 -76.5
geo
y sf
Aquí almacenamos el resultado de la geocodificación en un objeto llamado icesi, y verificamos su clase. Este objeto es inicialmente un data.frame, lo cual permite manipularlo fácilmente o convertirlo en otros formatos, como objetos espaciales.
## Almacenar la dirección en un objeto
icesi <- geo("Universidad Icesi, Cali, Colombia" , method="arcgis")
class(icesi)
## [1] "tbl_df" "tbl" "data.frame"
Para trabajar con datos espaciales en R es común utilizar el paquete
sf
, que proporciona una estructura de datos geoespaciales
moderna. Aquí usamos st_as_sf()
para convertir el
data.frame en un objeto espacial, indicando qué columnas contienen las
coordenadas (long y lat) y especificando el sistema de referencia
geográfica WGS 84 (crs = 4326
).
## Convertir el objeto a SF
icesi <- st_as_sf(x=icesi , coords=c("long","lat") , crs=4326)
icesi
## Simple feature collection with 1 feature and 1 field
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -76.5296 ymin: 3.34165 xmax: -76.5296 ymax: 3.34165
## Geodetic CRS: WGS 84
## # A tibble: 1 × 2
## address geometry
## * <chr> <POINT [°]>
## 1 Universidad Icesi, Cali, Colombia (-76.5296 3.34165)
Finalmente, usamos la función mapview()
para visualizar
el punto geocodificado en un mapa interactivo. mapview
es
una herramienta sencilla y potente para inspeccionar visualmente objetos
espaciales, añadiendo automáticamente una capa base de
OpenStreetMap
.
## la función mapview adiciona la capa de OpenStreetMap
mapview(icesi)
En esta sección se realiza la geocodificación masiva de un conjunto de direcciones almacenadas en una base de datos. Este procedimiento es útil cuando se dispone de varias ubicaciones (por ejemplo, instituciones, oficinas, puntos de interés) y se desea obtener sus coordenadas geográficas para posterior análisis o visualización.
Se utiliza la función import()
del paquete rio para leer
una base de datos en formato .rds
desde una URL. Esta base
contiene un vector de direcciones de instituciones o puntos de interés
en Cali, Colombia, en una columna llamada direccion.
## leer base de datos
cali <- import("https://eduard-martinez.github.io//workshop/gis_in_r/data/data_cali.rds")
## Warning: The `trust` argument of `import()` should be explicit for serialization formats
## as of rio 1.0.3.
## ℹ Missing `trust` will be set to FALSE by default for RDS in 2.0.0.
## ℹ The deprecated feature was likely used in the rio package.
## Please report the issue at <https://github.com/gesistsa/rio/issues>.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
cali
## id direccion
## 1 1 Cristo Rey, Cali, Colombia
## 2 2 Zoológico de Cali, Cali, Colombia
## 3 3 Museo La Tertulia, Cali, Colombia
## 4 4 Teatro Municipal Enrique Buenaventura, Cali, Colombia
## 5 5 Plaza de Cayzedo, Cali, Colombia
## 6 6 Cerro de las Tres Cruces, Cali, Colombia
## 7 7 Biblioteca Departamental Jorge Garcés Borrero, Cali, Colombia
## 8 8 Alcaldía de Santiago de Cali, Cali, Colombia
## 9 9 Gobernación del Valle del Cauca, Cali, Colombia
## 10 10 Centro Cultural de Cali, Cali, Colombia
Se utiliza la función geocode()
del paquete
tidygeocoder
para obtener las coordenadas (latitud y
longitud) asociadas a cada dirección en la columna direccion.cSe usa el
motor arcgis
, que no requiere clave API y ofrece buenos
resultados para direcciones en Colombia.
La función añade automáticamente dos columnas nuevas: lat y long.
cali <- geocode(cali , address="direccion" , method="arcgis")
cali
## # A tibble: 10 × 4
## id direccion lat long
## <int> <chr> <dbl> <dbl>
## 1 1 Cristo Rey, Cali, Colombia 3.44 -76.6
## 2 2 Zoológico de Cali, Cali, Colombia 3.42 -76.5
## 3 3 Museo La Tertulia, Cali, Colombia 3.45 -76.5
## 4 4 Teatro Municipal Enrique Buenaventura, Cali, Colombia 3.45 -76.5
## 5 5 Plaza de Cayzedo, Cali, Colombia 3.45 -76.5
## 6 6 Cerro de las Tres Cruces, Cali, Colombia 3.47 -76.5
## 7 7 Biblioteca Departamental Jorge Garcés Borrero, Cali, Colom… 3.44 -76.5
## 8 8 Alcaldía de Santiago de Cali, Cali, Colombia 3.45 -76.5
## 9 9 Gobernación del Valle del Cauca, Cali, Colombia 3.44 -76.5
## 10 10 Centro Cultural de Cali, Cali, Colombia 3.45 -76.5
El conjunto de datos cali se convierte en un objeto espacial de clase
sf utilizando st_as_sf()
, especificando que las columnas de
coordenadas son long (longitud) y lat (latitud), y asignando el sistema
de referencia geográfica WGS 84 (EPSG:4326), que es el estándar para
coordenadas GPS.
cali <- st_as_sf(x=cali , coords=c("long","lat") , crs=4326)
Finalmente, se visualiza el resultado en un mapa interactivo con
mapview()
, lo cual permite explorar visualmente la
distribución de los puntos sobre una capa base de OpenStreetMap.
mapview(cali)
OpenStreetMap (OSM) es un proyecto colaborativo de mapeo global y de acceso abierto, similar a una “Wikipedia de los mapas”. Fue creado con el objetivo de generar una base de datos geográficos libre y accesible para todos, y se construye con contribuciones de voluntarios que utilizan GPS, imágenes satelitales y otras fuentes abiertas.
OSM es gratuito y está licenciado bajo la Open Database License (ODbL), lo cual permite su uso, modificación y redistribución con algunas condiciones de atribución.
En R, el paquete osmdata
permite acceder directamente a
los datos de OSM mediante consultas a la API Overpass
, la
cual filtra y extrae información específica desde la base de datos
global.
Con osmdata
se pueden consultar objetos espaciales como
calles, hospitales, estaciones de buses, edificios, parques, ciclovías y
mucho más. La librería facilita descargar, transformar y visualizar
estos datos en estructuras compatibles con sf.
El proceso para descargar datos desde OSM con osmdata incluye 3 pasos fundamentales:
Antes de consultar OSM, es necesario definir una “bounding box” o caja de coordenadas que delimite la zona de interés. Se puede usar el nombre de una ciudad o país:
opq(bbox = getbb("Cali Colombia"))
## $bbox
## [1] "3.2734085,-76.7069442,3.548577,-76.4588983"
##
## $prefix
## [1] "[out:xml][timeout:25];\n(\n"
##
## $suffix
## [1] ");\n(._;>;);\nout body;"
##
## $features
## NULL
##
## $osm_types
## [1] "node" "way" "relation"
##
## attr(,"class")
## [1] "list" "overpass_query"
## attr(,"nodes_only")
## [1] FALSE
getbb()
obtiene automáticamente las coordenadas que
encierran el área especificada.
Se define el tipo de información que se desea descargar usando una combinación de key y value. Por ejemplo, para obtener restaurantes:
osm <- opq(bbox = getbb("Cali Colombia")) %>%
add_osm_feature(key = "amenity", value = "restaurant")
El objeto resultante es una consulta a la API de OSM que aún no se ha
ejecutado. Su clase es overpass_query.
Con osmdata_sf()
se ejecuta la consulta y se obtiene una
lista con objetos espaciales en formato sf
:
osm_sf <- osmdata_sf(osm)
Este objeto contiene elementos como:
osm_points
: objetos puntuales (coordenadas)
osm_lines
: líneas (como calles)
osm_polygons
: polígonos (como edificios o parques)
Por ejemplo, para obtener solo los puntos de tipo
restaurante
:
rest_cali <- osm_sf$osm_points %>% select(osm_id, name , amenity)
class(rest_cali)
## [1] "sf" "data.frame"
Y para visualizar el resultado de forma interactiva:
mapview(rest_cali, color = "red")
Esto genera un mapa con los puntos representando los restaurantes en
Calí, utilizando una base de OpenStreetMap. mapview
es muy
útil para inspecciones visuales rápidas durante la exploración y
validación de datos espaciales.
Este flujo permite enriquecer cualquier análisis espacial con datos
abiertos actualizados, sin necesidad de descargar archivos manualmente.
Además, la integración con sf
y mapview
permite realizar análisis y visualización directamente en R.
En este último ejemplo, se utiliza getbb()
para obtener
una geometría de tipo polígono correspondiente al barrio Granada en
Cali. En lugar de devolver solo una caja de coordenadas (bounding box),
aquí se indica que se desea una geometría de tipo sf_polygon. Esto
permite trabajar con unidades administrativas o barrios específicos de
manera más precisa.
granada <- getbb(place_name = "Granada, Cali",
featuretype = "boundary:administrative",
format_out = "sf_polygon")
mapview(granada)
El resultado es un objeto de clase sf que representa el límite administrativo del área consultada. Esto puede ser muy útil para delimitar zonas de interés antes de realizar consultas más específicas (por ejemplo, todos los parques, restaurantes u oficinas públicas dentro de Granada).
sf
La librería sf
(Simple Features) es el estándar moderno
para manejar datos espaciales vectoriales en R. Su integración con
dplyr
y su compatibilidad con otras librerías como
ggplot2
, mapview
o leaflet
la
convierten en una herramienta central para cualquier flujo de trabajo
geoespacial.
## Documentación extendida de sf
vignette("sf3") # Reading, writing and converting simple features
vignette("sf4") # Geometry operations
Una operación muy común en el análisis espacial es filtrar los
objetos que se encuentran dentro de una zona específica. En este caso,
se recorta el conjunto de restaurantes (rest_cali
) para
conservar únicamente aquellos que están dentro del barrio Granada,
utilizando la función st_crop()
:
rest_grana <- st_crop(x=rest_cali , y=granada , mask=T)
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries
x
: objeto espacial a recortar (Restaurantes).
y
: geometría de recorte (barrio Granada).
mask
= TRUE: garantiza que el resultado se recorta
exactamente al polígono.
Para verificar cuántos restaurantes hay antes y después del recorte:
nrow(rest_cali)
## [1] 655
nrow(rest_grana)
## [1] 48
Finalmente, se visualiza el resultado de forma interactiva:
mapview(granada , color="red") + mapview(rest_grana)
Otra operación fundamental es el cálculo de distancias entre objetos espaciales. En este caso, se calcula la distancia desde el punto icesi (previamente geocodificado) a cada uno de los puntos en el objeto cali (direcciones institucionales en Cali):
cali$dist <- st_distance(x=cali , y=icesi)
cali %>% head()
## Simple feature collection with 6 features and 3 fields
## Geometry type: POINT
## Dimension: XY
## Bounding box: xmin: -76.56479 ymin: 3.4151 xmax: -76.53246 ymax: 3.46732
## Geodetic CRS: WGS 84
## # A tibble: 6 × 4
## id direccion geometry dist[,1]
## <int> <chr> <POINT [°]> [m]
## 1 1 Cristo Rey, Cali, Colombia (-76.56479 3.435925) 11187.
## 2 2 Zoológico de Cali, Cali, Colombia (-76.53472 3.4151) 8187.
## 3 3 Museo La Tertulia, Cali, Colombia (-76.54514 3.45049) 12225.
## 4 4 Teatro Municipal Enrique Buenaventur… (-76.53585 3.449456) 12008.
## 5 5 Plaza de Cayzedo, Cali, Colombia (-76.53246 3.45176) 12248.
## 6 6 Cerro de las Tres Cruces, Cali, Colo… (-76.54619 3.46732) 14095.
cali$dist <- as.numeric(cali$dist)/1000
La función st_distance()
devuelve una matriz de
distancias geodésicas entre los elementos de dos objetos espaciales. En
este caso, se calcula la distancia entre cada punto de cali y el punto
único de icesi.
Dado que icesi contiene un solo punto, el resultado es una columna con una distancia por cada fila de cali. Es decir, se mide la distancia entre cada dirección en Cali y la Universidad Icesi.
Las distancias se expresan por defecto en metros, ya que el sistema de referencia espacial (crs) utilizado es WGS 84 (EPSG:4326). Este tipo de cálculo permite realizar análisis como encontrar la ubicación más cercana, establecer zonas de influencia o clasificar puntos por cercanía a un lugar de referencia.
El paquete ggplot2
, parte del ecosistema
tidyverse
, también permite trabajar con objetos espaciales
gracias a la función geom_sf()
. A diferencia de
mapview
, que es interactivo, ggplot2
permite
crear gráficos estáticos personalizables, ideales para informes,
artículos o publicaciones.
Este gráfico muestra todos los puntos del objeto espacial cali sin aplicar ninguna estética adicional. Es útil para una visualización rápida de la distribución espacial de los datos.
## basic plot
ggplot() + geom_sf(data=cali , size=3)
En este gráfico se utiliza la variable dist (distancia a Icesi) como estética para asignar color a los puntos. De esta forma, el color representa la proximidad de cada ubicación respecto a la Universidad Icesi. Esta técnica permite comunicar información cuantitativa a través de una representación espacial.
## plot variable
ggplot() + geom_sf(data=cali , aes(color=dist) , size=3)
Aquí se mejora la visualización anterior utilizando la paleta Viridis, que es perceptualmente uniforme y adecuada para personas con daltonismo. Se define también el tamaño de los puntos (size = 3) para darles mayor visibilidad. El uso de scale_color_viridis_b() permite crear una escala de color continua bien definida y estéticamente agradable para representar valores numéricos.
## plot variable + scale
map <- ggplot() +
geom_sf(data=cali , aes(color=dist) , size=3) +
scale_color_viridis_b(option = "D") +
theme_minimal()
map
Ahora, se incorpora un mapa base utilizando
annotation_map_tile()
del paquete ggspatial
,
que permite agregar mosaicos (tiles) provenientes de OpenStreetMap
(OSM), Carto, Stamen, entre otros. El parámetro zoom controla el nivel
de detalle (mayores valores → más zoom), y type = “osm” indica que se
desea usar OpenStreetMap como fondo.
## plot variable + scale
map <- ggplot() +
annotation_map_tile(type="osm" , zoom=14) +
geom_sf(data=cali , aes(color=dist) , size=3) +
scale_color_viridis_b(option = "D") +
theme_minimal()
map
Finalmente, se añaden dos elementos cartográficos importantes:
• Una flecha de norte, que orienta al lector respecto a la dirección geográfica.
• Una barra de escala, que indica la relación entre la distancia en el mapa y la distancia real.
Ambos elementos se agregan con funciones del paquete ggspatial y pueden personalizarse en estilo y ubicación.
map +
annotation_north_arrow(location="tr" , which_north="true" , style=north_arrow_fancy_orienteering) +
annotation_scale(location = "bl",width_hint = 0.4)
Lovelace, R., Nowosad, J., & Muenchow, J. (2019). Geocomputation with R. [Ver aquí]
Bivand, R. S., Pebesma, E. J., Gómez-Rubio, V., & Pebesma, E. J. (2013). Applied spatial data analysis with R. [Ver aquí]
Pebesma, E. (2018). Simple Features for R: Standardized Support for Spatial Vector Data. Ver artículo
Curso de Earth Data Science - University of Colorado. Ver curso