library(readxl)
library(dplyr)
library(sf)
library(ggplot2)
library(janitor)
library(tidyr)
library(viridis)
library(knitr)
library(stringr)
library(scales)
library(grid)

knitr::opts_chunk$set(
  echo = TRUE,
  message = FALSE,
  warning = FALSE,
  fig.align = "center",
  dpi = 150,
  out.width = "100%"
)

theme_set(theme_minimal(base_family = "Arial"))

proyecto_dir <- "C:/Users/Usuario/Documents/PROYECTOS GEO/ACTIVIDAD 1"
if (!dir.exists(file.path(proyecto_dir, "Casos"))) {
  proyecto_dir <- getwd()
}

paletas <- list(
  origen = c("#fff7bc", "#fec44f", "#fe9929", "#d95f0e", "#8c2d04"),
  destino = c("#edf8fb", "#b2e2e2", "#66c2a4", "#2ca25f", "#006d2c"),
  bicicleta = c("#f7fcf5", "#c7e9c0", "#74c476", "#238b45", "#005a32"),
  moto = c("#fff5eb", "#fdd0a2", "#fd8d3c", "#e6550d", "#a63603"),
  automovil = c("#eff3ff", "#bdd7e7", "#6baed6", "#3182bd", "#08519c"),
  flujo = c("#f7f7f7", "#cccccc", "#969696", "#636363", "#252525")
)

formato_num <- function(x) comma(x, big.mark = ".", decimal.mark = ",")

nota_html <- function(titulo, texto) {
  sprintf(
    '<div class="nota"><strong>%s.</strong> %s</div>',
    titulo,
    texto
  )
}

1 Introducción

Este reporte analiza los viajes origen-destino registrados en la encuesta, usando como unidad espacial las comunas de Cali. El interés principal es identificar las comunas desde donde sale la mayor cantidad de personas, diferenciar el patrón según tipo de vehículo y observar hacia dónde se dirigen los viajes que parten de los principales lugares de origen.

El ejercicio se conecta con el objetivo de la unidad: reconocer áreas de la estadística espacial y tipos de datos espaciales mediante una aplicación real. En este caso se combinan datos tabulares de encuesta con datos vectoriales de polígonos comunales.

encuesta <- read_excel(file.path(proyecto_dir, "Casos/EncuestaOrigenDestino.xlsx"), sheet = "Hoja1") %>%
  clean_names()

comunas <- st_read(file.path(proyecto_dir, "Casos/cali/Comunas.shp"), quiet = TRUE)

2 Preparación de los datos

35.054
Registros de la encuesta
28.076
Viajes con origen en comuna cartografiable
27.866
Viajes con destino en comuna cartografiable
31.908
Viajes en bicicleta, moto o automóvil
encuesta_limpia %>%
  count(vehiculo_nombre, sort = TRUE, name = "total_viajes") %>%
  mutate(porcentaje = percent(total_viajes / sum(total_viajes), accuracy = 0.1, decimal.mark = ",")) %>%
  kable(caption = "Distribución de viajes por tipo de vehículo")
Distribución de viajes por tipo de vehículo
vehiculo_nombre total_viajes porcentaje
Moto 16077 45,9%
Automóvil 14100 40,2%
Otro 3146 9,0%
Bicicleta 1731 4,9%
cat(nota_html(
  "Criterio espacial",
  "Los registros marcados como 'Fuera de Cali', valores cero o valores vacíos se conservan en el diagnóstico, pero no se dibujan en los mapas de comunas porque no tienen un polígono equivalente en la cartografía usada."
))
Criterio espacial. Los registros marcados como ‘Fuera de Cali’, valores cero o valores vacíos se conservan en el diagnóstico, pero no se dibujan en los mapas de comunas porque no tienen un polígono equivalente en la cartografía usada.

3 Técnicas aplicadas

Para solucionar el caso se aplicaron técnicas descriptivas y cartográficas propias del análisis espacial. Primero se integró una base tabular de viajes con una capa vectorial de comunas; luego se limpiaron y estandarizaron los códigos de origen, destino y tipo de vehículo; finalmente se construyeron mapas temáticos para representar la intensidad de viajes por comuna.

