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)
})
}
)
Related
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)
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)
Leaflet provides an option, when setting up your map, to hide the zoom controls
leaflet(options = leafletOptions(zoomControl = FALSE)
However, I would like to call this option after having already created a map so that a user can download the map without the zoom controls and without me having to re-create a different version of the map from scratch.
Here's a simple version of my app at the moment:
library(shiny)
library(tidyverse)
library(leaflet)
library(mapview)
ui <- fluidPage(
fluidPage(
leafletOutput(outputId = "map"),
downloadButton(outputId = "save")
)
)
server <- function(input, output, session) {
map <- reactive({
leaflet() %>%
addTiles()
})
output$map <- renderLeaflet({
map()
})
output$save <- downloadHandler(
filename = "map.jpeg",
content = function(file){
latRng <- range(input$map_bounds$north,
input$map_bounds$south)
lngRng <- range(input$map_bounds$east,
input$map_bounds$west)
map() %>%
setView(lng = (lngRng[1] + lngRng[2])/2,
lat = (latRng[1] + latRng[1])/2,
zoom = input$map_zoom) %>%
### HERE ###
mapshot(file = file)
}
)
}
shinyApp(ui, server)
I'd like to be able to add a line of code where I've commented ### HERE ### that would turn off zoom controls. In my actual code the displayed map is really complex with lots of options and I wouldn't want to have all that code twice just for the sake of removing zoom controls in the initial call to leaflet().
Thanks
You can do it like so:
library(shiny)
library(tidyverse)
library(leaflet)
library(mapview)
ui <- fluidPage(
fluidPage(
leafletOutput(outputId = "map"),
downloadButton(outputId = "save")
)
)
server <- function(input, output, session) {
map <- reactive({
leaflet() %>%
addTiles()
})
output$map <- renderLeaflet({
map()
})
output$save <- downloadHandler(
filename = "map.jpeg",
content = function(file){
latRng <- range(input$map_bounds$north,
input$map_bounds$south)
lngRng <- range(input$map_bounds$east,
input$map_bounds$west)
m = map() %>%
setView(lng = (lngRng[1] + lngRng[2])/2,
lat = (latRng[1] + latRng[1])/2,
zoom = input$map_zoom)
m$x$options = append(m$x$options, list("zoomControl" = FALSE))
mapshot(m, file = file)
}
)
}
shinyApp(ui, server)
which is updating the leaflet options after map creation. I will incorporate this in the mapshot function to optionally remove the zoomControl.
Using a Easybutton, I created a button in a Shiny-Leaflet environment, which zooms and pans the map to the user's geolocated position. An working example:
library(shiny)
library(leaflet)
ui <- fluidPage(leafletOutput("map"))
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() %>%
addProviderTiles(providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)) %>%
addEasyButton(
easyButton(
position = "topleft",
icon = "fa-crosshairs",
title = "Locate Me",
onClick = JS(
c(
"function(btn, map){map.locate({setView:true,enableHighAccuracy: true })}"
)
)
)
)
})
}
shinyApp(ui,server)
This works fine. However, I want to capture the lat/long of the user's geolocated position into a input variable. This functionality exists for a mouse click on the map, in which case the lat/long of the clicked position is stored in 'input$map_click'. Does anyone have an idea?
As a starting point you could observe the map bounds changing, and return the centre of the bounds
library(shiny)
library(leaflet)
ui <- fluidPage(leafletOutput("map"))
server <- function(input, output, session) {
output$map <- renderLeaflet({
leaflet() %>%
addProviderTiles(providers$Stamen.TonerLite,
options = providerTileOptions(noWrap = TRUE)) %>%
addEasyButton(
easyButton(
position = "topleft",
icon = "fa-crosshairs",
title = "Locate Me",
onClick = JS(
c(
"function(btn, map){map.locate({setView:true,enableHighAccuracy: true })}"
)
)
)
)
})
observeEvent(input$map_bounds, {
event <- input$map_bounds
lat <- mean(event$north, event$south)
lon <- mean(event$west, event$east)
print(paste0("map center - lat: ", lat, ", lon: ", lon))
})
}
shinyApp(ui,server)
However, you'll get the coordinates everytime the map is panned. You could maybe work this into being observed only when the button is pressed, although at the moment I'm not sure how to do that.
I found another opportunity myself, by following these procedures and adding JavaScript logic.
http://www.r-graph-gallery.com/2017/03/14/4-tricks-for-working-with-r-leaflet-and-shiny/
Is it possible to get the lat long from a click event in leaflet/shiny (in R) from the tile map? (i.e. NOT from any loaded markers, polygons etc). Just to show positional (lat/long) info i guess.
I thought maybe from this qu it was possible but no luck.
ui <- bootstrapPage(
tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
leafletOutput("map", width = "100%", height = "100%")
)
server <- function(input, output,session) {
output$map <- renderLeaflet({
leaflet() %>%
addProviderTiles("CartoDB.Positron")%>%
setView(lng = -4, lat= 52.54, zoom = 7)
})
#Show popup on click
observeEvent(input$map_marker_click, {
click <- input$map_marker_click
text<-paste("Lattitude ", click$lat, "Longtitude ", click$lng)
proxy <- leafletProxy("map")
proxy %>% clearPopups() %>%
addPopups(click$lng, click$lat, text)
})
}
runApp(shinyApp(ui, server), launch.browser = TRUE)
Ultimately i want to create a click marker for raster data (using the returned lat/long) in Leaflet & Shiny but this would be a good start (This qu seems to have done something but i cannot recreate it at all).