# Shiny app for cycle hire from https://github.com/geocompx/geocompr/issues/584
# Author - Kiranmayi Vadlamudi
# 2020-12-25
# Last updated: 2023-04-19 by Jakub Nowosad
library(shiny)
library(sf)
library(spData)
library(spDataLarge)
library(leaflet)
library(units)
library(dplyr)
library(stringr)
# Based on input coordinates finding the nearest bicycle points
ui = fluidPage(
# Application title
titlePanel("CycleHireApp"),
# Numeric Input from User
bootstrapPage(
div(style = "display:inline-block",
numericInput("x", ("Enter x-coordinate of your location"), value = 51.5, step = 0.001)),
div(style = "display:inline-block",
numericInput("y", ("Enter y-coordinate of your location"), value = -0.1, step = 0.001)),
div(style = "display:inline-block",
numericInput("num", "How many cycles are you looking for?", value = 1, step = 1))
),
# Where leaflet map will be rendered
fluidRow(
leafletOutput("map", height = 300)
)
)
server = function(input, output) {
#Centering the leaflet map onto London - use if needed
map_centre = matrix(c(-0.2574846, 51.4948089), nrow = 1, ncol = 2,
dimnames = list(c("r1"), c("X", "Y")))
#Based on input coords calculating top 5 closest stations to be displayed
#Making reactive object of input location coordinates
input_pt = reactive({
matrix(c(input$y, input$x), nrow = 1, ncol = 2,
dimnames = list(c("r1"), c("X", "Y")))
})
#Rendering the output map showing the input coordinates
output$map = renderLeaflet({
leaflet() |>
addTiles() |>
setView(lng = input_pt()[, "X"], input_pt()[, "Y"], zoom = 15)
})
#Finding the top distance between input coordinates and all other cycle stations, then sorting them.
data = reactive({
cycle_hire$dist = st_point(input_pt()) |>
st_sfc() |>
st_set_crs("EPSG:4326") |>
st_distance(cycle_hire$geometry) |>
t() |>
set_units("km")
cycle_hire[order(cycle_hire$dist), ]
})
#Filtering the distance data from above to show top 5 closest stations meeting requirement of # of bikes needed
filteredData = reactive({
data() |>
filter(nbikes >= input$num) |>
head(5) |>
mutate(popup = str_c(str_c("Station:", name, sep = " "),
str_c("Available bikes:", nbikes, sep = " "), sep = "<br/>"))
})
#Making changes to the output leaflet map reflecting the cycle stations found above
icons = awesomeIcons(icon = "bicycle", library = "fa",
squareMarker = TRUE, markerColor = "blue")
observe({
proxy = leafletProxy("map", data = filteredData()) |> clearMarkers()
proxy |>
clearMarkers() |>
addAwesomeMarkers(icon = icons, popup = ~popup) |>
addMarkers(lng = input_pt()[, "X"], input_pt()[, "Y"], label = "Your Location")
})
}
# Run the application
shinyApp(ui = ui, server = server)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.