Search code examples
rshinyr-leaflet

Table Display based on filter selection and custom polyline click


I have a shapefile with segments of varying lengths. For each segment, I have attributes including segment id, year, time period, and other variables like traffic volume. Right now a user is able to select a year, time period, and segment id from a drop down and it will populate a table with the associated values for that filter.

I also want the user to be able to click any of my custom segments (added via addPolylines() command) on the map and it should render the same table as above. I would prefer to not have the segment id as an item in my dropdown menu items list but rather as a selection from a map. However, my implementation does not do the following:

  1. Display my segments on the OpenStreets base map.
  2. Allow me to select the segment I want from the map and update the table accordingly for the selected segment.

Do you have any insights to address this? My code, data, and screenshot of my output are below.

Code

library(shiny)
library(leaflet)
library(dplyr)
library(sf)
library(scales)
library(bslib)

# Data 
# sample_data 
# segment_data




ui <- page_sidebar(
  title = "Cap Analysis",
  sidebar = sidebar(
    selectInput("yr1", "Year", choices = sample_data$Year),
    selectInput("per1", "Time Period", choices = sample_data$Period),
  selectInput("segs","Segment ID",choices = unique(c(sample_data$SegID,segment_data$SegID))),
    width = 300
  ),
  card(
    leafletOutput("map")
  ),
  card(
    tableOutput("attrib"),fill = TRUE
  )
)

server <- function(input, output, session) {
  selected <- reactive(sample_data %>% filter(Year == input$yr1 & Period==input$per1 & SegID==input$segs))
  #selected <- reactive(sample_data %>% filter(Year == input$yr1 & Period==input$per1))
  selectmap <- reactive(segment_data %>% filter(SegID == input$segs))
  
  output$map <- renderLeaflet({
    selectmap %>% leaflet() %>%
      addTiles() %>%  # Add OpenStreetMap tiles
      setView(lng = -76.538192, lat = 39.310621, zoom = 13)
  })
  
  observe({
    leafletProxy("map") %>%
      clearShapes() %>%
      addPolylines(
        data = segment_data,
        lng = ~c(start_lon,end_lon),
        lat = ~c(start_lat,end_lat),
        layerId = ~SegID,
        color = "red",
        weight = 3
      )
  })
  
  observeEvent(input$map_shape_click, {
    click <- input$map_shape_click
    if (!is.null(click)) {
      sample_data %>%
          filter(SegID == click$SegID)
    }
 
  })
  
  output$attrib <- renderTable(
    selected()  %>% count(`Segment ID`= SegID, Direction = Direction, `Segment Type` = SegType, Segment=Segment,`Number of Lanes`= NumLane, `Segment Length (ft)`= Segment_Length_ft, Type=Type,`FFS (mph)`= FFS_mph, `Volume (vph)` =  scales::comma(round(Vol_vph,digits=0),big.mark = ","), `Truck Percent` = Truck_Percent, LOS = LOS, sort = TRUE, width="100%") %>% subset(select=c(1:11))
  )
}


# Run the application 
shinyApp(ui = ui, server = server)

Sample Data

