Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save szechno/a46ff8b60252eeb5aaf4bc95810f4f4e to your computer and use it in GitHub Desktop.

Select an option

Save szechno/a46ff8b60252eeb5aaf4bc95810f4f4e to your computer and use it in GitHub Desktop.
library(shiny)
library(shinyWidgets)
library(bslib)
library(mapgl)
library(sf)
library(stringr)
library(dplyr)
library(DBI)
library(RSQLite)
library(callr)
# library(bsicons) ## https://icons.getbootstrap.com
# !! need to include attribution: <a href="https://www.flaticon.com/free-icons/adress" title="adress icons">Adress icons created by Boris farias - Flaticon</a>
# West_Sussex_TSS_2025
# https://mackaszechno.shinyapps.io/West_Sussex_TSS_maplibre_2025/
# West_Sussex_TSS_maplibre_2025
# variables ----
## geodata ----
geodata <- "./shapefile/west sussex_tss_review_20250714a_esuid.gpkg"
# IMPORTANT 2 RECORDS SET TO tss I AND C FOR TESTING... CHANGE BACK AS REQUIRED
map_start <- c(-0.404549247616387, 50.9365654134795)
initial_zoom <- 10
dft_color <- c("coral", "#DC143C", "darkred")
cj_color <- c("#bc9958")
bus_color <- c("#658e3b")
train_color <- c("#6b717a", "#707f94")
school_color <- c("#e2e218")
emergency_color <- c("#5959f9")
medical_color <- c("#78c5d3")
retail_color <- c("#825e76")
commerce_color <- c("#826a5e")
leisure_color <- c("#bed378")
grid_color <- c("#75b7a0")
border_color <- c("#758cb7")
NH_color <- c("pink")
esusline_color <- c("#c997b8")
lookup_class <- tibble(
column = rep("CLASS", 7),
classification = c("A", "B", "C", "D", "P", "Q", ""),
colours = c("#22A884", "#2A788E", "#414487", "#440154", "#7AD151", "#f06060", "#ff02ff"),
lwd = c( 5, 4, 3, 2, 1, 1, 1)
)
lookup_tss <- tibble(
column = rep("TSS", 5),
classification = c("C", "D", "H", "I", ""),
colours = c("#1f78b4", "#33a02c", "#e31a1c", "#ff7f00", "#f0f0f0"),
lwd = rep(3, 5)
)
# https://mastering-shiny.org/action-transfer.html#downloading-reports
# to work on shinyapps.io
## report_path ----
report_path <- tempfile(fileext = ".Rmd")
file.copy("./rmd/test__wscc_tss_review_v6a1_tss.Rmd",
report_path,
overwrite = TRUE)
## set colour squares for layer sidecard ----
dft_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
dft_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
dft_color[2],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
dft_color[3],";\"></div>"))
cj_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
cj_color[1],";\"></div>"))
transport_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
bus_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
train_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
train_color[2],";\"></div>"))
school_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
school_color[1],";\"></div>"))
emergency_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
emergency_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
medical_color[1],";\"></div>"))
landuse_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
retail_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
commerce_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
leisure_color[1],";\"></div>"))
boundary_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
grid_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
border_color[1],";\"></div>",
"<div style=\"width: 10px; height: 10px; background-color: ",
NH_color[1],";\"></div>"))
esusline_icons <- span(HTML("<div style=\"width: 10px; height: 10px; background-color: ",
esusline_color[1],";\"></div>"))
#  preload functions ----
load_data <- function(layer, bb = NULL, query = NA){
# https://r-spatial.github.io/sf/reference/st_read.html
if(is.null(bb)){
st_read(geodata,
layer = layer,
quiet = TRUE) |> st_transform(crs = 4326)
} else {
bb <- st_bbox(c(xmin = bb$xmin,
xmax = bb$xmax,
ymax = bb$ymax,
ymin = bb$ymin),
crs = st_crs(4326)) |>
st_transform(crs = 27700)
st_read(geodata,
layer = layer,
wkt_filter = st_as_text(
# st_as_sfc(bb |> st_transform(crs = 27700))
st_as_sfc(bb)
),
query = query,
quiet = TRUE) |> st_transform(crs = 4326)
}
}
# https://mastering-shiny.org/action-transfer.html#downloading-reports
get_params <- function(type = "TSS",
year = "2025",
filename = "unknown.html"){
has_old_tss <- FALSE
old_tss <- NULL
# version <- type # version6 single-layer version" type = TSS or LR?
page_description <- paste0(year, " ", type, " Review") #"2025 TSS Review"
page_council <- "West Sussex County Council"
page_council_image <- "https://github.com/szechno/wscc_shinyapp/blob/main/wscc.png?raw=true"
page_image_styling <- "width: 100px; height: 100px; float: left;"
# page_image_styling <- "width: 475px; height: 96.3px; float: left;"
# data_path <- paste0(home, stringr::str_sub(geodata, start = 3L, end = -1L))
checklist <- "TSS Checklist"
border <- "TSS Boundary"
has_old_tss <- FALSE
old_tss <- ""
report_type <- type
# input_file <- "https://github.com/szechno/wscc_shinyapp/blob/main/test__wscc_tss_review_v6a_tss.Rmd?raw=true"
# output_file <- paste0(home, type, "_review_", version, "_",
# Sys.Date(), "_",
# str_replace_all(format(Sys.time(), "%X"), ":", ""),
# ".html") #Sys.time
params_list <- list(version = type,
page_description = page_description,
page_council = page_council,
page_council_image = page_council_image,
page_image_styling = page_image_styling,
checklist = load_data(layer = checklist) |> filter(TSS %in% c("D", "I", "C", "H")), # remove when sufficient space or perform calcs shiny side
border = load_data(layer = border)
)
if(type == "TSS"){
params_list <- c(params_list,
list(
has_old_tss = has_old_tss,
old_tss = old_tss))
}
return(params_list)
}
render_report <- function(input, output, params) {
rmarkdown::render(input,
output_file = output,
params = params,
envir = new.env(parent = globalenv())
)
}
add_polygons <- function(m,
data,
group,
...){
m |> add_fill_layer(
source = data,
id = group,
...
)
}
add_lines <- function(m,
data,
group,
...){
m |> add_line_layer(
source = data,
id = group,
...
)
}
add_points <- function(m,
data,
group,
...){
m |> add_circle_layer(
source = data,
id = group,
...
)
}
convert_true_false <- function(x){
if(x){
x <- 1
} else {
x <- 0
}
}
## reuseable control function ----
# https://mastering-shiny.org/scaling-functions.html
# ... maybe need a list where multiple checkboxes???
# create_accordion_panel <- function(title, chkbox_id, layer_name, val = TRUE){
# accordion_panel(
# title,
# checkboxInput(chkbox_id, layer_name, value = val),
# )
# }
# ui -----
ui <-
page_sidebar(
tags$head(
tags$link(
rel="shortcut icon",
href="https://github.com/szechno/wscc_shinyapp/blob/main/favicon.ico?raw=true"
)
),
theme = bs_theme(bootswatch = "simplex",
"bslib_spacer" = "0.1rem",
# fg = "rgb(158, 79, 79)",
# fg = "#555555",
# bg = "white",
primary = "#555566",
base_font = font_google("Inter"),
code_font = font_google("JetBrains Mono")),
# theme = "main1_v6a.css",
title = "West Sussex TSS Shiny prototype 2025",
window_title = "West Sussex TSS 2025",
##  main sidebar ----
sidebar = sidebar(
position = "left",
title = "Layers and options",
# bg = "white",
open = TRUE,
# gap = 0,
# padding = 0, # use elsewhere in menu
accordion(
open = FALSE,
accordion_panel(
title = "map options",
radioGroupButtons(
"toggle_roads", "Toggle roads", choices = c("All roads", "TSS potential", "TSS actual"),
size = "sm"
),
# "colours"
sliderInput("map_refresh", "Map refresh rate (ms)", min = 100, max = 3000,
step = 50, value = 100),
### select basemaps ----
selectInput("basemap",
"Change basemap",
choices = c("voyager", "positron", "dark-matter",
"voyager-no-labels", "positron-no-labels",
"dark-matter-no-labels",
"liberty", "osm-bright", "fiord"),
selected = "voyager")
),
accordion_panel(
title = "layers",
radioGroupButtons(
"toggle_layers", "Toggle all layers", c("Custom", "On", "Off"),
size = "sm"
),
p(HTML("If road network is not selectable, toggle TSS Checklist OFF and ON."),
style = "font-size:0.7em;"),
## layers accordion ----
accordion_panel(
"TSS Checklist",
checkboxInput("chkbox_TSSChecklist", "TSS Checklist", value = TRUE)
),
accordion_panel(
"DfT Counts",
icon = dft_icons,
checkboxInput("chkbox_DfTCounts", "DfT Counts", value = TRUE)
),
accordion_panel(
"Critical junctions",
icon = cj_icons,
checkboxInput("chkbox_GEOCJ_TrafficSignals", "GEO CJ Traffic Signals", value = FALSE),
checkboxInput("chkbox_GEOCJ_Roundabouts", "GEO CJ Roundabouts", value = FALSE)
),
accordion_panel(
"Transport",
icon = transport_icons,
checkboxInput("chkbox_OpenBusBusStops", "OpenBus Bus Stops", value = FALSE),
checkboxInput("chkbox_OpenBusroutes", "OpenBus routes", value = FALSE),
checkboxInput("chkbox_GEOTransport_Bus_Stations", "GEO Transport Bus Stations", value = FALSE),
checkboxInput("chkbox_GEOTransport_Train_Stations", "GEO Transport Train Stations", value = FALSE),
checkboxInput("chkbox_ORRTransport_Train_Station_Passengers", "ORR Transport Train Station Passengers", value = FALSE)
),
accordion_panel(
"Education",
icon = school_icons,
checkboxInput("chkbox_GEOEducation", "GEO Education", value = TRUE),
checkboxInput("chkbox_MHCLGEducation_Capacity", "MHCLG Education_Capacity", value = FALSE)
),
accordion_panel(
"Emergency",
icon = emergency_icons,
checkboxInput("chkbox_GEOMedical", "GEO Medical", value = FALSE),
checkboxInput("chkbox_GEOBlueLights", "GEO Blue Lights", value = FALSE),
),
accordion_panel(
"Land use",
icon = landuse_icons,
checkboxInput("chkbox_GEORetail", "GEO Retail", value = FALSE),
checkboxInput("chkbox_GEOCommercialIndustrial", "GEO Commercial-Industrial", value = TRUE),
checkboxInput("chkbox_GEOLeisure", "GEO Leisure", value = FALSE)
),
accordion_panel(
"Boundary",
icon = boundary_icons,
checkboxInput("chkbox_InspectionGrid", "Inspection Grid", value = FALSE),
checkboxInput("chkbox_TSSBoundary", "TSS Boundary", value = TRUE),
checkboxInput("chkbox_NationalHighwaysboundary", "National Highways boundary", value = FALSE)
)
),
## downloads accordion ----
accordion_panel(
title = "downloads",
"Download TSS Checklist",
actionButton("download_geopackage", "GPKG", disabled = TRUE),
actionButton("download_shapefile", "SHP", disabled = TRUE),
actionButton("download_csv", "CSV", disabled = TRUE),
"Create ASD file",
actionButton("geoplace_csv", "ASD update", disabled = TRUE),
"Create TSS polygon",
downloadButton("geoplace_poly", "Geoplace")
),
## reports accordion ----
accordion_panel(
title = "reports",
"Create TSS report",
downloadButton("report_tss", "TSS"),
"Create LR report",
downloadButton("report_lr", "LR")
)
)
),
#  map card ----
card(
full_screen = TRUE,
card_header("The map"),
layout_sidebar(
fillable = TRUE, # need to include this if dealing with plotly or leaflet
#  map sidebar ----
sidebar = sidebar(
title = "Edit USRN/ESUID",
id = "edit_usrn",
open = FALSE,
p(HTML("Choose between:<br />1. editing this ESUID [ESUID] <b>or</b> <br />2. all ESUIDs ",
"associated with this USRN with the same class [USRN class] <b>or</b> <br />3. all ESUIDs ",
"associated with this USRN regardless of class [USRN all]."),
style = "font-size:0.6em;"),
radioGroupButtons(
"toggle_usrn_esuid", "Toggle ESUID/USRN", choices = c("ESUID", "USRN class", "USRN all"),
size = "sm"
),
"USRN",
verbatimTextOutput("usrn_edit", placeholder = TRUE),
"ESUIDs",
verbatimTextOutput("esuid_edit", placeholder = TRUE),
"Street",
verbatimTextOutput("street_edit", placeholder = TRUE),
"CLASS",
verbatimTextOutput("class_edit", placeholder = TRUE),
selectInput("tss_edit", "TSS", c("D", "I", "C", "H", "")),
p(HTML("Use backspace to remove from TSS."),
style = "font-size:0.7em;"),
"LR", checkboxInput("lr_edit", "", FALSE),
"Traffic_flow", checkboxInput("traffic_flow_edit", "", FALSE),
"HGVs", checkboxInput("hgvs_edit", "", FALSE),
"Buses", checkboxInput("buses_edit", "", FALSE),
"Peds", checkboxInput("peds_edit", "", FALSE),
"Carriageway", checkboxInput("carriageway_edit", "", FALSE),
"CJ", checkboxInput("cj_edit", "", FALSE),
"Medical", checkboxInput("medical_edit", "", FALSE),
"Educational", checkboxInput("educational_edit", "", FALSE),
"Retail", checkboxInput("retail_edit", "", FALSE),
"Commercial", checkboxInput("commercial_edit", "", FALSE),
"Recreational", checkboxInput("recreational_edit", "", FALSE),
"Transport", checkboxInput("transport_edit", "", FALSE),
"Emergency", checkboxInput("emergency_edit", "", FALSE),
"AM_peak", checkboxInput("am_peak_edit", "", FALSE),
"PM_peak", checkboxInput("pm_peak_edit", "", FALSE),
"Inter_peak", checkboxInput("inter_peak_edit", "", FALSE),
"Off_peak", checkboxInput("off_peak_edit", "", FALSE),
"Inc_sats", checkboxInput("inc_sats_edit", "", FALSE),
"Sat_rec", checkboxInput("sat_rec_edit", "", FALSE),
"All_year", checkboxInput("all_year_edit", "", FALSE),
"Term_time", checkboxInput("term_time_edit", "", FALSE),
"Key_shopping", checkboxInput("key_shopping_edit", "", FALSE),
"Notes",
verbatimTextOutput("notes_edit", placeholder = TRUE),
textInput("notes_edit_plus", "Additional Notes"),
actionButton("add_notes", "Add Note", disabled = FALSE),
"Length (m)",
verbatimTextOutput("length_edit", placeholder = TRUE),
# "Save changes to record",
# actionButton("save_changes", "Save"),
# "Discard changes to record",
# actionButton("discard_changes", "Discard"),
"Save changes to file",
actionButton("commit_changes", "Commit", disabled = FALSE)
),
maplibreOutput("map", height = "800px")
)
),
#  info card ----
card(verbatimTextOutput("info")),
#  datatable card ----
card(
card_header("The data table")
)
)
# server ----
server <- function(input, output, session) {
# bs_themer()
#  selected/clicked esuid we call `v` ----
## values set observeEvent(input$map_shape_click...)
## ensuring that we only store the clicked ESUID in `v`
v <- reactiveValues()
map_refresh_rate <- reactive(input$map_refresh)
#  server-side functions ----
create_reactive_data <- function(checkbox, layer_name, max_zoom = initial_zoom){
if(checkbox){
print(paste("checkbox is", checkbox))
if(is.null(bboxed())){
return(NULL)
} else if(input$map_zoom <= max_zoom){
return(NULL)
} else {
road <- load_data(layer_name, bb = bboxed())
if(layer_name == "DfT Counts"){
road <- road |> mutate(hourly = trunc(all_motor_vehicles / 24))
} else {
road
}
}
}
}
create_observation <- function(checkbox,
layer_name,
reactive_data,
map = "map",
...){
m <- maplibre_proxy(map) |> clear_layer(layer_name)
if(checkbox & !is.null(reactive_data) && nrow(reactive_data) > 0){
m <- maplibre_proxy(map) #|> showGroup(layer_name)
# determine type of layer to add
# 0 for points,
# 1 for lines,
# 2 for surfaces, and,
# if NA_if_empty is TRUE, NA for empty geometries
if(st_dimension(reactive_data[1, ]) == 0){
add_points(m, data = reactive_data, group = layer_name, ...)
} else if(st_dimension(reactive_data[1, ]) == 1){
add_lines(m, data = reactive_data, group = layer_name, ...)
} else if(st_dimension(reactive_data[1, ]) == 2){
add_polygons(m, data = reactive_data, group = layer_name, ...)
}
if(layer_name != "tss_data"){
move_layer(m, layer_id = layer_name, before_id = "tss_data")
} else {
m
}
}
}
#  reactive data ----
### reactive mousemove ----
hov_reac <- reactive({
input$map_bbox
})
hov_reac_d <- debounce(hov_reac, map_refresh_rate)
### reactive bbox ----
bboxed <- reactiveVal()
# see observeEvent(hov_reac_d())
### commercial_data ----
commercial_data <- reactive({
create_reactive_data(input$chkbox_GEOCommercialIndustrial, "GEO Commercial-Industrial")
})
### dftcounts_data ----
dftcounts_data <- reactive({
d <- create_reactive_data(input$chkbox_DfTCounts, "DfT Counts")
})
### trafficsignals_data ----
trafficsignals_data <- reactive({
create_reactive_data(input$chkbox_GEOCJ_TrafficSignals, "GEO CJ_Traffic Signals")
})
### roundabouts_data ----
roundabouts_data <- reactive({
create_reactive_data(input$chkbox_GEOCJ_Roundabouts, "GEO CJ_Roundabouts")
})
### openbusstops_data ----
openbusstops_data <- reactive({
create_reactive_data(input$chkbox_OpenBusBusStops, "OpenBus Bus Stops")
})
### openbusroutes_data ----
openbusroutes_data <- reactive({
create_reactive_data(input$chkbox_OpenBusroutes, "OpenBus routes")
})
### busstations_data ----
busstations_data <- reactive({
create_reactive_data(input$chkbox_GEOTransport_Bus_Stations, "GEO Transport_Bus_Stations")
})
### trainstations_data ----
trainstations_data <- reactive({
create_reactive_data(input$chkbox_GEOTransport_Train_Stations, "GEO Transport_Train_Stations")
})
### trainpassengers_data ----
trainpassengers_data <- reactive({
create_reactive_data(input$chkbox_ORRTransport_Train_Station_Passengers, "ORR Transport_Train_Station_Passengers")
})
### education_data ----
education_data <- reactive({
create_reactive_data(input$chkbox_GEOEducation, "GEO Education")
})
### schoolcapacity_data ----
schoolcapacity_data <- reactive({
create_reactive_data(input$chkbox_MHCLGEducation_Capacity, "MHCLG Education_Capacity")
})
### medical_data ----
medical_data <- reactive({
create_reactive_data(input$chkbox_GEOMedical, "GEO Medical")
})
### bluelights_data ----
bluelights_data <- reactive({
create_reactive_data(input$chkbox_GEOBlueLights, "GEO Blue Lights")
})
### retail_data ----
retail_data <- reactive({
create_reactive_data(input$chkbox_GEORetail, "GEO Retail")
})
### commercial_data ----
commercial_data <- reactive({
create_reactive_data(input$chkbox_GEOCommercialIndustrial, "GEO Commercial-Industrial")
})
### leisure_data ----
leisure_data <- reactive({
create_reactive_data(input$chkbox_GEOLeisure, "GEO Leisure")
})
### inspectiongrid_data ----
inspectiongrid_data <- reactive({
create_reactive_data(input$chkbox_InspectionGrid, "Inspection Grid")
})
### tssboundary_data ----
tssboundary_data <- reactive({
create_reactive_data(input$chkbox_TSSBoundary, "TSS Boundary")
})
### nationalhighways_data ----
nationalhighways_data <- reactive({
create_reactive_data(input$chkbox_NationalHighwaysboundary, "National Highways boundary")
})
### tss_data ----
tss_data <- reactive({
if(input$chkbox_TSSChecklist){
if(is.null(bboxed())){
return(NULL)
} else if(input$toggle_roads == "All roads"){
if(input$map_zoom >= 14){
road <- load_data(
"TSS Checklist",
bb = bboxed()
)
} else if(input$map_zoom >= 13){
road <- load_data(
"TSS Checklist",
bb = bboxed(),
query = sprintf(
"SELECT * FROM \"TSS Checklist\" WHERE CLASS IN ('A', 'B', 'C', 'D')"
)
)
} else if(input$map_zoom >= 12){
road <- load_data(
"TSS Checklist",
bb = bboxed(),
query = sprintf(
"SELECT * FROM \"TSS Checklist\" WHERE CLASS IN ('A', 'B', 'C')"
)
)
} else if(input$map_zoom >= 11){
road <- load_data(
"TSS Checklist",
bb = bboxed(),
query = sprintf(
"SELECT * FROM \"TSS Checklist\" WHERE CLASS IN ('A', 'B')"
)
)
} else if(input$map_zoom < 11){
road <- load_data(
"TSS Checklist",
bb = bboxed(),
query = sprintf(
"SELECT * FROM \"TSS Checklist\" WHERE CLASS LIKE 'A'"
)
)
}
} else if(input$toggle_roads == "TSS potential"){
road <- load_data(
"TSS Checklist",
bb = bboxed(),
query = sprintf(
"SELECT * FROM \"TSS Checklist\" WHERE TSS IN ('D', 'I', 'C', 'H')"
)
)
} else if(input$toggle_roads == "TSS actual"){
road <- load_data(
"TSS Checklist",
bb = bboxed(),
query = sprintf(
"SELECT * FROM \"TSS Checklist\" WHERE TSS IN ('D', 'I', 'C')"
)
)
}
# # testing
# road <- load_data(
# "TSS Checklist",
# bb = bboxed())
}
})
#  Initialize map ----
output$map <- renderMaplibre({
maplibre(
# style = carto_style("positron")
style = carto_style("voyager")
# style = carto_style(input$basemap)
) |>
fly_to(center = map_start, zoom = initial_zoom)
})
#  observe reactive data ----
### observe toggle all layers on ----
observe({
if(input$toggle_layers == "Custom"){
updateCheckboxInput(session, "chkbox_TSSChecklist", value = TRUE)
updateCheckboxInput(session, "chkbox_DfTCounts", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOCJ_TrafficSignals", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOCJ_Roundabouts", value = FALSE)
updateCheckboxInput(session, "chkbox_OpenBusBusStops", value = FALSE)
updateCheckboxInput(session, "chkbox_OpenBusroutes", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOTransport_Bus_Stations", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOTransport_Train_Stations", value = FALSE)
updateCheckboxInput(session, "chkbox_ORRTransport_Train_Station_Passengers", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOEducation", value = TRUE)
updateCheckboxInput(session, "chkbox_MHCLGEducation_Capacity", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOMedical", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOBlueLights", value = FALSE)
updateCheckboxInput(session, "chkbox_GEORetail", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOCommercialIndustrial", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOLeisure", value = FALSE)
updateCheckboxInput(session, "chkbox_InspectionGrid", value = FALSE)
updateCheckboxInput(session, "chkbox_TSSBoundary", value = FALSE)
updateCheckboxInput(session, "chkbox_NationalHighwaysboundary", value = FALSE)
} else if(input$toggle_layers == "On"){
# updateCheckboxInput(session, "chkbox_TSSChecklist", value = TRUE)
updateCheckboxInput(session, "chkbox_TSSChecklist", value = TRUE)
updateCheckboxInput(session, "chkbox_DfTCounts", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOCJ_TrafficSignals", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOCJ_Roundabouts", value = TRUE)
updateCheckboxInput(session, "chkbox_OpenBusBusStops", value = TRUE)
updateCheckboxInput(session, "chkbox_OpenBusroutes", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOTransport_Bus_Stations", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOTransport_Train_Stations", value = TRUE)
updateCheckboxInput(session, "chkbox_ORRTransport_Train_Station_Passengers", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOEducation", value = TRUE)
updateCheckboxInput(session, "chkbox_MHCLGEducation_Capacity", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOMedical", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOBlueLights", value = TRUE)
updateCheckboxInput(session, "chkbox_GEORetail", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOCommercialIndustrial", value = TRUE)
updateCheckboxInput(session, "chkbox_GEOLeisure", value = TRUE)
updateCheckboxInput(session, "chkbox_InspectionGrid", value = TRUE)
updateCheckboxInput(session, "chkbox_TSSBoundary", value = TRUE)
updateCheckboxInput(session, "chkbox_NationalHighwaysboundary", value = TRUE)
} else if(input$toggle_layers == "Off"){
# updateCheckboxInput(session, "chkbox_TSSChecklist", value = FALSE)
updateCheckboxInput(session, "chkbox_TSSChecklist", value = FALSE)
updateCheckboxInput(session, "chkbox_DfTCounts", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOCJ_TrafficSignals", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOCJ_Roundabouts", value = FALSE)
updateCheckboxInput(session, "chkbox_OpenBusBusStops", value = FALSE)
updateCheckboxInput(session, "chkbox_OpenBusroutes", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOTransport_Bus_Stations", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOTransport_Train_Stations", value = FALSE)
updateCheckboxInput(session, "chkbox_ORRTransport_Train_Station_Passengers", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOEducation", value = FALSE)
updateCheckboxInput(session, "chkbox_MHCLGEducation_Capacity", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOMedical", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOBlueLights", value = FALSE)
updateCheckboxInput(session, "chkbox_GEORetail", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOCommercialIndustrial", value = FALSE)
updateCheckboxInput(session, "chkbox_GEOLeisure", value = FALSE)
updateCheckboxInput(session, "chkbox_InspectionGrid", value = FALSE)
updateCheckboxInput(session, "chkbox_TSSBoundary", value = FALSE)
updateCheckboxInput(session, "chkbox_NationalHighwaysboundary", value = FALSE)
}
})
### observe dftcounts_data ----
observe({
create_observation(checkbox = input$chkbox_DfTCounts,
layer_name = "dftcounts_data",
reactive_data = dftcounts_data(),
# circle_color = interpolate(
# column = "all_motor_vehicles",
# type = "linear",
# values = c(0, 500, 1000, 5000, 20000, 50000, 100000),
# stops = c("#22A884", "#2A788E", "#414487", "#440154", "#7AD151", "#f06060", "#FDE725")
# ),
# circle_color = dft_color,
circle_color = interpolate(
column = "hourly",
values = c(0, 500, 1000),
stops = c(dft_color[[1]], dft_color[[2]], dft_color[[3]])
),
circle_radius = interpolate(
column = "all_motor_vehicles",
type = "linear",
values = c(0, 1000, 5000, 15000, 30000, 50000, 70000, 100000),
stops = c(1, 2, 4, 7, 9, 10, 12, 14)
),
tooltip = concat("Annual Daily Traffic Flow",
"<br /><big><b>",
number_format("all_motor_vehicles"),
"</b></big><br />(",
get_column("hourly"),
" vehicles ph)")
)
})
#
### observe trafficsignals_data ----
observe({
create_observation(checkbox = input$chkbox_GEOCJ_TrafficSignals,
layer_name = "trafficsignals_data",
reactive_data = trafficsignals_data(),
circle_color = cj_color[1],
circle_stroke_color = "black",
circle_stroke_width = 1,
circle_opacity = 1,
tooltip = concat("Traffic signals ",
"<br />",
get_column("highway"),
"<br />",
get_column("traffic_signals")
)
)
})
### observe roundabouts_data ----
observe({
create_observation(checkbox = input$chkbox_GEOCJ_Roundabouts,
layer_name = "roundabouts_data",
reactive_data = roundabouts_data(),
tooltip = concat("Roundabout ",
"<br />",
get_column("name"),
"<br />",
get_column("junction")),
line_color = cj_color[1],
line_width = 2
)
})
### observe openbusstops_data ----
# observe({
# create_observation(checkbox = input$chkbox_OpenBusBusStops,
# layer_name = "openbusstops_data",
# reactive_data = openbusstops_data(),
# tooltip = concat("Bus stop (8+ buses ph)",
# "<br />",
# get_column("stop_name")),
# circle_color = bus_color[1],
# circle_radius = 6,
# circle_opacity = 0.8
# )
# })
observe({
m <- maplibre_proxy("map") |> clear_layer("openbusstops_data")
if(input$chkbox_OpenBusBusStops & !is.null(openbusstops_data()) &&
nrow(openbusstops_data()) > 0){
# m |> add_image("busstop", url = "https://github.com/szechno/wscc_shinyapp/blob/main/busstop.png?raw=true")|>
# https://www.base64-image.de/ convert png to base64....
m |> add_image("busstop", url = "data:image/png;base64,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") |>
add_symbol_layer(
id = "openbusstops_data",
source = openbusstops_data(),
icon_image = "busstop",
icon_allow_overlap = TRUE,
icon_size = 0.1,
icon_opacity = 1,
# icon_color = bus_color,
tooltip = concat("Bus stop (8+ buses ph)",
"<br />",
get_column("stop_name"),
"<br />",
get_column("Total_ph"), " bus ph")
)
}
})
### observe openbusroutes_data ----
observe({
create_observation(checkbox = input$chkbox_OpenBusroutes,
layer_name = "openbusroutes_data",
reactive_data = openbusroutes_data(),
tooltip = concat("Bus route ",
"<br />",
get_column("shape_id")),
line_color = bus_color[1],
line_width = 3,
line_dasharray = c(5, 5),
)
})
### observe busstations_data ----
observe({
create_observation(checkbox = input$chkbox_GEOTransport_Bus_Stations,
layer_name = "busstations_data",
reactive_data = busstations_data(),
tooltip = concat("Bus station ",
get_column("name"),
"<br />",
get_column("amenity")),
fill_color = bus_color[1],
fill_opacity = 0.8
)
})
### observe trainstations_data ----
observe({
create_observation(checkbox = input$chkbox_GEOTransport_Train_Stations,
layer_name = "trainstations_data",
reactive_data = trainstations_data(),
tooltip = concat("Train station",
"<br />",
get_column("name")),
fill_color = train_color[[2]],
fill_outline_color = "black"
)
})
### observe trainpassengers_data ----
observe({
create_observation(checkbox = input$chkbox_ORRTransport_Train_Station_Passengers,
layer_name = "trainpassengers_data",
reactive_data = trainpassengers_data(),
tooltip = concat("Train Station annual passengers",
"<br />",
number_format("Annual_passengers")
),
circle_color = train_color[[1]],
circle_stroke_color = "white",
circle_stroke_width = 1,
circle_radius = interpolate(
column = "Annual_passengers",
type = "linear",
values = c(0, 5000, 50000, 100000, 300000, 500000, 1000000, 2000000),
stops = c(1, 2, 4, 7, 9, 10, 12, 14)
),
# circle_radius = 8
)
})
### observe education_data ----
observe({
create_observation(checkbox = input$chkbox_GEOEducation,
layer_name = "education_data",
reactive_data = education_data(),
fill_color = school_color[1],
fill_opacity = 0.5,
fill_outline_color = "purple",
# stroke = FALSE,
tooltip = concat("Education",
"<br />",
get_column("name"),
"<br />",
get_column("amenity")),
# highlightOptions = highlightOptions(
# fill_opacity = 0.7,
# fill_color = "#C4B454"
# )
)
})
### observe schoolcapacity_data ----
observe({
create_observation(checkbox = input$chkbox_MHCLGEducation_Capacity,
layer_name = "schoolcapacity_data",
reactive_data = schoolcapacity_data(),
# # tooltip = ~paste(name, school.capacity),
# radius = ~school.capacity/50,
# stroke = FALSE,
# color = "grey",
# fill_opacity = 0.8,
tooltip = concat(get_column("name"),
"<br />",
get_column("school.capacity")
),
circle_color = school_color[1],
circle_stroke_color = "white",
circle_stroke_width = 2,
circle_radius = interpolate(
column = "school.capacity",
type = "linear",
values = c(0, 50, 500, 1000, 1500, 2000, 2500, 5000),
stops = c(1, 2, 4, 7, 9, 10, 12, 14)
),
)
})
### observe medical_data ----
observe({
create_observation(checkbox = input$chkbox_GEOMedical,
layer_name = "medical_data",
reactive_data = medical_data(),
fill_color = medical_color[1],
fill_opacity = 0.5,
fill_outline_color = "navy",
# stroke = FALSE,
tooltip = concat("Medical",
"<br />",
get_column("name"),
"<br />",
get_column("amenity"),
"<br />",
"Emergency",
get_column("emergency"))
)
})
### observe bluelights_data ----
observe({
create_observation(checkbox = input$chkbox_GEOBlueLights,
layer_name = "bluelights_data",
reactive_data = bluelights_data(),
fill_color = emergency_color[1],
fill_opacity = 0.5,
fill_outline_color = "navy",
# stroke = FALSE,
tooltip = concat("Blue lights",
"<br />",
get_column("name"),
"<br />",
get_column("amenity"),
"<br />",
get_column("emergency"))
)
})
### observe retail_data ----
observe({
create_observation(checkbox = input$chkbox_GEORetail,
layer_name = "retail_data",
reactive_data = retail_data(),
fill_color = retail_color[1],
fill_opacity = 0.5,
fill_outline_color = "navy",
# stroke = FALSE,
tooltip = concat("Retail",
"<br />",
get_column("name"),
"<br />",
get_column("amenity"),
"<br />",
get_column("landuse"))
)
})
### observe commercial_data ----
observe({
create_observation(checkbox = input$chkbox_GEOCommercialIndustrial,
layer_name = "commercial_data",
reactive_data = commercial_data(),
# fill_color = "orange",
# fill_opacity = 0.5,
# stroke = FALSE,
# tooltip = ~name,
# highlightOptions = highlightOptions(
# fill_opacity = 0.7,
# fill_color = "#FF5F1F"
fill_color = commerce_color[1],
fill_opacity = 0.5,
fill_outline_color = "navy",
tooltip = concat("Commercial-Industrial",
"<br />",
get_column("name"),
"<br />",
get_column("amenity"))
)
})
### observe leisure_data ----
observe({
create_observation(checkbox = input$chkbox_GEOLeisure,
layer_name = "leisure_data",
reactive_data = leisure_data(),
fill_color = leisure_color[1],
fill_opacity = 0.8,
fill_outline_color = "darkgreen",
tooltip = concat("Leisure",
"<br />",
get_column("name"),
"<br />",
get_column("landuse"))
)
})
### observe inspectiongrid_data ----
observe({
create_observation(checkbox = input$chkbox_InspectionGrid,
layer_name = "inspection_grid",
reactive_data = inspectiongrid_data(),
# fill_color = "transparent",
# color = "#696969",
# weight = 1,
# stroke = TRUE,
# fill = FALSE,
# tooltip = ~id,
# labelOptions = labelOptions(noHide = TRUE,
# textOnly = TRUE,
# direction = 'center',
# permanent = TRUE,
# opacity = 1,
# style = list(
# color = "#696969")
# ),
# options = pathOptions(interactive = FALSE))
fill_color = "transparent",
fill_antialias = TRUE,
fill_opacity = 1,
fill_outline_color = grid_color[1])
})
### observe tssboundary_data ----
observe({
create_observation(checkbox = input$chkbox_TSSBoundary,
layer_name = "tssboundary_data",
reactive_data = tssboundary_data(),
fill_color = "transparent",
fill_outline_color = border_color
)
})
### observe nationalhighways_data ----
observe({
create_observation(checkbox = input$chkbox_NationalHighwaysboundary,
layer_name = "nationalhighways_data",
reactive_data = nationalhighways_data(),
# stroke = FALSE,
# color = "pink",
# fill_opacity = 0.8,
# tooltip = "National Highways land"
fill_color = NH_color,
fill_opacity = 0.5,
fill_outline_color = "pink",
tooltip = concat("NH boundary",
"<br />",
get_column("category"))
)
})
### observe tss_data ----
# NOTE: THIS OBSERVE ALWAYS GOES LAST AS EASIEST WAY TO KEEP LAYER ON TOP
observe({
# https://rstudio.github.io/leaflet/articles/shiny.html
m <- maplibre_proxy("map") |> clear_layer("tss_data")
if (input$chkbox_TSSChecklist & !is.null(tss_data()) && nrow(tss_data()) > 0){
if(input$toggle_roads == "All roads"){
set <- tss_data()$CLASS |> unique() |> sort()
set <- lookup_class |> filter(classification %in% set)
set$title <- "Class of road"
} else {
set <- tss_data()$TSS |> unique() |> sort()
set <- lookup_tss |> filter(classification %in% set)
set$title <- "TSS of road"
}
# pal <- list(
# values = set$classification,
# lwd = set$lwd,
# colors = set$colours,
# default = "pink",
# col = set$column[[1]])
m <- m |> add_line_layer(
source = tss_data(),
line_opacity = 0.5,
line_cap = "round",
line_width = match_expr(column = set$column[[1]],
values = set$classification,
stops = set$lwd,
default = 3),
line_color = match_expr(
column = set$column[[1]],
values = set$classification,
stops = set$colours,
default = "pink"
),
tooltip = "Street",
hover_options = list(
line_color = "gold",
line_opacity = 1,
line_width = 5
),
id = "tss_data"
)
m |> clear_controls()
m |>
add_legend(position = "top-left",
legend_title = set$title[[1]],
# colors = pal,
colors = set$colours,
values = set$classification,
patch_shape = "square",
type = "categorical",
style = list(
background_color = "#f0f0f0",
shadow = TRUE,
shadow_color = "white",
shadow_size = 8
)
)
}
})
#  observe events ----
### update basemap selected ----
observeEvent(input$basemap, {
# set_style(mapbox_style("dark"), config = list(showLabels = FALSE), diff = TRUE)
# https://codepen.io/g2g/pen/rNRJBZg <--- more free styles
basemap <- isolate(input$basemap)
m <- maplibre_proxy("map", session)
if(basemap == "liberty"){
m <- m |>
set_style(
style = "https://tiles.openfreemap.org/styles/liberty")
} else if(basemap == "osm-bright"){
m <- m |>
set_style(
style =
# "https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/openStreetMap.json")
"https://tiles.openfreemap.org/styles/bright")
} else if(basemap == "fiord"){
m <- m |>
set_style(
style =
# "https://raw.githubusercontent.com/go2garret/maps/main/src/assets/json/arcgis_hybrid.json")
"https://tiles.openfreemap.org/styles/fiord")
} else {
m <- m |> set_style(carto_style(basemap))
}
})
### hov_reac_d ----
observeEvent(hov_reac_d(), {
if (!is.null(hov_reac_d())){
bboxed(hov_reac_d())
}
})
### add_notes clicked ----
observeEvent(input$add_notes, {
print(paste("v is...", v$ESUID, " - ", v$Notes))
# get new input
text <- str_squish(input$notes_edit_plus) |> str_to_title()
# # check if existing notes is blank
if(is.null(v$Notes) | v$Notes == ""){
# print("Existing note is an empty string or null")
spacer <- ""
} else {
spacer <- " "
}
# if new note isn't blank
if(is.null(text) | text == ""){
print("New text is empty or null")
} else {
if(str_detect(text, ";$")){
v$Notes <- paste0(str_squish(v$Notes), spacer, text)
} else {
v$Notes <- paste0(str_squish(v$Notes), spacer, text, ";")
}
# update notes
output$notes_edit <- renderText(v$Notes, quoted = FALSE)
# blanbk off additional notes
updateTextInput(session,"notes_edit_plus", value="")
}
# confirm added
print(paste("new v$Notes is", v$Notes))
})
### commit_changes clicked ----
observeEvent(input$commit_changes, {
# check if anything clicked first
# need to update v based on input$lr_edit
#print(convert_true_false(v$LR))
if(length(reactiveValuesToList(v)) == 0){
showNotification(type = "warning",
closeButton = TRUE,
paste("Nothing selected. Click a road to edit.")
)
} else {
# if clicked *temporarily* check if notes blank to test logic
if(is.null(v$ESUID) | v$ESUID == ""){
showNotification(type = "warning",
closeButton = TRUE,
paste("ESUID is empty.")
)
} else {
# do some committing
conn = dbConnect(RSQLite::SQLite(), geodata)
# # disable triggers that work on geometries
triggers = dbGetQuery(conn, "SELECT name FROM sqlite_master WHERE type = 'trigger';")
if(nrow(triggers) != 0){
for (trigger_name in triggers$name) {
dbExecute(conn, paste0("DROP TRIGGER IF EXISTS '", trigger_name, "';"))
}
}
# check tables
## dbListTables(conn)
# check the table structure
## dbGetQuery(conn, "PRAGMA table_info(\"TSS Checklist\");")
# change just this ESUID
if(input$toggle_usrn_esuid == "ESUID"){
where_clause <- paste0("WHERE ESUID = '", v$ESUID, "';")
# change this USRN regardless of class
} else if(input$toggle_usrn_esuid == "USRN all"){
where_clause <- paste0("WHERE USRN = '", v$USRN, "';")
# change this USRN with the same class
} else if(input$toggle_usrn_esuid == "USRN class"){
where_clause <- paste0("WHERE USRN = '", v$USRN, "' AND CLASS = '", v$CLASS, "';")
} else {
return(NULL)
}
# ask_confirmation(inputId = "bob",
# type = "question",
# btn_labels = c("Confirm", "Cancel"))
# if(isTRUE(input$bob)){
# print("bob is NULL")
# } else if(!isTRUE(input$bob)){
# print("bob is TRUE")
# }
dbExecute(conn,
paste0("UPDATE \"TSS Checklist\" SET ",
# field2=value2,
# field3=value3
"TSS = '", input$tss_edit, "', ",
"LR = ", convert_true_false(input$lr_edit), ", ",
"Traffic_flow = ", convert_true_false(input$traffic_flow_edit), ", ",
"HGVs = ", convert_true_false(input$hgvs_edit), ", ",
"Buses = ", convert_true_false(input$buses_edit), ", ",
"Peds = ", convert_true_false(input$peds_edit), ", ",
"Carriageway = ", convert_true_false(input$carriageway_edit), ", ",
"CJ = ", convert_true_false(input$cj_edit), ", ",
"Medical = ", convert_true_false(input$medical_edit), ", ",
"Educational = ", convert_true_false(input$educational_edit), ", ",
"Retail = ", convert_true_false(input$retail_edit), ", ",
"Commercial = ", convert_true_false(input$commercial_edit), ", ",
"Recreational = ", convert_true_false(input$recreational_edit), ", ",
"Transport = ", convert_true_false(input$transport_edit), ", ",
"Emergency = ", convert_true_false(input$emergency_edit), ", ",
"AM_peak = ", convert_true_false(input$am_peak_edit), ", ",
"PM_peak = ", convert_true_false(input$pm_peak_edit), ", ",
"Inter_peak = ", convert_true_false(input$inter_peak_edit), ", ",
"Off_peak = ", convert_true_false(input$off_peak_edit), ", ",
"Inc_sats = ", convert_true_false(input$inc_sats_edit), ", ",
"Sat_rec = ", convert_true_false(input$sat_rec_edit), ", ",
"All_year = ", convert_true_false(input$all_year_edit), ", ",
"Term_time = ", convert_true_false(input$term_time_edit), ", ",
"Key_shopping = ", convert_true_false(input$key_shopping_edit), ", ",
"Notes = '", v$Notes, "' ",
where_clause)
# "WHERE ESUID = '", v$ESUID, "';")
)
dbDisconnect(conn)
showNotification(type = "message",
closeButton = FALSE,
paste("Committed changes. Move map to reload data.")
)
}
}
})
### map_shape_click clicked ----
observeEvent(input$map_feature_click, {
# p <- input$map_shape_click
# if(p$group == "tss_data"){
if(input$map_feature_click$layer == "tss_data"){
# print(p$id) # layerId ... which is now "esuid"
# data <- tss_data() |> filter(ESUID == p$id) |> st_drop_geometry()
data <- input$map_feature_click$properties
#### fill out edit_usrn boxes ----
output$usrn_edit <-renderText(data$USRN, quoted = FALSE)
output$esuid_edit <-renderText(data$ESUID, quoted = FALSE)
output$street_edit <-renderText(data$Street, quoted = FALSE)
output$class_edit <-renderText(data$CLASS, quoted = FALSE)
updateSelectInput(inputId = "tss_edit", selected = data$TSS)
updateCheckboxInput(inputId = "lr_edit", value = data$LR)
updateCheckboxInput(inputId = "traffic_flow_edit", value = data$Traffic_flow)
updateCheckboxInput(inputId = "hgvs_edit", value = data$HGVs)
updateCheckboxInput(inputId = "buses_edit", value = data$Buses)
updateCheckboxInput(inputId = "peds_edit", value = data$Peds)
updateCheckboxInput(inputId = "carriageway_edit", value = data$Carriageway)
updateCheckboxInput(inputId = "cj_edit", value = data$CJ)
updateCheckboxInput(inputId = "medical_edit", value = data$Medical)
updateCheckboxInput(inputId = "educational_edit", value = data$Educational)
updateCheckboxInput(inputId = "retail_edit", value = data$Retail)
updateCheckboxInput(inputId = "commercial_edit", value = data$Commercial)
updateCheckboxInput(inputId = "recreational_edit", value = data$Recreational)
updateCheckboxInput(inputId = "transport_edit", value = data$Transport)
updateCheckboxInput(inputId = "emergency_edit", value = data$Emergency)
updateCheckboxInput(inputId = "am_peak_edit", value = data$AM_peak)
updateCheckboxInput(inputId = "pm_peak_edit", value = data$PM_peak)
updateCheckboxInput(inputId = "inter_peak_edit", value = data$Inter_peak)
updateCheckboxInput(inputId = "off_peak_edit", value = data$Off_peak)
updateCheckboxInput(inputId = "inc_sats_edit", value = data$Inc_sats)
updateCheckboxInput(inputId = "sat_rec_edit", value = data$Sat_rec)
updateCheckboxInput(inputId = "all_year_edit", value = data$All_year)
updateCheckboxInput(inputId = "term_time_edit", value = data$Term_time)
updateCheckboxInput(inputId = "key_shopping_edit", value = data$Key_shopping)
output$notes_edit <-renderText(data$Notes, quoted = FALSE)
output$length_edit <-renderText(data$length, quoted = FALSE)
v$USRN = data$USRN
v$ESUID = data$ESUID
v$Street = data$Street
v$CLASS = data$CLASS
# v$TSS = data$TSS
# v$LR = data$LR
# v$Traffic_flow = data$Traffic_flow
# v$HGVs = data$HGVs
# v$Buses = data$Buses
# v$Peds = data$Peds
# v$Carriageway = data$Carriageway
# v$CJ = data$CJ
# v$Medical = data$Medical
# v$Educational = data$Educational
# v$Retail = data$Retail
# v$Commercial = data$Commercial
# v$Recreational = data$Recreational
# v$Transport = data$Transport
# v$Emergency = data$Emergency
# v$AM_peak = data$AM_peak
# v$PM_peak = data$PM_peak
# v$Inter_peak = data$Inter_peak
# v$Off_peak = data$Off_peak
# v$Inc_sats = data$Inc_sats
# v$Sat_rec = data$Sat_rec
# v$All_year = data$All_year
# v$Term_time = data$Term_time
# v$Key_shopping = data$Key_shopping
v$Notes = data$Notes
v$length = data$length
# print v to console for testing....
print(paste(
names(v),
c(v$USRN, v$ESUID, v$Street, v$CLASS, v$TSS, v$LR,
v$Traffic_flow, v$HGVs, v$Buses, v$Peds, v$Carriageway,
v$CJ, v$Medical, v$Educational, v$Retail, v$Commercial,
v$Recreational, v$Transport, v$Emergency, v$AM_peak,
v$PM_peak, v$Inter_peak, v$Off_peak, v$Inc_sats, v$Sat_rec,
v$All_year, v$Term_time, v$Key_shopping, v$Notes, v$length),
# v,
sep = ": "
)
)
toggle_sidebar("edit_usrn", open = TRUE)#, session = get_current_session())
} else {
toggle_sidebar("edit_usrn", open = FALSE)
}
})
### modal
# observe({
# showModal(
# modalDialog(
# tagList(
# textInput("newfilename", label = "Filename", placeholder = "my_file.txt")
# ),
# title="Create a file",
# footer = tagList(actionButton("confirmSave", "Save"),
# modalButton("Cancel")
# )
# )
# )
# }) |>
# bindEvent(input$report_tss)
#
# observeEvent(input$confirmSave, {
# req(input$newfilename)
# print(paste("File will be saved in:", input$newfilename))
# removeModal()
# })
### report_tss clicked ----
# observeEvent(input$report_tss,{
# run_report(type = "TSS", year = "2025")
# })
### downloadhandler tss ----
# https://mastering-shiny.org/action-transfer.html#downloading-reports
output$report_tss <- downloadHandler(
filename = paste0("tss_review_v6a_output-report_tss_",
Sys.Date(), "_",
str_replace_all(format(Sys.time(), "%X"), ":", ""),
".html"),
content = function(file) {
params <- get_params(type = "TSS", year = "2025", filename = filename())
id <- showNotification(
"Please stand by. This will take a minute: Rendering TSS report...",
duration = NULL,
type = "warning",
closeButton = FALSE
)
on.exit(removeNotification(id), add = TRUE)
callr::r(
render_report,
list(input = report_path,
output = file,
params = params)
)
}
)
### report_lr clicked ----
observeEvent(input$report_lr,{
# TODO need to check if LR selected in data
run_report(type = "LR", year = "2025")
})
##  rendertext ----
output$info <- renderText({
zoomlevel <- input$map_zoom
map_center <- input$map_center
edu_selected <- input$chkbox_GEOEducation
if (!is.null(tss_data())) {
paste0(
"Showing ", nrow(tss_data()),
" features in current view at zoom level ",
zoomlevel,
# ". Education is set to ",
# edu_selected,
". Map center is ", map_center$lng, ", ", map_center$lat, ". bboxed: ",
bboxed()[1], ", ", bboxed()[2], ", ", bboxed()[3], ", ", bboxed()[4]
)
} else {
paste0(
"Zoom level = ", zoomlevel, ". Pan/zoom map to load data. ",
"Zoom in passed level 14 to view entirety of road network. "
)
}
})
#  end of server function ----
}
# run me ----
shinyApp(ui = ui, server = server)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment