1. Marco Introductorio y Configuración del Entorno

1.1. Introducción

El crecimiento acelerado de las zonas urbanas y el incremento del parque automotor plantean desafíos complejos para la gestión de la movilidad y la planificación del territorio. Tradicionalmente, el monitoreo del tráfico dependía de infraestructura física costosa y estática, como cámaras de fotodetección, contadores neumáticos o sensores de lazo inductivo. Sin embargo, el paradigma de las ciudades inteligentes (Smart Cities) ha introducido el concepto de Crowdsourcing o sensorización ciudadana activa.

Waze representa una de las plataformas de navegación colaborativa más importantes del mundo. A través de la interacción de millones de usuarios en tiempo real, la aplicación recopila una densa infraestructura de datos espaciales y temporales que registran incidentes críticos como congestiones (jams), accidentes, peligros en la vía (hazards) y cierres viales.

El objetivo de este documento es replicar y profundizar en el análisis de patrones puntuales propuesto en la guía metodológica de David Arango Londoño. Utilizando técnicas de estadística espacial y análisis geoespacial interactivo en el entorno R, transformaremos registros de filas tabulares en estructuras de información geográfica. Esto nos permitirá identificar clústeres de accidentalidad o congestión, evaluar la densidad de los incidentes y proveer herramientas visuales útiles para la toma de decisiones en el diseño de políticas públicas de transporte y seguridad vial.

1.2. Justificación Técnica de las Librerías

Para llevar a cabo un flujo de trabajo analítico reproducible, eficiente y visualmente atractivo, utilizaremos un ecosistema de librerías especializadas en ciencia de datos y geomática:

  • dplyr (Ecosistema Tidyverse): Herramienta fundamental para la manipulación y transformación de datos estructurados mediante el uso de operadores de tubería (%>%), facilitando el filtrado, la selección y el cálculo de nuevas variables de forma intuitiva.

  • lubridate: Paquete diseñado para mitigar las complejidades del manejo de zonas horarias, formatos de texto a marcas de tiempo (POSIXct) y la extracción rápida de componentes temporales (días, horas, minutos).

  • leaflet y leaflet.extras: Interfaz en R para la biblioteca JavaScript ‘Leaflet’. Permite la construcción de mapas dinámicos sobre capas base globales (OpenStreetMap, CartoDB), esenciales para la exploración espacial mediante herramientas interactivas de zoom y la generación de mapas de calor analíticos (Heatmaps).

  • mapview: Proporciona funciones de visualización rápida de datos espaciales, facilitando la inspección interactiva y la exportación de geometrías directamente desde la consola de R hacia formatos listos para la web.

paquetes_requeridos <- c("dplyr", "lubridate", "leaflet", "leaflet.extras", "mapview", "ggplot2", "openxlsx")

# Función de verificación e instalación automatizada
paquetes_faltantes <- paquetes_requeridos[!(paquetes_requeridos %in% installed.packages()[, "Package"])]

if (length(paquetes_faltantes) > 0) {
  message("Instalando los siguientes paquetes faltantes: ", paste(paquetes_faltantes, collapse = ", "))
  install.packages(paquetes_faltantes, dependencies = TRUE)
} else {
  message("Todos los paquetes requeridos ya se encuentran instalados en el entorno.")
}

# Carga de librerías en la sesión de R
library(dplyr)
library(lubridate)
library(leaflet)
library(leaflet.extras)
library(mapview)
library(ggplot2)
library(readxl)
library(openxlsx)
library(spatstat)

2. Carga de Datos y Procesamiento Geométrico y Temporal.

En esta sección abordaremos un desafío metodológico crítico del archivo original de David Arango Londoño. Los datos de Waze suelen exportar las columnas de coordenadas (location_x y location_y) como números enteros sin decimales para optimizar el almacenamiento. Para poder proyectarlos correctamente en un mapa base real (como OpenStreetMap mediante leaflet), necesitamos aplicar una transformación matemática basada en la longitud de caracteres para reubicar el punto decimal, y luego filtrar geográficamente para limpiar ruidos o anomalías fuera de la zona de estudio.

