install.packages("mapSpain", dependencies = TRUE)
8 Operaciones geométricas
8.1 Introducción
Como ya comentamos en el anterior bloque, la librería sf
(Pebesma, 2018, 2022) es una de las más utilizadas para el manejo, análisis y visualización de datos geoespaciales. Proporciona funciones para manipular geometrías espaciales, realizar operaciones geométricas y trabajar con sistemas de coordenadas, entre otras capacidades. En este apartado, veremos algunas de las funciones más comunes relacionadas con operaciones geométricas.
En esta práctica usaremos la librería mapSpain
(Hernangómez, 2025) para obtener los límites de España por provincias y comunidades autónomas. Para su correcto funcionamiento, el autor recomienda instalar el paquete con dependencias:
Cargamos librerías:
library(tidyverse)
library(sf)
library(mapSpain)
Cargamos cartografía:
<- mapSpain::esp_get_ccaa()
spain_ccaa <- mapSpain::esp_get_prov(moveCAN = F)
spain_prov <- mapSpain::esp_get_munic()
spain_mun <- mapSpain::esp_get_can_box() box_can
8.1.1 st_geometry()
Esta función extrae o establece la geometría de un objeto sf
o sfc
(ya lo vimos en la práctica anterior).
class(spain_ccaa)
[1] "sf" "data.frame"
head(spain_ccaa,10)
<- st_geometry(spain_ccaa)
geometria class(geometria)
[1] "sfc_MULTIPOLYGON" "sfc"
head(geometria)
Geometry set for 6 features
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -13.21924 ymin: 34.70209 xmax: 4.320511 ymax: 43.65841
Geodetic CRS: ETRS89
First 5 geometries:
MULTIPOLYGON (((-4.275964 38.34999, -4.287161 3...
MULTIPOLYGON (((-0.74093 42.91957, -0.754975 42...
MULTIPOLYGON (((-4.536122 43.40053, -4.54544 43...
MULTIPOLYGON (((4.095952 40.08266, 4.091628 40....
MULTIPOLYGON (((-8.504825 36.09995, -8.487927 3...
ggplot() +
geom_sf(data = spain_ccaa) +
geom_sf(data = box_can, color = "grey50")
8.1.2 st_area()
Esta función calcula el área de cada elemento de un objeto sf
o sfc
.
<- spain_ccaa %>% filter(ine.ccaa.name=="Comunitat Valenciana")
gva ggplot() + geom_sf(data=gva)
<- sf::st_area(gva)
area_gva area_gva
23239151639 [m^2]
class(area_gva)
[1] "units"
::set_units(area_gva, km^2) units
23239.15 [km^2]
<- as.numeric(area_gva)
area_gva_num area_gva_num
[1] 23239151639
class(area_gva_num)
[1] "numeric"
8.1.3 st_length()
Esta función calcula la longitud de cada elemento de un objeto sf
o sfc
.
<- mapSpain::esp_get_rivers()
rios as.character(unique(sf::st_geometry_type(rios)))
[1] "LINESTRING"
head(rios,10)
ggplot() +
geom_sf(data = spain_prov) +
geom_sf(data = rios, color="blue")
<- rios %>% filter(rotulo == "Río Turia")
turia ggplot() +
geom_sf(data=turia)
::st_length(turia) sf
Units: [m]
[1] 84185.014 9715.642
::set_units(sf::st_length(turia),km) units
Units: [km]
[1] 84.185014 9.715642
<- st_geometry(turia[1,])
geom_turia1 class(geom_turia1)
[1] "sfc_LINESTRING" "sfc"
nrow(st_coordinates(geom_turia1))
[1] 83
<- st_coordinates(geom_turia1)[1,]
p1 class(p1)
[1] "numeric"
<- st_point(p1)
p1 class(p1)
[1] "XYZ" "POINT" "sfg"
<- st_sfc(p1, crs=st_crs(turia))
p1 class(p1)
[1] "sfc_POINT" "sfc"
<- st_sfc(st_point(st_coordinates(geom_turia1)[83,]), crs=st_crs(turia))
p2 ggplot() +
geom_sf(data = turia) +
geom_sf(data = p1, size=2, color="blue") +
geom_sf(data = p2, size=2, color="red")
8.1.4 st_distance()
Esta función calcula la distancia Euclídea entre pares de geometrías de dos objetos sf
o sfc
.
::st_distance(p1,p2) sf
st_as_s2(): dropping Z and/or M coordinate
st_as_s2(): dropping Z and/or M coordinate
Units: [m]
[,1]
[1,] 50802.45
::st_length(turia[1,]) sf
84185.01 [m]
- Crea una línea l1 que vaya de p1 a p2.
- Comprueba que la longitud de l1 es igual a la distancia entre p1 y p2.
8.1.5 st_buffer()
Esta función crea un buffer, es decir, un área alrededor de cada geometría de un objeto sf
o sfc
.
<- sf::st_buffer(turia, dist = 5000)
ribera_turia class(ribera_turia)
[1] "sf" "data.frame"
ggplot() +
geom_sf(data = turia, color="blue") +
geom_sf(data = ribera_turia, alpha=0.5, color="transparent", fill="#9BEAB9")
<- st_buffer(gva, 5000)
buffer_gva
ggplot() +
geom_sf(data = spain_ccaa) +
geom_sf(data = box_can, color = "grey50") +
geom_sf(data = buffer_gva, alpha=0.5, color="transparent", fill="#9BEAB9")
8.1.6 st_boundary()
Esta función se utiliza para obtener el límite de cualquier tipo de geometría espacial, entendiendo por límite la parte de la geometría que define su contorno externo.
Para un polígono, st_boundary()
devuelve las líneas (o anillos) que forman el contorno externo del polígono, excluyendo su interior. Para una línea, devuelve los puntos de inicio y fin de la línea.
<- st_buffer(st_boundary(gva), 5000)
buffer_gva ggplot() +
geom_sf(data = spain_ccaa) +
geom_sf(data = box_can, color = "grey50") +
geom_sf(data = buffer_gva, alpha=0.5, color="transparent", fill="#9BEAB9")
8.1.7 st_centroid()
Esta función calcula el centroide de cada geometría en un objeto sf
o sfc
. El centroide es el punto central de una geometría, que se calcula como el promedio de todas las coordenadas de los puntos que forman la geometría. En términos más simples, es el punto que se consideraría el centro geográfico de una forma.
A veces, el centroide (centro geográfico) queda fuera de los límites de sus objetos principales (imagina un polígono con forma de donut). En tales casos, se puede utilizar la función st_point_on_surface()
, que garantiza que el punto esté dentro del objeto principal.
<- spain_ccaa %>% filter(!codauto %in% c("04","05","18","19"))
spain ggplot() +
geom_sf(data = spain)
<- spain %>%
spain2 group_by() %>%
summarise()
ggplot() +
geom_sf(data = spain2)
<- spain %>%
madrid filter(codauto == "13")
ggplot() +
geom_sf(data = spain2) +
geom_sf(data = madrid, fill = "blue", alpha = 0.5)
<- st_centroid(madrid$geometry)
centro_madrid ggplot() +
geom_sf(data = spain2) +
geom_sf(data = madrid, fill = "blue", alpha = 0.5) +
geom_sf(data = centro_madrid, color = "red")
<- st_buffer(centro_madrid, dist = 10^6) # buffer 1000 km desde centro madrid
buffer class(buffer)
[1] "sfc_POLYGON" "sfc"
ggplot() +
geom_sf(data = buffer, fill = "orange", alpha = 0.2) +
geom_sf(data = spain2) +
geom_sf(data = madrid, fill = "blue", alpha = 0.5) +
geom_sf(data = centro_madrid, color = "red")
8.1.8 st_sample()
La función st_sample()
se usa para generar puntos aleatorios dentro de las geometrías de un objeto sf
o sfc
. Esta función permite especificar el número de puntos a generar y, opcionalmente, el tipo de distribución de los puntos (por ejemplo, uniforme) dentro de la geometría.
st_sample()
es particularmente útil en varios contextos, como:
- Crear muestras aleatorias para análisis espaciales, como estimar la densidad de características dentro de una región.
- Generar puntos para simulaciones espaciales.
- Visualización, para representar la extensión de una geometría mediante puntos aleatorios cuando el detalle completo de la geometría no es necesario.
set.seed(123)
<- st_sample(buffer, size = 1000)
puntos class(puntos)
[1] "sfc_POINT" "sfc"
ggplot() +
geom_sf(data = buffer, fill = "orange", alpha = 0.2) +
geom_sf(data = spain2) +
geom_sf(data = puntos, color = "green")
8.1.9 st_intersection()
Esta función calcula la geometría resultante de la intersección entre dos o más geometrías. Si dos polígonos se superponen, por ejemplo, st_intersection()
devuelve un nuevo polígono que representa la zona de superposición. Si no hay intersección, el resultado debe ser una geometría vacía. Esta función es útil cuando el interés está en la forma o el área de la intersección.
<- st_intersection(puntos,spain2)
puntos_spain class(puntos_spain)
[1] "sfc_POINT" "sfc"
ggplot() +
geom_sf(data = buffer, fill = "orange", alpha = 0.2) +
geom_sf(data = spain2) +
geom_sf(data = puntos, color = "green") +
geom_sf(data = puntos_spain, color = "red")
ggplot() +
geom_sf(data = spain2) +
geom_sf(data = puntos_spain, color = "red")
8.1.10 st_difference()
Función opuesta a st_intersection()
. Encuentra la diferencia entre pares de geometrías de dos objetos sf
o sfc
.
<- st_difference(puntos, spain2)
puntos_out class(puntos_out)
[1] "sfc_POINT" "sfc"
ggplot() +
geom_sf(data = buffer, fill = "orange", alpha = 0.2) +
geom_sf(data = spain2) +
geom_sf(data = puntos, color = "green") +
geom_sf(data = puntos_out, color = "blue")
- ¿Cuántos puntos “han caído” dentro de la Península Ibérica?
- ¿Y en Galicia?
- ¿Y dentro de la provincia de Valencia?
- ¿Y a una distancia inferior o igual a 15 km de las playas de Asturias?
8.1.11 st_intersects()
Esta función se utiliza para evaluar si dos geometrías se intersectan, es decir, si comparten algún espacio en común. El resultado es un objeto lógico (verdadero/falso) o una matriz/lista que indica qué geometrías de los dos conjuntos de entrada se intersectan entre sí. Es útil para pruebas lógicas, como filtrar geometrías basadas en su intersección con otras.
<- rios %>% filter(NOM_RIO == "Rio Ebro")
ebro ggplot() +
geom_sf(data = spain_ccaa) +
geom_sf(data = box_can, color = "grey50") +
geom_sf(data = ebro, color="blue")
<- st_intersects(ebro,spain_ccaa)
ccaa_ebro class(ccaa_ebro)
[1] "sgbp" "list"
<- unique(unlist(ccaa_ebro))
ccaa_ebro
ggplot() +
geom_sf(data = spain_ccaa) +
geom_sf(data = mapSpain::esp_get_can_box(style = "box"), color="grey40", linewidth=0.5) +
geom_sf(data = spain_ccaa[ccaa_ebro,], aes(fill=nuts2.name), color="white") +
geom_sf(data = ebro, color="blue") +
theme_minimal() +
theme(legend.position = "bottom",
legend.direction = "horizontal",
legend.title = element_blank(),
axis.title = element_blank(),
panel.background = element_rect(fill="lightblue", color = "transparent"))
8.2 Centros educativos de la Comunitat Valenciana
Probemos ahora con datos reales… En el catálogo de descargas de la Infraestructura de Datos Espaciales Valenciana (IDEV) se ofrecen datos geográficos agrupados por diferentes temáticas. Dentro del bloque Educación existe la posibilidad de obtener/descargar diversa información espacial, como los Grados y Másteres universitarios que se imparten, mapas escolares de Parques Naturales o la ubicación de los centros de exámenes ordinarios de la Junta Qualificadora de Coneixements de Valencià (JQCV). En esta ocasión vamos a trabajar con la ubicación de los centros educativos de la GVA, disponibles para su descarga directa de aquí.
Importamos los datos:
<- sf::st_read("data/centres_educatius.gpkg", quiet=T)
centres_edu_gva head(centres_edu_gva,10)
Y calculamos, por ejemplo, las distancias entre cada para de puntos (centros educativos):
<- sf::st_distance(centres_edu_gva)
dist_edu class(dist_edu)
[1] "units"
1:6,1:6] dist_edu[
Units: [m]
1 2 3 4 5 6
1 0.0000 397.3371 24598.17 35169.468 34302.365 31359.10
2 397.3371 0.0000 24838.28 34788.092 33911.817 31755.57
3 24598.1659 24838.2802 0.00 56780.701 54982.341 24166.79
4 35169.4675 34788.0919 56780.70 0.000 3536.969 66141.12
5 34302.3649 33911.8166 54982.34 3536.969 0.000 65548.32
6 31359.1018 31755.5715 24166.79 66141.119 65548.324 0.00
- ¿Qué centros educativos están fuera de los límites de la Comunitat Valenciana?
- Sustituye las coordenadas por las correctas (las puedes obtener, por ejemplo, de Google Maps)
- ¿Has detectado algún otro error en el conjunto de datos original? De ser así, ¿qué propones hacer?
- Guarda el objeto sf resultante como “centres_educatius_bueno.gpkg”.
8.3 Resumen
En este apartado hemos visto las siguientes funciones del paquete sf
:
st_area
st_length
st_distance
st_coordinates
st_buffer
st_boundary
st_centroid
st_sample
st_intersection
st_difference
st_intersects
st_bbox
st_read
st_write
¿Para qué sirve cada una de estas funciones?