🌳 Presentación de tema

Villa María es una ciudad de aproximadamente 100.000 habitantes y se encuentra localizada al sur de la Provincia de Córdoba.

Desde su fundación, a orillas del Río Tercero, se la consideró una ciudad verde y con amplia disponibilidad de espacios de esparcimiento como parques y plazas. Sin embargo, a partir de la década de los ochenta, su rápido crecimiento trajo asociado la expansión de infraestructura, la construcción de edificaciones en altura y la reducción de áreas naturales.

La dimensión de su transformación nunca ha sido explorada en profundidad, y no existen estudios que analicen la cantidad de áreas verdes disponibles actualmente en la ciudad y su distribución por barrios.

El presente informe pretende arrojar luz sobre esta situación, ofreciendo un análisis detallado sobre las áreas verdes de Villa María.

📚 Carga de librerías

Las librerías de R que utilizaremos engloban una amplia variedad de herramientas para el análisis espacial y la visualización de datos geográficos, abarcando desde el procesamiento de información hasta la integración de servicios de geocodificación.

library(tidyverse)
library(sf)
library(ggmap)
library(osmdata)
library(viridis)
library(ggiraph)
library(tidygeocoder)
library(leaflet)
library(osrm)

🌎 Descarga de datos geográficos

El primer paso de nuestro análisis consiste en crear el cuadro delimitador de Villa María y descargar el mapa de la ciudad. Para ello utilizaremos, en primer instancia, las funciones getbb() y get_stamenmap() de la librería osmdata.

bbox_villamaria <- getbb("Villa Maria, Cordoba, Argentina")
bbox_villamaria
##         min       max
## x -63.29439 -63.17833
## y -32.45553 -32.36030
mapa_villamaria <- get_stamenmap(bbox = bbox_villamaria,
                                 zoom = 12)

Visualicemos el mapa.

ggmap(mapa_villamaria)

Para poder comprender mejor qué extensión de territorio cubre Villa María, es importante tener también mapeados los límites de la ciudad. Para ello agregamos el parámetro format_out = “sf_polygon” en la función getbb().

polygon_villamaria <- getbb("Villa Maria, Cordoba, Argentina",
                            format_out = "sf_polygon")

Veamos el resultado.

polygon_villamaria
## Simple feature collection with 1 feature and 0 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -63.29439 ymin: -32.45553 xmax: -63.17833 ymax: -32.3603
## Geodetic CRS:  WGS 84
##                         geometry
## 1 POLYGON ((-63.29439 -32.412...

Ahora sí, podemos superponer el perímetro que realizamos de la ciudad con el mapa base descargado con ggmap().

ggmap(mapa_villamaria) +
  geom_sf(data = polygon_villamaria, inherit.aes = FALSE)

La superposición funciona, pero podemos realizar algunos ajustes como transparentar el polígono, definir los límites de la ciudad en color rojo, ajustar el theme y agregar título, subtítulo y fuente.

ggmap(mapa_villamaria) +
  geom_sf(data = polygon_villamaria, fill = NA, color = "red", lwd = 0.75, inherit.aes = FALSE) +
  labs(title = "Villa María, Córdoba, Argentina",
       caption = "Fuente: Open Street Map") +
  theme_test()

¡Tenemos listo el mapa de la ciudad! Ahora tenemos que identificar sus espacios verdes.

🌱 Mapeo de espacios verdes

Para identificar los espacios verdes de Villa María, tenemos que buscar primero las tags que Open Street Map considera espacios verdes. En un paper de Novack, Wang & Zipf (2018: 7), los autores consignan que los espacios verdes según Open Street Map son:

espacios_verdes <- c(
  "\"leisure\"=\"park\"",
  "\"leisure\"=\"golf_course\"",
  "\"leisure\"=\"nature_reserve\"",
  "\"leisure\"=\"pitch\"",
  "\"landuse\"=\"allotments\"",
  "\"landuse\"=\"cemetery\"",
  "\"landuse\"=\"farmland\"",
  "\"landuse\"=\"forest\"",
  "\"landuse\"=\"grass\"",
  "\"landuse\"=\"greenfield\"",
  "\"landuse\"=\"meadow\"",
  "\"landuse\"=\"orchad\"",
  "\"landuse\"=\"recreation_ground\"",
  "\"landuse\"=\"village_green\"",
  "\"leisure\"=\"garden\"",
  "\"natural\"=\"wood\"",
  "\"natural\"=\"scrub\"",
  "\"natural\"=\"health\"",
  "\"natural\"=\"grassland\"",
  "\"natural\"=\"wetland\"",
  "\"tourism\"=\"camp_site\"")

Guardamos las key y values en el objeto espacios_verdes —una lista que usaremos más adelante—, y creamos un overpass query con la función opq().

osm_area <- opq(bbox_villamaria)

Posteriormente utilizamos un bucle for, con la función add_osm_features(), para iterar a través de la lista espacios_verdes que contiene los lugares específicos que queremos descargar.

for (espacios in espacios_verdes) {
  osm_area <- add_osm_features(
    osm_area,
    features = espacios
  )
}

Una vez que se han agregado todas las características deseadas a la consulta osm_area, el código ejecuta la consulta utilizando la función osmdata_sf() para obtener los datos de Open Street Map correspondientes a las características y el área de interés definida. El resultado se almacena en el objeto espacios_verdes.

espacios_verdes <- osmdata_sf(osm_area)