Las técnicas usadas en el reporte son:

  • Limpieza y codificación de datos: transformación de códigos de comuna y clasificación del tipo de vehículo.
  • Agregación espacial: conteo de viajes por comuna de origen y comuna de destino.
  • Unión tabular con cartografía: asociación de los conteos de viajes con los polígonos de comunas.
  • Mapas coropléticos: representación temática de la cantidad de viajes mediante intensidad de color.
  • Comparación por modo de transporte: análisis separado para bicicleta, moto y automóvil.
  • Relaciones origen-destino: identificación de destinos asociados a los principales lugares de salida.

Estas técnicas son adecuadas porque el problema combina datos de movilidad con unidades espaciales discretas. El mapa coroplético permite reconocer concentración territorial, mientras que la desagregación por vehículo ayuda a detectar patrones espaciales diferenciados.

3.1 Código de apoyo cartográfico

Las siguientes funciones construyen una estética común para los mapas, asignan paletas diferenciadas por tema y resaltan las comunas con mayor cantidad de viajes. El código queda plegado por defecto y se puede desplegar desde el botón de visualización del reporte HTML.

tema_mapa <- function() {
  theme_void(base_family = "Arial") +
    theme(
      plot.title = element_text(face = "bold", size = 17, color = "#12343b"),
      plot.subtitle = element_text(size = 11, color = "#455a64", margin = margin(b = 8)),
      plot.caption = element_text(size = 8.5, color = "#607d8b", hjust = 0),
      legend.position = "right",
      legend.title = element_text(face = "bold", size = 9),
      legend.text = element_text(size = 8),
      panel.grid = element_blank(),
      plot.margin = margin(10, 12, 10, 12)
    )
}

preparar_mapa <- function(tabla, variable_tabla) {
  comunas_limpias %>%
    left_join(tabla, by = c("comuna_num" = variable_tabla)) %>%
    mutate(
      total_viajes = replace_na(total_viajes, 0L),
      etiqueta_top = if_else(
        total_viajes > 0 & min_rank(desc(total_viajes)) <= 5,
        paste0("C", comuna_num, "\n", formato_num(total_viajes)),
        NA_character_
      )
    )
}

dibujar_mapa_coropletico <- function(mapa, titulo, subtitulo, paleta, leyenda = "Viajes",
                                     resaltar_comuna = NULL) {
  base <- ggplot(mapa) +
    geom_sf(aes(fill = total_viajes), color = "#ffffff", linewidth = 0.28) +
    geom_sf(data = filter(mapa, total_viajes == 0), fill = NA, color = "#d8d8d8",
            linewidth = 0.22, linetype = "dotted") +
    geom_sf_text(aes(label = comuna_num), size = 2.6, color = "#263238", alpha = 0.75) +
    geom_sf_label(
      data = filter(mapa, !is.na(etiqueta_top)),
      aes(label = etiqueta_top),
      size = 3,
      label.size = 0.15,
      label.padding = unit(0.12, "lines"),
      fill = "white",
      color = "#1d2b2f",
      alpha = 0.94
    )

  if (!is.null(resaltar_comuna)) {
    base <- base +
      geom_sf(
        data = filter(mapa, comuna_num == resaltar_comuna),
        fill = NA,
        color = "#111111",
        linewidth = 1
      )
  }

  base +
    scale_fill_gradientn(
      colors = paleta,
      labels = formato_num,
      name = leyenda,
      guide = guide_colorbar(barheight = unit(70, "pt"), barwidth = unit(10, "pt"))
    ) +
    labs(
      title = titulo,
      subtitle = subtitulo,
      caption = "Fuente: Encuesta Origen-Destino y cartografía de comunas de Cali."
    ) +
    coord_sf(datum = NA) +
    tema_mapa()
}

crear_mapa_origen <- function(nombre_vehiculo = NULL) {
  datos <- encuesta_limpia %>%
    filter(!is.na(comuna_origen_num))

  titulo <- "Mapa general de origen de viajes"
  subtitulo <- "Cantidad de viajes que salen desde cada comuna"
  paleta <- paletas$origen

  if (!is.null(nombre_vehiculo)) {
    datos <- datos %>% filter(vehiculo_nombre == nombre_vehiculo)
    titulo <- paste("Origen de viajes en", nombre_vehiculo)
    subtitulo <- paste("Comunas desde donde salen los viajes realizados en", nombre_vehiculo)
    paleta <- switch(
      nombre_vehiculo,
      "Bicicleta" = paletas$bicicleta,
      "Moto" = paletas$moto,
      "Automóvil" = paletas$automovil,
      paletas$origen
    )
  }

  tabla <- datos %>%
    count(comuna_origen_num, name = "total_viajes")

  preparar_mapa(tabla, "comuna_origen_num") %>%
    dibujar_mapa_coropletico(titulo, subtitulo, paleta)
}