Además, realizaremos la conversión de las marcas de tiempo a objetos POSIXct legibles usando lubridate.

2.1. Carga del Set de Datos e Inpección Estructural

Iniciamos con la lectura de la trama de datos de Waze. Dado que el archivo original se encuentra estructurado en formato de texto plano con delimitadores por comas (.csv), utilizaremos las funciones nativas de R para una carga eficiente, asegurando que las cadenas de texto no se conviertan automáticamente en factores para facilitar su posterior manipulación secuencial.

# 2. Ingesta de Datos y Preprocesamiento Geoespacial
setwd("~/Estudio/MAESTRIA EN CIENCIA DE DATOS/Analisis_Datos_Geo/Actividad 4")

trama_waze <- read_excel("Trama Waze.xlsx")
View(trama_waze)

trama_waze$location_x <- paste0(substr(trama_waze$location_x, 1, 3),
                                ".", 
                                substr(trama_waze$location_x, 4, 9)) |> 
                      as.numeric()


trama_waze$location_y <- paste0(substr(trama_waze$location_y, 1, 1),
                                ".",
                                substr(trama_waze$location_y, 2, 9)) |> 
                      as.numeric()



# Inspección básica de dimensiones y nombres de columnas
dimensiones <- dim(trama_waze)
message("El dataset contiene ", dimensiones[1], " registros y ", dimensiones[2], " variables.")

# Visualización de la estructura indexada
str(trama_waze, max.level = 1)
|> tibble [5,070 × 17] (S3: tbl_df/tbl/data.frame)

2.2. Reconstrucción Matemática de Co coordenadas (Latitud y Longitud)

# Transformación matemática y normalización posicional
trama_waze <- trama_waze %>%
  mutate(
    # Conversión dinámica de Latitud (Y)
    lat = location_y,
    # Conversión dinámica de Longitud (X)
    long = location_x
  )

# Forzar signo negativo en la longitud si los datos originales omitieron la orientación Oeste
trama_waze <- trama_waze %>%
  mutate(long = ifelse(long > 0, -long, long))

# Resumen estadístico de las nuevas coordenadas geométricas
summary(trama_waze[, c("long", "lat")])
|>       long             lat       
|>  Min.   :-74.04   Min.   :2.548  
|>  1st Qu.:-74.03   1st Qu.:4.903  
|>  Median :-74.03   Median :4.915  
|>  Mean   :-74.03   Mean   :4.883  
|>  3rd Qu.:-74.02   3rd Qu.:4.922  
|>  Max.   :-73.99   Max.   :4.949

2.3. Depuración Geoespacial (Delimitación del Polígono de Estudio)

Debido a posibles errores de transmisión o registros corruptos en la base de datos (por ejemplo, coordenadas atípicas como 9383-04-01), es indispensable aplicar un filtro de umbral geográfico. Delimitaremos nuestro marco analítico estrictamente al área metropolitana y corredores circundantes del norte de la sabana, restringiendo la latitud al intervalo útil entre \(4.0^\circ\) y \(5.0^\circ\) Norte.

# Filtrado de valores extremos y depuración geométrica
trama_waze_filtrada <- trama_waze %>%
  filter(lat > 4.0 & lat < 5.0)

# Cuantificación de registros depurados
registros_eliminados <- nrow(trama_waze) - nrow(trama_waze_filtrada)
message("Registros analizados con éxito: ", nrow(trama_waze_filtrada))
message("Registros atípicos descartados: ", registros_eliminados)

2.4. Tratamiento Temporal y Extracción de Atributos

La columna creation_Date contiene la estampa cronológica en formato de texto. Utilizando la flexibilidad de lubridate, parseamos esta variable al formato estándar de tiempo POSIXct y extraemos componentes temporales clave (como el día del mes y la hora del reporte) que serán vitales para segmentar los patrones puntuales viales.