Por último, guardamos las geografías que nos interesan en espacios_verdes_polygons y espacios_verdes_multipolygons.

espacios_verdes_polygons <- espacios_verdes$osm_polygons
dim(espacios_verdes_polygons)
## [1] 1352   34
espacios_verdes_multipolygons <- espacios_verdes$osm_multipolygons
dim(espacios_verdes_multipolygons)
## [1] 19  7

Tenemos 1352 polígonos y 19 multipolígonos. Veamos ambas capas en el mapa.

ggmap(mapa_villamaria) +
  geom_sf(data = polygon_villamaria, fill = NA, color = "red", lwd = 0.75, inherit.aes = FALSE) +
  geom_sf(data = espacios_verdes_polygons, fill="forestgreen", color = NA, inherit.aes = FALSE) +
  geom_sf(data = espacios_verdes_multipolygons, fill = "forestgreen", color = NA, inherit.aes = FALSE) +
  labs(title = "Espacios verdes",
       subtitle = "Villa María, Córdoba",
       caption = "Fuente: Open Street Map") +
  theme_test()

Ya tenemos nuestras áreas verdes en dos capas diferentes: espacios_verdes_polygons y espacios_verdes_multipolygons. Idealmente, deberían estar unificadas, por lo tanto simplificaremos la cantidad de columnas de cada dataframe y las uniremos con rbind().

espacios_verdes_polygons <- espacios_verdes_polygons %>%
  select(osm_id, name)
espacios_verdes_multipolygons <- espacios_verdes_multipolygons %>%
  select(osm_id, name)
espacios_verdes <- rbind(espacios_verdes_polygons, espacios_verdes_multipolygons)
dim(espacios_verdes)
## [1] 1371    3

Nuestra nueva base unificada tiene 1371 áreas verdes. Hagamos un mapa con la nueva capa.

ggmap(mapa_villamaria) +
  geom_sf(data = polygon_villamaria, fill = NA, color = "red", lwd = 0.75, inherit.aes = FALSE) +
  geom_sf(data = espacios_verdes, fill = "forestgreen", color = NA, inherit.aes = FALSE) +
  labs(title = "Áreas verdes",
       subtitle = "Villa María, Córdoba, Argentina",
       caption = "Fuente: Open Street Map") +
  theme_test()

Si observamos detenidamente, vamos a advertir que algunos espacios verdes descargados están por fuera de los límites de Villa María. Para corregir esto utilizaremos st_make_valid() y st_intersection().

espacios_verdes <- st_make_valid(espacios_verdes)
espacios_verdes <- st_intersection(espacios_verdes, polygon_villamaria)
dim(espacios_verdes)
## [1] 823   3

Ahora tenemos 823 espacios verdes, o sea que 548 polígonos se ubicaban por fuera de los límites de la ciudad. Veamos el resultado en el mapa.

ggmap(mapa_villamaria) +
  geom_sf(data = polygon_villamaria, fill = NA, color = "red", lwd = 0.75, inherit.aes = FALSE) +
  geom_sf(data = espacios_verdes, fill = "forestgreen", color = NA, inherit.aes = FALSE) +
  labs(title = "Áreas verdes",
       subtitle = "Villa María, Córdoba, Argentina",
       x = NULL,
       y = NULL,
       caption = "\n Fuente: Open Street Map") +
  theme_test() +
  theme(legend.position = "bottom",
        legend.box = "vertical",
        plot.title = element_text(
          face = "bold",
          colour = "#3C3C3C",
          size = 18),
        plot.subtitle = element_text(
          colour = "#838383",
          size = 12),
        plot.caption = element_text(
          colour = "#838383",
          hjust = 0))

📏 Cálculo de superficies verdes

Para interpretar los datos, debemos realizar algunos análisis de estadística descriptiva básica. En función de ello, primero calcularemos la superficie total de Villa María en m2.

superficie_villamaria <- st_area(polygon_villamaria)
superficie_villamaria / 1000000
## 41.20489 [m^2]

Villa María tiene una superficie total de 41.204.891 m2 o 41,20 km2. ¿Pero qué superficie ocupan las áreas verdes? La calculamos a continuación.

espacios_verdes <- espacios_verdes %>%
  mutate(area_m2 = st_area(espacios_verdes))
sum(espacios_verdes$area_m2) / 1000000
## 11.50028 [m^2]

Como advertimos, las superficies verdes en Villa María tienen una extensión total de 11.500.278 m2 u 11,50 km2.

summary(espacios_verdes$area_m2)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##      0.1    466.7   1580.5  13973.6   7219.4 487138.3

Y, del análisis descriptivo que ejecutamos con summary(), podemos también decir que:

  • El espacio verde más reducido de la ciudad cubre una superficie de 0,1 m2.
  • El valor promedio de los espacios verdes en Villa María es de 13.973,6 m2.
  • El espacio verde más grande cubre una superficie de 487.138,3 m2.

¿Pero podríamos calcular qué porcentaje de la ciudad es verde? Sí, de manera muy simple.

porcentaje_verde <- (sum(espacios_verdes$area_m2) / superficie_villamaria) * 100
porcentaje_verde
## 27.90998 [1]

En términos porcentuales, el 27,91% de la superficie total de Villa María es verde. Pero es válido preguntarse si dicha superficie verde es igualmente accesible desde todos los barrios de la ciudad. Sobre este punto nos ocuparemos a continuación.

