library(here)
library(tidyverse)
library(sf)
library(tmap)
Find Bird Observations within Santa Barbara’s PAs
# Read Santa Barbara PA vectors
<- read_sf(here::here("data", "cpad_super_units_sb.shp")) %>%
sb_protected_areas st_transform("ESRI:102009")
# Read Santa Barbara's city boundaries vector
<- read_sf(here::here("data", "sb_city_boundaries_2003.shp")) %>%
sb_city_boundaries st_transform("ESRI:102009")
# Read Santa Barbara's county boundaries vector
<- read_sf(here::here("data", "sb_county_boundary_2020.shp")) %>%
sb_county_boundary st_transform("ESRI:102009")
# Read iNaturalist bird observations from 2020-2024
<- read_sf(here::here("data", "aves_observations_2020_2024.shp")) %>%
aves st_transform("ESRI:102009")
Approach with spatial subset:
- Spatially subset the PA geometries to only those with bird observations
<- sb_protected_areas[aves, ]
aves_PA_subset
tm_shape(sb_county_boundary) +
tm_fill() +
tm_shape(sb_protected_areas) +
tm_borders(lwd = 1, col = "#fb8500") +
tm_fill(col = "#fb8500", alpha = 0.2) +
tm_shape(aves_PA_subset) +
tm_dots(col = "#023047") +
tm_layout(main.title = "Birds in Santa Barbara\nCounty Protected Areas",
main.title.size = 1)
nrow(aves_PA_subset)
[1] 35
Approach with a spatial join:
- Append the Protected Area geometries to the bird observation geometries
<- st_join(aves, sb_protected_areas)
aves_PA_join
tm_shape(sb_county_boundary) +
tm_fill() +
tm_shape(sb_protected_areas) +
tm_borders(lwd = 1, col = "#fb8500") +
tm_fill(col = "#fb8500", alpha = 0.2) +
tm_shape(aves_PA_join) +
tm_dots(col = "#023047") +
tm_layout(main.title = "Birds in Santa Barbara\nCounty Protected Areas",
main.title.size = 1)
nrow(aves_PA_join)
[1] 500
And try adding a 5 km buffer around the protected areas:
# Check if units are in meters
st_crs(sb_protected_areas)$units
[1] "m"
# Create 5000m buffer around PAs
<- st_buffer(sb_protected_areas, dist = 5000)
PA_buffer_5km
# Subset the buffered PA geoms to only those with bird observations
<- PA_buffer_5km[aves, ]
aves_buffer_subset
tm_shape(sb_county_boundary) +
tm_fill() +
tm_shape(sb_protected_areas) +
tm_borders(lwd = 1, col = "#fb8500") +
tm_fill(col = "#fb8500", alpha = 0.2) +
tm_shape(aves_buffer_subset) +
tm_dots(col = "#023047") +
tm_layout(main.title = "Birds in Santa Barbara\nCounty Protected Areas",
main.title.size = 1)
nrow(aves_buffer_subset)
[1] 327
Find PAs within 15 km of Goleta
# Subset SB county to Goleta
<- sb_city_boundaries %>%
goleta ::filter(NAME == "Goleta")
dplyr
# Create 15km buffer around Goleta
st_crs(goleta)$units
[1] "m"
<- st_buffer(goleta, dist = 15000)
goleta_buffer_15km
# Explore the different outputs with different spatial operations
<- st_within(sb_protected_areas, goleta_buffer_15km)
goleta_PAs_within <- st_intersects(sb_protected_areas, goleta_buffer_15km)
goleta_PAs_intersect <- st_intersection(sb_protected_areas, goleta_buffer_15km)
goleta_PAs_intersection
# Check class
class(goleta_PAs_intersect) == class(goleta_PAs_intersection)
[1] FALSE FALSE FALSE FALSE
# Compute distance-based join
<- st_join(sb_protected_areas, goleta, st_is_within_distance, dist = 15000)
goleta_PAs_join
# Print the number of observations included in outputs
nrow(goleta_PAs_intersection)
[1] 185
nrow(goleta_PAs_join)
[1] 369
Find Distance between Goleta and Dangermond Preserve
# Subset PA to Dangermond Preserve
<- sb_protected_areas %>%
dangermond ::filter(UNIT_NAME == "Jack and Laura Dangermond Preserve")
dplyr
# Compute the distance between geometries edges, output as a matrix
<- st_distance(goleta, dangermond)
danger_dist
# Calculate the geometric center
<- st_centroid(dangermond)
dangermond_centroid <- st_centroid(goleta)
goleta_centroid
<- st_distance(goleta_centroid, dangermond_centroid)
danger_dist_centroid
# Check if the distance matrices are equal
== danger_dist_centroid danger_dist
[,1]
[1,] FALSE