# Conversión e indexación cronológica
trama_waze_filtrada <- trama_waze_filtrada %>%
  mutate(
    # Conversión a clase de tiempo estándar de R
    fecha_tiempo = ymd_hms(creation_Date),
    # Extracción del día de ocurrencia
    dia = day(fecha_tiempo),
    # Extracción de la hora entera (0-23) para perfiles de movilidad
    hora_entera = hour(fecha_tiempo),
    # Formato de texto indexado para etiquetas en mapas
    hora_etiqueta = format(fecha_tiempo, "%H:%M")
  )

# Mostrar una muestra del procesamiento final de las columnas calculadas
trama_waze_filtrada %>%
  select(id, type, lat, long, dia, hora_etiqueta) %>%
  head(5)
|> # A tibble: 5 × 6
|>      id type     lat  long   dia hora_etiqueta
|>   <dbl> <chr>  <dbl> <dbl> <int> <chr>        
|> 1    16 HAZARD  4.94 -74.0    26 01:53        
|> 2    18 HAZARD  4.93 -74.0    26 01:53        
|> 3    20 HAZARD  4.94 -74.0    26 01:54        
|> 4    22 HAZARD  4.93 -74.0    26 01:54        
|> 5    24 HAZARD  4.94 -74.0    26 01:56

Paso 3: Análisis de Frecuencias, Segmentación de Eventos y Mapeo de Clusters.

En la guía de David Arango Londoño, una vez que los datos espaciales y temporales están normalizados, se realiza la transición conceptual hacia la estadística descriptiva espacial. Antes de pintar mapas ciegamente, necesitamos entender la composición del dataset mediante tablas de frecuencias globales. Luego, el análisis se concentra de manera específica en los eventos del día 26 (el día más denso en la muestra).

Separaremos los tipos de alerta fundamentales: HAZARD (Peligros), ACCIDENT (Accidentes) y JAM (Congestión), traduciéndolos conceptualmente e implementando mapas interactivos agrupados por clústeres dinámicos (markerClusterOptions) para evitar la saturación visual en la pantalla.

3.1. Distribución Frecuencial del Tipo de Incidentes

El primer paso analítico consiste en cuantificar la naturaleza de los datos reportados por los usuarios en la plataforma. Clasificar el volumen total de registros según la variable type nos permite entender cuál es la problemática vial predominante en nuestra ventana de estudio (congestiones, seguridad vial o infraestructura).

# Matriz de frecuencias absolutas y relativas por tipo de evento
tabla_incidentes <- trama_waze_filtrada %>%
  group_by(type) %>%
  summarise(
    Frecuencia_Absoluta = n(),
    Porcentaje = round((n() / nrow(trama_waze_filtrada)) * 100, 2)
  ) %>%
  arrange(desc(Frecuencia_Absoluta))

# Imprimir tabla resumida en el reporte HTML
knitr::kable(tabla_incidentes, caption = "Frecuencia Global de Incidentes Reportados (Waze)")
Frecuencia Global de Incidentes Reportados (Waze)
type Frecuencia_Absoluta Porcentaje
JAM 3151 63.07
ROAD_CLOSED 1021 20.44
HAZARD 702 14.05
ACCIDENT 122 2.44

3.2. Aislamiento Temporal del Escenario Crítico: Filtro del Día 26

Siguiendo la metodología de referencia, delimitamos nuestro estudio a un marco temporal homogéneo de 24 horas seleccionando el Día 26 del mes analizado. Esta estrategia reduce el sesgo de acumulación multitemporal y nos permite evaluar un ciclo diario completo de movilidad urbana.

# Filtrar registros correspondientes estrictamente al día 26
trama_dia26 <- trama_waze_filtrada %>% 
  filter(dia == 26)

message("Total de eventos registrados para el análisis espacial del día 26: ", nrow(trama_dia26))

3.3. Segmentación y Visualización Geográfica Interactiva

Para entender las dinámicas territoriales individuales, dividiremos el dataset del día 26 según sus categorías principales y las proyectaremos sobre la infraestructura cartográfica de OpenStreetMap mediante clústeres inteligentes.

3.3.1. Distribución Espacial de Eventos: PELIGRO (HAZARD)