🏠 Cálculo de superficies verdes por barrio

Si examinamos cuidadosamente los mapas generados previamente, podemos observar una notable concentración de espacios verdes en las zonas periféricas de la ciudad. Esta distribución podría estar sugiriendo que los barrios del centro tienen acceso limitado a áreas verdes.

Para investigar esto en mayor detalle, necesitamos obtener un conjunto de datos que contenga información sobre los barrios de la ciudad. La Municipalidad de Villa María ofrece un conjunto de datos en su Catálogo de Datos Abiertos que podemos utilizar para este propósito.

El dataset tiene cuatro columnas que podemos ver a continuación.

colnames(barrios_villamaria)
## [1] "WKT"      "id"       "NOMBRE"   "geometry"

Como puede resultar confuso más adelante, vamos a quitarle dos columnas al dataset: WKT y id.

barrios_villamaria <- barrios_villamaria %>%
  select(-WKT, -id)

Con el fin de prevenir cualquier posible error relacionado con las proyecciones y garantizar una visualización precisa de las capas superpuestas que incluyen el polígono de la ciudad, los espacios verdes y los barrios, es necesario estandarizar los sistemas de referencia de coordenadas de los tres objetos geoespaciales. Para lograr esto, asignaremos a los tres objetos el sistema de referencia EPSG 4326.

st_crs(barrios_villamaria) <- st_crs(4326)
st_crs(polygon_villamaria) <- st_crs(4326)
st_crs(espacios_verdes) <- st_crs(4326)

Y generamos el mapa.

ggmap(mapa_villamaria) +
  geom_sf(data = polygon_villamaria, fill = NA, color = "red", lwd = 0.75, inherit.aes = FALSE) +
  geom_sf(data = espacios_verdes, fill = "forestgreen", color = NA, inherit.aes = FALSE) +
  geom_sf(data = barrios_villamaria, fill = NA, color = "black", lwd = 0.30, color = NA, inherit.aes = FALSE) +
  labs(title = "Áreas verdes",
       subtitle = "Villa María, Córdoba, Argentina",
       caption = "Fuente: Open Street Map") +
  theme_test()

Con el propósito de determinar qué espacios verdes están asociados a cada barrio, procedemos a crear un nuevo objeto geoespacial denominado barrios_verdes. Este objeto incorporará la información de los barrios en conjunto con los datos de los espacios verdes que se intersectan espacialmente con ellos.

barrios_verdes <- st_join(barrios_villamaria, espacios_verdes, join = st_intersects)

Y calculamos también la superficie de cada barrio en m2. Este cálculo nos servirá más adelante para entender qué porcentaje de superficie verde tiene cada barrio.

superficie_barrios <- st_area(barrios_villamaria)

Para concluir, y antes de visualizar los barrios con mayor porcentaje de superficie verde, es necesario aplicar algunas transformaciones al objeto barrios_verdes. Específicamente:

  • Calcular la superficie de área verde para cada barrio (area_m2).
  • Agregar al objeto barrios_verdes el cálculo de la superficie total de cada barrio (m2_barrio).
  • Calcular el porcentaje de área verde en relación con el área total del barrio (porcentaje_verde).

Además, y aprovechando la edición del objeto barrios_verdes, corregiremos el nombre de un barrio que estaba mal registrado en el conjunto de datos original (Roque Sáenz Peña).

barrios_verdes <- barrios_verdes %>% 
  group_by(NOMBRE) %>% 
  summarise_all(list(~ if (is.character(.)) toString(unique(.)) else first(.))) %>% 
  mutate(area_m2 = ifelse(is.na(area_m2), 0, area_m2)) %>% 
  select(-name, -osm_id) %>% 
  group_by(NOMBRE) %>% 
  summarise(m2_verde = sum(area_m2)) %>%
  mutate(NOMBRE = if_else(NOMBRE == "ROQUE SAENZ PEÑA", "ROQUE SAENZ PEÑA", NOMBRE)) %>% 
  mutate(m2_barrio = superficie_barrios) %>%
  mutate(porcentaje_verde = (m2_verde / m2_barrio) * 100) %>% 
  mutate(porcentaje_verde = as.numeric(gsub("\\[.*?\\]", "", porcentaje_verde)))

Realizados los cálculos necesarios, ahora sí podemos calcular y visualizar qué barrios tienen mayor porcentaje de áreas verdes.

summary(barrios_verdes$porcentaje_verde)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##  0.03486  0.25106  0.83604  4.12979  2.22994 30.70849
barrios_verdes %>%
  arrange(desc(porcentaje_verde)) %>% 
  head(3)
## Simple feature collection with 3 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -63.29405 ymin: -32.44238 xmax: -63.20396 ymax: -32.4017
## Geodetic CRS:  WGS 84
## # A tibble: 3 × 5
##   NOMBRE        m2_verde                     geometry m2_barrio porcentaje_verde
##   <chr>            <dbl>                <POLYGON [°]>     [m^2]            <dbl>
## 1 VILLA DEL SUR  133042. ((-63.21633 -32.44238, -63.…   433241.             30.7
## 2 LAS ACACIAS    300007. ((-63.26752 -32.4017, -63.2…  1109559.             27.0
## 3 LOS OLMOS      272928. ((-63.20396 -32.42072, -63.…  1206589.             22.6
barrios_verdes %>%
  arrange(porcentaje_verde) %>% 
  head(3)
