R Leaflet Offline Map Tiles Not Loading
You were almost there. You can run the server in daemon
mode, with servr::httd(port = 8000, daemon = TRUE)
:
# Set the working folder
setwd("C:/Users/OTAD USER/Documents")
# Load the tiles in working_folder/mapTiles/OSM/
library(RgoogleMaps)
for (zoom in 10:16)
GetMapTiles("Washington Square Park;NY", zoom = zoom,
nTiles = round(c(20,20)/(17-zoom)))
# Start serving working folder on port 8000 in demon mode
deamon_id <- servr::httd(port = 8000, daemon = TRUE)
# Plot with leaflet
library(leaflet)
m = leaflet() %>%
addTiles( urlTemplate = "http:/localhost:8000/mapTiles/OSM/{z}_{x}_{y}.png")
m = m %>% leaflet::setView(-73.99733, 40.73082 , zoom = 16)
m = m %>% leaflet::addMarkers(-73.99733, 40.73082 )
m
# Stop serving
servr::daemon_stop(deamon_id)
Shiny leaflet map tiles not appearing
Your application is working fine. I tried two different mapbox tokens and they are both working. Try this:
accessToken = 'your_token_from_your_mapbox_account')) %>%
R: Using addResourcePath for rendering local leaflet tiles
In my case, I create my own tiles via gdal2tiles
, which takes your data and automatically creates a {z}/{x}/{y}.png folder structure. Please see this link for a nice tutorial and what i mean about the file structure;
+---14
| +---8185
| +---5460.png
| +---5461.png
| +---etc.png
| \---8186
# I use the following server (see how my addTiles has a folder structure)
server <- function(input, output,session) {
addResourcePath("mytiles", "C:/.../tiles")
output$tilemap <- renderLeaflet({
leaflet() %>%
setView(lng = -4.4, lat = 52, zoom = 12) %>%
addTiles(urlTemplate = "mytiles/{z}/{x}/{y}.png")
})
}
Now, as you are downloading tiles from Google Maps to your hard drive, you'll want a slightly different approach as the files are downloaded in a {z}_{x}_{y}.png
format, and not produced into a file structure like gdal creates;
+---11_1098_671.png
etc.
so you need to adjust your addTiles
code to reflect this, using underscores, like the Google filenames;
server <- function(input, output,session) {
addResourcePath("mytiles", "C:/.../OSM")
output$tilemap <- renderLeaflet({
leaflet() %>%
setView(lng = 13.194773, lat = 52.431635, zoom = 11) %>%
addTiles(urlTemplate = "mytiles/{z}_{x}_{y}.png")
})
}
Lastly, my setView arguments are in a different order to yours but i'm not sure whether that makes a difference or not.
R Shiny & Leaflet, Create a shiny filter that can iterate through a list within a dataframe column
What about using a logical vector as an index instead of filter
? See the code below where sapply
is used to create a logical vector of the rows that match the input$PointUseInput
value.
library(shiny)
library(shinydashboard)
library(leaflet)
##The Data
Point_ID = c("A1", "B1", "C3")
Latitude = c(38.05, 39.08, 40.05)
Longitude = c(-107.00, -107.05, -108.00)
PointUse = I(list("farm", c("farm", "house"), "house")) # <- the column with the list entries
Map_DF <- data.frame(Point_ID, Latitude, Longitude, PointUse)
choiseList <- c("farm", "house")
#############################################
# UI
ui <- dashboardPage(
dashboardHeader(),
dashboardSidebar(checkboxGroupInput(inputId = "PointUseInput", label = "Select Point Use", choices = choiseList, selected = choiseList)),
dashboardBody(fluidRow(leafletOutput(outputId = 'mapA')))
)
#############################################
# SERVER
server <- function(input, output, session) {
## The Filter
filter_df <- reactive({
Map_DF[sapply(Map_DF$PointUse, function(p) {any(input$PointUseInput %in% p)}), ]
})
## Base Map Creation
output$mapA <- renderLeaflet({
leaflet() %>%
addProviderTiles(
providers$Esri.DeLorme,
options = providerTileOptions(
updateWhenZooming = FALSE,
updateWhenIdle = TRUE)
) %>%
setView(lng = -107.50, lat = 39.00, zoom = 7)
})
## Update Map with Filter Selection
observe({
leafletProxy("mapA", session) %>%
clearMarkers() %>%
addCircleMarkers(
data = filter_df(),
radius = 10,
color = "red",
lat = ~Latitude,
lng = ~Longitude,
popupOptions(autoPan = FALSE),
popup = ~paste("PointUse: ", filter_df()$PointUse))
})
}
############################################
shinyApp(ui = ui, server = server)
Prevent user from moving beyond boundaries R Leaflet
You can achieve this with setMaxBounds()
leaflet() %>%
addProviderTiles(providers$Esri.WorldGrayCanvas,
options = providerTileOptions(
minZoom = 4,
bounds = list(
c(-7.275292, 57.04102),
c(-43.45292, 221.1328)
)
)
) %>%
setView(134.4727, -25.87899, zoom = 4) %>%
setMaxBounds(57.04102, -7.275292, 221.1328, -43.45292)
Prevent flyTo within a leaflet in shiny from refreshing map
You answered the question yourself in your last sentence. The map will always be redrawn whenever the reactive All_NMEA
changes. To prevent that, you would normally use leafletProxy
but apparently you cannot add an easyButton
like that, so I offer you another solution.
A click on the easyButton
will trigger another shiny input that is called my_easy_button
. In an observeEvent
you listen to this event and do the flyTo
there within a leafletProxy
.
library(shiny)
library(leaflet)
map_data <- data.frame(lat = c(36.05, 36.25), lon = c(-132.13, -132.33))
ui <- fluidPage(
titlePanel("Map"),
mainPanel(tags$style(type = "text/css", "#map {height: calc(100vh - 80px) !important;}"),
leafletOutput("map"))
)
server <- function(input, output, session) {
All_NMEA <- shiny::reactivePoll(
intervalMillis = 5000,
session = session,
checkFunc = Sys.time,
valueFunc = function() {
NMEA_out <- data.frame(lat = runif(1, 0, 20),
long = runif(1, 0, 20))
leafletProxy("map", session = session) %>%
addCircleMarkers(
lng = NMEA_out$long,
lat = NMEA_out$lat,
radius = 1,
fillOpacity = 1, color = "red"
)
return(NMEA_out)
}
)
observe({All_NMEA()})
output$map <- renderLeaflet({
map <- leaflet(map_data) %>%
addProviderTiles(providers$Esri.OceanBasemap, group = "ocean basemap (default)") %>%
addTiles(group = "Basic") %>%
addLayersControl(
baseGroups = c("ocean basemap (default)", "Basic"),
options = layersControlOptions(collapsed = FALSE)) %>%
addEasyButton(
easyButton(id = "buttonid",
icon = "fa-crosshairs", title = "Locate Vessel",
onClick = JS("function(btn, map) {
Shiny.onInputChange('my_easy_button', 'clicked', {priority: 'event'});
}")
))
})
observeEvent(input$my_easy_button, {
print("easyButton is clicked")
allnmea <- req(All_NMEA())
leafletProxy("map", session = session) %>%
flyTo(lng = allnmea$long, lat = allnmea$lat, zoom = 5)
})
}
shinyApp(ui = ui, server = server)
Related Topics
Cannot Install Rgdal Package in R on Rhel6, Unable to Load Shared Object Rgdal.So
Is There a General Inverse of The Table() Function
Line Spacing for Wrapped Text in Ggplot
Shiny Sliderinput from Max to Min
How to Round Percentage to 2 Decimal Places in Ggplot2
Extract Names of Deeply Nested Lists
Shiny Slider Customized Values
How to Convert a Data Frame of Integer64 Values to Be a Matrix
Creating Categorical Variables from Mutually Exclusive Dummy Variables
R: How to Expand a Row Containing a "List" to Several Rows...One for Each List Member
Create New Variable by Multiple Conditions via Mutate Case_When
Use Different Font Sizes for Different Portions of Text in Ggplot2 Title
Is There an Equivalent in Ggplot to The Varwidth Option in Plot
How to Use Different Font Sizes in Ggplot Facet Wrap Labels
Split Violin Plot with Ggplot2 with Quantiles
Strange Behaviour Dropping Column from Data.Frame in R
Creating a Table with Individual Trials from a Frequency Table in R (Inverse of Table Function)