Today we will be focusing on the practice of fancy geospatial data analysis and visualization.
Load libraries
── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.2 ✔ readr 2.1.4
✔ forcats 1.0.0 ✔ stringr 1.5.0
✔ ggplot2 3.4.2 ✔ tibble 3.2.1
✔ lubridate 1.9.2 ✔ tidyr 1.3.0
✔ purrr 1.0.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
Linking to GEOS 3.9.3, GDAL 3.5.2, PROJ 8.2.1; sf_use_s2() is TRUE
Data
The school database from California School Campus Database. I have posted a cleaned up version for the Inland Empire to this class github.
schoolURL <- 'https://raw.githubusercontent.com/RadicalResearchLLC/WarehouseAssemblyBill/main/IEschools.geojson'
schools <- sf::read_sf(dsn = schoolURL) %>%
st_transform(crs = 4326)
head(schools)
Simple feature collection with 6 features and 5 fields
Geometry type: MULTIPOLYGON
Dimension: XY
Bounding box: xmin: -117.6022 ymin: 33.89027 xmax: -117.4624 ymax: 34.11768
Geodetic CRS: WGS 84
# A tibble: 6 × 6
School District City GradesServed Level geometry
<chr> <chr> <chr> <chr> <chr> <MULTIPOLYGON [°]>
1 Cucamonga Middle Central… Ranc… 6-8 Inte… (((-117.5996 34.11482, -…
2 Allan Orrenmaa El… Alvord … Rive… K-5 Elem… (((-117.4766 33.89399, -…
3 Alvord Continuati… Alvord … Rive… 10-12 High… (((-117.4885 33.89154, -…
4 Arizona Middle Alvord … Rive… 6-8 Inte… (((-117.4637 33.89473, -…
5 Arlanza Elementary Alvord … Rive… K-5 Elem… (((-117.4684 33.94243, -…
6 Collett Elementary Alvord … Rive… K-5 Elem… (((-117.479 33.90745, -1…
fig-Schools would show the location of school campuses in the Inland Empire if I wasn’t running out of space.
palGrades <- colorFactor(palette = 'Dark2', domain = schools$Level)
leaflet() %>%
addTiles() %>%
setView(lat = 33.9, lng = -117.4, zoom = 9) %>%
addProviderTiles(providers$CartoDB.PositronNoLabels) %>%
addPolygons(data = schools,
color = ~palGrades(Level),
fillOpacity = 0.8,
weight = 2,
group = 'Schools',
label = ~htmlEscape(School)) %>%
addLegend(data = schools,
pal = palGrades,
values = ~Level,
position = 'bottomleft')
Let’s import the planned Warehouse layer for comparison.
I’ve shown the quiet = TRUE
argument in st_read to remove the message import from st_read()
plannedWH.url <- 'https://raw.githubusercontent.com/RadicalResearchLLC/PlannedWarehouses/main/plannedWarehouses.geojson'
plannedWarehouses <- st_read(plannedWH.url, quiet = TRUE) %>%
st_transform("+proj=longlat +ellps=WGS84 +datum=WGS84")
Add the planned warehouses next to the schools and zoom in a bit to the City of Fontana.
fig-plannedWHs shows the data for schools in the Inland Empire with planned warehouse projects, or it would if I wasn’t running out of space.
palGrades <- colorFactor(palette = 'Dark2', domain = schools$Level)
leaflet() %>%
addTiles() %>%
setView(lat = 34, lng = -117.5, zoom = 11) %>%
addProviderTiles(providers$CartoDB.PositronNoLabels) %>%
addPolygons(data = schools,
color = ~palGrades(Level),
fillOpacity = 0.8,
weight = 2,
group = 'Schools',
label = ~htmlEscape(School)) %>%
addLegend(data = schools,
pal = palGrades,
values = ~Level,
position = 'bottomleft') %>%
addPolygons(data = plannedWarehouses,
color = 'black',
fillOpacity = 0.3,
weight = 2,
group = 'Planned and Approved Warehouses')
Analysis
Create a 1,000 foot buffer around planned warehouses. The goal is to identify schools within a set distance of warehouses.
The st_buffer()
function can be used to create shape specific boundaries around polygons.
buffWH1000 <- plannedWarehouses %>%
#default units are meters, 304 m = 1000 ft
st_buffer(dist = 304)
Figure 25.2 shows the schools with their new buffer as a gray overlay.
leaflet() %>%
addTiles() %>%
addProviderTiles(provider = providers$CartoDB.PositronNoLabels) %>%
setView(lat = 34, lng = -117.5, zoom = 12) %>%
addPolygons(data = buffWH1000,
fillOpacity = 0.4,
color = 'gray',
weight = 1,
group = '1000 foot buffer') %>%
addPolygons(data = plannedWarehouses,
color = 'black',
fillOpacity = 0.3,
weight = 2,
group = 'Planned and Approved Warehouses') %>%
addPolygons(data = schools,
color = ~palGrades(Level),
fillOpacity = 0.8,
weight = 2,
group = 'Schools',
label = ~htmlEscape(School)) %>%
addLegend(data = schools,
pal = palGrades,
values = ~Level,
position = 'bottomleft') #%>%