几周前,我发现了很棒的网站https://windy.com,它提供了一个免费的 API,可以将地图包含在您自己的网页中(请参阅https://api.windy.com)。
我想将此地图作为基础层/提供者图块包含在传单中,以在 Shiny 应用程序中展示。
我可以包含地图,但是我无法让地图与 R Leaflet 函数(例如 addMarkers)进行交互。假设我想在单击按钮时向地图添加一些随机标记。
我尝试了不同的东西,它们都没有显示标记:
尝试 1
library(shiny)
library(leaflet)
ui <- fluidPage(
# Load leaflet.js
tags$head(HTML("<script src='https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js'></script> ")),
# Either Use the two following lines or..
tags$head(HTML("<style type='text/css'>
#windyty { height: 800px; width: 1000px;
margin-left: auto; margin-right: auto;
position: relative;
margin-top: 50px; }
</style>")),
leafletOutput("windyty", height = "800px"),
# .. the two following lines
# tags$div(id = "windyty", style = "height: 500px; width: 1000px;
# margin-left: auto; margin-right: auto;
# position: relative;
# margin-top: 50px;"),
#htmlOutput("<div id='windyty'></div>"),
# Setup Windy.Com API
tags$head(tags$script(
"
var windytyInit = {
// Required: API key
key: 'PsL-At-XpsPTZexBwUkO7Mx5I',
// Optional: Initial state of the map
lat: 50.4,
lon: 14.3,
zoom: 5,
}
// Required: Windyty main function is called after
// initialization of API
//
// @map is instance of Leaflet maps
//
function windytyMain(map) {
var popup = L.popup()
.setLatLng([50.4, 14.3])
.setContent('Hello World')
.openOn( map );
}
"
)),
# Load map by running the following js script. It creates a Leaflet Map inside windyty div with id = "map_container"
tags$head(HTML("<script async defer src='https://api.windytv.com/v2.3/boot.js'></script> ")),
p(),
actionButton("recalc", "New points")
)
server <- function(input, output, session) {
# Create Random Data Point
points <- eventReactive(input$recalc, {
cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
}, ignoreNULL = FALSE)
# When recalc is clicked add markers to map - Doesn't work :-/
observeEvent(input$recalc,{
leafletProxy("map_container") %>% #windyty doesn't work either!
addMarkers(data = points())
})
}
shinyApp(ui, server)
尝试 2(包括 JS 作为插件)
library(shiny)
library(leaflet)
library(htmltools)
library(htmlwidgets)
ui <- fluidPage(
tags$head(HTML("<style type='text/css'>
#windyty { height: 800px; width: 1000px;
margin-left: auto; margin-right: auto;
position: relative;
margin-top: 50px; }
</style>")),
tags$head(HTML("<script src='https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/leaflet.js'></script> ")),
leafletOutput("windyty", height = "800px"),
# tags$div(id = "windyty", style = "height: 500px; width: 1000px;
# margin-left: auto; margin-right: auto;
# position: relative;
# margin-top: 50px;"),
#htmlOutput("<div id='windyty'></div>"),
tags$head(tags$script(
"
var windytyInit = {
// Required: API key
key: 'PsL-At-XpsPTZexBwUkO7Mx5I',
// Optional: Initial state of the map
lat: 50.4,
lon: 14.3,
zoom: 5,
}
// Required: Windyty main function is called after
// initialization of API
//
// @map is instance of Leaflet maps
//
function windytyMain(map) {
var popup = L.popup()
.setLatLng([50.4, 14.3])
.setContent('Hello World')
.openOn( map );
}
"
)),
p(),
actionButton("recalc", "New points")
)
WindyPlugin <- htmlDependency("leaflet.windy", "2.3",
src = c(href = "https://api.windytv.com/v2.3/"),
script = "boot.js"
)
registerPlugin <- function(map, plugin) {
map$dependencies <- c(map$dependencies, list(plugin))
map
}
server <- function(input, output, session) {
# Create Random Data Point
points <- eventReactive(input$recalc, {
cbind(rnorm(40) * 2 + 13, rnorm(40) + 48)
}, ignoreNULL = FALSE)
# When recalc is clicked add markers to map - Doesn't work :-/
observeEvent(input$recalc,{
leafletProxy("map_container") %>% #windyty
addMarkers(data = points())
})
# Render Leaflet and Activate Windy.Com Plugin!
output$windyty <- renderLeaflet({
leaflet() %>%
registerPlugin(WindyPlugin)
})
}
shinyApp(ui, server)
可能的解释
“Hello World”标记有效(包含在 js 脚本中)。但是随机数据点没有显示。通过检查由闪亮的应用程序生成的 HTML,我发现风传单地图未存储在风的 id 中。相反,它会在 id = "map_container" 的 windyty div 内创建传单地图。
此外,“map_container”具有类“leaflet-container leaflet-fade-anim”而不是类“leaflet html-widget html-widget-output shiny-bound-output Leaflet-container Leaflet-fade-anim”我认为地图通常有。这可能是问题所在。
任何帮助将不胜感激!干杯