Setup
library(tidyverse)
library(sf)
library(readr)
library(readxl)
library(lubridate)
library(tmap)
library(raster)
library(tmaptools)
library(ggspatial)
library(prettymapr)
library(basemaps)
library(cowplot)
library(shiny)
tmap_mode("plot")
Define File Paths
mapping_dir <- "C:/Users/zklein/OneDrive - DOI/Documents/zk_whitebark_learning_and_strategizing/mapping_related"
cone_dir <- "C:/Users/zklein/OneDrive - DOI/Documents/R-directory/cone_collection_mapping"
gis_dir <- "C:/Users/zklein/OneDrive - DOI/General - NPS-SIEN-White Pine Mortality/GIS_layers"
Load Spatial Data
YOSE_boundary <- st_read(file.path(mapping_dir,
"NPS_ParkBoundaries/YOSE_NP_boundary/YOSE_NP_boundary.shp"),
quiet = TRUE)
SEKI_boundary <- st_read(file.path(mapping_dir,
"NPS_ParkBoundaries/SEKI_NP_boundary/SEKI_NP.shp"),
quiet = TRUE)
SEKI_whitebark_dist <- st_read(file.path(
gis_dir,
"WhitePine_Distribution/White_Pine_Distribution_dissolved/SEKI_WhitebarkPine_Dist_Dissolved.shp"
), quiet = TRUE)
SEKI_foxtail_dist <- st_read(file.path(
gis_dir,
"WhitePine_Distribution/White_Pine_Distribution_dissolved/SEKI_FoxtailPine_Dist_Dissolved.shp"
), quiet = TRUE)
YOSE_whitebark_dist <- st_read(file.path(
gis_dir,
"WhitePine_Distribution/White_Pine_Distribution_dissolved/YOSE_WhitebarkPine_Dist_Dissolved.shp"
), quiet = TRUE)
USFS_boundary <- st_read(file.path(
mapping_dir,
"Forest_Administrative_Boundaries/Forest_Administrative_Boundaries_(Feature_Layer).shp"
), quiet = TRUE)
ca_boundary <- st_read(file.path(
mapping_dir,
"NPS_ParkBoundaries/ca_state/CA_State.shp"
), quiet = TRUE)
cone_sites <- read_excel(file.path(cone_dir,
"2024_2025_ConeCollections.xlsx"))
Prepare Spatial Layers
USFS_boundary_sosierra <-
USFS_boundary %>%
filter(FORESTNAME %in%
c("Inyo National Forest",
"Sierra National Forest",
"Sequoia National Forest")) %>%
dplyr::select(-c(
OBJECTID, ADMINFORES, FORESTNUMB,
FORESTORGC, REGION, GIS_ACRES,
SHAPELEN, SHAPEAREA
)) %>%
rename(UNIT_NAME = FORESTNAME) %>%
mutate(
UNIT_TYPE = "National Forest",
UNIT_CODE = case_when(
UNIT_NAME == "Inyo National Forest" ~ "INYO_NF",
UNIT_NAME == "Sequoia National Forest" ~ "SEQU_NF",
UNIT_NAME == "Sierra National Forest" ~ "SIER_NF"
)
) %>%
st_transform(26911)
SEKI_boundary <- st_transform(SEKI_boundary, 26911)
YOSE_boundary <- st_transform(YOSE_boundary, 26911)
SEKI_foxtail_dist <- st_transform(SEKI_foxtail_dist, 26911)
cone_sites_sf <-
st_as_sf(cone_sites,
coords = c("Long", "Lat"),
crs = 4326) %>%
mutate(
Date = as.factor(Date),
`Area Name` = as.factor(`Area Name`)
) %>%
st_transform(26911)
parks_boundary <-
bind_rows(YOSE_boundary, SEKI_boundary)
parks_boundary_sosierra <-
parks_boundary %>%
dplyr::select(-c(
GIS_Notes,
STATE,
REGION,
GNIS_ID,
PARKNAME,
DATE_EDIT,
CREATED_BY
))
so_sierra_boundaries <-
bind_rows(
parks_boundary_sosierra,
USFS_boundary_sosierra
)
Load California Whitebark Pine Distribution
USFS_CA_WBP_fgdb <-
file.path(mapping_dir,
"USFS_Slaton_WBP_Map/WhitebarkPine_CA_2020_v1.gdb")
st_layers(USFS_CA_WBP_fgdb)
## Driver: OpenFileGDB
## Available layers:
## layer_name geometry_type features fields
## 1 WhitebarkPine_CA_2020_v1 Multi Polygon 12926 3
## crs_name
## 1 NAD83 / California Albers
USFS_WBP_dist <-
st_read(
USFS_CA_WBP_fgdb,
layer = "WhitebarkPine_CA_2020_v1",
quiet = TRUE
) %>%
st_transform(26911)
## Warning in CPL_read_ogr(dsn, layer, query, as.character(options), quiet, : GDAL
## Message 1: organizePolygons() received a polygon with more than 100 parts. The
## processing may be really slow. You can skip the processing by setting
## METHOD=SKIP, or only make it analyze counter-clock wise parts by setting
## METHOD=ONLY_CCW if you can assume that the outline of holes is counter-clock
## wise defined
USFS_WBP_dist_dissolved <-
st_union(USFS_WBP_dist)
California Distribution Map
tm_shape(ca_boundary) +
tm_borders() +
tm_shape(USFS_WBP_dist) +
tm_polygons(col = "#458B74")