## Simple feature collection with 3 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -63.25488 ymin: -32.42275 xmax: -63.21991 ymax: -32.39727
## Geodetic CRS:  WGS 84
## # A tibble: 3 × 5
##   NOMBRE           m2_verde                  geometry m2_barrio porcentaje_verde
##   <chr>               <dbl>             <POLYGON [°]>     [m^2]            <dbl>
## 1 DOMINGO F. SARM…     126. ((-63.23798 -32.42264, -…   362735.           0.0349
## 2 GENERAL SAN MAR…     260. ((-63.22098 -32.40576, -…   631407.           0.0412
## 3 ALMIRANTE BROWN      521. ((-63.24876 -32.39727, -…  1011647.           0.0515

Como podemos observar:

  • El barrio con la mayor proporción de superficie verde con respecto a su extensión total es Villa del Sur (30,71%), seguido por Las Acacias (27,04%) y Los Olmos (22,62%).
  • En términos promedio, la superficie verde en los barrios de Villa María representa el 4,13% de su área total. No obstante, la mediana nos indica que la mitad de los barrios tiene un porcentaje de superficie verde inferior al 0,83%.
  • El barrio con el menor porcentaje de superficie verde en relación con su extensión total es Domingo F. Sarmiento (0,03%), seguido por Gral. San Martín (0,04%) y Almirante Brown (0,05%).

Si queremos visualizar estos datos en un gráfico, podemos hacerlo así.

plot_barrios <- ggplot(data = barrios_verdes, aes(x = reorder(NOMBRE, porcentaje_verde), y = porcentaje_verde)) +
  geom_bar(stat = "identity", fill = "forestgreen") +
  geom_text(aes(label = paste0(round(porcentaje_verde, 2), "%")), hjust = -0.2, color = "black", size = 3) +
  coord_flip() +
  labs(x = NULL, y = NULL,
       title = "Porcentaje de superficie verde por barrio",
       subtitle = "Villa María, Córdoba, Argentina") +
  theme_test() +
  theme(legend.position = "bottom",
        legend.box = "vertical",
        plot.title = element_text(
          face = "bold",
          colour = "#3C3C3C",
          size = 18),
        plot.subtitle = element_text(
          colour = "#838383",
          size = 12),
        plot.caption = element_text(
          colour = "#838383",
          hjust = 0))
plot_barrios

Y guardamos el plot en caso de querer compartir la visualización.

ggsave(
  plot_barrios,
  filename = "Outputs/plot_barrios.png",
  width = 35,
  height = 20,
  units = "cm",
  dpi = 300
)

Si queremos visualizar espacialmente el cálculo que realizamos, creamos un nuevo mapa de Villa María —en escala de blancos y grises— y le superponemos la capa que guardamos en barrios_verdes.

mapa_villamaria_bnw <- get_stamenmap(bbox = bbox_villamaria,
                                     maptype = "toner-background",
                                     zoom = 12)
mapa_barrios <- ggmap(mapa_villamaria_bnw) +
  geom_sf(data = barrios_verdes, aes(fill = porcentaje_verde), color = NA, inherit.aes = FALSE, alpha = 0.8) +
  scale_fill_distiller(palette = "29 gradient", direction = 1) +
  labs(x = NULL, y = NULL,
       title = "Superficie verde por barrio",
       subtitle = "Villa María, Córdoba, Argentina",
       fill = "Superficie verde por barrio (en %):  ") +
  theme_test() +
  theme(legend.position = "bottom",
        legend.box = "vertical",
        plot.title = element_text(
          face = "bold",
          colour = "#3C3C3C",
          size = 18),
        plot.subtitle = element_text(
          colour = "#838383",
          size = 12),
        plot.caption = element_text(
          colour = "#838383",
          hjust = 0))
mapa_barrios

Si queremos, podemos guardar este mapa también.

ggsave(
  mapa_barrios,
  filename = "Outputs/mapa_barrios.png",
  width = 20,
  height = 20,
  units = "cm",
  dpi = 300
)

Como bien advertimos, los barrios con mayor superficie verde de la ciudad de Villa María son aquellos de desarrollo más reciente. Los barrios más antiguos y céntricos, por su parte, presentan una marcada carencia de espacios verdes en su diseño espacial.

🛝 Espacios recreativos verdes

El universo de espacios verdes que hemos analizado hasta ahora incluye parques, campos de golf, reservas naturales, canchas deportivas, cementerios, zonas de cultivo, bosques y jardines, entre otros. Es decir, no todos son recreativos —como parques y plazas—, y no todos son de acceso público.

¿Con qué panorama nos encontraríamos si realizamos el análisis de espacios verdes incluyendo solamente aquellos que son recreativos y de acceso público?

Para poder responder a esa pregunta, procederemos a descargar nuevos datos.

plazas_villamaria <- opq(bbox_villamaria)

Anteriormente, utilizamos la función add_osm_features() para descargar múltiples values. Ahora utilizaremos la función add_osm_feature() para descargar los polígonos y multipolígonos que correspondan únicamente a parques y plazas.

plazas_villamaria <- plazas_villamaria %>%
  add_osm_feature(key = "leisure", value = "park")
plazas_villamaria <- osmdata_sf(plazas_villamaria)

Y, al igual que hicimos antes, guardamos las geografías que nos interesan en plazas_polygons y plazas_multipolygons.

