A few weeks ago i discovered the great site, https://windy.com, which offers a free API to include the map in your own webpage (see https://api.windy.com).
I would like to include this map as a base layer/provider tile in a leaflet to be featured in a Shiny App.
It is possible for me to include the map however I can't get the map to interact with the R Leaflet functions such as addMarkers. Suppose I want to add some random markers to the map when clicking a button.
I have tried to different things, both of them fail to show the markers:
Attempt 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)
Attempt 2 (Including JS as Plugin)
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)
Possible Explanations
The "Hello World"-marker works (included in the js script) . However the random datapoints doesn't show.
By inspecting the HTML generated by the shiny app I see that the windy leaflet map isn't stored in the windyty id. Instead it creates the leaflet map inside the windyty div with id = "map_container".
Furthermore the "map_container" has class "leaflet-container leaflet-fade-anim" instead of the class "leaflet html-widget html-widget-output shiny-bound-output leaflet-container leaflet-fade-anim" which I think R Leaflet maps usually have. This could be the problem.
Any help would be greatly appreciated! Cheers