Mapping with Leaflet - r

I am new to shiny and trying to do some mapping with leaflet.I already have the map layers though in qgs format.How can I use these qgis layers and make custom tiles(layers) for interactive mapping? Guidance on converting the qgis layers into leaflet mapping format would be appreciated.
Here is an image of the layers in QGIS:
Map Layers in QGIS

You can add layers by using e.g. addWMSTiles. Here's a workable example below which add QGIS layer to interactive leaflet Shiny app.
library(shiny)
library(leaflet)
library(leaflet.extras)
ui <- fluidPage(
leafletOutput("mymap")
)
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
leaflet(
options = leafletOptions(
center = c(-33.95293, 20.82824),
zoom = 14,
minZoom = 5,
maxZoom = 18,
maxBounds = list(
c(-33.91444, 20.75351),
c(-33.98731, 20.90626)
)
)
) %>%
addWMSTiles(
baseUrl = paste0(
"http://maps.kartoza.com/web/?",
"map=/web/Boosmansbos/Boosmansbos.qgs"
),
layers = "Boosmansbos",
options = WMSTileOptions(format = "image/png", transparent = TRUE),
attribution = paste0(
"(c)Kartoza.com and ",
"SA-NGI"
)
) %>%
addWMSLegend(
uri = paste0(
"http://maps.kartoza.com/web/?",
"map=/web/Boosmansbos/Boosmansbos.qgs&&SERVICE=WMS&VERSION=1.3.0",
"&SLD_VERSION=1.1.0&REQUEST=GetLegendGraphic&FORMAT=image/jpeg&LAYER=Boosmansbos&STYLE="
)
)
})
}
shinyApp(ui, server)

Related

Update plotly data (chloropleth) in R shiny without re-rendering entire map

I am trying to use shiny controls to modify the data underlying a plotly chloropleth map.
Whenever I change the data the entire plot re-renders, which is quite slow. I'm guessing the bottleneck is redrawing the geojson polygons. Because the geojson never changes, I'm wondering if there is a way to keep the rendered widget intact but modify the z values only.
It looks like using plotlyProxy and plotlyProxyInvoke might be the right direction, but I can only see examples of an entire trace (which includes the geojson data) being replaced.
Sorry if I'm missing something or have been unclear - I have not used plotly very much, and even less so the js side of things.
See below for example code:
library(shiny)
library(dplyr)
library(plotly)
library(readr)
library(rjson)
zip_geojson <- fromJSON(file="https://raw.githubusercontent.com/hms1/testData/main/zip3_2.json")
plot_data <- read_csv(file="https://raw.githubusercontent.com/hms1/testData/main/plot_data.csv")
mapboxToken <- "pk.eyJ1IjoiaG1vcmdhbnN0ZXdhcnQiLCJhIjoiY2tmaTg5NDljMDBwbDMwcDd2OHV6cnd5dCJ9.8eLR4FtlO079Gq0NeSNoeg" #burner token
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("multip",
"n:",
min = 1,
max = 10,
value = 1)
),
mainPanel(
plotlyOutput("cPlot")
)
)
)
server <- function(input, output) {
output$cPlot <- renderPlotly({
plot_data_i <- plot_data%>%
mutate(log_count = case_when(log_count <= input$multip ~ log_count * input$multip,
TRUE ~ log_count))
plot_ly() %>%
add_trace(
type = "choroplethmapbox",
geojson = zip_geojson,
locations = plot_data_i$zip,
z = plot_data_i$log_count
) %>%
layout(
mapbox = list(
style = "light",
zoom = 3,
center = list(lon = -95.7129, lat = 37.0902)
)
) %>%
config(mapboxAccessToken = mapboxToken)
})
}
shinyApp(ui = ui, server = server)
For anyone else who comes across this post later, I found a solution.
It turns out that you can change data using the restyle method in plotlyProxyInvoke, as shown below.
library(shiny)
library(dplyr)
library(plotly)
library(readr)
library(rjson)
zip_geojson <- fromJSON(file="https://raw.githubusercontent.com/hms1/testData/main/zip3_2.json")
plot_data <- read_csv(file="https://raw.githubusercontent.com/hms1/testData/main/plot_data.csv")
mapboxToken <- "pk.eyJ1IjoiaG1vcmdhbnN0ZXdhcnQiLCJhIjoiY2tmaTg5NDljMDBwbDMwcDd2OHV6cnd5dCJ9.8eLR4FtlO079Gq0NeSNoeg"
ui <- fluidPage(
sidebarLayout(
sidebarPanel(
sliderInput("multip",
"n:",
min = 1,
max = 10,
value = 1),
actionButton("Remove", "Remove Trace")
),
mainPanel(
plotlyOutput("cPlot")
)
)
)
server <- function(input, output, session) {
output$cPlot <- renderPlotly({
plot_ly(type = "choroplethmapbox", geojson = zip_geojson) %>%
layout(
mapbox = list(
style = "light",
zoom = 3,
center = list(lon = -95.7129, lat = 37.0902)
)
) %>%
config(mapboxAccessToken = mapboxToken)
})
plotproxy <- plotlyProxy("cPlot", session, deferUntilFlush = FALSE)
observeEvent(input$multip, {
plot_data_i <- plot_data %>%
mutate(log_count = case_when(log_count <= input$multip ~ log_count * input$multip,
TRUE ~ log_count))
plotproxy %>%
plotlyProxyInvoke("restyle", list(z = list(plot_data_i$log_count),
locations = list(plot_data_i$zip)))
})
}
shinyApp(ui = ui, server = server)