plazas_polygons <- plazas_villamaria$osm_polygons
dim(plazas_polygons)
## [1] 95 23
plazas_multipolygons <- plazas_villamaria$osm_multipolygons
dim(plazas_multipolygons)
## [1] 1 3

Tenemos 95 polígonos y 1 multipolígono que, por cuestiones de orden y conveniencia, unificaremos en un solo dataframe.

plazas_polygons <- plazas_polygons %>%
  select(osm_id, name)

El dataframe plazas_multipolygons no tiene las variables osm_id y name que necesitamos para unirlo al dataframe plazas_polygons. Para ello, tenemos que hacer algunos cambios primero.

plazas_multipolygons <- plazas_multipolygons %>%
  rename(osm_id = leisure, name = type, geometry = geometry) %>%
  mutate(osm_id = "1744682")

Ahora estamos listos para elegir las columnas que nos resultan relevantes y utilizar la función rbind() para combinar los datos.

plazas_multipolygons <- plazas_multipolygons %>%
  select(osm_id, name)
plazas_poligonos <- rbind(plazas_polygons, plazas_multipolygons)
dim(plazas_poligonos)
## [1] 96  3

Después de combinar los objetos plazas_polygons y plazas_multipolygons, nos encontramos con un único objeto llamado plazas_poligonos que consta de 96 polígonos. Sin embargo, sabemos que algunos de estos polígonos estarán ubicados fuera de los límites del municipio de Villa María. Para corregir esta situación recurriremos a la función st_intersection().

plazas_poligonos <- st_intersection(plazas_poligonos, polygon_villamaria)

Con nuestra capa geográfica lista para visualizar, estamos en condiciones de generar un mapa.

ggmap(mapa_villamaria) +
  geom_sf(data = polygon_villamaria, fill = NA, color = "red", lwd = 0.75, inherit.aes = FALSE) +
  geom_sf(data = plazas_poligonos, fill = "forestgreen", color = NA, inherit.aes = FALSE) +
  labs(title = "Áreas recreativas verdes",
       subtitle = "Villa María, Córdoba, Argentina",
       x = NULL,
       y = NULL,
       caption = "\n Fuente: Open Street Map") +
  theme_test() +
  theme(legend.position = "bottom",
        legend.box = "vertical",
        plot.title = element_text(
          face = "bold",
          colour = "#3C3C3C",
          size = 18),
        plot.subtitle = element_text(
          colour = "#838383",
          size = 12),
        plot.caption = element_text(
          colour = "#838383",
          hjust = 0))

Siguiendo el mismo enfoque que empleamos previamente, procederemos a calcular el porcentaje total de áreas verdes destinadas a recreación en la ciudad. Ya realizamos el cálculo de la superficie total de Villa María (superficie_villamaria), y ahora nos concentraremos en calcular la superficie total de los espacios verdes destinados a recreación.

plazas_poligonos <- plazas_poligonos %>%
  mutate(area_m2 = st_area(plazas_poligonos))
sum(plazas_poligonos$area_m2)
## 667922.4 [m^2]

Como advertimos, las superficies recreativas verdes de Villa María tienen una extensión total de 667.922,40 m2.

sum(plazas_poligonos$area_m2) / 100000
## 6.679224 [m^2]

667.922,40 m2 sobre 100.000 habitantes que, aproximadamente tiene la ciudad, dan como resultado 6,68 m2 de espacio recreativo verde per capita.

porcentaje_recreativo <- (sum(plazas_poligonos$area_m2) / superficie_villamaria) * 100
porcentaje_recreativo
## 1.620979 [1]

En términos porcentuales, por su parte, solo el 1,62% de la superficie total de Villa María está destinada a espacios recreativos verdes.

Con el objetivo de analizar qué barrios poseen una mayor cantidad de espacios verdes recreativos, procederemos a continuación a crear un nuevo objeto espacial denominado barrios_recreativos. Este objeto englobará tanto los datos de los barrios como los datos de los espacios verdes recreativos que se intersectan espacialmente con ellos.

barrios_recreativos <- st_join(barrios_villamaria, plazas_poligonos, join = st_intersects)

Y, antes de concluir acerca de qué barrios cuentan con un mayor porcentaje de superficie recreativa verde, necesitaremos efectuar ciertas transformaciones en el objeto barrios_recreativos. En particular:

  • Debemos calcular la superficie de área recreativa verde por cada barrio (area_m2).
  • Debemos añadir al objeto barrios_recreativos el cálculo de la superficie total de cada barrio que previamente realizamos (m2_barrio).
  • Necesitamos calcular el porcentaje de área recreativa verde con respecto al área total de cada barrio (porcentaje_recreativo).

Procedamos.

barrios_recreativos <- barrios_recreativos %>% 
  group_by(NOMBRE) %>% 
  summarise_all(list(~ if (is.character(.)) toString(unique(.)) else first(.))) %>% 
  mutate(area_m2 = ifelse(is.na(area_m2), 0, area_m2)) %>% 
  select(-name, -osm_id) %>% 
  group_by(NOMBRE) %>% 
  summarise(m2_recreativo = sum(area_m2)) %>%
  mutate(NOMBRE = if_else(NOMBRE == "ROQUE SAENZ PEÑA", "ROQUE SAENZ PEÑA", NOMBRE)) %>% 
  mutate(m2_barrio = superficie_barrios) %>%
  mutate(porcentaje_recreativo = (m2_recreativo / m2_barrio) * 100) %>% 
  mutate(porcentaje_recreativo = as.numeric(gsub("\\[.*?\\]", "", porcentaje_recreativo)))