crear_mapa_destino <- function(nombre_vehiculo = NULL) {
  datos <- encuesta_limpia %>%
    filter(!is.na(comuna_destino_num))

  titulo <- "Mapa general de destino de viajes"
  subtitulo <- "Cantidad de viajes que llegan a cada comuna"
  paleta <- paletas$destino

  if (!is.null(nombre_vehiculo)) {
    datos <- datos %>% filter(vehiculo_nombre == nombre_vehiculo)
    titulo <- paste("Destino de viajes en", nombre_vehiculo)
    subtitulo <- paste("Comunas a donde llegan los viajes realizados en", nombre_vehiculo)
    paleta <- switch(
      nombre_vehiculo,
      "Bicicleta" = paletas$bicicleta,
      "Moto" = paletas$moto,
      "Automóvil" = paletas$automovil,
      paletas$destino
    )
  }

  tabla <- datos %>%
    count(comuna_destino_num, name = "total_viajes")

  preparar_mapa(tabla, "comuna_destino_num") %>%
    dibujar_mapa_coropletico(titulo, subtitulo, paleta)
}

crear_mapa_destino_desde_origen <- function(origen_elegido, nombre_vehiculo = NULL) {
  datos <- encuesta_limpia %>%
    filter(
      comuna_origen_num == origen_elegido,
      !is.na(comuna_destino_num)
    )

  titulo <- paste("Destinos de viajes que salen desde la comuna", origen_elegido)
  subtitulo <- "Distribución espacial de los destinos asociados al origen seleccionado"
  paleta <- paletas$flujo

  if (!is.null(nombre_vehiculo)) {
    datos <- datos %>% filter(vehiculo_nombre == nombre_vehiculo)
    titulo <- paste("Destinos desde la comuna", origen_elegido, "en", nombre_vehiculo)
    subtitulo <- paste("Flujos de destino para viajes realizados en", nombre_vehiculo)
    paleta <- switch(
      nombre_vehiculo,
      "Bicicleta" = paletas$bicicleta,
      "Moto" = paletas$moto,
      "Automóvil" = paletas$automovil,
      paletas$flujo
    )
  }

  tabla <- datos %>%
    count(comuna_destino_num, name = "total_viajes")

  preparar_mapa(tabla, "comuna_destino_num") %>%
    dibujar_mapa_coropletico(
      titulo,
      subtitulo,
      paleta,
      leyenda = "Viajes destino",
      resaltar_comuna = origen_elegido
    )
}

4 Mapa general de origen

crear_mapa_origen()

cat(sprintf(
  '<div class="conclusion"><strong>Lectura del mapa.</strong> La comuna con mayor número de viajes de origen es la comuna %s (%s), con %s viajes registrados. Esto indica una mayor intensidad de salida frente al resto de comunas cartografiadas.</div>',
  origen_principal,
  origen_principal_nombre,
  formato_num(top_origenes$total_viajes[1])
))
Lectura del mapa. La comuna con mayor número de viajes de origen es la comuna 2 (Comuna 2), con 2.968 viajes registrados. Esto indica una mayor intensidad de salida frente al resto de comunas cartografiadas.
top_origenes %>%
  transmute(
    comuna = comuna_origen_num,
    nombre_comuna,
    viajes_salida = total_viajes
  ) %>%
  slice_head(n = 10) %>%
  kable(caption = "Diez comunas con mayor cantidad de viajes de origen")
Diez comunas con mayor cantidad de viajes de origen
comuna nombre_comuna viajes_salida
2 Comuna 2 2968
19 Comuna 19 2850
17 Comuna 17 2377
3 Comuna 3 2121
18 Comuna 18 1536
4 Comuna 4 1493
10 Comuna 10 1401
13 Comuna 13 1238
15 Comuna 15 1171
22 Comuna 22 1153

5 Origen por tipo de vehículo