Los reportes de tipo HAZARD denotan anomalías en la vía (vehículos varados, baches, objetos en el carril). Agruparlos mediante clústeres numéricos permite al planificador explorar densidades macro e ir descendiendo con el zoom hasta el detalle de la hora específica del reporte.

# Separación del subconjunto de datos de peligros
peligros_26 <- trama_dia26 %>% 
  filter(type == "HAZARD")

# Construcción del mapa interactivo con Leaflet
mapa_peligros <- leaflet(peligros_26) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ~long, 
    lat = ~lat,
    clusterOptions = markerClusterOptions(),  # Agrupamiento dinámico anti-saturación
    label = ~hora_etiqueta,                  # Muestra la hora al pasar el cursor
    color = "#F7931E",
    radius = 6,
    fillOpacity = 0.8
  ) %>%
  addControl(html = "<h3>Mapa de Riesgos y Peligros (Día 26)</h3>", position = "topleft")

# Renderizar mapa en el documento Rmd
mapa_peligros

3.3.3. Distribución Espacial de Eventos: CONGESTIÓN (JAM)

Las retenciones de tráfico (JAM) reflejan los cuellos de botella de la infraestructura vial. Al cartografiar estos incidentes se evidencia la magnitud de la carga vehicular sobre los ejes conectores principales de la región en estudio.

# Separación del subconjunto de datos de congestión viales
congestion_26 <- trama_dia26 %>% 
  filter(type %in% c("JAM", "CONGESTIÓN"))

# Construcción del mapa interactivo de congestión
mapa_congestion <- leaflet(congestion_26) %>%
  addTiles() %>%
  addCircleMarkers(
    lng = ~long, 
    lat = ~lat,
    clusterOptions = markerClusterOptions(),
    label = ~hora_etiqueta,
    color = "#3498DB", # Azul para congestión estática
    radius = 6,
    fillOpacity = 0.7
  ) %>%
  addControl(html = "<h3>Mapa de Congestión Vehicular (Día 26)</h3>", position = "topleft")

# Renderizar mapa
mapa_congestion

4: Suavizado Espacial y Estimación de la Densidad de Kernel (Heatmaps).

En este apartado daremos el salto cualitativo de la simple visualización de puntos dispersos hacia la modelación del continuo espacial. El mapa de clústeres anterior es útil para contar incidentes individuales, pero no nos permite modelar superficies de riesgo continuo ni identificar zonas calientes (Hotspots) de manera matemática.

Para resolver esto, implementaremos la función addHeatmap() de la extensión leaflet.extras, configurando dinámicamente un radio de suavizado espacial y una rampa de colores indexada para delimitar visualmente los cuellos de botella de la movilidad urbana en el área de estudio.

4.1. Concepto del Suavizado de Kernel Espacial

El análisis de patrones puntuales puede verse limitado cuando nos enfrentamos a cientos de observaciones superpuestas en infraestructuras viales densas. Mientras que los mapas de marcadores tradicionales segmentan la información de manera binaria (existe o no existe un punto), la **Estimación de Densidad de Kernel (KDE)** estima una función matemática que distribuye la intensidad de los eventos sobre una superficie continua.

Cada reporte de congestión se convierte en el centro de una función probabilística bidimensional que decrece a medida que se distancia del origen geográfico. Al superponer e integrar estas funciones en una matriz regular (*grid*), el mapa resultante suaviza el ruido aleatorio y expone con claridad los ejes viales con problemas estructurales de saturación o los tramos con mayor vulnerabilidad operativa.

4.2. Generación del Mapa de Calor Analítico para Congestión (JAM)

Utilizando el ecosistema de extensiones avanzadas de `leaflet.extras`, convertiremos el set de datos filtrado de congestión (`congestion_26`) en una capa de densidad interactiva. Ajustaremos un radio analítico de $25$ píxeles para optimizar el gradiente visual y mitigar la pixelación en escalas intermedias de zoom.