Con los cálculos pertinentes finalizados, ya estamos en condiciones de determinar y representar visualmente qué barrios poseen el mayor porcentaje de áreas verdes recreativas.

barrios_recreativos %>%
  arrange(desc(porcentaje_recreativo)) %>% 
  head(3)
## Simple feature collection with 3 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -63.26198 ymin: -32.42262 xmax: -63.24506 ymax: -32.40607
## Geodetic CRS:  WGS 84
## # A tibble: 3 × 5
##   NOMBRE m2_recreativo                  geometry m2_barrio porcentaje_recreativo
##   <chr>          <dbl>             <POLYGON [°]>     [m^2]                 <dbl>
## 1 CENTR…        14350. ((-63.24774 -32.40931, -…    91878.                  15.6
## 2 GENER…        47335. ((-63.25074 -32.41583, -…   316571.                  15.0
## 3 GENER…        47335. ((-63.2473 -32.41978, -6…   364477.                  13.0

El barrio que tiene mayor superficie recreativa verde sobre el total de su extensión es Barrio Centro Oeste (15,61%), seguido por los barrios General Guemes (14,94%%) y General Paz (12,98%).

barrios_recreativos %>%
  arrange(porcentaje_recreativo) %>% 
  head(15)
## Simple feature collection with 15 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: -63.29405 ymin: -32.4449 xmax: -63.18221 ymax: -32.38292
## Geodetic CRS:  WGS 84
## # A tibble: 15 × 5
##    NOMBRE               m2_recreativo                         geometry m2_barrio
##    <chr>                        <dbl>                    <POLYGON [°]>     [m^2]
##  1 DOMINGO F. SARMIENTO            0  ((-63.23798 -32.42264, -63.2378…   362735.
##  2 DR. RAMON CARRILLO              0  ((-63.25954 -32.39549, -63.2557…   426553.
##  3 EVITA                           0  ((-63.2154 -32.4216, -63.21617 …   568871.
##  4 FLORENTINO AMEGHINO             0  ((-63.23312 -32.39966, -63.2363…   637281.
##  5 INDUSTRIAL                      0  ((-63.21103 -32.42074, -63.2110…   107320.
##  6 LAS ACACIAS                     0  ((-63.26752 -32.4017, -63.26798…  1109559.
##  7 MALVINAS ARGENTINAS             0  ((-63.21568 -32.40425, -63.2128…  2433313.
##  8 MANUEL BELGARANO                0  ((-63.2487 -32.3971, -63.24911 …  1298091.
##  9 NICOLAS AVELLANEDA              0  ((-63.22907 -32.39122, -63.2308…   824147.
## 10 SAN NICOLAS                     0  ((-63.22301 -32.39803, -63.2181…  1057147.
## 11 VILLA ALBERTINA                 0  ((-63.18952 -32.4449, -63.18221…   759699.
## 12 VILLA DEL SUR                   0  ((-63.21633 -32.44238, -63.2141…   433241.
## 13 PARQUE NORTE                  363. ((-63.24755 -32.39862, -63.2436…   625556.
## 14 SANTA ANA                     648. ((-63.22856 -32.42402, -63.2325…   725833.
## 15 SAN JUAN BAUTISTA            2272. ((-63.22238 -32.40853, -63.2224…   971712.
## # ℹ 1 more variable: porcentaje_recreativo <dbl>

Por su parte, hay doce barrios que no poseen ninguna superficie recreativa verde: Domingo F. Sarmiento, Dr. Ramón Carrillo, Evita, Florentino Ameghino, Industrial, Las Acacias, Malvinas Argentinas, Manuel Belgrano, Nicolás Avellaneda, San Nicolás, Villa Albertina y Villa del Sur.

Si queremos visualizar estos datos en un gráfico, podemos hacerlo así.

plot_recreativo <- ggplot(data = barrios_recreativos, aes(x = reorder(NOMBRE, porcentaje_recreativo), y = porcentaje_recreativo)) +
  geom_bar(stat = "identity", fill = "forestgreen") +
  geom_text(aes(label = paste0(round(porcentaje_recreativo, 2), "%")), hjust = -0.2, color = "black", size = 3) +
  coord_flip() +
  labs(x = NULL, y = NULL,
       title = "Porcentaje de superficie recreativa verde por barrio",
       subtitle = "Villa María, Córdoba, Argentina") +
  theme_test() +
  theme(legend.position = "bottom",
        legend.box = "vertical",
        plot.title = element_text(
          face = "bold",
          colour = "#3C3C3C",
          size = 18),
        plot.subtitle = element_text(
          colour = "#838383",
          size = 12),
        plot.caption = element_text(
          colour = "#838383",
          hjust = 0))
plot_recreativo

Y, si queremos, guardamos el plot.

ggsave(
  plot_recreativo,
  filename = "Outputs/plot_recreativo.png",
  width = 35,
  height = 20,
  units = "cm",
  dpi = 300
)

Para representar de manera visual el resultado de nuestro cálculo, podemos utilizar el mapa de Villa María en escala de blancos y grises que generamos previamente. Luego, superponemos la capa de información contenida en el objeto barrios_recreativos. De esta manera, podremos observar en el mapa los barrios que tienen mayor porcentaje de áreas verdes recreativas.