Load ADS 2025 Data
ADS_2025_fgdb <-
file.path(mapping_dir,
"ADS_2025.gdb")
st_layers(ADS_2025_fgdb)
## Driver: OpenFileGDB
## Available layers:
## layer_name geometry_type features fields
## 1 Flightlines_2025 Multi Line String 59 8
## 2 Buffered_Flightlines_2025 Multi Polygon 3 2
## 3 ADS_2025 Multi Polygon 2573 25
## crs_name
## 1 USA_Contiguous_Albers_Equal_Area_Conic
## 2 USA_Contiguous_Albers_Equal_Area_Conic
## 3 USA_Contiguous_Albers_Equal_Area_Conic
ADS_2025 <-
st_read(
ADS_2025_fgdb,
layer = "ADS_2025",
quiet = TRUE
)
ADS_2025_whitebark <-
ADS_2025 %>%
filter(
HOST %in%
c(
"whitebark pine",
"lodgepole pine",
"limber pine",
"Unknown conifer",
"foxtail pine",
"California red fir"
)
)
Initial ADS Map
tm_shape(so_sierra_boundaries) +
tm_borders() +
tm_shape(USFS_WBP_dist_dissolved) +
tm_borders() +
tm_shape(SEKI_foxtail_dist) +
tm_borders() +
tm_shape(ADS_2025_whitebark) +
tm_polygons(fill = "HOST")

Filter ADS Polygons by Species Distribution
combined_dist <-
st_union(
USFS_WBP_dist_dissolved,
SEKI_foxtail_dist
)
ADS_2025_whitebark <-
ADS_2025_whitebark %>%
st_transform(st_crs(combined_dist)) %>%
st_cast("MULTIPOLYGON")
polygons_filtered <-
ADS_2025_whitebark[
st_intersects(
ADS_2025_whitebark,
combined_dist,
sparse = FALSE
),
]
polygons_filtered_2 <- polygons_filtered %>% group_by(HOST) %>%
mutate(
Site_ID = paste0(
case_when(
HOST == "whitebark pine" ~ "WBP-",
HOST == "foxtail pine" ~ "FTP-",
HOST == "California red fir" ~ "CRF-",
HOST == "limber pine" ~ "LP-",
TRUE ~ "UNK-"
),
sprintf("%03d", row_number())
)
) %>%
ungroup()
Filtered ADS Map
tm_shape(SEKI_boundary) +
tm_borders() +
#tm_shape(USFS_WBP_dist_dissolved) +
tm_borders() +
#tm_shape(SEKI_foxtail_dist) +
tm_borders() +
tm_shape(polygons_filtered_2) +
tm_polygons(fill = "HOST") +
tm_text(
text = "Site_ID",
size = 0.6,
just = "left",
xmod = 0.5,
ymod = 0.3
)
##
## ── tmap v3 code detected ───────────────────────────────────────────────────────
## [v3->v4] `tm_text()`: migrate the layer options 'just' to 'options =
## opt_tm_text(<HERE>)'
