LANDFIRE R Toolkit
  • Home
  • Download data
  • Prepare rasters
  • Make charts
  • Make hex map
  • Process events data
  • Compiled code
  • About
  • LANDFIRE Logo

On this page

  • Skills learned
  • Set up
    • Code to load packages and inputs
  • Crop, mask and split out the raster layers
  • Build Raster Attribute Table for Biophysical Settings Data, write files
  • Build Raster Attribute Table for Existing Vegetation Type Data, write files
  • Next steps

Clip and prep LANDFIRE rasters

Skills learned

Use this page to: - Clip LANDFIRE data to a specific landscape (for this example, Mapzone 34)

  • Crop, mask and build attribute table for the area then write the files to our ‘outputs’ folder for later use

Set up

To run the code below you will need to:

  1. Follow the set up instructions and run the code on the Download data page, or similar for your landscape and LANDFIRE datasets of interest.
  2. Create a new script for the following code.

Once this set up is complete, you should be able to copy/paste the code below into the r script you created above.

Code to load packages and inputs

# install packages if needed
  # install.packages("foreign")
  # install.packages("sf")
  # install.packages("terra")
  # install.packages("tidyverse")

# load packages

library(foreign)
library(sf)
library(terra)
library(tidyverse)


# read in Area of Interest (aoi) shapefile, plot to check

shp <- st_read("inputs/map_zone_35.shp", quiet = TRUE) %>% 
  st_transform(crs = 5070) %>%
  st_union() %>%
  st_sf()


# read in .csv of CONUS-wide attributes for later joining to AoI BpS table

bps_conus_atts <- read_csv("inputs/LF20_BPS_220.csv")

# another way is directly from landfire.gov
# bps_url <- "https://landfire.gov/sites/default/files/CSV/LF2016/LF16_BPS.csv" # will likely get warning, but it's OK
# bps_conus_atts <- read.csv(bps_url)


evt_conus_atts <- read_csv("inputs/LF23_EVT_240.csv")

# evt_url <- "https://landfire.gov/sites/default/files/CSV/2024/LF2024_EVT.csv" # will likely get warning, but it's OK
# evt_conus_atts <- read.csv(evt_url)


# look at the first few rows of the CONUS-wide attribute tables
print(head(bps_conus_atts))
print(head(evt_conus_atts))

Crop, mask and split out the raster layers

Now that we have LANDFIRE data for the extent of our area of interest, we need to crop/mask it to the exact area of interest, build the raster attribute table and do a few calculations:

  • First, we load our stacked raster data from the file landfire_data.tif.
  • Next, we crop and mask this raster using a shapefile to focus on our area of interest.
  • We then plot the cropped and masked raster to visualize our area of interest.
  • We set the levels of the raster to match our attribute data and specify the active category.

Extracting and Processing Values: We extract values from the raster, remove any NA values, and convert the data into a dataframe. This dataframe is then processed to create a frequency table, which is further refined and joined with the raster categories.

Saving the Results: Finally, we save the processed raster and the attributes dataframe to files for future use.

# load in landfire stacked raster
stacked_rasters <- rast("inputs/landfire_data.tif")

# crop and mask stacked raster 
aoi_stacked_rasters <- stacked_rasters %>%
  crop(shp) %>%
  mask(shp)

# "split" cropped and masked stacked raster into separate layers
for(lyr in names(aoi_stacked_rasters)) assign(lyr, aoi_stacked_rasters[[lyr]])

Build Raster Attribute Table for Biophysical Settings Data, write files

#| label: Build Raster Attribute Table for Biophysical Settings Data, write files
#| echo: true
#| message: false
#| warning: false
#| code-overflow: wrap
#| include: true
#| results: hide
#| eval: false




# Assign categories
levels(US_200BPS) <- bps_conus_atts
activeCat(US_200BPS) <- "VALUE"

# Get frequency table 
bps_freq <- freq(US_200BPS) %>%
  as.data.frame()

# Join with attributes and calculate acres and percent
bps_aoi_atts <- bps_freq %>%
  rename(VALUE = value, COUNT = count) %>%
  mutate(VALUE = as.integer(VALUE)) %>%
  left_join(bps_conus_atts, by = "VALUE") %>%
  filter(COUNT != 0) %>%
  mutate(
    ACRES = round((COUNT * 900 / 4046.86), 0),
    REL_PERCENT = round((COUNT / sum(COUNT)) * 100, 3)) %>%
  arrange(desc(REL_PERCENT)) %>%
  select(-layer)  # Optional: remove 'layer' column

# write the raster to a file with specified options
writeRaster(US_200BPS, "outputs/bps_aoi.tif",
            gdal = c("COMPRESS=NONE", "TFW=YES"),
            datatype = "INT2S",
            overwrite = T)