sample_data <- structure(list(SegID = c("210", "211", "211A", "212", "213", 
"213A", "214", "201", "202", "202A", "203", "210", "211", "211A", 
"212", "213", "213A", "214", "201", "202", "202A", "203", "210", 
"211", "211A", "212", "213", "213A", "214", "201", "202", "202A", 
"203", "210", "211", "211A", "212", "213", "213A", "214", "201", 
"202", "202A", "203", "210", "211", "211A", "212", "213", "213A", 
"214", "201", "202", "202A", "203", "210", "211", "211A", "212", 
"213", "213A", "214", "201", "202", "202A", "203", "210", "211", 
"211A", "212", "213", "213A", "214", "201", "202", "202A", "203", 
"210", "211", "211A", "212", "213", "213A", "214", "201", "202", 
"202A", "203", "210", "211", "211A", "212", "213", "213A", "214", 
"201", "202", "202A", "203"), Direction = c("NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
"NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB"), SegType = c("Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
"Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
"Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway"), Segment = c("I-95 NB North of Ramp from Eastern Ave WB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
"I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
"I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
"I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
"I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
"I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
"I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
"I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
"I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
"I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
"I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
"I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
"I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
"I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB"
), NumLane = c(4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 
1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 
4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 
4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 
1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4), 
    Segment_Length_ft = c(5280, 1500, 1500, 5280, 1500, 420, 
    5280, 5280, 1500, 1070, 5280, 5280, 1500, 1500, 5280, 1500, 
    420, 5280, 5280, 1500, 1070, 5280, 5280, 1500, 1500, 5280, 
    1500, 420, 5280, 5280, 1500, 1070, 5280, 5280, 1500, 1500, 
    5280, 1500, 420, 5280, 5280, 1500, 1070, 5280, 5280, 1500, 
    1500, 5280, 1500, 420, 5280, 5280, 1500, 1070, 5280, 5280, 
    1500, 1500, 5280, 1500, 420, 5280, 5280, 1500, 1070, 5280, 
    5280, 1500, 1500, 5280, 1500, 420, 5280, 5280, 1500, 1070, 
    5280, 5280, 1500, 1500, 5280, 1500, 420, 5280, 5280, 1500, 
    1070, 5280, 5280, 1500, 1500, 5280, 1500, 420, 5280, 5280, 
    1500, 1070, 5280), Type = c("Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
    "Level", "Level", "Level", "Level"), FFS_mph = c(60, 60, 
    50, 60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 
    60, 60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 
    60, 60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 
    60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 60, 
    60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 60, 
    60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 60, 
    60, 40, 60, 60, 60, 30, 60), Year = c(2015, 2015, 2015, 2015, 
    2015, 2015, 2015, 2015, 2015, 2015, 2015, 2018, 2018, 2018, 
    2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2021, 2021, 
    2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2015, 
    2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 
    2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
    2018, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 
    2021, 2021, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 
    2015, 2015, 2015, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
    2018, 2018, 2018, 2018, 2021, 2021, 2021, 2021, 2021, 2021, 
    2021, 2021, 2021, 2021, 2021), Period = c("AM Peak", "AM Peak", 
    "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
    "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
    "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
    "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
    "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
    "AM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
    "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
    "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
    "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
    "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
    "PM Peak", "PM Peak", "PM Peak", "PM Peak", "WE Peak", "WE Peak", 
    "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
    "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
    "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
    "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
    "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
    "WE Peak"), Vol_vph = c(2800, 2800, 425, 2375, 2375, 375, 
    2000, 5550, 5550, 600, 6150, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, 3225, 3225, 450, 2775, 2775, 450, 2325, 4725, 
    4725, 500, 5225, 6150, 6150, 600, 5550, 5500, 550, 5000, 
    2700, 2700, 325, 3025, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, NA, 5975, 5975, 650, 5325, 5325, 650, 4675, 3300, 3300, 
    325, 3625, 4125, 4125, 350, 3775, 3775, 275, 3500, 3450, 
    3450, 250, 3700, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, 3950, 3950, 300, 3650, 3650, 350, 3300, 3725, 3725, 275, 
    4000), Truck_Percent = c(9.7, 9.7, 2, 10.7, 10.7, 6.1, 7.3, 
    7.9, 7.9, 6.1, 7.7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
    NA, 12.7, 12.7, 1.7, 14, 14, 5.3, 15.3, 14.7, 14.7, 8, 14.1, 
    9.7, 9.7, 2, 10.7, 10.7, 6.1, 7.3, 7.9, 7.9, 6.1, 7.7, NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 12.7, 12.7, 1.7, 
    14, 14, 5.3, 15.3, 14.7, 14.7, 8, 14.1, 4.4, 4.4, 1, 4.7, 
    4.7, 5.8, 3.6, 3.2, 3.2, 2.3, 3.1, NA, NA, NA, NA, NA, NA, 
    NA, NA, NA, NA, NA, 6.7, 6.7, 0.8, 7.3, 7.3, 2.2, 7.9, 6.5, 
    6.5, 2.7, 6.2), LOS = c("B", "B", "B", "B", "B", "B", "B", 
    "D", "C", "C", "D", "B", "A", "A", "B", "B", "B", "A", "C", 
    "C", "C", "C", "B", "A", "A", "B", "B", "B", "B", "C", "C", 
    "C", "D", "D", "F", "F", "E", "D", "D", "D", "B", "B", "B", 
    "B", "C", "C", "C", "D", "D", "D", "C", "B", "B", "B", "B", 
    "D", "C", "C", "D", "D", "D", "C", "B", "B", "B", "C", "C", 
    "B", "B", "C", "C", "C", "C", "B", "B", "B", "B", "B", "A", 
    "A", "B", "B", "B", "B", "B", "B", "B", "C", "C", "A", "A", 
    "B", "B", "B", "B", "B", "B", "B", "C")), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -99L))

Segment Data

