diff --git a/.gitignore b/.gitignore index 7eb9b56..6ed82b1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ data-bkup archive/ trash/ api_key +R/route_analysis.html diff --git a/R/route_analysis.html b/R/route_analysis.html deleted file mode 100644 index f91f004..0000000 --- a/R/route_analysis.html +++ /dev/null @@ -1,1876 +0,0 @@ - - - - - - - - - - - - - -Route Analysis - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
-
-
-
-
- -
- - - - - - - -
date()
-
## [1] "Thu Oct 31 16:37:36 2024"
-
rm(list=ls())
-library(tidyverse)
-library(ggmap)
-library(sf)
-library(osrm)
-library(smoothr)
-library(magick)
-library(ggnewscale)
-library(rsvg)
-fig.height <- 6
-set.seed(1)
-
-

Main R script

-
## school focus
-school_focus <- data.frame(name = c("East High School"), NCES_CODE = c("550852000925"))
-
-## walk boundary
-walk_boundary_m <- 1.5 * 1609
-
-## load school locations
-
-WI_schools <- st_transform(st_read(dsn = "data/Schools/Wisconsin_Public_Schools_-5986231931870160084.gpkg"), crs = 4326)
-
## Reading layer `WI_Public_Schools' from data source 
-##   `/home/ben/Bike Fed/Documents/data_analysis/route_analysis/data/Schools/Wisconsin_Public_Schools_-5986231931870160084.gpkg' 
-##   using driver `GPKG'
-## replacing null geometries with empty geometries
-## Simple feature collection with 2274 features and 32 fields (with 120 geometries empty)
-## Geometry type: POINT
-## Dimension:     XY
-## Bounding box:  xmin: 298957.7 ymin: 225953.4 xmax: 760547.6 ymax: 704946.8
-## Projected CRS: NAD83(HARN) / Wisconsin Transverse Mercator
-
WI_schools <- WI_schools %>% mutate(geom = SHAPE)
-
-## load addresses
-addresses <- read_csv(file="data/addresses/Addresses_Students_EastHS_2024_GeocodeResults.csv") %>%
-  filter(lat > 0) %>%
-  st_as_sf(coords=c("lon","lat"), crs=4326) # remember x=lon and y=lat
-
-## set osrm options
-options(osrm.server = "http://127.0.0.1:5000/")
-options(osrm.profile = "walk")
-
-register_stadiamaps(key = substr(read_file(file = "api_keys/stadia_api_key"), 1, 36))
-
-## subset addresses within 1.5 miles
-walk_boundary_poly <- fill_holes(st_make_valid(osrmIsodistance(
-  loc = WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE),
-  breaks = c(walk_boundary_m),
-  res = 80)
-), units::set_units(1, km^2))
-
-addresses_near <- st_intersection(addresses, walk_boundary_poly)
-
-## load bike tls
-bike_lts <- st_read("data/bike_lts/bike_lts_DANE.geojson")
-
## Reading layer `Bike_LTS' from data source 
-##   `/home/ben/Bike Fed/Documents/data_analysis/route_analysis/data/bike_lts/bike_lts_DANE.geojson' 
-##   using driver `GeoJSON'
-## Simple feature collection with 43355 features and 5 fields
-## Geometry type: MULTILINESTRING
-## Dimension:     XY
-## Bounding box:  xmin: -89.84212 ymin: 42.8404 xmax: -89.0082 ymax: 43.2942
-## Geodetic CRS:  WGS 84
-
bike_lts[["lts"]] <- as.factor(bike_lts$LTS_F)
-
-bike_lts_scale <- data.frame(code = c(1, 2, 3, 4, 9),
-                             color = c("#1a9641",
-                                       "#a6d96a",
-                                       "#fdae61",
-                                       "#d7191c",
-                                       "#d7191c"))
-
-## calculate routes
-routes <- list(NULL)
-for(i in addresses_near$number) {
- routes[[i]] <- osrmRoute(
-      src = addresses_near %>% filter(number == i),
-      dst = WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE))
-  message(paste0("done - ", i, "of", max(addresses_near$number)))
-}
-routes <- bind_rows(routes)
-
-## combine routes
-# Count the routes that intersect or overlap with each segment of the bike_tls network.
-# The intersections have a buffer of 20m
-bike_lts_buffer <- st_buffer(st_intersection(bike_lts, walk_boundary_poly), 20)
-
-bike_lts_buffer["student_use"] <- unlist(lapply(st_intersects(bike_lts_buffer, routes), length))
-
-bike_lts <- st_join(bike_lts, bike_lts_buffer %>% select(OBJECTID, student_use))
-
-## make maps
-# load logo
-logo <- image_read(path = "other/BFW_Logo_180_x_200_transparent_background.png")
-school_symbol <- image_read_svg(path = "other/school_FILL0_wght400_GRAD0_opsz24.svg")
-
-
-bbox <- st_bbox(st_buffer(walk_boundary_poly, dist = 500))
-bbox <- c(left = as.double(bbox[1]),
-          bottom = as.double(bbox[2]),
-          right = as.double(bbox[3]),
-          top = as.double(bbox[4]))
-
-#get basemap
-basemap <- get_stadiamap(bbox = bbox, zoom = 15, maptype = "stamen_toner_lite")
-
-# generate map
-ggmap(basemap) +
-  labs(title = paste0("Walking routes for students at ",
-    school_focus %>% pull(name)),
-    subtitle = "only showing routes within the 1.5 walk boundary",
-    x = NULL,
-    y = NULL,
-    color = NULL,
-    linewidth = "Potential student walkers") +
-  theme(axis.text=element_blank(),
-        axis.ticks=element_blank(),
-        plot.caption = element_text(color = "grey")) +
-  geom_sf(data = walk_boundary_poly,
-          inherit.aes = FALSE,
-          aes(color = paste0(1.5, " mile walking boundary")),
-          fill = NA,
-          linewidth = 1) +
-  scale_color_manual(values = "blue", name = NULL) +
-  new_scale_color() +
-  geom_sf(data = bike_lts %>% filter(!is.na(student_use), student_use > 3),
-          inherit.aes = FALSE,
-          aes(linewidth = student_use),
-          color = "mediumvioletred",
-          fill = NA) +
-  scale_linewidth_continuous(range = c(0, 3)) +
-  annotation_raster(school_symbol,
-                    # Position adjustments here using plot_box$max/min/range
-                    ymin = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[2] - 0.001,
-                    ymax = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[2] + 0.001,
-                    xmin = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[1] - 0.0015,
-                    xmax = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[1] + 0.0015) +
-  geom_sf_label(data = WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE),
-                inherit.aes = FALSE,
-                mapping = aes(label = school_focus %>% pull(name)),
-                nudge_y = 0.0015,
-                label.size = 0.04,
-                size = 2)
-

