multiple layers r shiny leaflet selection

multiple - r leaflet layers



Cambio de estilos al seleccionar y anular la selección de múltiples polígonos con Leaflet/Shiny (1)

La respuesta está en layerIds. No entendía cómo se aplicaban a mis polígonos y cómo se quitaban las formas, entendiendo que esto es la clave. ¡Esta podría no ser la solución más elegante, pero hace el trabajo!

En el siguiente código, la representación del mapa inicial de Ruanda tiene un layerId de rwa@data$NAME_1 , que son los nombres de la región. Puede ver esto en acción con la label también configurada como rwa@data$NAME_1 . Entonces, en la imagen de abajo, el polígono más a la izquierda se etiqueta como Iburengerazuba, su atributo en la columna NAME_1 . Este layerId establece el click$id para cualquier evento de clic que tenga en este renderizado inicial del mapa. Entonces, así como este polígono está etiquetado como Iburengerazuba, su click$id también se configurará como Iburengerazuba. Como se indica en la documentación de Leaflet Shiny , si tiene más de un polígono, este debe ser un argumento vectorizado. Si solo necesita seleccionar y deseleccionar UN polígono (por lo tanto, solo una región a la vez, en este ejemplo), podría usar una cadena layerId , como mencioné en mi pregunta (como layerId = "selected" ).

El siguiente paso es observeEvent el observeEvent para su forma de clic. Gracias a la ayuda del usuario @John Paul , descubrí cómo guardar todos los eventos de clic (haga clic en los ID específicamente en este caso) realizados en el mapa. Guardé esos en un vector reactivo, luego subconjunto mi shapefile por esos id. De clic. El código está bastante comentado, así que espero que cualquier otra persona que busque esta misma solución pueda descubrir exactamente qué está pasando.

El último bit de código (alojado en la sentencia condicional if...else ) es probablemente el más confuso. Miremos primero la parte else del código. (Nota: su clic en el mapa inicial va a desencadenar este evento porque no hay forma de que las condiciones se hayan cumplido con el primer clic). Si se hace clic en un polígono blanco, se activa la llamada addPolygons() se agrega el polígono al que se hace clic. el mapa con un estilo diferente (en este caso, es rojo). ¡Esto está trazando un polígono completamente diferente en la parte superior del objeto leafletProxy !

La clave para eliminar los polígonos en rojo hace que estos polígonos layerId un layerId diferente del renderizado del mapa inicial. Tenga en cuenta que en la imagen de arriba, el polígono blanco que recibió la etiqueta Iburengerazuba ahora está etiquetado como 3. Esto se debe a que layerId en la segunda llamada addPolygons se establece como CCA_1 OF NAME_1 . Por lo tanto, el mapa blanco de la capa inferior tiene un NAME_1 layerID y, por lo tanto, NAME_1 hacen clic en los identificadores, mientras que cualquier polígono con un clic rojo trazado encima tiene un CCA_1 layerId y, por lo tanto, CCA_1 hace clic en los identificadores.

Las sentencias if indican que si su click$id ya existe en el polígono clickedPolys , esta forma se elimina. Esto es algo confuso, así que de nuevo, podría ser útil ir a través de cada línea de código y jugar con ella para comprender realmente.

De nuevo, utilizando el ejemplo anterior, al hacer clic en el polígono layerId más a la izquierda, se agrega la layerId Id layerId Iburengerazuba al vector clickedIds$ids . Este evento de clic desencadena un segundo dibujo de mapa, trazando el polígono hecho clic encima de sí mismo en un estilo diferente y con un layerId de 3 (de la columna CCA_1 ). Queremos decir que si se hace clic dos veces en un polígono rojo ( if(click$id %in% clickedPolys@data$CCA_1) ), contará como deselección, y ese polígono debería eliminarse del mapa. Entonces, si haces clic en el polígono rojo más a la izquierda con un layerId de 3, el vector clickedIds$ids estará compuesto por Iburengerazuba y 3 . Iburengerazuba en la columna clickedPolys polígono clickedPolys corresponde a 3 en la columna CCA_1 , lo que activa la sentencia if . La llamada removeShape(layerId = click$id) significa eliminar la forma que corresponde a ese clic $ id. Entonces, en este caso, el polígono clickedPolys con CCA_1 layerId de 3.

Tenga en cuenta que cada ID de clic, tanto NAME_1 como CCA_1 se registran en su vector clickedIds$ids . Este vector está subdividiendo su shapefile de Ruanda para mapear todos los polígonos, de modo que al hacer clic en polígonos, el polígono clickedPolys se actualiza dinámicamente (¡use print llamadas de print para verificar cada bit de código si esto no tiene sentido para usted!). La eliminación de cualquier forma de doble clic no es suficiente para trazar todo correctamente . Necesita eliminar los ID de capa deseleccionados, tanto NAME_1 como CCA_1, del vector clickedIds$ids . CCA_1 layerId cada CCA_1 layerId deseleccionado con su correspondiente valor NAME_1 y NAME_1 ambos atributos del vector clickedIds$ids para que se eliminen del polígono clickedPolys .