get circle id from leaflet in shiny for later use

I am quite new to shiny, and I am facing a difficulty. I want to have a map with interactive circles. When clicked, these circles will allow me to make a query to a SQL database to get the corresponding data and so make plots.
I don't manage to get the circles info into a variable, although I am able to print it to the shiny ui.
Here is the example code:
library(shiny)
library(leaflet)
ui <- fluidPage(
leafletOutput("mymap"),
verbatimTextOutput("marker")
)
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
leaflet(data = mapStates, options = leafletOptions(minZoom = 3, maxZoom = 18)) %>%
addTiles() %>%
addProviderTiles(providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE))%>%
addCircleMarkers(data = data.frame(lat = 51, lng = 13,STANAME = "somewhere",STAID = "1" ), lng = ~lng, lat = ~lat,radius = 1, color = "red", fill = "red", popup = ~STANAME,layerId = ~STAID)
})
# here the circle info
output$marker <- renderPrint(input$mymap_marker_click)
}
shinyApp(ui, server)
but I don't manage to get the id of the marker into a variable in the server function. I tried:
input$mymap_marker_click$id
But it tells me that I need a reactive context. If I do:
renderPrint(input$mymap_marker_click)$id
Error : object of type 'closure' is not subsettable
I can't use the output in the server side, but I need this variable in the server side to do the query and the plots.
I should I proceed ?
Thank you for your help.
In Shiny you need to create an observer to "listen" for the click event (or any event/change to input) and perform a certain response.
Removing the map tiles, bc I don't know where mapStates comes from but the idea is identical.
library(shiny)
library(leaflet)
ui <- fluidPage(
leafletOutput("mymap"),
verbatimTextOutput("marker")
)
server <- function(input, output, session) {
output$mymap <- renderLeaflet({
leaflet(options = leafletOptions(minZoom = 3, maxZoom = 18)) %>%
addCircleMarkers(data = data.frame(lat = 51, lng = 13,STANAME = "somewhere",STAID = "1" ), lng = ~lng, lat = ~lat,radius = 1, color = "red", fill = "red", popup = ~STANAME,layerId = ~STAID)
})
# needs to be in a observer to "listen" for events
observeEvent(input$mymap_marker_click, {
output$marker <- renderPrint(input$mymap_marker_click$id)
})
}
shinyApp(ui, server)
Live demo

R - Leaflet WMTS layer is not rendering