segment_data <- structure(list(Shape_Leng = c(1188.14747869, 604.391081074, 845.943032786, 
924.419150361, 1170.61433301, 1284.04786287, 592.277680455, 713.523651468, 
95.6789913537, 110.510041468, 184.887359789), ID = c("214", "213", 
"212", "211", "210", "203", "202", "201", "211A", "213A", "202A"
), SegID = c("214", "213", "212", "211", "210", "203", "202", 
"201", "211A", "213A", "202A"), start_lat = c(39.306108, 39.306108, 
39.305346, 39.299475, 39.298813, 39.299187, 39.309301, 39.309301, 
39.298813, 39.306108, 39.309301), start_lon = c(-76.530686, -76.530686, 
-76.530567, -76.530471, -76.530557, -76.530727, -76.531848, -76.531848, 
-76.530557, -76.530686, -76.531848), end_lat = c(39.31416, 39.310007, 
39.299475, 39.30554, 39.290808, 39.308053, 39.309029, 39.314113, 
39.299475, 39.305346, 39.308053), end_lon = c(-76.530686, -76.530686, 
-76.530567, -76.530471, -76.530557, -76.530727, -76.531848, -76.531848, 
-76.530557, -76.530686, -76.531848), geometry = structure(list(
    structure(c(-8519356.9876, -8519390.6853, -8519438.3123, 
    -8519512.6105, -8519617.4122, 4765614.3042, 4765830.5091, 
    4766061.9766, 4766350.5966, 4766772.7688), dim = c(5L, 2L
    ), class = c("XY", "LINESTRING", "sfg")), structure(c(-8519356.9876, 
    -8519347.8763, -8519357.7182, -8519372.9345, -8519376.8361, 
    -8519374.1049, -8519364.7411, -8519349.1346, -8519325.3348, 
    -8519267.7883, 4765614.3042, 4765620.2143, 4765731.774, 4765929.5856, 
    4765997.0834, 4766027.9061, 4766058.3386, 4766087.2106, 4766115.3021, 
    4766175.2652), dim = c(10L, 2L), class = c("XY", "LINESTRING", 
    "sfg")), structure(c(-8519343.8012, -8519339.2718, -8519321.1497, 
    -8519317.3396, -8519321.1497, -8519333.0071, 4765504.5837, 
    4765458.0392, 4765214.2149, 4764986.5575, 4764837.0086, 4764660.0102
    ), dim = c(6L, 2L), class = c("XY", "LINESTRING", "sfg")), 
    structure(c(-8519333.0071, -8519318.855, -8519305.4834, -8519287.0054, 
    -8519266.2801, -8519229.7454, -8519220.7717, -8519219.2111, 
    -8519223.893, -8519234.0372, -8519248.4731, -8519281.6368, 
    -8519324.1643, -8519346.5252, 4764660.0102, 4764686.1622, 
    4764829.5659, 4764937.4376, 4765026.8313, 4765186.3291, 4765235.4893, 
    4765271.7743, 4765317.8133, 4765365.4129, 4765405.9896, 4765462.1728, 
    4765515.2347, 4765532.5401), dim = c(14L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-8519342.6305, -8519357.7182, 
    -8519375.7875, -8519549.531, 4764564.8164, 4764415.7613, 
    4764286.3254, 4763413.3404), dim = c(4L, 2L), class = c("XY", 
    "LINESTRING", "sfg")), structure(c(-8519361.5967, -8519350.3051, 
    -8519344.0869, -8519345.3062, -8519362.109, -8519396.4005, 
    -8519411.5147, -8519441.7311, 4764618.5569, 4764759.8832, 
    4764926.4331, 4765122.7328, 4765444.7299, 4765692.3906, 4765770.9106, 
    4765894.1418), dim = c(8L, 2L), class = c("XY", "LINESTRING", 
    "sfg")), structure(c(-8519486.3647, -8519495.4003, -8519513.7825, 
    -8519541.3392, -8519555.0558, -8519570.144, -8519589.6902, 
    -8519605.8072, -8519621.2383, -8519639.7557, -8519651.4148, 
    -8519659.6448, -8519665.4743, -8519668.5606, -8519664.7885, 
    -8519650.3861, -8519622.9529, -8519590.7189, -8519571.5157, 
    -8519550.9408, -8519528.3084, -8519505.676, 4766073.5608, 
    4766076.6252, 4766147.8562, 4766216.6312, 4766238.9207, 4766253.666, 
    4766262.2389, 4766263.9534, 4766262.9247, 4766254.3518, 4766244.0644, 
    4766231.0336, 4766215.6024, 4766199.1425, 4766178.9106, 4766148.0482, 
    4766105.8697, 4766065.7487, 4766049.2887, 4766039.6871, 4766034.8863, 
    4766034.5434), dim = c(22L, 2L), class = c("XY", "LINESTRING", 
    "sfg")), structure(c(-8519486.3647, -8519658.6161, 4766073.5608, 
    4766765.9808), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
    "sfg")), structure(c(-8519342.6305, -8519333.0071, 4764564.8164, 
    4764660.0102), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
    "sfg")), structure(c(-8519356.9876, -8519343.8012, 4765614.3042, 
    4765504.5837), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
    "sfg")), structure(c(-8519486.3647, -8519441.7311, 4766073.5608, 
    4765894.1418), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
    "sfg"))), n_empty = 0L, crs = structure(list(input = "WGS 84 / Pseudo-Mercator", 
    wkt = "PROJCRS[\"WGS 84 / Pseudo-Mercator\",\n    BASEGEOGCRS[\"WGS 84\",\n        ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n            MEMBER[\"World Geodetic System 1984 (Transit)\"],\n            MEMBER[\"World Geodetic System 1984 (G730)\"],\n            MEMBER[\"World Geodetic System 1984 (G873)\"],\n            MEMBER[\"World Geodetic System 1984 (G1150)\"],\n            MEMBER[\"World Geodetic System 1984 (G1674)\"],\n            MEMBER[\"World Geodetic System 1984 (G1762)\"],\n            MEMBER[\"World Geodetic System 1984 (G2139)\"],\n            ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n                LENGTHUNIT[\"metre\",1]],\n            ENSEMBLEACCURACY[2.0]],\n        PRIMEM[\"Greenwich\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n        ID[\"EPSG\",4326]],\n    CONVERSION[\"Popular Visualisation Pseudo-Mercator\",\n        METHOD[\"Popular Visualisation Pseudo Mercator\",\n            ID[\"EPSG\",1024]],\n        PARAMETER[\"Latitude of natural origin\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433],\n            ID[\"EPSG\",8801]],\n        PARAMETER[\"Longitude of natural origin\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433],\n            ID[\"EPSG\",8802]],\n        PARAMETER[\"False easting\",0,\n            LENGTHUNIT[\"metre\",1],\n            ID[\"EPSG\",8806]],\n        PARAMETER[\"False northing\",0,\n            LENGTHUNIT[\"metre\",1],\n            ID[\"EPSG\",8807]]],\n    CS[Cartesian,2],\n        AXIS[\"easting (X)\",east,\n            ORDER[1],\n            LENGTHUNIT[\"metre\",1]],\n        AXIS[\"northing (Y)\",north,\n            ORDER[2],\n            LENGTHUNIT[\"metre\",1]],\n    USAGE[\n        SCOPE[\"Web mapping and visualisation.\"],\n        AREA[\"World between 85.06°S and 85.06°N.\"],\n        BBOX[-85.06,-180,85.06,180]],\n    ID[\"EPSG\",3857]]"), class = "crs"), class = c("sfc_LINESTRING", 
"sfc"), precision = 0, bbox = structure(c(xmin = -8519668.5606, 
ymin = 4763413.3404, xmax = -8519219.2111, ymax = 4766772.7688
), class = "bbox"))), row.names = c(NA, -11L), class = c("sf", 
"data.frame"), sf_column = "geometry", agr = structure(c(Shape_Leng = NA_integer_, 
ID = NA_integer_, SegID = NA_integer_, start_lat = NA_integer_, 
start_lon = NA_integer_, end_lat = NA_integer_, end_lon = NA_integer_
), class = "factor", levels = c("constant", "aggregate", "identity"
)))

