--- title: "`r params$hurdat_id` `r params$storm_name` `r params$storm_year` STORM REPORT" subtitle: "Generated on: `r Sys.Date()`" format: pdf: theme: cosmo geometry: - top=0.75in - bottom=0.75in - left=0.75in - right=0.75in - footskip=0.3in execute: warning: false message: false params: storm_basin: AL storm_year: 1900 storm_name: GALVESTON hurdat_id: AL011900 --- ```{r setup, echo=FALSE} library(ggplot2) library(sf) library(rnaturalearth) library(dplyr) library(scales) library(knitr) library(kableExtra) library(patchwork) 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) hurdat_id <- get_hurdat_id(storm) plot_theme <- theme( plot.title = element_text(hjust = 0.5, size = 10), axis.title = element_text(size = 10), axis.text = element_text(size = 8), legend.title = element_text(face = "bold"), legend.text = element_text(face = "bold") ) ``` ```{r storm_overview, echo=FALSE} # storm stats # mmh, mmp, landfalls, hurdat summary (max cat, min press, max wind, hurricane points, total points) # fatality data? hurdat_summary <- get_best_track_summary(storm) losses <- get_latest_aggregate_loss(storm) storm_track <- get_hurdat_track(storm) ``` # Storm Overview - **HURDAT2 ID** `r hurdat_id$hurdatid` - **HURDAT2 Revision Date** `r hurdat_id$hurdat_rev` ## Normalized Cost - **MMH24** `r dollar(losses$mmh)` - **MMP24** `r dollar(losses$mmp)` ## HURDAT2 Summary - **Date Range** `r min(storm_track$formatted_datetime)` to `r max(storm_track$formatted_datetime)` - **Total Observations** `r hurdat_summary$total_observations` - **Hurricane Observations** `r hurdat_summary$hurricane_observations` - **Landfall Observations** `r hurdat_summary$hurdat_landfalls` - **Maximum Saffir-Simpson Category** `r hurdat_summary$max_category` - **Minimum Pressure** `r hurdat_summary$min_pressure` mb - **Maximum Windspeed** `r hurdat_summary$max_windspeed` kts ## Storm Track ```{r track_map, echo=FALSE} #| fig-width: 10 #| fig-height: 8 #| out-width: "100%" 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) 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) ) + plot_theme 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) ``` ## Track Observations ```{r track_table, echo=FALSE} landfall_rows <- which(storm_track$record_identifier == "L") storm_track %>% select( formatted_datetime, storm_status, record_identifier, lon, lat, rmw, pressure, windspeed ) %>% kable( col.names = c( "Date", "Status", "Record ID", "Lon", "Lat", "RMW", "Pressure", "Windspeed" ), align = c("l", "c", "c", "r", "r", "r", "r", "r"), booktabs = TRUE ) %>% kable_styling( #latex_options = c("striped"), font_size = 9, position = "center" ) %>% column_spec( 2, color = "white", background = paste0(storm_track$line_color, "A0"), bold = T ) %>% row_spec( landfall_rows, color = "white", background = paste0(storm_track$line_color[landfall_rows], "A0") ) %>% column_spec( 6, color = "white", background = spec_color(storm_track$rmw, end = 0.7), bold = T ) %>% column_spec( 7, color = "white", background = spec_color(storm_track$pressure, end = 0.7), bold = T ) %>% column_spec( 8, color = "white", background = spec_color(storm_track$windspeed, end = 0.7), bold = T ) ``` ## Cost Normalization ```{r normalization, echo=FALSE} #| out-width: "100%" costs <- get_all_normalized_cost_index(storm) # for each lf, create charts of mmh/mmp unique_lf_ids <- unique_lfs$full_lf_id for(lf in unique_lf_ids) { filtered_costs <- costs %>% filter( full_lf_id == lf ) mmh_plot <- ggplot(filtered_costs, aes(x = normalization_year, y = mmh_loss)) + geom_area(fill = "blue", alpha = 0.7) + scale_y_continuous(labels = scales::label_dollar(scale_cut = cut_short_scale())) + labs( title = paste(lf, "MMH Loss"), x = "Year", y = "Aggregate Loss (USD)" ) + theme_minimal() + plot_theme mmp_plot <- ggplot(filtered_costs, aes(x = normalization_year, y = mmp_loss)) + geom_area(fill = "red", alpha = 0.7) + scale_y_continuous(labels = scales::label_dollar(scale_cut = cut_short_scale())) + labs( title = paste(lf, "MMP Loss"), x = "Year", y = "Aggregate Loss (USD)" ) + theme_minimal() + plot_theme print(mmh_plot) print(mmp_plot) } ```