-
ggsave(file = paste0("figures/",
-                     school_focus %>% pull(name),
-                     " Routes.pdf"),
-       title = paste0(school_focus %>% pull(name), " Walking Routes"),
-       device = pdf,
-       height = 8.5,
-       width = 11,
-       units = "in",
-       create.dir = TRUE)
-
-# generate map
-ggmap(basemap) +
-  labs(title = paste0("Walking routes for students at ",
-                      school_focus %>% pull(name)),
-       subtitle = "only showing routes within the walk boundary",
-       x = NULL,
-       y = NULL,
-       color = NULL,
-       linewidth = "Potential student walkers") +
-  theme(axis.text=element_blank(),
-        axis.ticks=element_blank(),
-        plot.caption = element_text(color = "grey")) +
-  geom_sf(data = walk_boundary_poly,
-          inherit.aes = FALSE,
-          aes(color = paste0(1.5, " mile walking boundary")),
-          fill = NA,
-          linewidth = 1) +
-  scale_color_manual(values = "blue", name = NULL) +
-  new_scale_color() +
-  geom_sf(data = bike_lts %>% filter(!is.na(student_use), student_use > 0),
-         inherit.aes = FALSE,
-         aes(color = lts,
-             linewidth = student_use)) +
-  scale_color_manual(values = bike_lts_scale$color, name = "Bike Level of Traffic Stress") +
-  scale_linewidth_continuous(range = c(0, 3)) +
-  annotation_raster(school_symbol,
-                    # Position adjustments here using plot_box$max/min/range
-                    ymin = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[2] - 0.001,
-                    ymax = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[2] + 0.001,
-                    xmin = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[1] - 0.0015,
-                    xmax = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[1] + 0.0015) +
-  geom_sf_label(data = WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE),
-                inherit.aes = FALSE,
-                mapping = aes(label = school_focus %>% pull(name)),
-                nudge_y = 0.0015,
-                label.size = 0.04,
-                size = 2)
-

-
ggsave(file = paste0("figures/",
-                     school_focus %>% pull(name),
-                     " Routes - Traffic Stress.pdf"),
-       title = paste0(school_focus %>% pull(name), " Walking Routes - Traffic Stress"),
-       device = pdf,
-       height = 8.5,
-       width = 11,
-       units = "in",
-       create.dir = TRUE)
-
-ggmap(basemap) +
-  labs(title = paste0("Student homes at ",
-                      school_focus %>% pull(name)),
-       x = NULL,
-       y = NULL,
-       color = NULL,
-       fill = "How many students live there") +
-  theme(axis.text=element_blank(),
-        axis.ticks=element_blank(),
-        plot.caption = element_text(color = "grey")) +
-  geom_hex(data = addresses %>% extract(geometry, into = c('Lat', 'Lon'), '\\((.*),(.*)\\)', conv = T),
-           aes(x = Lat,
-               y = Lon),
-           alpha = 0.7) +
-  scale_fill_distiller(palette = "YlOrRd", direction = "reverse") +
-  geom_sf(data = walk_boundary_poly,
-          inherit.aes = FALSE,
-          aes(color = paste0(1.5, " mile walking boundary")),
-          fill = NA,
-          linewidth = 1) +
-  scale_color_manual(values = "blue", name = NULL) +
-  new_scale_color() +
-  annotation_raster(school_symbol,
-                    # Position adjustments here using plot_box$max/min/range
-                    ymin = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[2] - 0.001,
-                    ymax = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[2] + 0.001,
-                    xmin = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[1] - 0.0015,
-                    xmax = as.double((WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE) %>% pull(geom))[[1]])[1] + 0.0015) +
-  geom_sf_label(data = WI_schools %>% filter(NCES_CODE %in% school_focus$NCES_CODE),
-                inherit.aes = FALSE,
-                mapping = aes(label = school_focus %>% pull(name)),
-                nudge_y = 0.0015,
-                label.size = 0.04,
-                size = 2)
-

