Closed mstrimas closed 7 years ago
Thanks for filing issue, and I want to make sure that I fully understand your question.
Are you asking if leafletProxy
can be used with the edit
module? If so, here is an example that might help. leafletProxy
with modules is slightly more complicated. We will need to use shiny::NS()
with the id provided in editModUI
("editme"
in example below).
library(shiny)
library(leaflet)
library(leaflet.extras)
library(mapedit)
library(mapview)
ui <- tagList(
editModUI("editme"),
actionButton("clear", "clear points"),
actionButton("remove", "remove draw")
)
server <- function(input, output, session) {
# to use the namespace that we gave
ns <- NS("editme")
callModule(
editMod,
"editme",
leaflet() %>% addFeatures(breweries)
)
observeEvent(
input$clear,
{
print(ns("map"))
# editMod uses "map" as the id for the map
leafletProxy(ns("map")) %>%
clearMarkers()
}
)
observeEvent(
input$remove,
{
leafletProxy(ns("map")) %>%
removeDrawToolbar()
}
)
}
shinyApp(ui,server)
If your question is more in regards to leafletProxy
+ Leaflet.draw
, then this very recent issue https://github.com/bhaskarvk/leaflet.extras/issues/96 might be helpful.
Thanks, @timelyportfolio! In hindsight my question was a bit vague, and I've edited the title to better reflect what I was actually asking. Despite the vagueness, the example you gave mostly answers what I'm looking to do. In case anyone else stumbles across this, the following slight modification allows adding and removing the editing toolbar:
library(shiny)
library(leaflet)
library(leaflet.extras)
library(mapedit)
library(mapview)
ui <- tagList(
editModUI("editor"),
actionButton("clear", "Clear Points"),
actionButton("start", "Start Drawing"),
actionButton("end", "Finish Drawing")
)
server <- function(input, output, session) {
# to use the namespace that we gave
ns <- NS("editor")
base_map <- leaflet() %>%
addTiles() %>%
addFeatures(breweries)
drawn <- callModule(editMod, "editor", base_map)
# start with drawing off
leafletProxy(ns("map")) %>%
removeDrawToolbar()
observe({print(drawn())})
observeEvent(input$clear, {
leafletProxy(ns("map")) %>%
clearMarkers()
})
observeEvent(input$start, {
leafletProxy(ns("map")) %>%
addDrawToolbar(editOptions = editToolbarOptions())
})
observeEvent(input$end, {
leafletProxy(ns("map")) %>%
removeDrawToolbar(clearFeatures = TRUE)
})
}
shinyApp(ui, server)
Great and glad you asked since I think leafletProxy in general with Shiny modules does not have enough examples. Please let us know all the great things you create and please keep asking.
Dear Matt and Kent, Sorry to post my question here as the issue is now closed and my question is not (completely) related to the original question. (Let me know if I should move this post somewhere more appropriate). I want to interactively modify a shapefile on Shiny (add and remove parts) and then save it. I've been struggling for weeks to do it but your post gave me awesome clues. Now I can do half of what I want, I can add new features on the shapefile and save it. However, I'm still struggling with removing features of the original shapefile I loaded. I would like to be able to modify my loaded shapefile by clicking on the bin icon and then on road segments to remove them and then save the new version of the road network (with the new parts added and without the ones removed). Do you know if it is possible and do you have any hint on how to do this? Here is my code. Thanks in advance!
ui <- fluidPage(
editModUI("editor"),
downloadButton("saveChanges", "Save map modifications")
)
server <- function(input, output){
roadShp <- shapefile("data/roads.shp")
roadShpCRS <- spTransform(roadShp, CRS("+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs"))
roadConvert <- st_as_sfc(roadShpCRS)
ns <- NS("editor")
base_map <- leaflet() %>%
addTiles() %>%
addPolylines(data = roadConvert)
drawn <- callModule(editMod, "editor", base_map)
leafletProxy(ns("map")) %>%
addDrawToolbar(editOptions = editToolbarOptions())
newRoads <- reactiveValues()
observe({
if(!is.null(drawn()))
isolate(
newRoads <<- drawn()
)
})
output$saveChanges <- downloadHandler(
filename = "newRoads.RData",
content = function(file) {
save(newRoads, file = file)
}
)
}
@SarahBauduin, no need to apologize and happy you are trying mapedit
. Let's see if I might be able to help.
Do you need to specifically add the drawing toolbar? The previous example only did this since Matt wanted to be able to add and remove the toolbar. If you want it always there, then the leafletProxy
part should not be necessary.
Also, leaflet
and leaflet.extras
just got massive upgrades, so I would recommend updating to their newest versions on CRAN.
Does editFeatures()
accomplish the objective, or are you trying to integrate into a larger Shiny app?
Thanks @timelyportfolio for your time!
I used the leafletProxy
part because I later added some options to only keep the line drawing tool:
leafletProxy(ns("map")) %>%
addDrawToolbar(editOptions = editToolbarOptions(),
polygonOptions = FALSE,
circleOptions = FALSE,
rectangleOptions = FALSE,
markerOptions = FALSE)
Can I add these options somewhere else without using leafletProxy
?
I installed the latest versions of leaflet
and leaflet.extras
! Thanks for the info!
The code I shared with you will be integrated into a larger Shiny app where I will, among other things, add a selectInput
to select a shapefile among severals (e.g., highways, roads, rails). Then I want the user to be able to modify the selected layer by adding or removing linear segments and then save it to use the modified layer in a model later.
I tried to reproduce this example but I couldn't figure out how to use editMap()
inside a Shiny app and then save the result in an R object.
Found my solution! I used
output$mapRoadOrigin <- renderLeaflet({
leaflet() %>%
addProviderTiles("OpenMapSurfer.Roads") %>%
addPolylines(data = roadNetwork, layerId = ~ID, color = "black", opacity = 1) %>%
addDrawToolbar(
polygonOptions = FALSE,
circleOptions = FALSE,
rectangleOptions = FALSE,
markerOptions = FALSE,
circleMarkerOptions = FALSE
)
})
# Segment selection by click
observeEvent(input$mapRoadOrigin_shape_click, {
click <- input$mapRoadOrigin_shape_click
newRoad$segmToModif <- click$id # selected segment
})
Then, I used newRoad$segmToModif
with another map in another tab to modify my road network!
Hi,
The examples given above by @timelyportfolio and @mstrimas doesn't seem to work anymore. Adding and removing markers with leafletproxy still works, but removeDrawToolbar() doesn't seem to do anything.
Also, library(leafem) is required for addFeatures() but isn't listed in the example code.
As far as I can tell, the current Shiny modules don't allow any interaction with the map beyond the editing. You essentially hard code what's displayed on the map and there doesn't seem to be a way to modify the map interactively as with a normal leaflet map via leafletProxy(). In addition, I want to be able to add and remove the editing toolbar. As it stands, I need two map interfaces, one to collect the data (using editModUI) and another to do something with it (using leafletOutput).
Here's an example of what I want to. The only difference is I want to save the edits in a reactive object.