library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.4 ✔ readr 2.1.5
## ✔ forcats 1.0.0 ✔ stringr 1.6.0
## ✔ ggplot2 4.0.2 ✔ tibble 3.2.1
## ✔ lubridate 1.9.3 ✔ tidyr 1.3.1
## ✔ purrr 1.0.2
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(sf)
## Linking to GEOS 3.11.2, GDAL 3.8.2, PROJ 9.3.1; sf_use_s2() is TRUE
library(osmdata)
## Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
library(leaflet)
library(units)
## udunits database from C:/Users/Asus/AppData/Local/R/win-library/4.3/units/share/udunits/udunits2.xml
library(stringr)
library(ggplot2)
library(tidyr)
library(networkD3)
##
## Attaching package: 'networkD3'
##
## The following object is masked from 'package:leaflet':
##
## JS
library(dplyr)
library(htmlwidgets)
##
## Attaching package: 'htmlwidgets'
##
## The following object is masked from 'package:networkD3':
##
## JS
library(htmltools)
library(webshot2)
library(ggspatial)
library(showtext)
## Loading required package: sysfonts
## Loading required package: showtextdb
library(RColorBrewer)
library(hereR)
library(viridis)
## Loading required package: viridisLite
library(lwgeom)
## Linking to liblwgeom 3.0.0beta1 r16016, GEOS 3.11.2, PROJ 9.3.1
##
## Attaching package: 'lwgeom'
##
## The following objects are masked from 'package:sf':
##
## st_minimum_bounding_circle, st_perimeter
library(grid)
bbox <- getbb("San Salvador de Jujuy, Argentina")
calles <- opq(bbox = bbox, timeout = 300) %>%
add_osm_feature(key = "highway",
value = c("motorway", "primary", "secondary", "tertiary")) %>%
osmdata_sf()
leaflet() %>%
addTiles() %>%
addPolylines(data = calles$osm_lines,
color = "royalblue",
weight = 2,
opacity = 0.8,
group = "Calles") %>%
setView(lng = -65.2995, lat = -24.1858, zoom = 13)
municipio <- "San Salvador de Jujuy, Argentina"
q <- getbb(municipio) %>%
opq() %>%
add_osm_feature(key = "route", value = "bus")
bus_routes <- osmdata_sf(q)
rutas_limpias <- bus_routes$osm_multilines
head(rutas_limpias[, c("name", "ref")])
## Simple feature collection with 6 features and 2 fields
## Geometry type: MULTILINESTRING
## Dimension: XY
## Bounding box: xmin: -65.49014 ymin: -24.25024 xmax: -65.2469 ymax: -24.16131
## Geodetic CRS: WGS 84
## name ref
## 9704061-(no role) Línea 40: Hospital de Niños → La Arbolada 40
## 9704993-(no role) Línea 38: Alem → Termas de Reyes 38
## 9707820-(no role) Línea 23: Villa San Martín → Avenida El Éxodo 23
## 9707987-(no role) Línea 13: Sector B5 → Hospital Pablo Soria 13
## 9709376-(no role) Línea 1: Hospital Snopek → Hospital Pablo Soria 1
## 9717664-(no role) Línea 47: Campo Verde → Alem 47A
## geometry
## 9704061-(no role) MULTILINESTRING ((-65.30236...
## 9704993-(no role) MULTILINESTRING ((-65.30042...
## 9707820-(no role) MULTILINESTRING ((-65.29032...
## 9707987-(no role) MULTILINESTRING ((-65.25782...
## 9709376-(no role) MULTILINESTRING ((-65.25586...
## 9717664-(no role) MULTILINESTRING ((-65.29174...
rutas_limpias <- rutas_limpias %>%
mutate(longitud=st_length(rutas_limpias))
head(rutas_limpias)
## Simple feature collection with 6 features and 12 fields
## Geometry type: MULTILINESTRING
## Dimension: XY
## Bounding box: xmin: -65.49014 ymin: -24.25024 xmax: -65.2469 ymax: -24.16131
## Geodetic CRS: WGS 84
## osm_id name
## 9704061-(no role) 9704061 Línea 40: Hospital de Niños → La Arbolada
## 9704993-(no role) 9704993 Línea 38: Alem → Termas de Reyes
## 9707820-(no role) 9707820 Línea 23: Villa San Martín → Avenida El Éxodo
## 9707987-(no role) 9707987 Línea 13: Sector B5 → Hospital Pablo Soria
## 9709376-(no role) 9709376 Línea 1: Hospital Snopek → Hospital Pablo Soria
## 9717664-(no role) 9717664 Línea 47: Campo Verde → Alem
## role from operator
## 9704061-(no role) (no role) Hospital de Niños Transporte Xibi- Xibi
## 9704993-(no role) (no role) Alem Santa Ana
## 9707820-(no role) (no role) Punta Diamante San Jorge
## 9707987-(no role) (no role) Sector B5 El Urbano
## 9709376-(no role) (no role) Hospital Snopek El Urbano
## 9717664-(no role) (no role) Campo Verde El Urbano
## public_transport:version ref route to type
## 9704061-(no role) 2 40 bus La Arbolada route
## 9704993-(no role) 38 bus Termas de Reyes route
## 9707820-(no role) 2 23 bus Terminal route
## 9707987-(no role) 2 13 bus Hospital Pablo Soria route
## 9709376-(no role) 2 1 bus Hospital Pablo Soria route
## 9717664-(no role) 2 47A bus Alem route
## via geometry longitud
## 9704061-(no role) MULTILINESTRING ((-65.30236... 9736.677 [m]
## 9704993-(no role) MULTILINESTRING ((-65.30042... 24813.398 [m]
## 9707820-(no role) MULTILINESTRING ((-65.29032... 6741.800 [m]
## 9707987-(no role) MULTILINESTRING ((-65.25782... 14835.845 [m]
## 9709376-(no role) MULTILINESTRING ((-65.25586... 14604.649 [m]
## 9717664-(no role) MULTILINESTRING ((-65.29174... 7308.490 [m]
rutas_limpias$longitud <- str_remove(rutas_limpias$longitud, fixed(" [m]"))
rutas_limpias$longitud <- as.numeric(rutas_limpias$longitud) / 1000
rutas_limpias <- rutas_limpias %>%
filter(
!name %in% c(
"Línea 36: León → Alem",
"Línea 39: Alem → León"))
limites <- st_bbox(rutas_limpias)
ggplot() +
geom_sf(data = calles$osm_lines, color = "grey85", linewidth = 0.2) +
geom_sf(data = rutas_limpias, aes(color = operator, linewidth = longitud)) +
scale_linewidth_continuous(range = c(0.25, 1)) +
coord_sf(xlim = c(limites["xmin"], limites["xmax"]),
ylim = c(limites["ymin"], limites["ymax"])) +
labs(
title = "LINEAS DE BUSES en San Salvador de Jujuy",
subtitle = "Extension de Recorridos por Lineas",
caption = "Elaboración:\nJuan José VARGAS\narquitecto & urban manager",
color = "Empresa Operadora") +
guides(linewidth = "none") +
theme_minimal() +
theme(
axis.text = element_blank(),
axis.title = element_blank(),
axis.ticks = element_blank(),
panel.grid = element_blank(),
plot.caption = element_text(face = "bold", size = 9, hjust = 0.5, color = "grey20", vjust = -1) )