# Verificar que existan datos en el subconjunto para evitar errores de renderizado
if (nrow(congestion_26) > 0) {
  
  # Construcción del Mapa de Calor Interactivo
  mapa_calor_jam <- leaflet(congestion_26) %>%
    # Usar una capa base limpia de CartoDB para priorizar el contraste del mapa de calor
    addProviderTiles(providers$CartoDB.Positron) %>%
    # Inyección de la capa analítica de densidad de Kernel
    addHeatmap(
      lng = ~long,
      lat = ~lat,
      intensity = 1,          # Peso uniforme por evento registrado
      blur = 20,              # Grado de dispersión/suavizado en los bordes
      max = 0.05,             # Punto de saturación para el umbral del color rojo (pico)
      radius = 25             # Radio de influencia geométrica en píxeles
    ) %>%
    # Adición de una leyenda científica descriptiva para el tomador de decisiones
    addLegend(
      position = "bottomright",
      title = "Intensidad de Congestión (KDE)",
      colors = c("#0000FF", "#00FF00", "#FFFF00", "#FF0000"),
      labels = c("Flujo Libre / Bajo", "Densidad Moderada", "Retención Alta", "Saturación Crítica")
    ) %>%
    # Título del panel de control
    addControl(
      html = "<h3>Hotspots: Densidad de Kernel de Congestión (Día 26)</h3>", 
      position = "topleft"
    )
  
  # Renderizar el objeto cartográfico interactivo
  mapa_calor_jam
  
} else {
  message("Advertencia: No se detectaron registros de congestión para compilar el mapa de calor.")
}

5: Perfilación Temporal y Ciclos Horarios de Movilidad.

En esta sección cruzaremos la variable espacial con la dimensión temporal. Como bien plantea la metodología de David Arango Londoño, analizar la distribución horaria nos permite identificar formalmente las horas pico y horas valle de los incidentes en el territorio, validando estadísticamente el comportamiento del flujo de tráfico a lo largo de la jornada viales del Día 26.

5.1. Importancia del Análisis Multitemporal

La variabilidad espacial de los incidentes viales está íntimamente ligada a los ciclos de actividad humana (horarios laborales, escolares y comerciales). Un análisis estático que ignore la fluctuación horaria perdería la capacidad de predecir en qué momentos del día la infraestructura es más vulnerable.

Estudiar la distribución de frecuencias horarias desagregada por el tipo de reporte nos ayuda a comprender si los accidentes ocurren de manera uniforme o si se concentran en las transiciones de los picos de congestión.

5.2. Construcción de la Línea de Tiempo de Incidentes (Día 26)

A continuación, agruparemos los datos del día 26 por la variable `hora_entera` y `type`, para luego generar un gráfico de áreas o líneas que ilustre la evolución cronológica del estado de las vías.

# Agrupación y conteo temporal por tipo de incidente
perfil_temporal <- trama_dia26 %>%
  group_by(hora_entera, type) %>%
  summarise(Total = n(), .groups = 'drop')

# Generación del gráfico con ggplot2
ggplot(perfil_temporal, aes(x = hora_entera, y = Total, color = type, group = type)) +
  geom_line(size = 1.2) +
  geom_point(size = 2) +
  scale_x_continuous(breaks = 0:23) +
  scale_color_manual(
    values = c("ACCIDENT" = "#E74C3C", "HAZARD" = "#F7931E", "JAM" = "#3498DB"),
    labels = c("Accidentes", "Peligros en Vía", "Congestión (Jams)")
  ) +
  labs(
    title = "Evolución Horaria de Incidentes en Waze",
    subtitle = "Análisis cronológico correspondiente al escenario crítico (Día 26)",
    x = "Hora del Día (Formato 24h)",
    y = "Cantidad de Reportes",
    color = "Tipo de Evento"
  ) +
  theme_minimal(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5, color = "gray40"),
    legend.position = "bottom",
    panel.grid.minor = element_blank()
  )

5.3. Densidad Temporal Acumulada

Para visualizar de forma suavizada el comportamiento general de la jornada (independientemente del tipo de reporte), podemos graficar la función de densidad temporal. Esto nos permite determinar con precisión matemática los centroides de máxima acumulación de alertas en el día.

