CONSIGNA: PARTE 1
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
leaflet(Cgobierno) |>
addTiles() |>
addMarkers(~long, ~lat)
caba_comisaria <- read.csv("datos/caba_comisarias.csv",
encoding = "UTF-8",
stringsAsFactors = TRUE)
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
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)
#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
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.
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))