rutas_limpias <- st_transform(rutas_limpias, crs = 4326)
calles$osm_lines <- st_transform(calles$osm_lines, crs = 4326)
velocidad_promedio <- 18
rutas_limpias <- rutas_limpias %>%
mutate(
longitud_km = as.numeric(st_length(geometry)) / 1000,
tiempo_minutos = (longitud_km / velocidad_promedio) * 60,
ORIGEN = ifelse("from" %in% names(.), from, "Inicio"),
DESTINO = ifelse("to" %in% names(.), to, "Final"),
LINEA = ifelse("ref" %in% names(.), ref, "S/N")
)
puntos_extremos <- rutas_limpias %>%
rowwise() %>%
mutate(
coords = list(st_coordinates(geometry)),
lon_ini = coords[1, 1],
lat_ini = coords[1, 2],
lon_fin = coords[nrow(coords), 1],
lat_fin = coords[nrow(coords), 2]
) %>%
ungroup()
bounds <- st_bbox(rutas_limpias)
ggplot(data = rutas_limpias, aes(x = reorder(ref, -longitud), y = longitud, fill = operator)) +
geom_col(show.legend = TRUE) +
geom_text(aes(label = round(longitud, 1)), vjust = -0.5, size = 3, fontface = "bold") +
labs(
title = "Extensión de Recorridos por Operador de Línea",
subtitle = "San Salvador de Jujuy",
x = "Línea de Bus (REF)",
y = "Longitud (km)",
fill = "Empresa Operadora",
caption = "Elaboración:\nJuan José VARGAS\narquitecto & urban manager" ) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
plot.title = element_text(face = "bold", size = 14),
plot.caption = element_text(face = "bold", size = 9, hjust = 0.5, color = "grey20", vjust = -1),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank() )

