Files
hurricane_normalization_app/app/storm_report.qmd
T
2025-12-18 16:28:15 -05:00

210 lines
5.8 KiB
Plaintext

---
title: "`r params$storm_name` `r params$storm_year` STORM REPORT"
subtitle: "Generated on: `r Sys.Date()`"
format:
pdf:
theme: cosmo
execute:
warning: false
message: false
params:
storm_basin: AL
storm_year: 1900
storm_name: GALVESTON
---
```{r setup}
#| echo: false
library(ggplot2)
library(sf)
library(rnaturalearth)
library(dplyr)
source(file = "queries.R")
storm <- list(
storm_basin = params$storm_basin,
storm_year = params$storm_year,
storm_name = params$storm_name
)
unique_lfs <- get_unique_lf_ids(storm)
storm_track <- get_hurdat_track(storm)
```
```{r track_map}
#| echo: false
#| fig-width: 10
#| fig-height: 8
# Add color and category classification
storm_track <- storm_track %>%
mutate(
hurricane_category = case_when(
storm_status == "HU" & windspeed >= 64 & windspeed <= 82 ~ 1,
storm_status == "HU" & windspeed >= 83 & windspeed <= 95 ~ 2,
storm_status == "HU" & windspeed >= 96 & windspeed <= 112 ~ 3,
storm_status == "HU" & windspeed >= 113 & windspeed <= 136 ~ 4,
storm_status == "HU" & windspeed >= 137 ~ 5,
),
status_label = case_when(
storm_status == "TD" ~ "Tropical Depression (TD)",
storm_status == "TS" ~ "Tropical Storm (TS)",
hurricane_category == 1 ~ "Hurricane Category 1",
hurricane_category == 2 ~ "Hurricane Category 2",
hurricane_category == 3 ~ "Hurricane Category 3",
hurricane_category == 4 ~ "Hurricane Category 4",
hurricane_category == 5 ~ "Hurricane Category 5",
storm_status == "EX" ~ "Extratropical Cyclone (EX)",
storm_status == "SD" ~ "Subtropical Depression (SD)",
storm_status == "SS" ~ "Subtropical Storm (SS)",
storm_status %in% c("LO", "WV", "DB") ~ "Low/Wave/Disturbance",
TRUE ~ "Missing Data"
),
line_color = case_when(
storm_status == "TD" ~ "#2AFF00",
storm_status == "TS" ~ "#FFD020",
hurricane_category == 1 ~ "#FF4343",
hurricane_category == 2 ~ "#FF6FFF",
hurricane_category == 3 ~ "#FF23D3",
hurricane_category == 4 ~ "#C916FF",
hurricane_category == 5 ~ "#FFFFFF",
storm_status == "EX" ~ "#202020",
storm_status == "SD" ~ "#0055FF",
storm_status == "SS" ~ "#6CE2FF",
storm_status %in% c("LO", "WV", "DB") ~ "#A1A1A1",
TRUE ~ "#FF5C00"
)
) %>%
arrange(datetime)
# Create ordered factor for legend
storm_track$status_label <- factor(
storm_track$status_label,
levels = c(
"Tropical Depression (TD)",
"Tropical Storm (TS)",
"Hurricane Category 1",
"Hurricane Category 2",
"Hurricane Category 3",
"Hurricane Category 4",
"Hurricane Category 5",
"Extratropical Cyclone (EX)",
"Subtropical Depression (SD)",
"Subtropical Storm (SS)",
"Low/Wave/Disturbance",
"Missing Data"
)
)
world <- ne_countries(scale = "medium", returnclass = "sf")
states <- ne_states(returnclass = "sf")
min_lon_range <- range(-100, -40)
min_lat_range <- range(10, 50)
#lon_range <- range(storm_track$lon)
#lat_range <- range(storm_track$lat)
#lon_padding <- diff(lon_range) * 0.1
#lat_padding <- diff(lat_range) * 0.1
p <- ggplot() +
geom_sf(data = world, fill = "#E5E5E5", color = "#999999", size = 0.3) +
geom_sf(data = states, fill = NA, color = "#CCCCCC", size = 0.2) +
#coord_sf(
#xlim = c(lon_range[1] - lon_padding, lon_range[2] + lon_padding),
#ylim = c(lat_range[1] - lat_padding, lat_range[2] + lat_padding),
#expand = FALSE
#) +
coord_sf(
xlim = c(min_lon_range[1], min_lon_range[2]),
ylim = c(min_lat_range[1], min_lat_range[2]),
expand = FALSE
) +
theme_minimal() +
theme(
panel.background = element_rect(fill = "#D4E6F1"),
panel.grid.major = element_line(color = "#BBBBBB", size = 0.2),
legend.position = "right",
legend.key.size = unit(0.4, "cm"),
legend.text = element_text(size = 8)
)
if (nrow(storm_track) >= 2) {
for (i in 1:(nrow(storm_track) - 1)) {
segment_data <- storm_track[i:(i + 1), ]
p <- p +
geom_path(
data = segment_data,
aes(x = lon, y = lat),
color = storm_track$line_color[i],
size = 1
)
}
}
p <- p +
geom_point(
data = storm_track,
aes(x = lon, y = lat, color = status_label),
size = 1.5
)
landfall_data <- storm_track %>%
filter(record_identifier == "L")
if (nrow(landfall_data) > 0) {
landfall_data <- landfall_data %>%
mutate(rmw_degrees = rmw_meters / 111320)
p <- p +
geom_point(
data = landfall_data,
aes(x = lon, y = lat),
color = landfall_data$line_color,
size = 4,
shape = 19
) +
geom_point(
data = landfall_data,
aes(x = lon, y = lat),
color = landfall_data$line_color,
size = landfall_data$rmw_degrees * 100,
shape = 1,
stroke = 1.5,
alpha = 0.5
)
}
color_values <- c(
"Tropical Depression (TD)" = "#2AFF00",
"Tropical Storm (TS)" = "#FFD020",
"Hurricane Category 1" = "#FF4343",
"Hurricane Category 2" = "#FF6FFF",
"Hurricane Category 3" = "#FF23D3",
"Hurricane Category 4" = "#C916FF",
"Hurricane Category 5" = "#FFFFFF",
"Extratropical Cyclone (EX)" = "#202020",
"Subtropical Depression (SD)" = "#0055FF",
"Subtropical Storm (SS)" = "#6CE2FF",
"Low/Wave/Disturbance" = "#A1A1A1",
"Missing Data" = "#FF5C00"
)
p <- p +
scale_color_manual(
name = "Storm Status",
values = color_values,
breaks = names(color_values),
drop = FALSE
) +
labs(
title = paste(params$storm_name, params$storm_year),
x = "Longitude",
y = "Latitude"
)
print(p)
```