Output

Output


Solution

  • Below is a variant which addresses both of your requirements. I made several adjustments:

    • In segment_data you have reversed lat and lon, compare e.g. what is provided in setView and in the corresponding data columns. I made the fix below in addPolylines, you should edit the data to what is required.
    • You can't use |> addPolylines( ... ) as above because then leaflet treats it all as one line. I wrote an lapply which adds the lines per segment_data$ID.
    • I removed the ID dropdown and rewrote things to input$map_shape_click, some smaller adjustments here, e.g. you need click$id.
    • Some reactivity changes, e.g. using reactiveVal.

    enter image description here

    library(shiny)
    library(leaflet)
    library(dplyr)
    library(bslib)
    
    ui <- page_sidebar(
      title = "Cap Analysis",
      sidebar = sidebar(
        selectInput("yr1", "Year", choices = sample_data$Year),
        selectInput("per1", "Time Period", choices = sample_data$Period),
        width = 300
      ),
      card(
        leafletOutput("map")
      ),
      card(
        tableOutput("attrib"), fill = TRUE
      )
    )
    
    server <- function(input, output, session) {
      selected <- reactiveVal("")
      selectmap <- reactiveVal("")
      
      output$map <- renderLeaflet({
        segment_data %>% leaflet() %>%
          addTiles() %>%  # Add OpenStreetMap tiles
          setView(lng = -76.538192, lat = 39.310621, zoom = 13)
      })
      
      observe({
        m <- leafletProxy("map") |>
          clearShapes()
        
        lapply(segment_data$ID, function(id) {
          addPolylines(
            m, 
            data = as.data.frame(segment_data[segment_data$ID == id, ]),
            lat = ~c(start_lon,end_lon), # to-do: correct data
            lng = ~c(start_lat,end_lat), # to-do: correct data
            layerId = ~SegID,
            color = "red",
            weight = 3,
            opacity = 1
          )
        })
      })
      
      observeEvent(input$map_shape_click, {
        click <- input$map_shape_click
        sample_data %>% filter(Year == input$yr1 & 
                                  Period==input$per1 & SegID==click$id) |> 
        selected()
      })
      
      output$attrib <- renderTable({
        req(nrow(selected()) > 0)
        selected()  %>% 
          count(`Segment ID`= SegID, 
                Direction = Direction, 
                `Segment Type` = SegType, 
                Segment=Segment,
                `Number of Lanes`= NumLane, 
                `Segment Length (ft)`= Segment_Length_ft, 
                Type=Type,`FFS (mph)`= FFS_mph, 
                `Volume (vph)` =  scales::comma(round(Vol_vph,digits=0),big.mark = ","), 
                `Truck Percent` = Truck_Percent, 
                LOS = LOS)
      })
    }
    
    # Run the application 
    shinyApp(ui = ui, server = server)
    

    Data:

    sample_data:

    > dput(sample_data)
    structure(list(SegID = c("210", "211", "211A", "212", "213", 
    "213A", "214", "201", "202", "202A", "203", "210", "211", "211A", 
    "212", "213", "213A", "214", "201", "202", "202A", "203", "210", 
    "211", "211A", "212", "213", "213A", "214", "201", "202", "202A", 
    "203", "210", "211", "211A", "212", "213", "213A", "214", "201", 
    "202", "202A", "203", "210", "211", "211A", "212", "213", "213A", 
    "214", "201", "202", "202A", "203", "210", "211", "211A", "212", 
    "213", "213A", "214", "201", "202", "202A", "203", "210", "211", 
    "211A", "212", "213", "213A", "214", "201", "202", "202A", "203", 
    "210", "211", "211A", "212", "213", "213A", "214", "201", "202", 
    "202A", "203", "210", "211", "211A", "212", "213", "213A", "214", 
    "201", "202", "202A", "203"), Direction = c("NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB", "NB", "NB", "NB", 
    "NB", "NB", "NB", "NB", "SB", "SB", "SB", "SB"), SegType = c("Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway", "Freeway", 
    "Freeway", "Ramp Diverge", "Freeway", "Freeway", "Ramp Diverge", 
    "Freeway", "Freeway", "Freeway", "Ramp Merge", "Freeway"), Segment = c("I-95 NB North of Ramp from Eastern Ave WB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
    "I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
    "I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
    "I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
    "I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
    "I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
    "I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
    "I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB", 
    "I-95 NB North of Ramp from Eastern Ave WB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB North of Ramp to Moravia Rd NB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB North of Ramp to Pulaski Hwy EB", "I-95 SB South of Ramp to I-895 SB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB South of Ramp from Pulaski Hwy WB", "I-95 NB North of Ramp from Eastern Ave WB", 
    "I-95 NB Ramp to Moravia Rd NB", "I-95 NB Ramp to Moravia Rd NB", 
    "I-95 NB North of Ramp to Moravia Rd NB", "I-95 NB Ramp to Pulaski Hwy EB", 
    "I-95 NB Ramp to Pulaski Hwy EB", "I-95 NB North of Ramp to Pulaski Hwy EB", 
    "I-95 SB South of Ramp to I-895 SB", "I-95 SB Ramp from Pulaski Hwy WB", 
    "I-95 SB Ramp from Pulaski Hwy WB", "I-95 SB South of Ramp from Pulaski Hwy WB"
    ), NumLane = c(4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 
    1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 
    4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 
    4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 
    1, 4, 4, 1, 4, 4, 4, 1, 4, 4, 4, 1, 4, 4, 1, 4, 4, 4, 1, 4), 
        Segment_Length_ft = c(5280, 1500, 1500, 5280, 1500, 420, 
        5280, 5280, 1500, 1070, 5280, 5280, 1500, 1500, 5280, 1500, 
        420, 5280, 5280, 1500, 1070, 5280, 5280, 1500, 1500, 5280, 
        1500, 420, 5280, 5280, 1500, 1070, 5280, 5280, 1500, 1500, 
        5280, 1500, 420, 5280, 5280, 1500, 1070, 5280, 5280, 1500, 
        1500, 5280, 1500, 420, 5280, 5280, 1500, 1070, 5280, 5280, 
        1500, 1500, 5280, 1500, 420, 5280, 5280, 1500, 1070, 5280, 
        5280, 1500, 1500, 5280, 1500, 420, 5280, 5280, 1500, 1070, 
        5280, 5280, 1500, 1500, 5280, 1500, 420, 5280, 5280, 1500, 
        1070, 5280, 5280, 1500, 1500, 5280, 1500, 420, 5280, 5280, 
        1500, 1070, 5280), Type = c("Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level", "Level", "Level", "Level", 
        "Level", "Level", "Level", "Level"), FFS_mph = c(60, 60, 
        50, 60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 
        60, 60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 
        60, 60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 
        60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 60, 
        60, 60, 30, 60, 60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 60, 
        60, 60, 50, 60, 60, 40, 60, 60, 60, 30, 60, 60, 60, 50, 60, 
        60, 40, 60, 60, 60, 30, 60), Year = c(2015, 2015, 2015, 2015, 
        2015, 2015, 2015, 2015, 2015, 2015, 2015, 2018, 2018, 2018, 
        2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2021, 2021, 
        2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2015, 
        2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 
        2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
        2018, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 
        2021, 2021, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 2015, 
        2015, 2015, 2015, 2018, 2018, 2018, 2018, 2018, 2018, 2018, 
        2018, 2018, 2018, 2018, 2021, 2021, 2021, 2021, 2021, 2021, 
        2021, 2021, 2021, 2021, 2021), Period = c("AM Peak", "AM Peak", 
        "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
        "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
        "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
        "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
        "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", "AM Peak", 
        "AM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
        "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
        "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
        "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
        "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", "PM Peak", 
        "PM Peak", "PM Peak", "PM Peak", "PM Peak", "WE Peak", "WE Peak", 
        "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
        "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
        "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
        "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
        "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", "WE Peak", 
        "WE Peak"), Vol_vph = c(2800, 2800, 425, 2375, 2375, 375, 
        2000, 5550, 5550, 600, 6150, NA, NA, NA, NA, NA, NA, NA, 
        NA, NA, NA, NA, 3225, 3225, 450, 2775, 2775, 450, 2325, 4725, 
        4725, 500, 5225, 6150, 6150, 600, 5550, 5500, 550, 5000, 
        2700, 2700, 325, 3025, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
        NA, NA, 5975, 5975, 650, 5325, 5325, 650, 4675, 3300, 3300, 
        325, 3625, 4125, 4125, 350, 3775, 3775, 275, 3500, 3450, 
        3450, 250, 3700, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
        NA, 3950, 3950, 300, 3650, 3650, 350, 3300, 3725, 3725, 275, 
        4000), Truck_Percent = c(9.7, 9.7, 2, 10.7, 10.7, 6.1, 7.3, 
        7.9, 7.9, 6.1, 7.7, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
        NA, 12.7, 12.7, 1.7, 14, 14, 5.3, 15.3, 14.7, 14.7, 8, 14.1, 
        9.7, 9.7, 2, 10.7, 10.7, 6.1, 7.3, 7.9, 7.9, 6.1, 7.7, NA, 
        NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 12.7, 12.7, 1.7, 
        14, 14, 5.3, 15.3, 14.7, 14.7, 8, 14.1, 4.4, 4.4, 1, 4.7, 
        4.7, 5.8, 3.6, 3.2, 3.2, 2.3, 3.1, NA, NA, NA, NA, NA, NA, 
        NA, NA, NA, NA, NA, 6.7, 6.7, 0.8, 7.3, 7.3, 2.2, 7.9, 6.5, 
        6.5, 2.7, 6.2), LOS = c("B", "B", "B", "B", "B", "B", "B", 
        "D", "C", "C", "D", "B", "A", "A", "B", "B", "B", "A", "C", 
        "C", "C", "C", "B", "A", "A", "B", "B", "B", "B", "C", "C", 
        "C", "D", "D", "F", "F", "E", "D", "D", "D", "B", "B", "B", 
        "B", "C", "C", "C", "D", "D", "D", "C", "B", "B", "B", "B", 
        "D", "C", "C", "D", "D", "D", "C", "B", "B", "B", "C", "C", 
        "B", "B", "C", "C", "C", "C", "B", "B", "B", "B", "B", "A", 
        "A", "B", "B", "B", "B", "B", "B", "B", "C", "C", "A", "A", 
        "B", "B", "B", "B", "B", "B", "B", "C")), class = c("tbl_df", 
    "tbl", "data.frame"), row.names = c(NA, -99L))
    

    segment_data:

    > dput(segment_data)
    structure(list(Shape_Leng = c(1188.14747869, 604.391081074, 845.943032786, 
    924.419150361, 1170.61433301, 1284.04786287, 592.277680455, 713.523651468, 
    95.6789913537, 110.510041468, 184.887359789), ID = c("214", "213", 
    "212", "211", "210", "203", "202", "201", "211A", "213A", "202A"
    ), SegID = c("214", "213", "212", "211", "210", "203", "202", 
    "201", "211A", "213A", "202A"), start_lat = c(-76.530686, -76.530686, 
    -76.530567, -76.530471, -76.530557, -76.530727, -76.531848, -76.531848, 
    -76.530557, -76.530686, -76.531848), start_lon = c(39.306108, 
    39.306108, 39.305346, 39.299475, 39.298813, 39.299187, 39.309301, 
    39.309301, 39.298813, 39.306108, 39.309301), end_lat = c(-76.533025, 
    -76.529885, -76.530471, -76.530592, -76.532416, -76.531447, -76.532022, 
    -76.533396, -76.530471, -76.530567, -76.531447), end_lon = c(39.31416, 
    39.310007, 39.299475, 39.30554, 39.290808, 39.308053, 39.309029, 
    39.314113, 39.299475, 39.305346, 39.308053), geometry = structure(list(
        structure(c(-8519356.9876, -8519390.6853, -8519438.3123, 
        -8519512.6105, -8519617.4122, 4765614.3042, 4765830.5091, 
        4766061.9766, 4766350.5966, 4766772.7688), dim = c(5L, 2L
        ), class = c("XY", "LINESTRING", "sfg")), structure(c(-8519356.9876, 
        -8519347.8763, -8519357.7182, -8519372.9345, -8519376.8361, 
        -8519374.1049, -8519364.7411, -8519349.1346, -8519325.3348, 
        -8519267.7883, 4765614.3042, 4765620.2143, 4765731.774, 4765929.5856, 
        4765997.0834, 4766027.9061, 4766058.3386, 4766087.2106, 4766115.3021, 
        4766175.2652), dim = c(10L, 2L), class = c("XY", "LINESTRING", 
        "sfg")), structure(c(-8519343.8012, -8519339.2718, -8519321.1497, 
        -8519317.3396, -8519321.1497, -8519333.0071, 4765504.5837, 
        4765458.0392, 4765214.2149, 4764986.5575, 4764837.0086, 4764660.0102
        ), dim = c(6L, 2L), class = c("XY", "LINESTRING", "sfg")), 
        structure(c(-8519333.0071, -8519318.855, -8519305.4834, -8519287.0054, 
        -8519266.2801, -8519229.7454, -8519220.7717, -8519219.2111, 
        -8519223.893, -8519234.0372, -8519248.4731, -8519281.6368, 
        -8519324.1643, -8519346.5252, 4764660.0102, 4764686.1622, 
        4764829.5659, 4764937.4376, 4765026.8313, 4765186.3291, 4765235.4893, 
        4765271.7743, 4765317.8133, 4765365.4129, 4765405.9896, 4765462.1728, 
        4765515.2347, 4765532.5401), dim = c(14L, 2L), class = c("XY", 
        "LINESTRING", "sfg")), structure(c(-8519342.6305, -8519357.7182, 
        -8519375.7875, -8519549.531, 4764564.8164, 4764415.7613, 
        4764286.3254, 4763413.3404), dim = c(4L, 2L), class = c("XY", 
        "LINESTRING", "sfg")), structure(c(-8519361.5967, -8519350.3051, 
        -8519344.0869, -8519345.3062, -8519362.109, -8519396.4005, 
        -8519411.5147, -8519441.7311, 4764618.5569, 4764759.8832, 
        4764926.4331, 4765122.7328, 4765444.7299, 4765692.3906, 4765770.9106, 
        4765894.1418), dim = c(8L, 2L), class = c("XY", "LINESTRING", 
        "sfg")), structure(c(-8519486.3647, -8519495.4003, -8519513.7825, 
        -8519541.3392, -8519555.0558, -8519570.144, -8519589.6902, 
        -8519605.8072, -8519621.2383, -8519639.7557, -8519651.4148, 
        -8519659.6448, -8519665.4743, -8519668.5606, -8519664.7885, 
        -8519650.3861, -8519622.9529, -8519590.7189, -8519571.5157, 
        -8519550.9408, -8519528.3084, -8519505.676, 4766073.5608, 
        4766076.6252, 4766147.8562, 4766216.6312, 4766238.9207, 4766253.666, 
        4766262.2389, 4766263.9534, 4766262.9247, 4766254.3518, 4766244.0644, 
        4766231.0336, 4766215.6024, 4766199.1425, 4766178.9106, 4766148.0482, 
        4766105.8697, 4766065.7487, 4766049.2887, 4766039.6871, 4766034.8863, 
        4766034.5434), dim = c(22L, 2L), class = c("XY", "LINESTRING", 
        "sfg")), structure(c(-8519486.3647, -8519658.6161, 4766073.5608, 
        4766765.9808), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
        "sfg")), structure(c(-8519342.6305, -8519333.0071, 4764564.8164, 
        4764660.0102), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
        "sfg")), structure(c(-8519356.9876, -8519343.8012, 4765614.3042, 
        4765504.5837), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
        "sfg")), structure(c(-8519486.3647, -8519441.7311, 4766073.5608, 
        4765894.1418), dim = c(2L, 2L), class = c("XY", "LINESTRING", 
        "sfg"))), n_empty = 0L, crs = structure(list(input = "WGS 84 / Pseudo-Mercator", 
        wkt = "PROJCRS[\"WGS 84 / Pseudo-Mercator\",\n    BASEGEOGCRS[\"WGS 84\",\n        ENSEMBLE[\"World Geodetic System 1984 ensemble\",\n            MEMBER[\"World Geodetic System 1984 (Transit)\"],\n            MEMBER[\"World Geodetic System 1984 (G730)\"],\n            MEMBER[\"World Geodetic System 1984 (G873)\"],\n            MEMBER[\"World Geodetic System 1984 (G1150)\"],\n            MEMBER[\"World Geodetic System 1984 (G1674)\"],\n            MEMBER[\"World Geodetic System 1984 (G1762)\"],\n            MEMBER[\"World Geodetic System 1984 (G2139)\"],\n            ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n                LENGTHUNIT[\"metre\",1]],\n            ENSEMBLEACCURACY[2.0]],\n        PRIMEM[\"Greenwich\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n        ID[\"EPSG\",4326]],\n    CONVERSION[\"Popular Visualisation Pseudo-Mercator\",\n        METHOD[\"Popular Visualisation Pseudo Mercator\",\n            ID[\"EPSG\",1024]],\n        PARAMETER[\"Latitude of natural origin\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433],\n            ID[\"EPSG\",8801]],\n        PARAMETER[\"Longitude of natural origin\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433],\n            ID[\"EPSG\",8802]],\n        PARAMETER[\"False easting\",0,\n            LENGTHUNIT[\"metre\",1],\n            ID[\"EPSG\",8806]],\n        PARAMETER[\"False northing\",0,\n            LENGTHUNIT[\"metre\",1],\n            ID[\"EPSG\",8807]]],\n    CS[Cartesian,2],\n        AXIS[\"easting (X)\",east,\n            ORDER[1],\n            LENGTHUNIT[\"metre\",1]],\n        AXIS[\"northing (Y)\",north,\n            ORDER[2],\n            LENGTHUNIT[\"metre\",1]],\n    USAGE[\n        SCOPE[\"Web mapping and visualisation.\"],\n        AREA[\"World between 85.06°S and 85.06°N.\"],\n        BBOX[-85.06,-180,85.06,180]],\n    ID[\"EPSG\",3857]]"), class = "crs"), class = c("sfc_LINESTRING", 
    "sfc"), precision = 0, bbox = structure(c(xmin = -8519668.5606, 
    ymin = 4763413.3404, xmax = -8519219.2111, ymax = 4766772.7688
    ), class = "bbox"))), row.names = c(NA, -11L), class = "data.frame", sf_column = "geometry", agr = structure(c(Shape_Leng = NA_integer_, 
    ID = NA_integer_, SegID = NA_integer_, start_lat = NA_integer_, 
    start_lon = NA_integer_, end_lat = NA_integer_, end_lon = NA_integer_
    ), class = "factor", levels = c("constant", "aggregate", "identity"
    )))