pal <- colorFactor("Paired", domain = rutas_limpias$ref)
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
fitBounds(lng1 = bounds[["xmin"]], lat1 = bounds[["ymin"]],
lng2 = bounds[["xmax"]], lat2 = bounds[["ymax"]]) %>%
addPolylines(data = calles$osm_lines, color = "grey", weight = 1, opacity = 0.2) %>%
addPolylines(data = rutas_limpias,
color = ~pal(ref),
weight = ~longitud * 0.5,
opacity = 0.6,
group = "Recorridos",
popup = ~paste0("<b>Línea:</b> ", ref,
"<br><b>Longitud:</b> ", round(longitud, 2), " km",
"<br><b>Empresa:</b> ", operator)) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_ini, lat = ~lat_ini,
color = ~pal(ref), fillColor = ~pal(ref),
fillOpacity = 0.2, weight = 1, radius = 10, stroke = FALSE) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_fin, lat = ~lat_fin,
color = ~pal(ref), fillColor = ~pal(ref),
fillOpacity = 0.2, weight = 1, radius = 10, stroke = FALSE) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_ini, lat = ~lat_ini,
color = "white", fillColor = ~pal(ref),
fillOpacity = 1, weight = 1.5, radius = 4, stroke = TRUE,
label = ~paste("INICIO - Línea", ref)) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_fin, lat = ~lat_fin,
color = "white", fillColor = ~pal(ref),
fillOpacity = 1, weight = 1.5, radius = 4, stroke = TRUE,
label = ~paste("FINAL - Línea", ref)) %>%
addLegend(pal = pal, values = rutas_limpias$ref,
title = "Línea de Colectivo", position = "bottomleft") %>%
addControl(
html = "<div style='background: rgba(255,255,255,0.8); padding: 10px; border-radius: 8px;
box-shadow: 0 0 15px rgba(0,0,0,0.1); text-align: center;'>
<span style='font-weight: bold; color: #444; font-size: 14px;'>MOVILIDAD URBANA</span><br>
<span style='font-size: 12px; color: #666;'>Recorrido por Linea de Operador (km)</span><hr style='margin: 5px 0;'>
<span style='font-weight: bold; font-size: 13px;'>Juan J. VARGAS</span><br>
<span style='font-size: 10px; text-transform: uppercase;'>arquitecto & urban manager</span>
</div>",
position = "bottomright")
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
## Warning in RColorBrewer::brewer.pal(max(3, n), palette): n too large, allowed maximum for palette Paired is 12
## Returning the palette you asked for with that many colors
top_rutas <- rutas_limpias %>%
arrange(desc(longitud)) %>%
head(20)
ggplot(data = top_rutas, aes(x = reorder(ref, -longitud), y = longitud, fill = operator)) +
geom_col(show.legend = TRUE, color = "white", size = 0.2) +
geom_text(aes(label = paste0(round(longitud, 1), " km")),
vjust = -0.7,
size = 3.2,
fontface = "bold",
color = "grey30") +
scale_fill_brewer(palette = "Set1") +
labs(
title = "EXTENSIÓN DE RECORRIDOS POR LÍNEA",
subtitle = "San Salvador de Jujuy | Líneas con mayor extensión",
x = "Número de Línea (REF)",
y = "Extensión Total (km)",
fill = "Empresa Operadora",
caption = "Elaboración:\nJuan J. VARGAS\narquitecto & urban manager"
) +
scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1, face = "bold", size = 10),
axis.title = element_text(face = "bold", color = "grey40"),
plot.title = element_text(face = "bold", size = 16, color = "#2c3e50"),
plot.subtitle = element_text(size = 11, color = "#7f8c8d", margin = margin(b = 20)),
plot.caption = element_text(face = "bold", size = 9, hjust = 0.5, color = "grey20", vjust = -2, lineheight = 1.2),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
legend.position = "bottom",
plot.margin = margin(1, 1, 1.5, 1, "cm")
)
## Warning in geom_col(show.legend = TRUE, color = "white", size = 0.2): Ignoring
## unknown parameters: `size`

velocidad_promedio <- 18 # km/h
rutas_limpias <- rutas_limpias %>%
mutate(
longitud = as.numeric(st_length(.)) / 1000,
tiempo_minutos = (longitud / velocidad_promedio) * 60
)
puntos_extremos <- rutas_limpias %>%
rowwise() %>%
mutate(
coords = list(st_coordinates(geometry)),
lon_ini = coords[1, 1], lat_ini = coords[1, 2],
lon_fin = coords[nrow(coords), 1], lat_fin = coords[nrow(coords), 2]
) %>%
ungroup()
color_profesional <- "#1B4F72"
leaflet() %>%
addProviderTiles(providers$CartoDB.Positron) %>%
fitBounds(lng1 = min(puntos_extremos$lon_ini), lat1 = min(puntos_extremos$lat_ini),
lng2 = max(puntos_extremos$lon_ini), lat2 = max(puntos_extremos$lat_ini)) %>%
addPolylines(data = calles$osm_lines, color = "grey", weight = 1, opacity = 0.2) %>%
addPolylines(data = rutas_limpias,
color = color_profesional,
weight = ~tiempo_minutos * 0.2,
opacity = 0.6,
group = "Recorridos",
popup = ~paste0("<b>Línea:</b> ", ref,
"<br><b>Origen:</b> ", from,
"<br><b>Destino:</b> ", to,
"<br><b>Duración Est.:</b> ", round(tiempo_minutos, 0), " min")) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_ini, lat = ~lat_ini,
color = color_profesional, fillColor = color_profesional,
fillOpacity = 0.2, weight = 1, radius = 12, stroke = FALSE) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_ini, lat = ~lat_ini,
color = "white", fillColor = color_profesional,
fillOpacity = 1, weight = 1.5, radius = 5, stroke = TRUE,
label = ~paste("ORIGEN:", from)) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_fin, lat = ~lat_fin,
color = color_profesional, fillColor = color_profesional,
fillOpacity = 0.2, weight = 1, radius = 12, stroke = FALSE) %>%
addCircleMarkers(data = puntos_extremos, lng = ~lon_fin, lat = ~lat_fin,
color = "white", fillColor = color_profesional,
fillOpacity = 1, weight = 1.5, radius = 5, stroke = TRUE,
label = ~paste("DESTINO:", to)) %>%
addControl(
html = "<div style='background: rgba(255,255,255,0.9); padding: 12px; border-radius: 8px;
box-shadow: 0 0 15px rgba(0,0,0,0.15); text-align: center; border-left: 5px solid #1B4F72;'>
<span style='font-weight: bold; color: #1B4F72; font-size: 15px;'>MOVILIDAD URBANA</span><br>
<span style='font-size: 12px; color: #555;'>Jerarquía por Tiempo de Viaje (min)</span><hr style='margin: 6px 0;'>
<span style='font-weight: bold; font-size: 13px;'>Juan J. VARGAS</span><br>
<span style='font-size: 10px; text-transform: uppercase; color: #777;'>arquitecto & urban manager</span>
</div>",
position = "bottomright")
links <- rutas_limpias %>%
st_drop_geometry() %>%
select(from, to, tiempo_minutos) %>%
rename(source = from, target = to, value = tiempo_minutos) %>%
mutate(value = round(value, 0))
nodes <- data.frame(
name = c(as.character(links$source), as.character(links$target)) %>% unique()
)
links$IDsource <- match(links$source, nodes$name) - 1
links$IDtarget <- match(links$target, nodes$name) - 1
sankey <- sankeyNetwork(
Links = links,
Nodes = nodes,
Source = "IDsource",
Target = "IDtarget",
Value = "value",
NodeID = "name",
units = "minutos",
fontSize = 12,
nodeWidth = 30,
colourScale = JS('d3.scaleOrdinal().range(["#1B4F72"])')
)
sankey_final <- sankey %>%
prependContent(
tags$h2("SISTEMA DE TRANSPORTE PÚBLICO ACTUAL",
style = "font-family: Arial; font-weight: bold; color: #1B4F72; text-align: center; margin-top: 20px;"),
tags$h4("Sistema de Viajes Radiales",
style = "font-family: Arial; color: #666; text-align: center; margin-bottom: 20px;")
) %>%
appendContent(
tags$div(
style = "text-align: center; margin-top: 20px; font-family: Arial; border-top: 1px solid #eee; padding-top: 10px;",
tags$p(style = "margin: 0; font-weight: bold; color: #333; font-size: 13px;", "Elaboración:"),
tags$p(style = "margin: 0; font-weight: bold; color: #1B4F72; font-size: 15px;", "Juan José VARGAS"),
tags$p(style = "margin: 0; color: #777; font-size: 11px; text-transform: uppercase;", "arquitecto & urban manager")
)
)
sankey_final
Elaboración:
Juan José VARGAS
arquitecto & urban manager
#exportar imagen completa
ctm_nombre <- "CENTROS DE TRANSFERENCIA MODAL"
red_alimentadora <- rutas_limpias %>%
st_drop_geometry() %>%
select(from, tiempo_minutos) %>%
rename(source = from) %>%
mutate(
target = ctm_nombre,
value = round(tiempo_minutos * 0.5, 0)
)
red_troncal <- rutas_limpias %>%
st_drop_geometry() %>%
select(to, tiempo_minutos) %>%
rename(target = to) %>%
mutate(
source = ctm_nombre,
value = round(tiempo_minutos * 0.15, 0)
) %>%
group_by(source, target) %>%
summarise(value = sum(value), .groups = 'drop')
links_total <- bind_rows(red_alimentadora, red_troncal)
nodes <- data.frame(name = unique(c(links_total$source, links_total$target)))
links_total$IDsource <- match(links_total$source, nodes$name) - 1
links_total$IDtarget <- match(links_total$target, nodes$name) - 1
sankey_jujuy <- sankeyNetwork(
Links = links_total,
Nodes = nodes,
Source = "IDsource",
Target = "IDtarget",
Value = "value",
NodeID = "name",
units = "minutos",
fontSize = 12,
nodeWidth = 40,
nodePadding = 15,
colourScale = JS('d3.scaleOrdinal().range(["#1B4F72"])')
)
sankey_final <- sankey_jujuy %>%
prependContent(
tags$h2("SISTEMA DE TRANSPORTE INTEGRADO San Salvador de Jujuy",
style = "font-family: sans-serif; font-weight: bold; color: #1B4F72; text-align: center;"),
tags$h4("Red Alimentadora y Troncal",
style = "font-family: sans-serif; color: #666; text-align: center; margin-bottom: 20px;")
) %>%
appendContent(
tags$div(
style = "text-align: center; margin-top: 20px; font-family: sans-serif; border-top: 1px solid #eee; padding-top: 10px;",
tags$p(style = "margin: 0; font-weight: bold; color: #333; font-size: 13px;", "Elaboración:"),
tags$p(style = "margin: 0; font-weight: bold; color: #1B4F72; font-size: 15px;", "Juan José VARGAS"),
tags$p(style = "margin: 0; color: #777; font-size: 11px; text-transform: uppercase;", "arquitecto & urban manager")
)
)
sankey_final
Elaboración:
Juan José VARGAS
arquitecto & urban manager
top_tiempos <- rutas_limpias %>%
arrange(desc(tiempo_minutos)) %>%
head(20)
ggplot(data = top_tiempos, aes(x = reorder(ref, -tiempo_minutos), y = tiempo_minutos, fill = operator)) +
geom_col(show.legend = TRUE, color = "white", size = 0.2) +
geom_text(aes(label = paste0(round(tiempo_minutos, 0), " min")),
vjust = -0.7,
size = 3.2,
fontface = "bold",
color = "grey30") +
scale_fill_brewer(palette = "Set1") +
labs(
title = "TIEMPO DE VIAJE ESTIMADO",
subtitle = "San Salvador de Jujuy | Basado en la velocidad urbana promedio para transporte público",
x = "Número de Línea (REF)",
y = "Duración Estimada (minutos)",
fill = "Empresa Operadora",
caption = "Elaboración:\nJuan J. VARGAS\narquitecto & urban manager") +
scale_y_continuous(expand = expansion(mult = c(0, 0.15))) +
theme_minimal() +
theme(
axis.text.x = element_text(angle = 45, hjust = 1, face = "bold", size = 10),
axis.title = element_text(face = "bold", color = "grey40"),
plot.title = element_text(face = "bold", size = 16, color = "#2c3e50"),
plot.subtitle = element_text(size = 11, color = "#7f8c8d", margin = margin(b = 20)),
plot.caption = element_text(face = "bold", size = 9, hjust = 0.5, color = "grey20", vjust = -2, lineheight = 1.2),
panel.grid.minor = element_blank(),
panel.grid.major.x = element_blank(),
legend.position = "bottom",
plot.margin = margin(1, 1, 1.5, 1, "cm") )
## Warning in geom_col(show.legend = TRUE, color = "white", size = 0.2): Ignoring
## unknown parameters: `size`