La desagregación por vehículo permite comparar patrones espaciales distintos. Bicicleta, moto y automóvil no necesariamente salen de las mismas comunas con la misma intensidad; por eso cada mapa usa una paleta propia.

5.1 Bicicleta

crear_mapa_origen("Bicicleta")

5.2 Moto

crear_mapa_origen("Moto")

5.3 Automóvil

crear_mapa_origen("Automóvil")

tabla_origenes_vehiculo <- encuesta_limpia %>%
  filter(
    vehiculo_nombre %in% vehiculos_interes,
    !is.na(comuna_origen_num)
  ) %>%
  count(vehiculo_nombre, comuna_origen_num, name = "total_viajes") %>%
  left_join(st_drop_geometry(comunas_limpias) %>% select(comuna_num, nombre_comuna),
            by = c("comuna_origen_num" = "comuna_num")) %>%
  arrange(vehiculo_nombre, desc(total_viajes))

tabla_origenes_vehiculo %>%
  group_by(vehiculo_nombre) %>%
  slice_max(order_by = total_viajes, n = 5, with_ties = FALSE) %>%
  ungroup() %>%
  transmute(
    vehiculo = vehiculo_nombre,
    comuna = comuna_origen_num,
    nombre_comuna,
    viajes_salida = total_viajes
  ) %>%
  kable(caption = "Cinco principales comunas de origen por tipo de vehículo")
Cinco principales comunas de origen por tipo de vehículo
vehiculo comuna nombre_comuna viajes_salida
Automóvil 19 Comuna 19 1165
Automóvil 2 Comuna 2 1121
Automóvil 17 Comuna 17 899
Automóvil 3 Comuna 3 854
Automóvil 18 Comuna 18 559
Bicicleta 2 Comuna 2 159
Bicicleta 17 Comuna 17 141
Bicicleta 19 Comuna 19 141
Bicicleta 18 Comuna 18 111
Bicicleta 3 Comuna 3 99
Moto 2 Comuna 2 1414
Moto 19 Comuna 19 1280
Moto 17 Comuna 17 1136
Moto 3 Comuna 3 970
Moto 18 Comuna 18 746
top_origen_vehiculo <- tabla_origenes_vehiculo %>%
  group_by(vehiculo_nombre) %>%
  slice_max(order_by = total_viajes, n = 1, with_ties = FALSE) %>%
  ungroup()

texto_origen_vehiculo <- top_origen_vehiculo %>%
  mutate(
    frase = sprintf(
      "%s presenta su mayor origen en la comuna %s (%s), con %s viajes",
      vehiculo_nombre,
      comuna_origen_num,
      nombre_comuna,
      formato_num(total_viajes)
    )
  ) %>%
  pull(frase) %>%
  paste(collapse = "; ")

cat(sprintf(
  '<div class="conclusion"><strong>Interpretación comparativa.</strong> %s. Esto muestra que la movilidad no tiene una distribución única: cada modo de transporte concentra sus salidas en comunas específicas, por lo que el análisis por vehículo aporta más detalle que el mapa general.</div>',
  texto_origen_vehiculo
))
Interpretación comparativa. Automóvil presenta su mayor origen en la comuna 19 (Comuna 19), con 1.165 viajes; Bicicleta presenta su mayor origen en la comuna 2 (Comuna 2), con 159 viajes; Moto presenta su mayor origen en la comuna 2 (Comuna 2), con 1.414 viajes. Esto muestra que la movilidad no tiene una distribución única: cada modo de transporte concentra sus salidas en comunas específicas, por lo que el análisis por vehículo aporta más detalle que el mapa general.

6 Mapas de destino

Los mapas de destino muestran hacia dónde llegan los viajes. Esta lectura complementa los mapas de origen porque una comuna puede producir muchos viajes, recibir muchos viajes o cumplir ambas funciones.

crear_mapa_destino()

cat(sprintf(
  '<div class="conclusion"><strong>Lectura del mapa.</strong> La comuna con mayor número de llegadas es la comuna %s (%s), con %s viajes. Comparar esta comuna con el principal origen ayuda a distinguir zonas generadoras y zonas atractoras de viajes.</div>',
  destino_principal,
  destino_principal_nombre,
  formato_num(top_destinos$total_viajes[1])
))
Lectura del mapa. La comuna con mayor número de llegadas es la comuna 2 (Comuna 2), con 4.810 viajes. Comparar esta comuna con el principal origen ayuda a distinguir zonas generadoras y zonas atractoras de viajes.
top_destinos %>%
  transmute(
    comuna = comuna_destino_num,
    nombre_comuna,
    viajes_llegada = total_viajes
  ) %>%
  slice_head(n = 10) %>%
  kable(caption = "Diez comunas con mayor cantidad de viajes de destino")
