El análisis geoespacial permite estudiar fenómenos que tienen una ubicación específica. En datos de movilidad, las coordenadas de los reportes permiten identificar patrones de concentración, zonas críticas, corredores con mayor cantidad de incidentes y diferencias entre tipos de eventos.
En esta actividad, los reportes de Waze se convierten en una lectura espacial de la movilidad: cada punto representa un evento reportado y cada concentración ayuda a entender dónde se intensifican los riesgos, cierres, accidentes o congestiones.
Los datos colaborativos de movilidad aportan información útil para la planeación urbana porque capturan eventos reportados por usuarios en tiempo casi real.
La base de Waze permite observar cómo se distribuyen los eventos viales en el territorio, facilitando una lectura visual de las zonas donde se presentan más afectaciones y de los horarios donde la actividad es más intensa.
Analizar espacial y temporalmente los eventos reportados por Waze, identificando su distribución por hora, tipo de evento y ubicación geográfica.
El propósito es transformar una trama de registros en mapas interpretables que permitan reconocer zonas críticas, patrones de concentración y posibles puntos de intervención vial.
En esta sección se cargan las librerías necesarias para leer el archivo de Excel, transformar los datos, manejar fechas y construir visualizaciones geoespaciales interactivas.
Algunos paquetes avanzados se manejan como opcionales para que el
reporte pueda ejecutarse incluso cuando no estén instalados, manteniendo
funcionales los mapas principales con leaflet.
library(readxl) # readxl: Para la carga de datos desde archivos Excel.
library(dplyr) # dplyr: Para la manipulación y transformación de datos.
library(lubridate) # lubridate: Para el manejo y procesamiento de fechas y tiempos.
library(leaflet) # leaflet: Para la creación de mapas interactivos.
library(ggplot2) # ggplot2: Para la creación de gráficos y visualizaciones.
# Paquetes opcionales usados por algunos bloques del HTML original.
# Si no están instalados, el Rmd sigue ejecutándose y muestra una alternativa.
tiene_sf <- requireNamespace("sf", quietly = TRUE)
tiene_mapview <- requireNamespace("mapview", quietly = TRUE)
tiene_leaflet_extras <- requireNamespace("leaflet.extras", quietly = TRUE)
tiene_spatstat <- requireNamespace("spatstat.geom", quietly = TRUE) &&
requireNamespace("spatstat.explore", quietly = TRUE)
tiene_terra <- requireNamespace("terra", quietly = TRUE)
tiene_leafsync <- requireNamespace("leafsync", quietly = TRUE)
tiene_htmltools <- requireNamespace("htmltools", quietly = TRUE)
La base se importa desde el archivo Trama Waze.xlsx.
Posteriormente se convierte la fecha de creación y se traducen los tipos
de eventos al español para facilitar la lectura del reporte.
Este paso es fundamental porque organiza los datos antes de iniciar el análisis temporal y espacial.
# Cargar los datos de Waze
Trama_Waze = read_excel("C:/Users/Usuario/Downloads/Trama Waze.xlsx")
# Convertir la columna de fechas a formato adecuado
Trama_Waze$fecha = as.Date(Trama_Waze$creation_Date, format ="%Y-%m-%d %H:%M")
# Cambiar los nombres de los tipos de eventos a español
Trama_Waze$tipo_evento <- recode(Trama_Waze$type,
"ACCIDENT" = "ACCIDENTE",
"HAZARD" = "PELIGRO",
"JAM" = "CONGESTIÓN",
"ROAD_CLOSED" = "VÍA CERRADA")
El análisis temporal permite observar en qué horas del día se concentran
más reportes. Para ello, se extrae la hora desde la columna
creation_Date y se grafica la frecuencia por franja
horaria.
Esta visualización ayuda a identificar momentos de mayor actividad vial, lo cual puede relacionarse con horas pico o periodos de alta movilidad.
# Cargar la librería lubridate
library(lubridate)
# Convertir la fecha y extraer la hora y el día
fecha_hora = ymd_hms(Trama_Waze$creation_Date)
hora = hour(fecha_hora)
dia = day(fecha_hora)
hora_factorizado <- factor(hora, levels = 0:23)
g_hora=ggplot(mapping = aes(x = hora_factorizado)) +
geom_bar(fill = "orange", color = "black") +
labs(
title = "Frecuencia de Eventos por Hora del Día",
x = "Hora del Día",
y = "Frecuencia (Conteo)"
) +
theme_minimal() +
scale_x_discrete(drop = FALSE)
g_hora
La tabla de frecuencia permite revisar cuántos registros existen para cada tipo de evento. Esta salida sirve como primer control descriptivo antes de construir los mapas.
# Agregar la columna de hora a los datos
Trama_Waze$hora = hora
# Mostrar la tabla de frecuencia de tipos de eventos
table(Trama_Waze$tipo_evento)
##
## ACCIDENTE CONGESTIÓN PELIGRO VÍA CERRADA
## 125 3205 719 1021
La distribución de eventos resume visualmente qué tipo de reporte aparece con mayor frecuencia en la trama de Waze.
Este gráfico facilita comparar la magnitud de accidentes, peligros, congestiones y cierres de vías antes de pasar al componente espacial.
# Calcular la frecuencia de cada tipo de evento en Trama_Waze
frecuencia_eventos <- Trama_Waze %>%
group_by(tipo_evento) %>% # Agrupar por tipo de evento
summarise(Frecuencia = n()) %>% # Contar la frecuencia de cada tipo
arrange(desc(Frecuencia)) # Ordenar por frecuencia descendente
# Crear un gráfico de barras con ggplot2 usando los datos de Trama_Waze
ggplot(frecuencia_eventos, aes(x = tipo_evento, y = Frecuencia, fill = tipo_evento)) +
geom_bar(stat = "identity") +
theme_minimal() +
labs(title = "Distribución de Tipos de Eventos en Trama Waze",
x = "Tipo de Evento", y = "Frecuencia") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) + # Rotar etiquetas para mejor visualización
scale_fill_brewer(palette = "Set2") # Utilizar una paleta de colores predefinida
En este apartado, se filtran los eventos de tipo PELIGRO
que ocurrieron específicamente el día 26. El propósito es reducir el
volumen de datos y centrar el análisis en los reportes que representan
riesgos potenciales en las vías.
Este filtro permite trabajar con un subconjunto más preciso para identificar zonas críticas y patrones de concentración espacial.
# Identificar eventos PELIGRO del día 26
pos <- which(Trama_Waze$tipo_evento == "PELIGRO" & dia == 26)
peligro26 <- Trama_Waze[pos,]
Una vez filtrados los eventos PELIGRO, se procede a
visualizarlos en un mapa interactivo utilizando la librería
leaflet. El mapa permite explorar las ubicaciones exactas
de los peligros reportados y agrupar los puntos en clusters para mejorar
la legibilidad.
Esta visualización facilita reconocer las zonas donde se acumulan más reportes y apoya la lectura espacial del comportamiento de los incidentes.
# Cargar librerías necesarias para visualización
library(leaflet)
# Ajustar las coordenadas de latitud y longitud
peligro26$lat <- peligro26$location_y / 10^(nchar(peligro26$location_y) - 1)
peligro26$long <- peligro26$location_x / 10^(nchar(peligro26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
peligro26 <- peligro26[peligro26$lat > 4 & peligro26$lat < 5,]
# Crear un mapa interactivo con leaflet
m26_peligro <- leaflet() %>%
addTiles() %>%
addCircleMarkers(lng = peligro26$long, lat = peligro26$lat,
clusterOptions = markerClusterOptions(),
label = peligro26$hora) %>%
addControl(html = "<h3>Mapa de Riesgos</h3>", position = "topleft")
# Mostrar el mapa
m26_peligro
En esta sección, se realiza un análisis espacial de los eventos
PELIGRO del día 26 y se genera un mapa de calor para
destacar las áreas con mayor intensidad de reportes.
El mapa de calor resume la concentración de eventos y permite observar de forma más clara los puntos donde el riesgo vial aparece con mayor frecuencia.
# Cargar las librerías necesarias
library(leaflet)
library(dplyr)
# Filtrar datos relevantes de peligro26
peligro26 <- peligro26 %>%
filter(lat > 4 & lat < 5, long > -75 & long < -73) # Ajustar las coordenadas de interés
# Crear un mapa interactivo con leaflet y addHeatmap
if (tiene_leaflet_extras) {
leaflet(peligro26) %>%
addProviderTiles("OpenStreetMap") %>% # Añadir la capa base del mapa
leaflet.extras::addHeatmap(
lng = ~long, lat = ~lat, # Especificar las columnas de longitud y latitud
intensity = ~hora, # Intensidad opcional basada en la hora (o cualquier otra variable)
blur = 20, # Nivel de desenfoque del mapa de calor
max = 0.08, # Ajustar el valor máximo para la intensidad
radius = 15 # Radio de cada punto en el mapa de calor
) %>%
addLegend("bottomright", # Añadir leyenda
title = "Mapa de Calor de Riesgos",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
} else {
leaflet(peligro26) %>%
addProviderTiles("OpenStreetMap") %>%
addCircleMarkers(lng = ~long, lat = ~lat, radius = 5, fillOpacity = 0.45,
clusterOptions = markerClusterOptions(), label = ~hora) %>%
addControl(html = "<h3>Mapa de Calor de Riesgos</h3><p>Instale leaflet.extras para ver el heatmap.</p>",
position = "bottomright")
}
Aquí se genera un segundo mapa de densidad basado en los eventos de
cierre de vías (VÍA CERRADA), con un enfoque más detallado
en las áreas de mayor afectación.
Este mapa destaca las zonas con mayor cantidad de cierres reportados, lo que permite identificar sectores donde las interrupciones son más frecuentes y pueden afectar la movilidad general.
# Filtrar eventos VÍA CERRADA del día 26
pos <- which(Trama_Waze$tipo_evento == "VÍA CERRADA" & dia == 26)
via_cerrada_26 <- Trama_Waze[pos,]
# Ajustar las coordenadas de latitud y longitud
via_cerrada_26$lat <- via_cerrada_26$location_y / 10^(nchar(via_cerrada_26$location_y) - 1)
via_cerrada_26$long <- via_cerrada_26$location_x / 10^(nchar(via_cerrada_26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
via_cerrada_26 <- via_cerrada_26[via_cerrada_26$lat > 4 & via_cerrada_26$lat < 5,]
Con los eventos de VÍA CERRADA filtrados, se construye un
mapa interactivo para revisar los cierres de forma puntual sobre el
territorio.
Los clusters permiten agrupar reportes cercanos y ayudan a detectar rápidamente corredores o zonas donde se concentran las afectaciones.
# Cargar librería leaflet
require(leaflet)
# Crear el mapa interactivo
m26_via_cerrada = leaflet(via_cerrada_26) %>%
addTiles() %>%
addCircleMarkers(lng = ~long, lat = ~lat,
clusterOptions = markerClusterOptions(),
label = ~hora) %>%
addControl(html = "<h3>Mapa de Cierre de Vías<h3>", position = "topleft")
# Mostrar el mapa interactivo
m26_via_cerrada
Este bloque analiza el patrón espacial de los cierres de vías mediante herramientas de puntos y cuadrantes. La idea es observar si los eventos aparecen dispersos o concentrados dentro de la zona de interés.
Cuando los paquetes espaciales opcionales están disponibles, el Rmd replica el análisis del HTML original; si no están instalados, conserva una gráfica base para que el documento siga funcionando.
if (tiene_spatstat && nrow(via_cerrada_26) > 1) {
# Definir la zona de interés
zona <- spatstat.geom::owin(xrange = c(-74.04331, -73.9929), yrange = c(4.885736, 4.948562))
# Crear un patrón de puntos espaciales a partir de los eventos VÍA CERRADA
patron_via_cerrada <- spatstat.geom::ppp(x = via_cerrada_26$long, y = via_cerrada_26$lat, window = zona)
# Graficar el test de cuadrantes
plot(spatstat.geom::quadratcount(patron_via_cerrada), main = "Patrón de Puntos y Test de Cuadrantes")
# Superponer los puntos sobre los cuadrantes
points(patron_via_cerrada, col = "red")
} else {
plot(via_cerrada_26$long, via_cerrada_26$lat,
main = "Patrón de Puntos: Vía Cerrada",
xlab = "Longitud", ylab = "Latitud", col = "red", pch = 19)
}
# Gráfico independiente: Función K-Estimación
if (tiene_spatstat && exists("patron_via_cerrada")) {
plot(spatstat.explore::Kest(patron_via_cerrada), main = "Función K-Estimación")
}
Este mapa de calor transforma los puntos de cierre en una superficie de densidad, resaltando visualmente los sectores donde los reportes se acumulan con mayor fuerza.
La lectura por intensidad permite comparar zonas de baja, media y alta concentración de cierres sin perder la referencia geográfica del mapa base.
if (tiene_spatstat && tiene_terra && tiene_leaflet_extras && nrow(via_cerrada_26) > 1) {
# Crear un patrón de puntos espaciales utilizando los datos correctos (via_cerrada_26)
zona <- spatstat.geom::owin(xrange = c(-74.04331, -73.9929), yrange = c(4.885736, 4.948562))
patron_via_cerrada <- spatstat.geom::ppp(x = via_cerrada_26$long, y = via_cerrada_26$lat, window = zona)
# Calcular la densidad espacial
im1 <- spatstat.explore::density.ppp(patron_via_cerrada, sigma = 0.01)
# Convertir la densidad a un objeto raster usando terra
mapa_via_cerrada <- terra::rast(im1)
# Convertir el raster a data.frame para leaflet
df_via_cerrada <- as.data.frame(mapa_via_cerrada, xy = TRUE)
colnames(df_via_cerrada) <- c("long", "lat", "intensity")
# Normalizar los valores de intensidad entre 0 y 1
df_via_cerrada$intensity <- (df_via_cerrada$intensity - min(df_via_cerrada$intensity)) /
(max(df_via_cerrada$intensity) - min(df_via_cerrada$intensity))
# Crear un mapa interactivo usando leaflet
leaflet(df_via_cerrada) %>%
addProviderTiles("OpenStreetMap") %>%
leaflet.extras::addHeatmap(lng = ~long, lat = ~lat, intensity = ~intensity,
blur = 20, max = 1, radius = 15) %>%
addLegend("bottomright",
title = "Mapa de Calor de Cierres de Vías",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
} else {
leaflet(via_cerrada_26) %>%
addProviderTiles("OpenStreetMap") %>%
addCircleMarkers(lng = ~long, lat = ~lat, radius = 5, fillOpacity = 0.45,
clusterOptions = markerClusterOptions(), label = ~hora) %>%
addControl(html = "<h3>Mapa de Calor de Cierres de Vías</h3><p>Instale spatstat, terra y leaflet.extras para ver el heatmap.</p>",
position = "bottomright")
}
En esta sección se aíslan los eventos de tipo ACCIDENTE
registrados el día 26 para analizarlos de manera independiente.
Separar esta categoría permite revisar con más detalle las ubicaciones donde se reportaron incidentes viales críticos.
# Filtrar eventos de accidentes del día 26
pos <- which(Trama_Waze$tipo_evento == "ACCIDENTE" & dia == 26)
accidente_26 <- Trama_Waze[pos,]
# Ajustar las coordenadas de latitud y longitud
accidente_26$lat <- accidente_26$location_y / 10^(nchar(accidente_26$location_y) - 1)
accidente_26$long <- accidente_26$location_x / 10^(nchar(accidente_26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
accidente_26 <- accidente_26[accidente_26$lat > 4 & accidente_26$lat < 5,]
El mapa interactivo de accidentes muestra los reportes sobre la cartografía base y los agrupa mediante clusters cuando existen puntos cercanos.
Esta visualización permite ubicar rápidamente los lugares donde se presentaron accidentes y compararlos con el resto de eventos analizados.
# Cargar librerías necesarias
library(leaflet)
# Crear el mapa interactivo
m26_accidente <- leaflet(accidente_26) %>%
addTiles() %>%
addCircleMarkers(lng = ~long, lat = ~lat,
clusterOptions = markerClusterOptions(),
label = ~hora) %>%
addControl(html = "<h3>Mapa de Accidentes</h3>", position = "topleft")
# Mostrar el mapa interactivo
m26_accidente
El análisis espacial de accidentes permite estudiar si los reportes se concentran en áreas específicas o si aparecen de forma más dispersa.
La comparación mediante cuadrantes y la función K, cuando los paquetes están disponibles, aporta una lectura más formal del patrón de distribución.
if (tiene_spatstat && nrow(accidente_26) > 1) {
# Definir la zona de interés
zona = spatstat.geom::owin(xrange = c(-74.04331, -73.9929), yrange = c(4.885736, 4.948562))
# Crear un patrón de puntos espaciales a partir de los eventos ACCIDENTE
patron_accidente = spatstat.geom::ppp(x = accidente_26$long, y = accidente_26$lat, window = zona)
# Gráfico combinado: Test de Cuadrantes y Patrón de Puntos
par(mfrow = c(1, 1)) # Asegurarse de que solo haya una gráfica
# Graficar el test de cuadrantes
plot(spatstat.geom::quadratcount(patron_accidente), main = "Patrón de Puntos y Test de Cuadrantes")
# Superponer los puntos sobre los cuadrantes
points(patron_accidente, col = "red" )
} else {
plot(accidente_26$long, accidente_26$lat,
main = "Patrón de Puntos: Accidentes",
xlab = "Longitud", ylab = "Latitud", col = "red", pch = 19)
}
# Calcular la función K-estimación
if (tiene_spatstat && exists("patron_accidente")) {
plot(spatstat.explore::Kest(patron_accidente))
}
El mapa de calor de accidentes resalta las zonas donde los reportes presentan mayor densidad, ayudando a identificar posibles puntos críticos de seguridad vial.
La escala de intensidad sintetiza la concentración espacial y facilita una lectura rápida de las áreas que requieren mayor atención.
if (tiene_spatstat && tiene_terra && tiene_leaflet_extras && nrow(accidente_26) > 1) {
# Usar las coordenadas correctas de los accidentes
zona <- spatstat.geom::owin(xrange = c(-74.04331, -73.9929), yrange = c(4.885736, 4.948562))
patron_accidente <- spatstat.geom::ppp(x = accidente_26$long, y = accidente_26$lat, window = zona)
# Calcular la densidad espacial
im1 <- spatstat.explore::density.ppp(patron_accidente)
# Convertir la densidad a un objeto raster usando terra
mapa_accidente <- terra::rast(im1)
# Convertir el raster a data.frame para leaflet
df_accidente <- as.data.frame(mapa_accidente, xy = TRUE)
colnames(df_accidente) <- c("long", "lat", "intensity")
# Normalizar los valores de intensidad entre 0 y 1
df_accidente$intensity <- (df_accidente$intensity - min(df_accidente$intensity)) /
(max(df_accidente$intensity) - min(df_accidente$intensity))
# Crear un mapa interactivo usando leaflet
leaflet(df_accidente) %>%
addProviderTiles("OpenStreetMap") %>%
leaflet.extras::addHeatmap(lng = ~long, lat = ~lat, intensity = ~intensity,
blur = 15, max = 0.5, radius = 10) %>%
addLegend("bottomright",
title = "Mapa de Calor de Accidentes",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
} else {
leaflet(accidente_26) %>%
addProviderTiles("OpenStreetMap") %>%
addCircleMarkers(lng = ~long, lat = ~lat, radius = 5, fillOpacity = 0.45,
clusterOptions = markerClusterOptions(), label = ~hora) %>%
addControl(html = "<h3>Mapa de Calor de Accidentes</h3><p>Instale spatstat, terra y leaflet.extras para ver el heatmap.</p>",
position = "bottomright")
}
Este apartado filtra los eventos de tipo CONGESTIÓN
ocurridos el día 26, para observar únicamente los reportes asociados a
tráfico lento o acumulación vehicular.
El filtrado permite separar el comportamiento de la congestión de otros incidentes y analizar su distribución espacial con mayor claridad.
# Filtrar eventos de congestión del día 26
pos <- which(Trama_Waze$tipo_evento == "CONGESTIÓN" & dia == 26)
congestion_26 <- Trama_Waze[pos,]
# Ajustar las coordenadas de latitud y longitud
congestion_26$lat <- congestion_26$location_y / 10^(nchar(congestion_26$location_y) - 1)
congestion_26$long <- congestion_26$location_x / 10^(nchar(congestion_26$location_x) - 3)
# Filtrar eventos dentro del rango geográfico adecuado
congestion_26 <- congestion_26[congestion_26$lat > 4 & congestion_26$lat < 5,]
El mapa interactivo de congestión representa los puntos reportados sobre el territorio y facilita la exploración visual de los sectores con mayor acumulación de tráfico.
La agrupación por clusters mejora la lectura cuando existen muchos puntos cercanos y permite identificar corredores con mayor presión vehicular.
# Cargar las librerías necesarias
library(leaflet)
# Crear el mapa interactivo
m26_congestion <- leaflet(congestion_26) %>%
addTiles() %>%
addCircleMarkers(lng = ~long, lat = ~lat,
clusterOptions = markerClusterOptions(),
label = ~hora) %>%
addControl(html = "<h3>Mapa de Congestión</h3>", position = "topleft")
# Mostrar el mapa interactivo
m26_congestion
Este análisis revisa el patrón espacial de la congestión para determinar si los reportes tienden a concentrarse en zonas específicas de la vía.
Los resultados ayudan a interpretar la recurrencia espacial del tráfico y a relacionarla con posibles corredores de alta demanda.
if (tiene_spatstat && nrow(congestion_26) > 1) {
# Definir la zona de interés
zona <- spatstat.geom::owin(xrange = c(-74.04331, -73.9929), yrange = c(4.885736, 4.948562))
# Crear un patrón de puntos espaciales a partir de los eventos CONGESTIÓN
patron_congestion <- spatstat.geom::ppp(x = congestion_26$long, y = congestion_26$lat, window = zona)
# Visualizar el patrón de puntos
par(mfrow = c(1, 1)) # Asegurarse de que solo haya una gráfica
# Graficar el test de cuadrantes
plot(spatstat.geom::quadratcount(patron_congestion), main = "Patrón de Puntos y Test de Cuadrantes")
# Superponer los puntos sobre los cuadrantes
points(patron_congestion, col = "red")
} else {
plot(congestion_26$long, congestion_26$lat,
main = "Patrón de Puntos: Congestión",
xlab = "Longitud", ylab = "Latitud", col = "red", pch = 19)
}
# Calcular la función K-estimación
if (tiene_spatstat && exists("patron_congestion")) {
plot(spatstat.explore::Kest(patron_congestion))
}
El mapa de calor de congestión sintetiza la concentración de reportes en una capa de intensidad, destacando las zonas donde el tráfico se acumula con mayor frecuencia.
Esta vista complementa el mapa de puntos porque permite reconocer patrones amplios de congestión y no solo ubicaciones individuales.
if (tiene_spatstat && tiene_terra && tiene_leaflet_extras && nrow(congestion_26) > 1) {
# Definir el patrón de puntos
zona <- spatstat.geom::owin(xrange = c(-74.04331, -73.9929), yrange = c(4.885736, 4.948562))
patron_congestion <- spatstat.geom::ppp(x = congestion_26$long, y = congestion_26$lat, window = zona)
# Calcular la densidad espacial del patrón de puntos
im1 <- spatstat.explore::density.ppp(patron_congestion)
# Convertir la densidad en un raster utilizando terra
mapa_congestion <- terra::rast(im1)
# Convertir el objeto raster a un data.frame para usarlo en leaflet
df_congestion <- as.data.frame(mapa_congestion, xy = TRUE)
colnames(df_congestion) <- c("long", "lat", "intensity")
# Normalizar los valores de intensidad entre 0 y 1
df_congestion$intensity <- (df_congestion$intensity - min(df_congestion$intensity)) /
(max(df_congestion$intensity) - min(df_congestion$intensity))
# Crear un mapa interactivo usando leaflet
leaflet(df_congestion) %>%
addProviderTiles("OpenStreetMap") %>%
leaflet.extras::addHeatmap(lng = ~long, lat = ~lat, intensity = ~intensity,
blur = 35, max = max(df_congestion$intensity) * 2, radius = 25) %>%
addLegend("bottomright",
title = "Mapa de Calor de Congestión",
colors = c("blue", "green", "yellow", "red"),
labels = c("Bajo", "Moderado", "Alto", "Muy Alto"))
} else {
leaflet(congestion_26) %>%
addProviderTiles("OpenStreetMap") %>%
addCircleMarkers(lng = ~long, lat = ~lat, radius = 5, fillOpacity = 0.45,
clusterOptions = markerClusterOptions(), label = ~hora) %>%
addControl(html = "<h3>Mapa de Calor de Congestión</h3><p>Instale spatstat, terra y leaflet.extras para ver el heatmap.</p>",
position = "bottomright")
}
En esta última sección se consolidan los mapas interactivos creados
previamente para mostrar los eventos de peligros (PELIGRO),
accidentes (ACCIDENTE), congestión
(CONGESTIÓN) y cierres de vías (VÍA CERRADA)
en una sola vista.
Esta consolidación facilita la comparación de los diferentes tipos de
eventos en una sola interfaz. Cuando leafsync está
disponible, los mapas quedan sincronizados para navegar el mismo espacio
geográfico de manera coordinada.
# Sincronizar los mapas interactivos de distintos tipos de eventos
if (tiene_leafsync) {
leafsync::sync(m26_peligro, m26_accidente, m26_congestion, m26_via_cerrada)
} else if (tiene_htmltools) {
htmltools::tagList(
htmltools::tags$div(
class = "sync-fallback-note",
"Vista consolidada sin sincronización: instale leafsync para activar navegación sincronizada."
),
htmltools::tags$div(
class = "map-grid",
htmltools::tags$div(class = "map-cell", m26_peligro),
htmltools::tags$div(class = "map-cell", m26_accidente),
htmltools::tags$div(class = "map-cell", m26_congestion),
htmltools::tags$div(class = "map-cell", m26_via_cerrada)
)
)
} else {
m26_peligro
}
El análisis realizado sobre los datos proporcionados por Waze para el
día 26 permite obtener una visión integral de los eventos que afectan la
movilidad urbana, como peligros en las vías (PELIGRO),
congestión (CONGESTIÓN), accidentes
(ACCIDENTE) y cierres de vías (VÍA CERRADA).
A través de herramientas de análisis espacial y visualización en mapas interactivos, se identifican patrones importantes en la distribución espacial y temporal de estos eventos.
PELIGRO permite ubicar áreas con mayor probabilidad de
incidentes y orientar acciones preventivas.