Firewise Buffer Analysis
Visualizing site buffers with Magick
The Problem: I’ve got a list of lat-long coordinates for Firewise sites across California, and I want to understand, ata rudimentary level, where these sites fall in the grand scheme of Wildfire Hazard.
The sites are spread throughout California, and I have a suspicion there’s some regionality trends I might want to delve into later, so I do a some basic K-nearest neighbor clustering to split the sites into four distinct groups: Southern Cali (green), the Bary Area (red), Northern Cali (yellow), and the Sierras (blue).
Then, I’ve got this underlying Fire Hazard Severity Map from CALFIRE.
Rather than pick an arbitrary buffer size, like 5 Km or something subjective and prone to sensitivity issues (this is the big issue I have with buffer analyses), I decided to compute a continuous buffer from 1-60 Km to get a sense of how the fire hazard environment changes over distance.
Computing the Buffers
I understand why computing continuous buffers isn’t common, it can get pretty messy. I have 500 site points, and three FHSZ values (Moderate, High, Very High), and I want to calcultae the proportion of area each FHSZ occuppies throughout the continuous buffer (ie %Very High, %High, etc).
I thought this would be a good oportunity for parallel computing - its the same redundant calculation over and over again. So rather than just for-loop it (or apply it), I used the foreach
package to parallelize a for-loop to calculate the percent area of each risk zone, for each buffer size from 1-60km.
Registering clusters for parallel computation
library(parallel)
library(doParallel)
cores <- detectCores()
cl <- makeCluster(cores[1]-1)
registerDoParallel(cl)
The Loop
mod <- list()
high <- list()
vhigh <- list()
all <- list()
cbuff <- foreach(i = 1:50) %dopar% {
library(sf)
buff <- st_intersection(st_buffer(sites.sf[,1], i*1000), cali)
buff.area <- st_area(buff)
mod[[i]] <- st_intersection(risk[2,], buff)
mod[[i]]$buff <- i*1000
mod[[i]]$area <- as.numeric(st_area(mod[[i]]))
mod[[i]] <- st_drop_geometry(mod[[i]])
high[[i]] <- st_intersection(risk[1,], buff)
high[[i]]$buff <- i*1000
high[[i]]$area <- as.numeric(st_area(high[[i]]))
high[[i]] <- st_drop_geometry(high[[i]])
vhigh[[i]] <- st_intersection(risk[4,], buff)
vhigh[[i]]$buff <- i*1000
vhigh[[i]]$area <- as.numeric(st_area(vhigh[[i]]))
vhigh[[i]] <- st_drop_geometry(vhigh[[i]])
all[[i]] <- c(mod[i], high[i], vhigh[i])
all
}
stopCluster(cl)
end <- proc.time()
ttime <- end - st
df.mod <- as.data.frame(do.call(rbind, mod))
df.high <- as.data.frame(do.call(rbind, high))
df.vhigh <- as.data.frame(do.call(rbind, vhigh))
df <- bind_rows(df.high, df.mod, df.vhigh)
lapply(list(df.mod, df.high, df.vhigh), function(x){rm(x)})
library(magick)
## list file names and read in
imgs <- list.files("plots/gif", full.names = TRUE)
img_list <- lapply(imgs, image_read)
## join the images together
img_joined <- image_join(img_list)
## animate at 2 frames per second
img_animated <- image_animate(img_joined, fps = 2)
## save to disk
image_write(image = img_animated,
path = "plots/cont_buff2.gif")