R Leaflet Offline Tiles Within Shiny

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



Leave a reply



Submit