mapa_barrios_recreativos <- ggmap(mapa_villamaria_bnw) +
  geom_sf(data = barrios_recreativos, aes(fill = porcentaje_recreativo), color = NA, inherit.aes = FALSE, alpha = 0.8) +
  scale_fill_distiller(palette = "29 gradient", direction = 1) +
  labs(x = NULL, y = NULL,
       title = "Superficie recreativa verde por barrio",
       subtitle = "Villa María, Córdoba, Argentina",
       fill = "Superficie verde por barrio (en %):  ") +
  theme_test() +
  theme(legend.position = "bottom",
        legend.box = "vertical",
        plot.title = element_text(
          face = "bold",
          colour = "#3C3C3C",
          size = 18),
        plot.subtitle = element_text(
          colour = "#838383",
          size = 12),
        plot.caption = element_text(
          colour = "#838383",
          hjust = 0))
mapa_barrios_recreativos

Si queremos, podemos guardar este mapa también.

ggsave(
  mapa_barrios_recreativos,
  filename = "Outputs/mapa_barrios_recreativos.png",
  width = 20,
  height = 20,
  units = "cm",
  dpi = 300
)

🚶‍♀️ Espacios recreativos verdes a distancia caminable desde mi casa

¿Cuánto tendría que caminar desde mi casa en el Barrio Santa Ana para llegar a un espacio recreativo verde? ¡Vamos a analizarlo! Para ello, en primera instancia, crearemos un punto de localización con la dirección de mi casa.

casa <- geo(address = "Roma 472, Villa Maria, Cordoba, Argentina",
                  method = "osm")

Sobre un mapa, que en esta ocasión será interactivo gracias al uso de la librería leaflet(), se verá de la siguiente manera.

leaflet(casa) %>%
  addProviderTiles(providers$CartoDB.Positron) %>% 
  addMarkers(~long, ~lat) %>% 
    addMarkers(~long, ~lat,
             popup = "Mi casa")

El siguiente paso es calcular la distancia desde mi casa hasta cada espacio recreativo verde. Sin embargo, antes de hacerlo, necesitamos determinar qué punto de cada espacio verde vamos a utilizar como referencia. Una opción es calcular los centroides de cada polígono almacenado en el objeto plazas_poligonos, y para ello usaremos la función st_point_on_surface().

centroides <- st_point_on_surface(plazas_poligonos)

A continuación, generamos una intersección entre los centroides de cada espacio recreativo verde y el polígono de la ciudad.

centroides <- st_intersection(centroides, polygon_villamaria)

Pero nos encontramos con un nuevo problema: los centroides que hemos calculado no contienen las coordenadas de latitud y longitud necesarias para ubicarlos en un mapa creado con la biblioteca leaflet(). Por lo tanto, necesitamos calcular la latitud y longitud de cada centroide. Para hacer esto, podemos crear una función que extraiga las coordenadas de latitud y longitud de cada centroide y las almacene en el dataframe coordenadas_verdes que contendrá dos columnas: lon y lat.

extraer_coordenadas <- function(geo) {
  coordenadas <- unlist(strsplit(gsub("POINT |\\(|\\)", "", geo), " "))
  return(data.frame(lon = as.numeric(coordenadas[1]), lat = as.numeric(coordenadas[2])))
}
coordenadas_verdes <- do.call(rbind, lapply(centroides$geometry, extraer_coordenadas))

Finalmente, podemos visualizar nuestros datos. En el mapa que se muestra a continuación, cada círculo representa un punto creado a partir de las coordenadas extraídas de los centroides de cada área recreativa verde.

leaflet(coordenadas_verdes) %>%
  addProviderTiles(providers$CartoDB.Positron) %>% 
  addCircles(~lon, ~lat,
             color = "forestgreen")

Ya tenemos las coordenadas de cada centroide, pero si queremos calcular qué espacios recreativos verdes se ubican a una distancia caminable desde mi casa, necesitamos conocer la dirección de cada punto. Para lograrlo, debemos realizar una geolocalización inversa.

Al igual que la geolocalización de mi casa, que demoró cerca de un segundo, la función reverse_geocode() ejecuta su comando con la misma duración: aproximadamente un segundo por registro. Por lo tanto, si calculamos las coordenadas de los 84 puntos almacenados en el objeto coordenadas_verdes, tendremos que esperar cerca de un minuto y medio.

coordenadas_verdes <- coordenadas_verdes %>%
  reverse_geocode(lat = lat, long = lon, method = "osm")

Hasta este punto, ya disponemos de todos nuestros datos geolocalizados. No obstante, aún no podemos responder a la pregunta de cuántos espacios verdes se hallan a una distancia caminable desde mi hogar. Abordaremos este análisis mediante el uso de las isócronas.

Las isócronas representan el área a la que se puede llegar desde un punto determinado en el mismo intervalo de tiempo y a una velocidad específica. Calculamos la nuestra de la siguiente manera:

isocrona <- osrmIsochrone(loc = c(casa$long, casa$lat),
                          breaks = seq(from = 0, to = 20, by = 5),
                          res = 35,
                          osrm.profile = "foot")

Visualicemos nuestra isócrona con ggplot().

ggplot() +
  geom_sf(data = isocrona, aes(fill = isomax), color = NA) +
  scale_fill_viridis_c(direction = -1) +
  labs(fill = "Minutos") +
  theme_test()

Y hagamos nuevamente un mapa interactivo para darle contexto a los datos.