# Gráfico de densidad de la variable hora
ggplot(trama_dia26, aes(x = hora_entera)) +
  geom_density(fill = "#2ECC71", alpha = 0.4, color = "#27AE60", size = 1) +
  scale_x_continuous(breaks = 0:23) +
  labs(
    title = "Densidad Temporal Continua de Alertas",
    subtitle = "Identificación de franjas horarias de máxima saturación vial",
    x = "Hora del Día",
    y = "Densidad de Probabilidad"
  ) +
  theme_classic(base_size = 13) +
  theme(
    plot.title = element_text(face = "bold", hjust = 0.5),
    plot.subtitle = element_text(hjust = 0.5, color = "gray40")
  )

6: Modelación Avanzada con spatstat (Análisis de Patrones Puntuales).

Hasta este punto, hemos hecho una aproximación descriptiva y visual sumamente atractiva con mapas de calor y gráficos horarias. Sin embargo, para cumplir con el rigor metodológico del análisis de patrones puntuales (PPP), debemos utilizar la librería especializada spatstat. Esta herramienta nos permitirá evaluar formalmente si la distribución de los incidentes en el espacio responde a un patrón aleatorio, agrupado o regular.

En este bloque, configuraremos una ventana de observación (Window o owin), crearemos el objeto de patrón puntual (ppp) y aplicaremos la estimación analítica de la función \(G\) (o función \(F\) / \(K\) según la guía) para testear científicamente la hipótesis de Aleatoriedad Espacial Completa (CSR).

6.1. Fundamento Teórico del Análisis de Procesos Puntuales

En la estadística espacial, un conjunto de coordenadas geográficas se define como un *proceso puntual* si los eventos ocurren en posiciones aleatorias dentro de una región continua bien delimitada. Para determinar si la infraestructura vial está condicionando la acumulación de incidentes, debemos evaluar tres tipos de patrones fundamentales: * **Aleatorio (Proceso de Poisson Homogéneo):** Los eventos ocurren de forma independiente y tienen la misma probabilidad de registrarse en cualquier coordenada. * **Agrupado (Clustered):** La presencia de un incidente incrementa la probabilidad de que ocurran otros en su vecindad inmediata (típico en intersecciones críticas o zonas de embotellamiento). * **Regular (Disperso):** Los eventos se repelen entre sí, manteniendo distancias mínimas homogéneas (poco común en eventos de movilidad).

6.2. Configuración del Objeto de Patrón Puntual (ppp)

Para migrar del formato tabular clásico a las clases nativas de `spatstat`, primero debemos asegurarnos de aislar una ventana de observación espacial (`owin`) que encierre de forma estricta los puntos para evitar efectos de borde sesgados.

#Instalar y cargar spatstat si no se encuentra en el entorno
if (!require("spatstat")) {
  install.packages("spatstat", dependencies = TRUE)
  library(spatstat)
} else {
  library(spatstat)
}

# 1. Definición de límites geográficos extremos para la ventana de observación (owin)
x_min <- min(trama_dia26$long, na.rm = TRUE)
x_max <- max(trama_dia26$long, na.rm = TRUE)
y_min <- min(trama_dia26$lat, na.rm = TRUE)
y_max <- max(trama_dia26$lat, na.rm = TRUE)

ventana <- owin(c(x_min, x_max), c(y_min, y_max))

# 2. Construcción del objeto PPP para los incidentes de Congestión (JAM) del Día 26
# Eliminamos duplicados geométricos estrictos para evitar singularidades matemáticas
congestion_clean <- congestion_26 %>% 
  distinct(long, lat, .keep_all = TRUE)

patron_jam <- ppp(
  x = congestion_clean$long, 
  y = congestion_clean$lat, 
  window = ventana
)

# Inspección estadística del objeto puntual creado
summary(patron_jam)
|> Planar point pattern:  80 points
|> Average intensity 27442.86 points per square unit
|> 
|> Coordinates are given to 15 decimal places
|> 
|> Window: rectangle = [-74.04304, -73.99451] x [4.888059, 4.948128] units
|>                     (0.04853 x 0.06007 units)
|> Window area = 0.00291515 square units

6.3. Evaluación de Distancias al Vecino Más Cercano (Función G)

