在 Shiny 中应用传单地图边界来过滤数据
Applying leaflet map bounds to filter data, within Shiny
下面的代码旨在重现 this example 中的内容,但为 "speed" 添加了一个附加参数。但是,我的地图数据table link 坏了 - 谁能帮我找出错误?原始代码根据地图的边界更新 table,而在我的代码中更改地图缩放对我的 table 没有影响。我也无法让 "speed" 过滤器在 table 和地图上工作,这是我正在寻找的功能。任何指针将不胜感激。
library(shiny)
library(magrittr)
library(leaflet)
library(DT)
ships <-
read.csv(
"https://raw.githubusercontent.com/Appsilon/crossfilter-demo/master/app/ships.csv"
)
ui <- shinyUI(fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(width = 3,
numericInput(
"speed", label = h5("Ship's Speed"), value = 100
)),
mainPanel(tabsetPanel(
type = "tabs",
tabPanel(
"Leaflet",
leafletOutput("leafletmap", width = "350px"),
dataTableOutput("tbl")
)
))
)
))
server <- shinyServer(function(input, output) {
in_bounding_box <- function(data, lat, long, bounds, speed) {
data %>%
dplyr::filter(
lat > bounds$south &
lat < bounds$north &
long < bounds$east & long > bounds$west & ship_speed < input$speed
)
}
output$leafletmap <- renderLeaflet({
leaflet() %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI World Imagery") %>%
addCircleMarkers(
data = ships,
~ long ,
~ lat,
popup = ~ speed,
radius = 5 ,
stroke = FALSE,
fillOpacity = 0.8,
popupOptions = popupOptions(closeButton = FALSE)
)
})
data_map <- reactive({
if (is.null(input$map_bounds)) {
ships
} else {
bounds <- input$map_bounds
in_bounding_box(ships, lat, long, bounds, speed)
}
})
output$tbl <- DT::renderDataTable({
DT::datatable(
data_map(),
extensions = "Scroller",
style = "bootstrap",
class = "compact",
width = "100%",
options = list(
deferRender = TRUE,
scrollY = 300,
scroller = TRUE,
dom = 'tp'
)
)
})
})
shinyApp(ui = ui, server = server)
您正在渲染的传单地图名为leafletmap
。因此,与其引用 map_bounds
,不如尝试将其更改为 leafletmap_bounds
:
data_map <- reactive({
if (is.null(input$leafletmap_bounds)) {
ships
} else {
bounds <- input$leafletmap_bounds
in_bounding_box(ships, lat, long, bounds, speed)
}
})
同样在过滤器中,将 ship_speed
更改为 speed
。应该有希望工作。
两个小变化:
- 在您链接的示例中,
input$map_bounds
有效,因为传单输出对象称为 map
。但是,您将其重命名为leafletmap
,因此我们应该参考input$leafletmap_bounds
。
- 在
dplyr
语句中,我们应该引用speed
,而不是ship_speed
。
下面给出了工作代码,希望对您有所帮助!
library(shiny)
library(magrittr)
library(leaflet)
library(DT)
ships <-
read.csv(
"https://raw.githubusercontent.com/Appsilon/crossfilter-demo/master/app/ships.csv"
)
ui <- shinyUI(fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(width = 3,
numericInput(
"speed", label = h5("Ship's Speed"), value = 100
)),
mainPanel(tabsetPanel(
type = "tabs",
tabPanel(
"Leaflet",
leafletOutput("leafletmap", width = "350px"),
dataTableOutput("tbl")
)
))
)
))
server <- shinyServer(function(input, output) {
in_bounding_box <- function(data, lat, long, bounds, speed) {
data %>%
dplyr::filter(
lat > bounds$south &
lat < bounds$north &
long < bounds$east & long > bounds$west & speed < input$speed
)
}
output$leafletmap <- renderLeaflet({
leaflet() %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI World Imagery") %>%
addCircleMarkers(
data = ships,
~ long ,
~ lat,
popup = ~ speed,
radius = 5 ,
stroke = FALSE,
fillOpacity = 0.8,
popupOptions = popupOptions(closeButton = FALSE)
)
})
data_map <- reactive({
if (is.null(input$leafletmap_bounds)) {
ships
} else {
bounds <- input$leafletmap_bounds
in_bounding_box(ships, lat, long, bounds, speed)
}
})
output$tbl <- DT::renderDataTable({
DT::datatable(
data_map(),
extensions = "Scroller",
style = "bootstrap",
class = "compact",
width = "100%",
options = list(
deferRender = TRUE,
scrollY = 300,
scroller = TRUE,
dom = 'tp'
)
)
})
})
shinyApp(ui = ui, server = server)
下面的代码旨在重现 this example 中的内容,但为 "speed" 添加了一个附加参数。但是,我的地图数据table link 坏了 - 谁能帮我找出错误?原始代码根据地图的边界更新 table,而在我的代码中更改地图缩放对我的 table 没有影响。我也无法让 "speed" 过滤器在 table 和地图上工作,这是我正在寻找的功能。任何指针将不胜感激。
library(shiny)
library(magrittr)
library(leaflet)
library(DT)
ships <-
read.csv(
"https://raw.githubusercontent.com/Appsilon/crossfilter-demo/master/app/ships.csv"
)
ui <- shinyUI(fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(width = 3,
numericInput(
"speed", label = h5("Ship's Speed"), value = 100
)),
mainPanel(tabsetPanel(
type = "tabs",
tabPanel(
"Leaflet",
leafletOutput("leafletmap", width = "350px"),
dataTableOutput("tbl")
)
))
)
))
server <- shinyServer(function(input, output) {
in_bounding_box <- function(data, lat, long, bounds, speed) {
data %>%
dplyr::filter(
lat > bounds$south &
lat < bounds$north &
long < bounds$east & long > bounds$west & ship_speed < input$speed
)
}
output$leafletmap <- renderLeaflet({
leaflet() %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI World Imagery") %>%
addCircleMarkers(
data = ships,
~ long ,
~ lat,
popup = ~ speed,
radius = 5 ,
stroke = FALSE,
fillOpacity = 0.8,
popupOptions = popupOptions(closeButton = FALSE)
)
})
data_map <- reactive({
if (is.null(input$map_bounds)) {
ships
} else {
bounds <- input$map_bounds
in_bounding_box(ships, lat, long, bounds, speed)
}
})
output$tbl <- DT::renderDataTable({
DT::datatable(
data_map(),
extensions = "Scroller",
style = "bootstrap",
class = "compact",
width = "100%",
options = list(
deferRender = TRUE,
scrollY = 300,
scroller = TRUE,
dom = 'tp'
)
)
})
})
shinyApp(ui = ui, server = server)
您正在渲染的传单地图名为leafletmap
。因此,与其引用 map_bounds
,不如尝试将其更改为 leafletmap_bounds
:
data_map <- reactive({
if (is.null(input$leafletmap_bounds)) {
ships
} else {
bounds <- input$leafletmap_bounds
in_bounding_box(ships, lat, long, bounds, speed)
}
})
同样在过滤器中,将 ship_speed
更改为 speed
。应该有希望工作。
两个小变化:
- 在您链接的示例中,
input$map_bounds
有效,因为传单输出对象称为map
。但是,您将其重命名为leafletmap
,因此我们应该参考input$leafletmap_bounds
。 - 在
dplyr
语句中,我们应该引用speed
,而不是ship_speed
。
下面给出了工作代码,希望对您有所帮助!
library(shiny)
library(magrittr)
library(leaflet)
library(DT)
ships <-
read.csv(
"https://raw.githubusercontent.com/Appsilon/crossfilter-demo/master/app/ships.csv"
)
ui <- shinyUI(fluidPage(
titlePanel(""),
sidebarLayout(
sidebarPanel(width = 3,
numericInput(
"speed", label = h5("Ship's Speed"), value = 100
)),
mainPanel(tabsetPanel(
type = "tabs",
tabPanel(
"Leaflet",
leafletOutput("leafletmap", width = "350px"),
dataTableOutput("tbl")
)
))
)
))
server <- shinyServer(function(input, output) {
in_bounding_box <- function(data, lat, long, bounds, speed) {
data %>%
dplyr::filter(
lat > bounds$south &
lat < bounds$north &
long < bounds$east & long > bounds$west & speed < input$speed
)
}
output$leafletmap <- renderLeaflet({
leaflet() %>%
addProviderTiles("Esri.WorldImagery", group = "ESRI World Imagery") %>%
addCircleMarkers(
data = ships,
~ long ,
~ lat,
popup = ~ speed,
radius = 5 ,
stroke = FALSE,
fillOpacity = 0.8,
popupOptions = popupOptions(closeButton = FALSE)
)
})
data_map <- reactive({
if (is.null(input$leafletmap_bounds)) {
ships
} else {
bounds <- input$leafletmap_bounds
in_bounding_box(ships, lat, long, bounds, speed)
}
})
output$tbl <- DT::renderDataTable({
DT::datatable(
data_map(),
extensions = "Scroller",
style = "bootstrap",
class = "compact",
width = "100%",
options = list(
deferRender = TRUE,
scrollY = 300,
scroller = TRUE,
dom = 'tp'
)
)
})
})
shinyApp(ui = ui, server = server)