The LANDFIRE Program provides 25+ national geo-spatial layers (e.g. vegetation, fuel, disturbance, etc.), databases, and ecological models that are available to the public for the U.S. and insular areas.
We relied on Three LANDFIRE Products as inputs for this initial analysis:
*NOTE: LANDFIRE data is delivered as geotifs with 30M pixel size. All maps were created in ArcGIS Pro. All charts were plotted in R/R-Studio.
Area of interest:
Show the code
# load packages for pagelibrary(sf)library(terra)library(tidyverse)library(tmap)library(janitor)library(scales)library(kableExtra)# read shapeMapZone2<-st_read("data/mz2.shp", quiet =TRUE) %>%st_transform(crs =5070) %>%st_union() %>%st_sf()# toggle tmap mode to interactive viewingtmap_mode("view")# create a quick interactive mapquickmap <-qtm(MapZone2, borders ="darkgreen", fill =NULL, check.and.fix =TRUE, basemaps ='https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}',title ='LANDFIRE Map Zone 2',)quickmap
Figure 2. Study area is the western coast of Oregon along the western side of the coastal range of the Cascade Mountains. This area is also known in LANDFIRE as Map Zone 2. See map of all LANDFIRE Map Zones here.
Below we describe the data inputs and GIS operations.
GIS operations
Clipping ecosystem footprint data
We relied on LANDFIRE’s Biophysical Settings (BpS) to obtain “potential ecosystem footprints” to represent what would have been present prior to European colonization of North America. LANDFIRE’s BpS suite is based on both the current biophysical environment and an approximation of the historical disturbance regime.
For example, each BpS, (i.e. “western hemlock douglas fir forest”) is accompanied by a description that includes information on its succession classes and a model which captures historical disturbances and estimated amounts of succession classes.
We used the Clip Raster tool in ArcGIS pro to extract the area of interest from a broader extent of the raster data.
Obtaining historical percentages of late-successional forests
For each BpS, we needed to get estimates how much late-open and late-closed forest would have historically been present. This information was developed in BpS state-and-transition models, and available in a couple formats:
The BpS Reference Condition Table obtainable by clicking “Reference Conditions” here.
Example - Below is a screenshot of a BpS model: 1. Boxes represent the succession classes, or structural stages of an ecosystem 2. Lines represent succession and disturbance pathways 3. What’s missing from the diagram? The quantitative, disturbance inputs from the model, or the outputs which include percent of each succession class that would have occurred historically (visit the LANDFIRE Vegetation Modeling site to learn more about the modeling process).
Assessing current succession classes
We used the LANDFIRE succession class dataset to estimate the percentage of each succession class that occurs (per BpS) on today’s landscape. Each pixel within a BpS is labeled “A through E” for the “reference” states, and includes labels for other categories such as agriculture and urban.
Step 1: Use the “clip raster” tool to extract the area of interest from a broader extent of the raster data.
Step 2: Do a ‘combine’ using the Combine Tool of the BpS and succession class data to get a dataframe with pixel counts of each unique combination of BpS and succession class to allow for estimating of the amounts of current succession classes per BpS.
Step 3: Use the Join Field Tool to join the ‘BPS_NAME’, ‘BPS_MODEL’ attributes from the BpS dataset, and the ‘Label’ attribute from the Succession Class dataset (see output data example below).
The rules for defining the structural characteristics of each succession class are in the BpS descriptions, and are essentially combinations of height, cover and type.
Wrangling data exported from ArcGIS Pro
Once we have clipped, combined and attributed spatial data in ArcGIS pro, we need to do a little data wrangling in R to further prep the spatial data for mapping and to make some charts. In summary we:
Read the combined data attribute table and supporting data tables from LANDFIRE into R (all located in ‘data’ directory in Git repo)
BpS-Succession Class Combined attribute table (named “bps_scl_cmbn.csv”)
Succession Class Descriptions (named “scls_descriptions.csv”)
Map Zone 2 Biophysical Settings (named “bps_mz2.csv”)
Build and join in succession class ‘descriptions’ (e.g., ‘Late1-Closed’)
Do a little cleaning, and make a new ‘join_field’
Calculate reference and current acres per succession class per BpS
Click the “Code” button to see code.
Show the code
## read in raw data and sclass descriptionsraw_bps_scls <-read.csv("data/bps_scls_cmbn.csv")sclass_descriptions <-read.csv("data/scls_descriptions.csv")reference_percents <-read.csv("data/ref_con_long.csv")bps_mz2 <-read.csv("data/bps_mz2.csv")## clean and prep raw combined dataclean_bps_scls_cmbn <- raw_bps_scls %>%clean_names() %>% dplyr::select(-c(4, 5)) %>%unite("join_field", bps_model,label, sep ="_", remove =FALSE )## clean and prep sclass descriptionssclass_descriptions_clean <- sclass_descriptions %>% dplyr::select(-c(4)) %>%# remove columnrename("model_code"="StratumID","scls_label"="ClassLabelID","state_class_id"="StateClassID" ) %>%# rename columnsunite("join_field", model_code:scls_label, sep ="_", remove =FALSE ) %>%separate(state_class_id, into =c("age_category", "canopy_category"), sep =":", remove =FALSE) ## clean and prep reference percentsunique_sclass_labels_ref <-unique(reference_percents$refLabel)#print(unique_sclass_labels_ref)unique_sclass_lables_cmbn <-unique(clean_bps_scls_cmbn$label)#print(unique_sclass_lables_cmbn)# does not have barren/sparse and there are differences, e.g., Urban-Developed between this and sclass label# will assume Barren/Sparse, NoData and Snow/Ice is minimal; will change "Developed" to "Urban" in reference df cleaning code clean_ref_percents <- reference_percents %>%clean_names() %>%mutate(across('ref_label', str_replace, 'Developed', 'Urban')) %>%mutate(across('model_label', str_replace, 'Developed', 'Urban')) %>%rename("join_field"="model_label","bps_name"="bp_s_name" )## need to winnow this df to only the bps model codes in MZ 2clean_ref_percents_mz2 <- clean_ref_percents %>%filter(model_code %in% bps_mz2$BPS_MODEL)## create 'final' dataframe with reference and current sclass percents, acres and labels## first ref con and sclass descriptionsfinal_df <-left_join(clean_ref_percents_mz2, sclass_descriptions_clean) # looks OK, now full join to add reference percents then clean a bitfinal_df2 <-full_join(final_df, clean_bps_scls_cmbn) %>% dplyr::select(-c(6, 10, 13, 14)) %>%rename( "cur_scls_count"="count")# now for the math: need count/acres per bps, cur sclass percents and differencesfinal_df3 <- final_df2 %>%group_by(bps_name) %>%mutate(bps_count =sum(cur_scls_count, na.rm =TRUE)) %>%ungroup() %>%mutate(bps_acres = bps_count*0.2223945,ref_scls_acres = bps_acres*(ref_percent/100),cur_scls_acres = cur_scls_count*0.2223945,cur_percent = (cur_scls_acres/bps_acres)*100) %>%mutate(across(12:15, round, 0))# save to csv to explore in Excel, and reorder columns#write.csv(final_df3, file = "data/final_df.csv", row.names = FALSE)
The resulting final data table was then joined back to the combined BpS-Succession Class data in ArcGIS Pro for mapping.