-
ggsave(file = paste0("figures/",
-                     school_focus %>% pull(name),
-                     " Addresses.pdf"),
-       title = paste0(school_focus %>% pull(name), " Addresses"),
-       device = pdf,
-       height = 8.5,
-       width = 11,
-       units = "in",
-       create.dir = TRUE)
-
-
-

Appendix

-
date()
-
## [1] "Thu Oct 31 16:38:18 2024"
-
sessionInfo()
-
## R version 4.1.2 (2021-11-01)
-## Platform: x86_64-pc-linux-gnu (64-bit)
-## Running under: Pop!_OS 22.04 LTS
-## 
-## Matrix products: default
-## BLAS:   /usr/lib/x86_64-linux-gnu/blas/libblas.so.3.10.0
-## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0
-## 
-## locale:
-##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
-##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
-##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
-##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
-##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
-## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
-## 
-## attached base packages:
-## [1] stats     graphics  grDevices utils     datasets  methods   base     
-## 
-## other attached packages:
-##  [1] rsvg_2.6.1       ggnewscale_0.5.0 magick_2.8.5     smoothr_1.0.1   
-##  [5] osrm_4.2.0       sf_1.0-18        ggmap_4.0.0      lubridate_1.9.3 
-##  [9] forcats_1.0.0    stringr_1.5.1    dplyr_1.1.4      purrr_1.0.2     
-## [13] readr_2.1.5      tidyr_1.3.1      tibble_3.2.1     ggplot2_3.5.1   
-## [17] tidyverse_2.0.0 
-## 
-## loaded via a namespace (and not attached):
-##  [1] httr_1.4.7            sass_0.4.9            bit64_4.5.2          
-##  [4] vroom_1.6.5           jsonlite_1.8.9        bslib_0.8.0          
-##  [7] highr_0.11            yaml_2.3.10           lattice_0.20-45      
-## [10] pillar_1.9.0          glue_1.8.0            digest_0.6.37        
-## [13] RColorBrewer_1.1-3    colorspace_2.1-1      htmltools_0.5.8.1    
-## [16] plyr_1.8.9            pkgconfig_2.0.3       s2_1.1.7             
-## [19] scales_1.3.0          terra_1.7-83          jpeg_0.1-10          
-## [22] tzdb_0.4.0            timechange_0.3.0      proxy_0.4-27         
-## [25] generics_0.1.3        farver_2.1.2          googlePolylines_0.8.5
-## [28] cachem_1.1.0          withr_3.0.2           hexbin_1.28.4        
-## [31] cli_3.6.3             magrittr_2.0.3        crayon_1.5.3         
-## [34] evaluate_1.0.1        fansi_1.0.6           class_7.3-20         
-## [37] tools_4.1.2           hms_1.1.3             RgoogleMaps_1.5.1    
-## [40] mapiso_0.3.0          lifecycle_1.0.4       munsell_0.5.1        
-## [43] isoband_0.2.7         compiler_4.1.2        jquerylib_0.1.4      
-## [46] e1071_1.7-16          rlang_1.1.4           classInt_0.4-10      
-## [49] units_0.8-5           grid_4.1.2            rstudioapi_0.17.1    
-## [52] bitops_1.0-9          labeling_0.4.3        rmarkdown_2.28       
-## [55] wk_0.9.4              gtable_0.3.6          codetools_0.2-18     
-## [58] DBI_1.2.3             curl_5.2.3            RcppSimdJson_0.1.12  
-## [61] R6_2.5.1              knitr_1.48            fastmap_1.2.0        
-## [64] bit_4.5.0             utf8_1.2.4            KernSmooth_2.23-20   
-## [67] stringi_1.8.4         parallel_4.1.2        Rcpp_1.0.13          
-## [70] vctrs_0.6.5           png_0.1-8             tidyselect_1.2.1     
-## [73] xfun_0.48
-
- - - -
-
- -
- - - - - - - - - - - - - - - -