0

I want to develop a shiny app where users can draw a polygon on a raster image. As soon as the user finishes drawing a polygon, I want the app to show them a table of chosen pixels.

For example, terra provides a function draw that can be used as draw("polygon"). But, I cannot make it work with my shiny app.

The basic idea of the app is as follows (I have commented the problematic parts with #):

library(terra)
library(shiny)

r = rast(system.file("ex/elev.tif", package="terra"))

ui = fluidPage(
        plotOutput("map"),
        tableOutput("chosen_pixels")
)

server = function(input, output, session) {
        output$map = renderPlot({
                plot(r)
                # draw("polygon") # I comment it otherwise the app does not run
        })
        
        # output$chosen_pixels = renderPlot({
                # here I want to write code that shows a table of chosen pixels
        #})
}

shinyApp(ui, server)
bird
  • 2,938
  • 1
  • 6
  • 27

1 Answers1

2
library(shiny)
library(tidyverse)

ui <- basicPage(
  plotOutput("plot1", click = "plot_click"),
  tableOutput("table"),
  textInput("polygon_name", label = "Polygon name", value = "polygon 1")
)

server <- function(input, output) {
  coords <- reactiveVal(value = tibble(x = numeric(), y = numeric(), name = character()))

  observeEvent(input$plot_click, {
    add_row(coords(),
      x = isolate(input$plot_click$x),
      y = isolate(input$plot_click$y),
      name = isolate(input$polygon_name)
    ) %>% coords()
  })

  output$plot1 <- renderPlot({
    plot(r)
    
    coords() %>%
      nest(-name) %>%
      deframe() %>%
      map(~ polygon(.x$x, .x$y))
  })

  output$table <- renderTable(coords())
}

shinyApp(ui, server)

enter image description here

danlooo
  • 10,067
  • 2
  • 8
  • 22
  • This is a very nice approach! At the moment I cannot escape the drawn polygon. Is there a way to "refresh" it so that the user can start making new polygons somewhere else? – bird Nov 09 '21 at 09:09
  • @bird I added a new input to name the polygon. A new polygon will be created whenever the name changes. – danlooo Nov 09 '21 at 09:37
  • Thanks for this solution. `isolate()` is not needed. `nest(cols = -name)` avoids a warning. – SamGG Jul 30 '22 at 09:40
  • Works great, neat solution, thnx – Ronin scholar Aug 02 '22 at 06:57