Diez comunas con mayor cantidad de viajes de destino
comuna nombre_comuna viajes_llegada
2 Comuna 2 4810
3 Comuna 3 3859
19 Comuna 19 3158
17 Comuna 17 2164
22 Comuna 22 1860
4 Comuna 4 1856
9 Comuna 9 1279
8 Comuna 8 1025
10 Comuna 10 927
7 Comuna 7 748

6.1 Destino por tipo de vehículo

crear_mapa_destino("Bicicleta")

crear_mapa_destino("Moto")

crear_mapa_destino("Automóvil")

tabla_destinos_vehiculo <- encuesta_limpia %>%
  filter(
    vehiculo_nombre %in% vehiculos_interes,
    !is.na(comuna_destino_num)
  ) %>%
  count(vehiculo_nombre, comuna_destino_num, name = "total_viajes") %>%
  left_join(st_drop_geometry(comunas_limpias) %>% select(comuna_num, nombre_comuna),
            by = c("comuna_destino_num" = "comuna_num")) %>%
  arrange(vehiculo_nombre, desc(total_viajes))

tabla_destinos_vehiculo %>%
  group_by(vehiculo_nombre) %>%
  slice_max(order_by = total_viajes, n = 5, with_ties = FALSE) %>%
  ungroup() %>%
  transmute(
    vehiculo = vehiculo_nombre,
    comuna = comuna_destino_num,
    nombre_comuna,
    viajes_llegada = total_viajes
  ) %>%
  kable(caption = "Cinco principales comunas de destino por tipo de vehículo")
Cinco principales comunas de destino por tipo de vehículo
vehiculo comuna nombre_comuna viajes_llegada
Automóvil 2 Comuna 2 2006
Automóvil 3 Comuna 3 1557
Automóvil 19 Comuna 19 1302
Automóvil 17 Comuna 17 959
Automóvil 4 Comuna 4 757
Bicicleta 2 Comuna 2 218
Bicicleta 3 Comuna 3 189
Bicicleta 19 Comuna 19 147
Bicicleta 17 Comuna 17 115
Bicicleta 22 Comuna 22 100
Moto 2 Comuna 2 2177
Moto 3 Comuna 3 1734
Moto 19 Comuna 19 1421
Moto 17 Comuna 17 927
Moto 22 Comuna 22 911
top_destino_vehiculo <- tabla_destinos_vehiculo %>%
  group_by(vehiculo_nombre) %>%
  slice_max(order_by = total_viajes, n = 1, with_ties = FALSE) %>%
  ungroup()

texto_destino_vehiculo <- top_destino_vehiculo %>%
  mutate(
    frase = sprintf(
      "para %s, el principal destino es la comuna %s (%s), con %s viajes",
      vehiculo_nombre,
      comuna_destino_num,
      nombre_comuna,
      formato_num(total_viajes)
    )
  ) %>%
  pull(frase) %>%
  paste(collapse = "; ")

cat(sprintf(
  '<div class="conclusion"><strong>Interpretación de destinos por vehículo.</strong> %s. La comparación entre estos destinos permite identificar comunas atractoras de viajes según el modo de transporte y complementa la lectura de los orígenes.</div>',
  texto_destino_vehiculo
))
Interpretación de destinos por vehículo. para Automóvil, el principal destino es la comuna 2 (Comuna 2), con 2.006 viajes; para Bicicleta, el principal destino es la comuna 2 (Comuna 2), con 218 viajes; para Moto, el principal destino es la comuna 2 (Comuna 2), con 2.177 viajes. La comparación entre estos destinos permite identificar comunas atractoras de viajes según el modo de transporte y complementa la lectura de los orígenes.

7 ¿A dónde van quienes salen de los principales orígenes?

Para responder la pregunta de destino desde origen, se seleccionan las tres comunas con mayor cantidad de viajes de salida. En cada mapa se resalta con borde negro la comuna de origen y se colorean las comunas de destino según el número de viajes recibidos desde ese origen.