leaflet(isocrona) %>%
  addProviderTiles(providers$CartoDB.Positron) %>% 
  addPolygons(fillColor = ~colorBin("YlOrRd", domain = isocrona$isomax)(isomax),
  color = NA,
  fillOpacity = 0.5) %>% 
  addMarkers(data = casa) %>% 
  addCircles(data = coordenadas_verdes,
              color = "black")

A simple vista, podemos observar que es posible llegar a un espacio recreativo verde en menos de cinco minutos a pie, tal como se resalta en el área pintada de color beige. Pero, ¿qué sucede si decidimos caminar un poco más y alcanzar los círculos resaltados en color amarillo, naranja o rojo?

En primer lugar, para realizar este cálculo, debemos transformar coordenadas_verdes en un conjunto de datos espaciales con un sistema de coordenadas 4326, que es el mismo sistema utilizado en el objeto isocrona.

coordenadas_verdes <- coordenadas_verdes %>% st_as_sf(coords = c("lon", "lat"), crs = 4326)

Después de esto, y con el fin de prevenir posibles errores relacionados con las proyecciones, ejecutaremos el siguiente código para desactivar el uso de la biblioteca s2 de la librería sf. Esto implica que las operaciones espaciales en sf se llevarán a cabo utilizando métodos alternativos en lugar de los proporcionados por la biblioteca s2 (implementada en C++).

sf_use_s2(FALSE)

Finalmente, estamos en condiciones de integrar ambos datasets para conocer cuántos espacios recreativos verdes se solapan con la isócrona calculada.

coordenadas_verdes_intersec <- st_intersection(coordenadas_verdes, isocrona)

El resultado, que se presenta en el gráfico a continuación, nos mostrará la cantidad de espacios recreativos verdes que se encuentran dentro de un radio máximo de veinte minutos de caminata.

plot_casa <- ggplot(data = coordenadas_verdes_intersec) +
  geom_bar(aes(x = factor(isomax)), fill = "forestgreen") +
  geom_text(stat = "count", aes(x = factor(isomax), y = after_stat(count), label = after_stat(count)), vjust = -0.5) +
  labs(title = "Espacios recreativos verdes próximos a Roma 472",
       subtitle = "Cálculo realizado en base a desplazamiento a pie",
       x = "Distancia máxima (minutos)",
       y = "Cantidad de espacios recreativos verdes") +
  theme_test() +
  theme(legend.position = "bottom",
        legend.box = "vertical",
        plot.title = element_text(
          face = "bold",
          colour = "#3C3C3C",
          size = 18),
        plot.subtitle = element_text(
          colour = "#838383",
          size = 12),
        plot.caption = element_text(
          colour = "#838383",
          hjust = 0))
plot_casa

Como se puede apreciar en el gráfico de barras, un espacio recreativo verde se encuentra a una distancia de cinco minutos a pie desde mi casa, mientras que 6 espacios están a diez minutos, 4 a quince minutos y 5 a veinte minutos a pie.

Si deseamos guardar este último gráfico de barras, podemos hacerlo utilizando el siguiente código.

ggsave(
  plot_casa,
  filename = "Outputs/plot_casa.png",
  width = 20,
  height = 20,
  units = "cm",
  dpi = 300
)

💡 Takeaways

  1. Más de una cuarta parte de la superficie total de Villa María está ocupada por áreas verdes (27,91%). El mapeo contempla una amplia variedad de espacios como parques, campos de golf, reservas naturales, canchas de ejercicios físicos, parcelas, cementerios, tierras de cultivo, bosques, áreas de césped, terrenos baldíos, prados, huertos, terrenos de esparcimiento, plazas, jardines, bosques, matorrales, pastizales, humedales y zonas de camping.

  2. Al considerar únicamente los espacios recreativos verdes de acceso público, sin embargo, el porcentaje disminuye drásticamente a 1,62%.

  3. La distribución espacial revela una notoria concentración de espacios verdes en las áreas periurbanas, lo que se traduce en que los barrios de más reciente desarrollo cuentan con una mayor superficie verde. En contraste, los barrios más antiguos y céntricos presentan una marcada falta de espacios verdes en su diseño espacial.

  4. En relación a la distribución de espacios recreativos verdes por barrio, tres barrios ubicados en las proximidades de la costanera del Río Tercero presentan los mayores porcentajes de superficie destinada a dichos fines: Centro Oeste, General Güemes y General Paz. Por otro lado, quince barrios no cuentan con ninguna superficie destinada a espacios recreativos verdes: Domingo F. Sarmiento, Dr. Ramón Carrillo, Evita, Florentino Ameghino, Industrial, Las Acacias, Malvinas Argentinas, Manuel Belgrano, Nicolás Avellaneda, San Nicolás, Villa Albertina y Villa del Sur.

  5. Cada habitante de la ciudad de Villa María dispone de 6,68 metros cuadrados de espacio recreativo verde, casi tres y medio por debajo del mínimo recomendado a nivel internacional para garantizar un entorno urbano saludable y sostenible.


⚠️ Disclaimer: el presente estudio se ha realizado utilizando datos públicos y abiertos. Los resultados y conclusiones aquí presentados son producto del análisis y procesamiento de información accesible al público. Cualquier interpretación, conclusión o decisión basada en este estudio recae bajo la responsabilidad del usuario. Se recomienda verificar la fuente de los datos y considerar posibles limitaciones en la precisión y actualidad de la información utilizada.

💻 Más proyectos de datos en marialasa.ar.