I'm working on adding a WMTS layer to my R Leaflet map using this url:
https://mrdata.usgs.gov/mapcache/wmts?layer=alteration&service=WMTS&request=GetCapabilities&version=1.0.0
I add the url into my code under the "addWMSTiles" option in R Leaflet like such:
library(shiny)
library(leaflet)
ui <- shinyUI(
fluidPage(
leafletOutput("map", width = "100%", height = "900px")
)
)
server <- function(input, output) {
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
setView(-93.65, 42.0285, zoom = 4) %>%
addWMSTiles("https://mrdata.usgs.gov/mapcache/wmts?layer=alteration&service=WMTS&request=GetCapabilities&version=1.0.0",
layers = "sim3340",
options = WMSTileOptions(format = "image/png", transparent = TRUE),
attribution = "")
})
}
app <- shinyApp(ui = ui, server = server)
runApp(app, launch.browser = TRUE)
When I run this code the map will display in the browser but all that displays is the base leaflet (OpenStreets) Map (image below).
When there should be some coloring around CA and AZ since that's that WMTS layer is highlighting.
At first I thought it may be due to there being 3 different projection matrices in the WMTS layer but even if I call crs = "EPSG:6.3:3857" in the addWMSTiles options it still shows up as the base map.
What do I need to change or add to make this WMTS layer show up on the map?
Thank you and as always any help is appreciated!
This should do it. The call to your baseUrl was not correct.
library(shiny)
library(leaflet)
ui <- shinyUI(
fluidPage(
leafletOutput("map", width = "100%", height = "900px")
)
)
server <- function(input, output) {
output$map <- renderLeaflet({
leaflet() %>%
addTiles() %>%
setView(-93.65, 42.0285, zoom = 4) %>%
addWMSTiles(baseUrl = "https://mrdata.usgs.gov/mapcache/wms/",
layers = "sim3340",
options = WMSTileOptions(format = "image/png", transparent = TRUE),
attribution = "")
})
}
app <- shinyApp(ui = ui, server = server)
runApp(app, launch.browser = TRUE)

R Leaflet Offline Tiles within Shiny

Is it possible to load offline/local leaflet map tiles within a Shiny app? I am able to load the tiles in an interactive R session as shown here, but I now want to try and load them for use in a Shiny app. Here's an example of what I have so far. I'm thinking it has something to do with Shiny running through an IP and port and needing to load the tiles through an IP and port as well. I've tried a few things to change IPs and ports (making them the same) as explained here but haven't figured out anything that works. I can also get it to work using online tiles, but I need it to work with local map tiles.
library(shiny)
library(leaflet)
library(RColorBrewer)
library(RgoogleMaps)
options(shiny.port = 8000)
(bwi <- getGeoCode("BWI;MD"))
df <- as.data.frame(rbind(bwi))
df$col <- c("orange")
df$name <- c("BWI")
icons <- awesomeIcons(
icon = 'ios-close',
iconColor = 'black',
library = 'ion',
markerColor = df$col
)
#################################################################################
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%"),
absolutePanel(top = 10, right = 10,
style = "padding: 8px; background: #FFFFEE; opacity:.9",
checkboxInput("markers", "Show Markers?", TRUE)
)
)
#################################################################################
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() %>%
addTiles(urlTemplate = "http:/localhost:8000/C:/Users/OTAD USER/Documents/mapTiles/ESRIWorldTopoMap/{z}_{x}_{y}.png") %>%
setView(lat = bwi[1], lng = bwi[2], zoom = 8)
})
observe({
proxy <- leafletProxy("map", data = df)
# Remove/show any markers
proxy %>% clearMarkers()
if (input$markers) {
proxy %>% addAwesomeMarkers(lat = df$lat, lng = df$lon,
icon = icons, label = df$name)
}
})
}
#Put the ui and server together and run
runApp(shinyApp(ui = ui,
server = server), launch.browser=TRUE
)
1- You have to authorize shiny to serve tiles in that folder by providing an "alias" on the ressource with addResourcePath
2- then use that alias as the base URL in addTiles
server <- function(input, output, session) {
addResourcePath("mytiles", "C:/Users/OTAD USER/Documents/mapTiles/ESRIWorldTopoMap")
output$map <- renderLeaflet({
leaflet() %>%
addTiles(urlTemplate = "/mytiles/{z}_{x}_{y}.png") %>%
setView(lat = bwi[1], lng = bwi[2], zoom = 8)
})
...

Leaflet Coordinate Control in R

I'm working with Leaflet in RStudio. Now, I would like to capture the mouseclick and get its coordinates on a map. Something like this.
Do you know how to adapt that code for leaflet in R?
If you want to add the Shiny library you can use input$map_click, where map is the name of your map.:
library(shiny)
library(leaflet)
shinyApp(
ui = fluidPage(
leafletMap(
"map", "100%", 400,
initialTileLayer = "//{s}.tiles.mapbox.com/v3/jcheng.map-5ebohr46/{z}/{x}/{y}.png",
initialTileLayerAttribution = HTML('Maps by Mapbox'),
options=list(
center = c(37.45, -93.85),
zoom = 4,
maxBounds = list(list(17, -180), list(59, 180))))),
server = function(input, output, session){
map = createLeafletMap(session, 'map')
observe({
click<-input$map_click
if(is.null(click))
return()
text<-paste("Lattitude ", click$lat, "Longtitude ", click$lng)
map$showPopup( click$lat, click$lng, text)
})
}
)

Resources