tabla_od <- encuesta_limpia %>%
  filter(
    !is.na(comuna_origen_num),
    !is.na(comuna_destino_num)
  ) %>%
  count(comuna_origen_num, comuna_destino_num, name = "total_viajes") %>%
  arrange(desc(total_viajes))

tabla_od %>%
  slice_head(n = 20) %>%
  kable(caption = "Principales relaciones origen-destino entre comunas")
Principales relaciones origen-destino entre comunas
comuna_origen_num comuna_destino_num total_viajes
2 2 496
19 2 492
17 2 340
2 19 306
17 22 294
18 2 256
2 3 253
19 19 248
3 2 244
17 3 236
3 19 216
18 3 210
19 3 205
22 17 186
10 2 181
1 2 179
19 22 179
2 17 178
18 19 168
22 2 164
top_3_origenes <- top_origenes$comuna_origen_num[1:3]

for (origen in top_3_origenes) {
  print(crear_mapa_destino_desde_origen(origen))
}

7.1 Destinos desde el principal origen por vehículo

for (vehiculo in vehiculos_interes) {
  print(crear_mapa_destino_desde_origen(origen_principal, vehiculo))
}

8 Conclusiones

vehiculo_principal <- encuesta_limpia %>%
  filter(vehiculo_nombre %in% vehiculos_interes) %>%
  count(vehiculo_nombre, sort = TRUE) %>%
  slice(1)

cat(sprintf(
  '<div class="conclusion"><strong>1.</strong> La comuna %s (%s) concentra el mayor número de viajes de origen dentro de las comunas cartografiables, con %s viajes. Este resultado la identifica como una zona generadora relevante dentro de la muestra.</div>',
  origen_principal,
  origen_principal_nombre,
  formato_num(top_origenes$total_viajes[1])
))
1. La comuna 2 (Comuna 2) concentra el mayor número de viajes de origen dentro de las comunas cartografiables, con 2.968 viajes. Este resultado la identifica como una zona generadora relevante dentro de la muestra.
cat(sprintf(
  '<div class="conclusion"><strong>2.</strong> La comuna %s (%s) es el principal destino, con %s viajes. Esta diferencia entre origen y destino permite interpretar la movilidad como una relación espacial entre áreas productoras y atractoras de desplazamientos.</div>',
  destino_principal,
  destino_principal_nombre,
  formato_num(top_destinos$total_viajes[1])
))
2. La comuna 2 (Comuna 2) es el principal destino, con 4.810 viajes. Esta diferencia entre origen y destino permite interpretar la movilidad como una relación espacial entre áreas productoras y atractoras de desplazamientos.
cat(sprintf(
  '<div class="conclusion"><strong>3.</strong> Entre bicicleta, moto y automóvil, el modo con más registros es %s. La comparación cartográfica por vehículo muestra que los patrones espaciales cambian según el medio de transporte, por lo que no conviene interpretar la movilidad únicamente con el mapa general.</div>',
  vehiculo_principal$vehiculo_nombre
))
3. Entre bicicleta, moto y automóvil, el modo con más registros es Moto. La comparación cartográfica por vehículo muestra que los patrones espaciales cambian según el medio de transporte, por lo que no conviene interpretar la movilidad únicamente con el mapa general.
cat(
  '<div class="conclusion"><strong>4.</strong> Los mapas de destino desde los principales orígenes permiten pasar de una lectura descriptiva por comuna a una lectura relacional origen-destino. Esta mirada es útil para reconocer flujos, centralidades y posibles diferencias territoriales en la movilidad urbana.</div>'
)
4. Los mapas de destino desde los principales orígenes permiten pasar de una lectura descriptiva por comuna a una lectura relacional origen-destino. Esta mirada es útil para reconocer flujos, centralidades y posibles diferencias territoriales en la movilidad urbana.

9 Recomendaciones metodológicas

  • Para un análisis espacial posterior se puede calcular autocorrelación espacial, como Moran global o indicadores locales, sobre la intensidad de viajes por comuna.
  • Si se cuenta con coordenadas puntuales o centroides de origen-destino, se podrían construir líneas de deseo para representar flujos entre comunas.
  • Conviene reportar por separado los viajes Fuera de Cali, ya que son importantes para la movilidad metropolitana pero no se representan con la cartografía de comunas usada en este ejercicio.