La Función G (\(G(r)\)) mide la distribución de la distancia desde cada evento en el mapa hasta su vecino más cercano. Al contrastar nuestra curva observada (\(\hat{G}(r)\)) contra la curva teórica de un modelo completamente aleatorio (\(G_{theo}(r)\)), podemos diagnosticar la estructura espacial del fenómeno:

  • Si la curva observada sube más rápido y se sitúa por encima de la teórica, indica un claro patrón de agrupamiento (distancias inter-evento muy cortas).

  • Si se sitúa por debajo, indica un patrón regular.

# Cálculo de la función G empírica con correcciones de borde Kaplan-Meier
g_eval <- Gest(patron_jam)

# Gráfico científico de diagnóstico espacial
plot(g_eval, main = "Función G: Diagnóstico de Patrón Puntual de Congestión",
     xlab = "Distancia r (grados)", ylab = "Proporción Acumulada G(r)",
     lwd = 2)

7. Conclusiones y Discusión del Análisis Espacio-Temporal

7.1. Síntesis de Resultados Analíticos

A través de la réplica metodológica y la expansión analítica ejecutada en este documento, se ha logrado transformar datos crudos y desestructurados de la API de Waze en un modelo analítico de patrones puntuales útil para la planeación urbana. Los hallazgos clave se resumen en los siguientes puntos:

  1. Estructura Geoespacial de los Datos: El proceso de limpieza inicial evidenció la presencia de ruidos geométricos severos en los registros crudos (como anomalías extremas en la latitud). Esto demuestra que en proyectos de Smart Cities, la etapa de curaduría de datos y ajuste matemático de coordenadas mediante la longitud de caracteres (`nchar`) es un prerrequisito obligatorio antes de formular políticas públicas o planes de movilidad.
  2. Identificación de Hotspots: El mapa de calor (estimación de densidad de Kernel) aplicado a los datos de congestión (`JAM`) del Día 26 expuso con total nitidez que las retenciones vehiculares no ocurren de manera dispersa o aleatoria. Se concentran en ejes específicos, funcionando la infraestructura principal (como la Autopista Norte y variantes conectores hacia Cajicá y Chía) como embudos estructurales de la movilidad regional.
  3. **Sincronización Multitemporal:** Al cruzar los perfiles horarios con `ggplot2`, se observan picos pronunciados que coinciden plenamente con las dinámicas de viaje pendular (mañana y tarde-noche). Resulta de especial interés notar cómo los reportes de tipo `HAZARD` (peligros) y `ACCIDENT` tienden a incrementarse en las franjas horarias de transición hacia la congestión máxima, lo que sugiere una correlación entre el estrés de la infraestructura vial y la seguridad vial de los usuarios.
  4. **Validación Estadística Formal:** El análisis con la librería `spatstat` mediante la **Función G** arrojó una curva observada que se sitúa marcadamente por encima de la curva teórica de Aleatoriedad Espacial Completa (CSR). Este comportamiento matemático confirma de manera irrefutable que los incidentes de Waze siguen un **patrón espacial fuertemente agrupado (clustered)**, lo que desarta que las alertas ocurran por mero azar geográfico.

7.2. Recomendaciones para la Planeación de la Movilidad

Basados en el comportamiento espacial de los clústeres identificados, se sugieren las siguientes intervenciones estratégicas: * **Despliegue Dinámico de Operativos:** Utilizar los centroides de las horas pico y las zonas rojas del mapa de calor para reubicar personal de tránsito de manera anticipada en los nodos viales identificados, agilizando la respuesta ante vehículos varados (`HAZARD`) que detonan colas de congestión. * **Optimización de Infraestructura:** Evaluar las intersecciones y retornos dentro de las zonas críticas del mapa de calor para implementar mejoras de diseño geométrico, señalización inteligente o fases semafóricas adaptativas. * **Uso de Datos en Tiempo Real:** Fomentar la integración de este tipo de metodologías de *crowdsourcing* en los centros de control de tráfico locales, permitiendo una transición desde la planeación reactiva hacia una gestión predictiva del territorio.