Nothing
ui <- bslib::page_navbar(
title = "QuadKey Visualizer App",
bg = "#ffffff",
theme = bslib::bs_theme(
version = 5,
bootswatch = "simplex",
base_font = bslib::font_google("Raleway",
wght = "400"),
heading_font = bslib::font_google("Raleway",
wght = "200")
),
bslib::nav_panel(
title = 'Quadkey',
bslib::layout_sidebar(
class = 'p-0',
sidebar = bslib::sidebar(
width = 300,
shiny::textInput('qk',
'Visualising a QuadKey',
placeholder = "complete and click search"),
shiny::actionButton('search', 'Search'),
shiny::hr(),
DT::DTOutput('qkvalues')
),
leaflet::leafletOutput('mapqk')
)
),
bslib::nav_panel(
title = 'Creating a QuadKey grid',
bslib::layout_sidebar(
class = 'p-0',
sidebar = bslib::sidebar(
shiny::p(paste(
"Write the bounding box",
"coordinates in decimal degrees"
)),
bslib::layout_columns(
shiny::textInput('xmin', 'xmin'),
shiny::textInput('ymin', 'ymin')
),
bslib::layout_columns(
shiny::textInput('xmax', 'xmax'),
shiny::textInput('ymax', 'ymax')
),
shiny::sliderInput(
'zoom',
'Select the zoom level:',
min = 1,
max = 23,
value = 6
),
shiny::actionButton('grid',
'Create Grid'),
shiny::hr(),
textOutput("qk_nr"),
shiny::hr(),
shiny::p(
paste(
"Note that for higher zoom levels,",
"it is preferable to use smaller areas",
" (< 2000 QuadKeys)",
"to prevent long processing times."
)
)
),
leaflet::leafletOutput('mapgrid')
)
)
)
server <- function(input, output, session) {
# TAB 1: QuadKey
# Get the QuadKey Coordinates
qk_results <- shiny::eventReactive(input$search,
ignoreNULL = FALSE, {
shiny::validate(shiny::need(
input$qk,
paste("Please, insert a QuadKey",
"and press 'Search'")
))
tile <- quadkeyr::quadkey_to_tileXY(as.character(input$qk))
pixel <- quadkeyr::tileXY_to_pixelXY(tileX = tile$tileX,
tileY = tile$tileY)
coords <- quadkeyr::pixelXY_to_latlong(
pixelX = pixel$pixelX,
pixelY = pixel$pixelY,
zoom = tile$zoom
)
return(
list(
tileX = tile$tileX ,
tileY = tile$tileY,
zoom = tile$zoom,
pixelX = pixel$pixelX,
pixelY = pixel$pixelY,
lat = coords$lat,
lon = coords$lon
)
)
})
# Data table with QuadKey Info
output$qkvalues <- DT::renderDT({
dataqk <- t(data.frame(
c('TileX',
qk_results()$tileX),
c('TileY',
qk_results()$tileY),
c('Zoom Level',
qk_results()$zoom),
c('PixelX',
qk_results()$pixelX),
c('PixelY',
qk_results()$pixelY),
c('Latitude',
qk_results()$lat),
c('Longitude',
qk_results()$lon)
))
DT::datatable(
dataqk,
rownames = FALSE,
# remove table interactive default options
options = list(ordering = FALSE,
dom = 't'),
colnames = rep("", ncol(dataqk))
)
})
qk_polygon <- shiny::eventReactive(input$search,
ignoreNULL = FALSE, {
shiny::validate(shiny::need(
input$qk,
paste("Please, introduce a",
"QuadKey press 'Search'")
))
quadkeyr::quadkey_to_polygon(as.character(input$qk))
})
# Quadkey location map
output$mapqk <- leaflet::renderLeaflet({
# get polygon bounding box
bbx <- sf::st_bbox(qk_polygon())
# Map tab 1, QuadKey polygon and upper-left corner coordinate
leaflet::leaflet() |>
leaflet::addTiles() |>
leaflet::addMeasure(primaryLengthUnit = "kilometers",
secondaryLengthUnit = "kilometers") |>
leaflet::addPolygons(
data = qk_polygon(),
group = 'polygon',
layerId = ~ quadkey,
# https://rstudio.github.io/leaflet/showhide.html
color = "red",
fillColor = NA,
label = ~ as.character(input$qk)
) |>
leaflet::addMarkers(
data = qk_results(),
lat = ~ lat,
lng = ~ lon,
~ paste(qk_results()$lat,
qk_results()$lon),
label = ~ as.character(input$qk)
) |>
leaflet::fitBounds(
lng1 = bbx$xmin[[1]],
lat1 = bbx$ymin[[1]],
lng2 = bbx$xmax[[1]],
lat2 = bbx$ymax[[1]]
)
})
# TAB 2: Grid
grid_selected <- shiny::eventReactive(input$grid,
ignoreNULL = FALSE, {
# Warning to the user:
# all the fields should be complete
shiny::validate(
shiny::need(
input$xmin != '' &&
input$ymin != '' &&
input$xmax != '' &&
input$ymax != '',
paste("Please, complete",
"the fields and press 'Search'")
)
)
griduser <-
quadkeyr::create_qk_grid(
xmin = as.numeric(input$xmin),
xmax = as.numeric(input$xmax),
ymin = as.numeric(input$ymin),
ymax = as.numeric(input$ymax),
zoom = as.numeric(input$zoom)
)
griduser$data
})
output$qk_nr <- renderText({
paste("Number of QuadKeys in the grid:", nrow(grid_selected()))
})
polygrid <- reactive({
# Inform the user about potential high running times
if (nrow(grid_selected()) > 2000) {
shiny::showNotification(
duration = NULL,
paste(
"The grid you want to create has",
"more than 2000 polygons",
"and could take considerable time",
"to run"
),
type = "message"
)
}
grid_coords <- quadkeyr::get_qk_coord(data = grid_selected())
polygrid <- quadkeyr::grid_to_polygon(grid_coords)
polygrid
})
# QuadKey grid map
output$mapgrid <- leaflet::renderLeaflet({
shiny::req(polygrid())
leaflet::leaflet() |>
leaflet::addMeasure(primaryLengthUnit = "kilometers",
secondaryLengthUnit = "kilometers") |>
leaflet::addTiles() |>
leaflet::addPolygons(
data = polygrid(),
color = 'red',
layerId = ~ as.character(quadkey),
group = 'qks',
popup = ~ quadkey
)
})
}
shiny::shinyApp(ui = ui, server = server)
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.