font_add_google("Roboto", "roboto")
showtext_auto()
mapa_estatico <- ggplot() +
geom_sf(data = calles$osm_lines, color = "grey85", size = 0.2) +
geom_sf(data = rutas_limpias, aes(color = operator), size = 1.2, alpha = 0.8) +
geom_point(data = puntos_extremos, aes(x = lon_ini, y = lat_ini, color = operator),
size = 4, alpha = 0.3) +
geom_point(data = puntos_extremos, aes(x = lon_fin, y = lat_fin, color = operator),
size = 4, alpha = 0.3) +
geom_point(data = puntos_extremos, aes(x = lon_ini, y = lat_ini, fill = operator),
shape = 21, color = "white", size = 2.5, stroke = 0.8) +
geom_point(data = puntos_extremos, aes(x = lon_fin, y = lat_fin, fill = operator),
shape = 21, color = "white", size = 2.5, stroke = 0.8) +
scale_color_brewer(palette = "Set1") +
scale_fill_brewer(palette = "Set1") +
coord_sf(xlim = c(bounds[["xmin"]], bounds[["xmax"]]),
ylim = c(bounds[["ymin"]], bounds[["ymax"]])) +
labs(
title = "MOVILIDAD URBANA",
subtitle = "Recorridos y nodos de inicio/fin por empresa operadora",
caption = "JUAN J. VARGAS\nARQUITECTO & URBAN MANAGER",
color = "Operador",
fill = "Operador"
) +
theme_minimal() +
theme(
text = element_text(family = "roboto", color = "#333333"),
plot.title = element_text(face = "bold", size = 18, hjust = 0.5),
plot.subtitle = element_text(size = 11, hjust = 0.5, margin = margin(b = 20)),
plot.caption = element_text(face = "bold", size = 9, lineheight = 1.1, color = "#555555"),
panel.grid = element_blank(),
panel.background = element_rect(fill = "#fcfcfc", color = NA),
legend.position = "right",
legend.title = element_text(face = "bold")
)
print(mapa_estatico)
font_add_google("Roboto", "roboto")
showtext_auto()
n_lineas <- length(unique(rutas_limpias$ref))
colores_expandidos <- colorRampPalette(brewer.pal(12, "Paired"))(n_lineas)
mapa_lineas <- ggplot() +
geom_sf(data = calles$osm_lines, color = "grey88", size = 0.2) +
geom_sf(data = rutas_limpias,
aes(color = ref, size = longitud),
alpha = 0.8) +
geom_point(data = puntos_extremos, aes(x = lon_ini, y = lat_ini, color = ref),
size = 4, alpha = 0.3) +
geom_point(data = puntos_extremos, aes(x = lon_fin, y = lat_fin, color = ref),
size = 4, alpha = 0.3) +
geom_point(data = puntos_extremos, aes(x = lon_ini, y = lat_ini, fill = ref),
shape = 21, color = "white", size = 2, stroke = 0.7) +
geom_point(data = puntos_extremos, aes(x = lon_fin, y = lat_fin, fill = ref),
shape = 21, color = "white", size = 2, stroke = 0.7) +
scale_color_manual(values = colores_expandidos) +
scale_fill_manual(values = colores_expandidos) +
scale_size_continuous(range = c(0.6, 2.2), guide = "none") +
coord_sf(xlim = c(bounds[["xmin"]], bounds[["xmax"]]),
ylim = c(bounds[["ymin"]], bounds[["ymax"]])) +
labs(
title = "REDES DE TRANSPORTE PÚBLICO - San Salvador de Jujuy",
subtitle = "Recorrido de Línea por Operador",
caption = "JUAN J. VARGAS\nARQUITECTO & URBAN MANAGER",
color = "Línea de Colectivo",
fill = "Línea de Colectivo"
) +
theme_minimal() +
theme(
text = element_text(family = "roboto", color = "#333333"),
plot.title = element_text(face = "bold", size = 18, hjust = 0.5),
plot.subtitle = element_text(size = 11, hjust = 0.5, margin = margin(b = 15)),
plot.caption = element_text(face = "bold", size = 8, lineheight = 1.1, color = "#555555"),
panel.grid = element_blank(),
panel.background = element_rect(fill = "#fdfdfd", color = NA),
legend.position = "right",
legend.text = element_text(size = 7),
legend.key.height = unit(0.3, "cm")) +
guides(color = guide_legend(ncol = 2), fill = guide_legend(ncol = 2))
print(mapa_lineas)