---
title: "Optimal New School Locations in 2024"
---
The purpose of this page is to suggest locations for a future school in the ACT that would have the largest impact on reducing walking times for students. One suggestion is calculated for primary and high school, but a resonable amount of decent options exist. This tool could be used by the department for future planning purposes.
The "Optimal New School Location" was found by randomly sampling 100 locations in the ACT and then calculating the average weighted walk time to a primary and high school's if this new schools was included.
```{r setup}
#| echo: false
#| message: false
#| warning: false
library(sf)
library(leaflet)
library(dplyr)
library(htmltools)
# Load optimal location data
optimal_primary <- st_read(paste0(here::here(),"/data/new_schools/optimal_primary_location_2024.gpkg"), quiet = T)
optimal_high <- st_read(paste0(here::here(),"/data/new_schools/optimal_high_location_2024.gpkg"), quiet = T)
# Load 2024 walk time data for comparison
walk_2024 <- st_read(here::here("data", "walk_analysis", "school_walk_times_2024.gpkg"), quiet = TRUE)
primary_2024 <- walk_2024 |> filter(school_type == "primary")
high_2024 <- walk_2024 |> filter(school_type == "high")
# Create KPI callout function
create_kpi_callout <- function(title, value, subtitle, color = "#2166AC") {
div(
style = paste0("background-color: ", color, "; color: white; padding: 30px;
border-radius: 12px; text-align: center; margin: 10px;"),
h3(title, style = "margin: 0; font-size: 1.4em;"),
h1(paste0(value, " mins"),
style = "margin: 10px 0; font-size: 3em; font-weight: bold;"),
p(subtitle,
style = "margin: 0; font-size: 1.1em; opacity: 0.9;")
)
}
# Create a focused map showing the proposed school location with SA2 background
create_school_location_map <- function(optimal_data, school_type, rank = 1)
{
# Get the optimal location
new_school <- optimal_data[rank,]
# Get the corresponding walk time data
walk_data <- if(school_type == "Primary") primary_2024 else high_2024
# Calculate color palette - using plasma reversed so shorter times are yellow/bright
pal <- colorNumeric("plasma", walk_data$mean_walk_time_min, na.color = "#cccccc", reverse = TRUE)
leaflet() |>
addProviderTiles(providers$CartoDB.Positron) |>
# Add SA2 polygons showing walk times (50% opacity)
addPolygons(
data = walk_data,
fillColor = ~pal(mean_walk_time_min),
fillOpacity = ~ifelse(population == 0, 0, 0.5), # 50% opacity, transparent if no population
color = "#444444",
weight = 1,
label = ~paste0(
sa2_name, "<br>",
"Walk Time: ", round(mean_walk_time_min, 1), " mins<br>",
"Population (5-14): ", population
) |> lapply(htmltools::HTML),
labelOptions = labelOptions(sticky = TRUE),
group = "SA2 Walk Times"
) |>
# Add the proposed new school marker on top
addMarkers(
data = new_school,
lng = ~longitude,
lat = ~latitude,
popup = ~paste0(
"<strong>Proposed ", school_type, " School (Rank ", rank, ")</strong><br>",
"Location: ", round(longitude, 4), ", ", round(latitude, 4), "<br>",
"Time Reduction: ", round(time_reduction_min, 2), " minutes<br>",
"Current Average: ", round(current_avg_walk_time_min, 1), " mins<br>",
"New Average: ", round(new_avg_walk_time_min, 1), " mins"
),
icon = makeIcon(
iconUrl = "https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png",
shadowUrl = "https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png",
iconWidth = 30, iconHeight = 49,
iconAnchorX = 15, iconAnchorY = 49,
shadowWidth = 51, shadowHeight = 51
),
group = "New School"
) |>
# Add legend for walk times
addLegend(
pal = pal,
values = walk_data$mean_walk_time_min,
title = paste("Walk Time (mins)<br>", school_type, "Schools"),
position = "bottomright"
) |>
# Add layer control
addLayersControl(
overlayGroups = c("SA2 Walk Times", "New School"),
options = layersControlOptions(collapsed = FALSE)
) |>
setView(
lng = new_school$longitude,
lat = new_school$latitude,
zoom = 11 # Zoomed out slightly to show more context
)
}
```
# New Primary School Location
One of the best new primary school locations was estimated to be in North West Taylor. Worth noting that the pin is indicative of the area, not the exact location to place the school. Realistically, primary schools appear quite nicely distributed which results in only a small differences from this potential new school.
::: {.columns}
::: {.column width="60%"}
```{r}
#| echo: false
create_school_location_map(optimal_primary, "Primary", rank = 2)
```
:::
::: {.column width="40%"}
```{r}
#| echo: false
# Get values for rank 2 location
current_avg <- round(optimal_primary$current_avg_walk_time_min[2], 1)
projected_improvement <- round(optimal_primary$time_reduction_min[2], 2)
new_avg <- round(optimal_primary$new_avg_walk_time_min[2], 1)
# Current walk time KPI
create_kpi_callout(
title = "Current Average (2024)",
value = current_avg,
subtitle = "Population-weighted walk time to nearest primary school",
color = "#dc2626" # Red for current state
)
```
```{r}
#| echo: false
# Improved walk time KPI
create_kpi_callout(
title = "With New School",
value = new_avg,
subtitle = paste0("Improvement: -", projected_improvement, " minutes (",
round((projected_improvement/current_avg)*100, 1), "% reduction)"),
color = "#16a34a" # Green for improvement
)
```
:::
:::
# New High School Location
The best new high school location was estimated to be at the confluence of Wright, Coombs, Duffy and Holder. This makes a lot of sense, as this newly developed area in Canberra has attracted many young families. This is likely a more interesting finding that the primary school location, as high schools are fewer and more sparsely distributed.
::: {.columns}
::: {.column width="60%"}
```{r}
#| echo: false
create_school_location_map(optimal_high, "High")
```
:::
::: {.column width="40%"}
```{r}
#| echo: false
# Get values for rank 1 location
current_avg <- round(optimal_high$current_avg_walk_time_min[1], 1)
projected_improvement <- round(optimal_high$time_reduction_min[1], 2)
new_avg <- round(optimal_high$new_avg_walk_time_min[1], 1)
# Current walk time KPI
create_kpi_callout(
title = "Current Average (2024)",
value = current_avg,
subtitle = "Population-weighted walk time to nearest high school",
color = "#dc2626" # Red for current state
)
```
```{r}
#| echo: false
# Improved walk time KPI
create_kpi_callout(
title = "With New School",
value = new_avg,
subtitle = paste0("Improvement: -", projected_improvement, " minutes (",
round((projected_improvement/current_avg)*100, 1), "% reduction)"),
color = "#16a34a" # Green for improvement
)
```
:::
:::