Voila! ¡Ahora puede seleccionar y deseleccionar cualquier polígono que quiera!

library(raster) library(shiny) library(leaflet) #load shapefile rwa <- getData("GADM", country = "RWA", level = 1) shinyApp( ui = fluidPage( leafletOutput("map") ), server <- function(input, output, session){ #create empty vector to hold all click ids clickedIds <- reactiveValues(ids = vector()) #initial map output output$map <- renderLeaflet({ leaflet() %>% addTiles() %>% addPolygons(data = rwa, fillColor = "white", fillOpacity = 1, color = "black", stroke = T, weight = 1, layerId = rwa@data$NAME_1, group = "regions", label = rwa@data$NAME_1) }) #END RENDER LEAFLET observeEvent(input$map_shape_click, { #create object for clicked polygon click <- input$map_shape_click #define leaflet proxy for second regional level map proxy <- leafletProxy("map") #append all click ids in empty vector clickedIds$ids <- c(clickedIds$ids, click$id) #shapefile with all clicked polygons - original shapefile subsetted by all admin names from the click list clickedPolys <- rwa[rwa@data$NAME_1 %in% clickedIds$ids, ] #if the current click ID [from CCA_1] exists in the clicked polygon (if it has been clicked twice) if(click$id %in% clickedPolys@data$CCA_1){ #define vector that subsets NAME that matches CCA_1 click ID nameMatch <- clickedPolys@data$NAME_1[clickedPolys@data$CCA_1 == click$id] #remove the current click$id AND its name match from the clickedPolys shapefile clickedIds$ids <- clickedIds$ids[!clickedIds$ids %in% click$id] clickedIds$ids <- clickedIds$ids[!clickedIds$ids %in% nameMatch] #remove that highlighted polygon from the map proxy %>% removeShape(layerId = click$id) } else { #map highlighted polygons proxy %>% addPolygons(data = clickedPolys, fillColor = "red", fillOpacity = 1, weight = 1, color = "black", stroke = T, label = clickedPolys@data$CCA_1, layerId = clickedPolys@data$CCA_1) } #END CONDITIONAL }) #END OBSERVE EVENT }) #END SHINYAPP

Tengo problemas para cambiar los estilos de polígono al seleccionar y anular la selección de polígonos en una aplicación Leaflet Shiny en la que estoy trabajando. En mi aplicación actual, cuando haces clic en un polígono, ese polígono se resalta con un color diferente. Idealmente, quiero que el usuario pueda seleccionar y resaltar múltiples polígonos. También quiero que el usuario pueda volver a hacer clic en un único polígono resaltado para anular su selección.

Lo mejor que he podido gestionar es seleccionar varios polígonos, darles el mismo ID de grupo "seleccionado" y luego anular la selección de ese grupo completo cuando se vuelve a hacer clic en un polígono. Aquí hay algunos ejemplos / código reproducible:

library(raster) library(shiny) library(leaflet) #load shapefile rwa <- getData("GADM", country = "RWA", level = 1) shinyApp( ui = fluidPage( leafletOutput("map") ), server <- function(input, output, session){ #initial map output output$map <- renderLeaflet({ leaflet() %>% addTiles() %>% addPolygons(data = rwa, fillColor = "white", fillOpacity = 1, color = "black", stroke = T, weight = 1, layerId = rwa@data$OBJECTID, group = "regions") }) #END RENDER LEAFLET observeEvent(input$map_shape_click, { #create object for clicked polygon click <- input$map_shape_click #define leaflet proxy for second regional level map proxy <- leafletProxy("map") #subset regions shapefile by the clicked on polygons selectedReg <-rwa[rwa@data$OBJECTID == click$id,] #map clicked on polygons proxy %>% addPolygons(data = selectedReg, fillColor = "red", fillOpacity = 1, weight = 1, color = "black", stroke = T, group = "selected", # layerId = "selected") layerId = selectedReg@data$OBJECTID) #remove polygon group that are clicked twice if(click$group == "selected"){ proxy %>% clearGroup(group = "selected") } #END CONDITIONAL }) #END OBSERVE EVENT }) #END SHINYAPP

En el ejemplo anterior, cada polígono cliqueado se vuelve rojo. Si se hace clic nuevamente en un polígono rojo previamente seleccionado, cada polígono rojo se borra del mapa, dejando las representaciones de polígono blanco inicial.

Puedo lograr el efecto de selección / anulación de selección deseado cuando estoy trabajando con un solo polígono a la vez utilizando la cadena layerId "selected" (comentada en el código anterior), pero al hacerlo elimino mi capacidad para seleccionar y resaltar varios polígonos. al mismo tiempo.

¡Estoy abierto a todas las sugerencias!