Especialización en Big Data e Inteligencia Territorial - FLACSO, Argentina.

Ciudad: Ciudad Autónoma de Buenos Aires, Argentina

CONSIGNA: PARTE 1

  1. Obtener las coordenadas (longitud y latitud) de la Casa de Gobierno (Casa Rosada) de la Ciudad Autónoma de Buenos Aires.

Comenzamos activando librerías

library(tidyverse)
library(sf)
library(leaflet)
library(tidygeocoder)
library(osrm)

Obtenemos coordenadas

Cgobierno <-  geo(address = "Casa Rosada, Ciudad Autónoma de Buenos Aires, Argentina")
## Passing 1 address to the Nominatim single address geocoder
## Query completed in: 1 seconds
  1. Generar un mapa interactivo donde se ubique la Casa de Gobierno de la Ciudad de Buenos Aires.
leaflet(Cgobierno) |> 
  addTiles() |>  
  addMarkers(~long, ~lat)
  1. Cargar el dataset caba_comisarias.csv que se encuentra en la carpeta data y contiene el domicilio de todas las comisarías de la Ciudad.
caba_comisaria <- read.csv("datos/caba_comisarias.csv",
                           encoding = "UTF-8",
                           stringsAsFactors = TRUE)
  1. Realizar todas las funciones que sean necesarias para poder georreferenciar todas las comisarías del punto 3.
caba_comisaria <- caba_comisaria |> 
  mutate(direccion_norm = paste(direccion, ", Ciudad Autónoma de Buenos Aires, Argentina", sep = "")) |> 
  geocode(address = direccion_norm, method = "osm")
## Passing 49 addresses to the Nominatim single address geocoder
## Query completed in: 51.8 seconds
  1. Generar un mapa interactivo con los datos del punto 3. Realizar algunos ajustes estéticos a elección, como por ejemplo cambiar el mapa de fondo, agregar un pop-up, etc.
leaflet(caba_comisaria) |> 
  addProviderTiles(providers$Esri.WorldStreetMap) |> 
  addCircleMarkers(data = caba_comisaria, ~long, ~lat,
                   popup = paste(caba_comisaria$nombre, "|", caba_comisaria$direccion),
                   color = "grey",
                   fillOpacity = 1,
                   radius = 5)
  1. Calcular, a partir de isócronas, cuantas comisarías se encuentran a menos de 10 minutos en auto de la Casa de Gobierno. Hacer un mapa con los resultados.
#Calculamos las isocronas
isocronas <- osrmIsochrone(loc = c(Cgobierno$long, Cgobierno$lat),
                           breaks = seq(from = 0, to = 10),
                                        res = 35,
                                        osrm.profile = "car")
#paleta de colores para leyenda
pal <- colorBin("YlOrRd", domain = isocronas$isomax)

#graficamos resultado
leaflet(isocronas) |> 
  addProviderTiles(providers$CartoDB.Positron) |> 
  addPolygons(fillColor = ~colorBin("YlOrRd", domain = isocronas$isomax)(isomax),
  color = NA,
  fillOpacity = 0.5) |>
  addMarkers(data = Cgobierno,
             popup = Cgobierno$address) |> 
  addCircleMarkers(data = caba_comisaria, ~long, ~lat,
                   popup = paste(caba_comisaria$nombre, "|", caba_comisaria$direccion),
                   color = "grey",
                   fillOpacity = 1,
                   radius = 5) |>
  addMiniMap(tiles = providers$CartoDB.Positron) |> 
  addLegend(pal = pal,
            values = isocronas$isomax,
            title = "Tiempo Máximo (min) en Auto"
            ) |> 
  addScaleBar(position = "bottomleft",
              options = scaleBarOptions(
                maxWidth = 200,
                metric = TRUE,
                imperial = FALSE
              ))

CONSIGNA: PARTE 2

  1. Realizar un ruteo múltiple desde la Casa de Gobierno geolocalizada en el punto 1 (Parte 1) y las 5 comisarías que se ubican a menos de 10 minutos en auto. ¿Cuál es la comisaría más cercana a la Casa de Gobierno si utilizamos al auto como medio de transporte? ¿Cuánto tiempo tardaríamos en llegar?

Primero realizamos un intersección para solamente dejar las comisarías que están dentro de la isócrona con 10 minutos de recorrido. Para ello, debemos convertir el dataframe en un sf y luego aplicar la función st_intersection().

#Script para intersectar isocronas con comisarias
sf_use_s2(FALSE) # Desactivar S2 para cálculos planos 
## Spherical geometry (s2) switched off
#interseccion
caba_comisaria10m <- caba_comisaria |> 
  st_as_sf(coords = c("long", "lat"), crs = 4326) |> 
  st_intersection(isocronas)
## although coordinates are longitude/latitude, st_intersection assumes that they
## are planar
## Warning: attribute variables are assumed to be spatially constant throughout
## all geometries

Luego graficamos para revisar el resultado

#paleta de colores para leyenda
pal <- colorBin("YlOrRd", domain = isocronas$isomax)