|---------|---------|---------|---------|
=========================================
                                          
# write the attributes dataframe to a dbf file
write.dbf(bps_aoi_atts, "outputs/bps_aoi.tif.vat.dbf")

# write the attributes dataframe to a csv file
write.csv(bps_aoi_atts, "outputs/bps_aoi_attributes.csv")

# plot the cropped and masked raster-will just show values in the map.  Output not shown here.
plot(US_200BPS)

# look at the first few rows of the aoi attributes. Output not shown here.
print(head(bps_aoi_atts))
  VALUE    COUNT BPS_CODE ZONE         BPS_MODEL
1  1718 46439852    11320   35    11320_32_34_35
2  1725 44125598    13830   35    13830_32_35_36
3  1728 16449562    13930   35       13930_32_35
4  1730 13609703    14220   35 14220_32_35_36_37
5  1723 11475228    13080   35       13080_32_35
6  1737 10387249    15230   35       15230_32_35
                                             BPS_NAME  GROUPVEG FRI_REPLAC
1                          Central Mixedgrass Prairie Grassland          7
2      Edwards Plateau Limestone Savanna and Woodland  Hardwood         15
3                 Edwards Plateau Limestone Shrubland   Conifer         69
4                Southern Blackland Tallgrass Prairie Grassland          3
5                Crosstimbers Oak Forest and Woodland  Hardwood        158
6 Edwards Plateau Dry-Mesic Slope Forest and Woodland  Hardwood        103
  FRI_MIXED FRI_SURFAC FRI_ALLFIR PRC_REPLAC PRC_MIXED PRC_SURFAC FRG_NEW   R
1        44         21          5         65        12         23     I-A 112
2        24         14          6         38        23         39     I-B 209
3        44      -9999         27         39        61      -9999     I-C 255
4       171         35          2         91         2          7    II-A 255
5        93          5          5          3         5         92     I-A 137
6       133         30         20         19        15         66     I-C 102
    G   B      RED    GREEN     BLUE    ACRES REL_PERCENT
1 168 112 0.439216 0.658824 0.439216 10327974      26.029
2 255 115 0.819608 1.000000 0.450980  9813297      24.732
3 203 125 1.000000 0.796078 0.490196  3658295       9.220
4 127 127 1.000000 0.498039 0.498039  3026725       7.628
5  90  68 0.537255 0.352941 0.266667  2552029       6.432
6 255 171 0.400000 1.000000 0.670588  2310069       5.822

Build Raster Attribute Table for Existing Vegetation Type Data, write files

# Assign categories
levels(US_240EVT) <- evt_conus_atts
activeCat(US_240EVT) <- "VALUE"

# Get frequency table 
evt_freq <- freq(US_240EVT) %>%
  as.data.frame()

# Join with attributes and calculate acres and percent
evt_aoi_atts <- evt_freq %>%
  rename(VALUE = value, COUNT = count) %>%
  mutate(VALUE = as.integer(VALUE)) %>%
  left_join(evt_conus_atts, by = "VALUE") %>%
  filter(COUNT != 0) %>%
  mutate(
    ACRES = round((COUNT * 900 / 4046.86), 0),
    REL_PERCENT = round((COUNT / sum(COUNT)) * 100, 3)
  ) %>%
  arrange(desc(REL_PERCENT)) %>%
  select(-layer)  # Optional: remove 'layer' column

# write the raster to a file with specified options
writeRaster(US_240EVT, "outputs/evt_aoi.tif",
            gdal = c("COMPRESS=NONE", "TFW=YES"),
            datatype = "INT2S",
            overwrite = T)

# write the attributes dataframe to a dbf file
write.dbf(evt_aoi_atts, "outputs/evt_aoi.tif.vat.dbf")

# write the attributes dataframe to a csv file
write.csv(evt_aoi_atts, "outputs/evt_aoi_attributes.csv")

# plot the cropped and masked raster-will just show values in the map.  Output not shown here.
plot(US_240EVT)

# look at the first few rows of the aoi attributes. Output not shown here.
print(head(evt_aoi_atts))

Next steps

You can now open up the processed raster(s) in ArcGIS pro and/or QGIS to do further GIS. This process really shines when you do multiple LANDFIRE datasets at once and/or process data for multiple landscapes. Further, you can work in Excel, R or other software to make charts of the attributes that are saved as a .csv file. Go to the Make Charts page to get started.

While we are sure it is possible to make attractive, accessible maps with the processed LANDFIRE rasters in R, we typically move to a different GIS software for mapping, or summarize the data by polygons (e.g., watersheds or hexagons) in R. Try the code on the Make hex map for ways you might map LANDFIRE data in R.



Logo 3 Logo 2 Logo 1 Logo 3