#graficamos resultado
leaflet(isocronas) |> 
  addProviderTiles(providers$CartoDB.Positron) |> 
  addPolygons(fillColor = ~colorBin("YlOrRd", domain = isocronas$isomax)(isomax),
  color = NA,
  fillOpacity = 0.5) |>
  addMarkers(data = Cgobierno,
             popup = Cgobierno$address) |> 
  addCircleMarkers(data = caba_comisaria10m,
                   popup = paste(caba_comisaria10m$nombre, "|", caba_comisaria10m$direccion),
                   color = "grey",
                   fillOpacity = 1,
                   radius = 5) |>
  addMiniMap(tiles = providers$CartoDB.Positron) |> 
  addLegend(pal = pal,
            values = isocronas$isomax,
            title = "Tiempo Máximo (min) en Auto"
            ) |> 
  addScaleBar(position = "bottomleft",
              options = scaleBarOptions(
                maxWidth = 200,
                metric = TRUE,
                imperial = FALSE
              ))
## Assuming "long" and "lat" are longitude and latitude, respectively

Para ejecutar el ruteo múltiple entre la casa Rosada y las comisarías se debe crear una función con los parámetros de ruteo que usa la función osrmRoute.

#Función que permite el ruteo secuencial.
ruteo_funcion <- function(nombre_origen, lon_origen, lat_origen,
                          nombre_destino, lon_destino, lat_destino)
  {
  ruta <- osrmRoute(src = c(lon_origen, lat_origen),
                    dst = c(lon_destino, lat_destino),
                    overview = "full",
                    osrm.profile = "car")
  
  ruta |> 
  mutate(src = nombre_origen,
         dst = nombre_destino)
}

Luego, convertimos otra vez el objeto a un dataframe para utilizarlo en el ruteo.

#Intersectamos solo comisarias con isocronas
caba_comisaria10m <- caba_comisaria10m |> 
  mutate(long = st_coordinates(geometry)[,1],
         lat  = st_coordinates(geometry)[,2]) |> 
  st_drop_geometry()

Creamos un vector para que la función pmap() lo use como input y repita sobre cada elemento elegido (tipo loop). Entonces, la función creada la convertimos en lista para pasarle pmap.

#lista para recoger ruteo
ruteo <-  list("Casa Rosada", Cgobierno$long, Cgobierno$lat,
               caba_comisaria10m$nombre, caba_comisaria10m$long, caba_comisaria10m$lat)

Ahora si pasamos la función pmap con la lista

#aplicamos el ruteo
ruteo <- pmap(ruteo, ruteo_funcion)

Podemos observar que la función nos devolvió una lista con todos los objetos sf resultantes de los 19 ruteos. Para poder analizar y mapear los resultados, necesitamos utilizar reduce() que reduce una lista o un vector a un solo valor mediante la aplicación repetida de una función, que en nuestro caso será rbind().

#convertirmos en un dataframe.
ruteo <- ruteo |> 
  reduce(rbind)

Ahora si podemos contestarla pregunta:

¿Cuál es la comisaría más cercana a la Casa de Gobierno si utilizamos al auto como medio de transporte? ¿Cuánto tiempo tardaríamos en llegar?

La comisaría más cercana a la Casa de Gobierno es Comisaria Vecinal 1-B (edificio anexo) a la cual podemos llegar en menos de 1 minuto, ya que, está a una distancia aproximada de 375 m.

  1. Generar un mapa interactivo con todos los ruteos calculados en el punto 1. Realizar algunos ajustes estéticos a elección, como por ejemplo cambiar el mapa de fondo, agregar un pop-up, etc.

Vamos a graficar el ruteo para conocer la ruta precisa.

#paleta de colores
paleta <- c(low="gold", high= "deeppink4") 

#mapa dinámico
leaflet(ruteo) |> 
  #Servidor de mapas
  addProviderTiles(providers$CartoDB.Positron) |> 
  #Rutas con colores
  addPolylines(data = ruteo,
               color = ~colorNumeric(paleta, ruteo$distance)(distance),
               label = paste("Desde", ruteo$src, "hasta", ruteo$dst, "|", "Distancia:", round(ruteo$distance, 2), "km", "|",
                             "Duración:", round(ruteo$duration, 2), "min"),
               group = "Rutas") |>
  #Leyenda
  addLegend("topright", pal = colorNumeric(paleta, ruteo$distance), values = ~distance,
            title = "Distancia",
            labFormat = labelFormat(suffix = "km")) |> 
  #Gobierno
  addMarkers(data = Cgobierno,
             popup = Cgobierno$address,
             group = "Gobierno") |> 
  #Comisarías
  addCircleMarkers(data = caba_comisaria10m,
                   popup = paste(caba_comisaria10m$nombre, "|", caba_comisaria10m$direccion),
                   color = "grey",
                   fillOpacity = 1,
                   radius = 5,
                   group = "Comisarías") |>
  #Control de capas
  addLayersControl( overlayGroups = c("Rutas", "Comisarías", "Gobierno"),
                    options = layersControlOptions(collapsed = FALSE),
                    position = "topleft") |> 
  #Mapa de referencia
  addMiniMap(tiles = providers$CartoDB.Positron,
             toggleDisplay = TRUE) |> 
  #Barra de escala
  addScaleBar(position = "bottomleft",
              options = scaleBarOptions(
                maxWidth = 200,
                metric = TRUE,
                imperial = FALSE))