Aplicação Shiny para mapas

Estou trabalhando em uma aplicação Shiny para geração de mapas. O objetivo desta aplicação é gerar mapas utilizando a função mapview. Consegui construir uma estrutura reativa cujo output é uma variável do tipo ‘character’. Porém, não estou conseguindo utilizar esse valor output como parâmetro para a geração do mapa através de um renderMapview De uma forma simplificada, vou apresentar aqui dois códigos R (utilizando dados do pacote {geobr}) que podem ajudar a ilustrar o meu desafio.

#################################################################################

Código 01 → este código gera como saída o texto selecionado no menu.

library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(geobr)

ui ← dashboardPage(

dashboardHeader(

title = "Estados do Brasil",
titleWidth = 200

),
dashboardSidebar(sidebarMenuOutput(“menu”)
),
dashboardBody(
tabsetPanel(
id = “tabs”,
tabPanel(
title = “Unidades da Federacao”,
radioGroupButtons(
inputId = “UF”,
label = “UF”,
choices = c(“all”, sort(c(“RS”, “MT”, “MS”, “SC”, “RR”, “AL”, “RJ”, “MG”, “GO”, “BA”, “PR”, “TO”, “SP”, “PE”, “RN”, “PB”, “ES”, “SE”, “PI”, “RO”, “CE”, “MA”, “PA”, “DF”, “AM”, “AC”, “AP”))),
selected = “all”,
status = “primary”,
justified = TRUE
),

    fluidRow(
      column(12,
             verbatimTextOutput(outputId = "estado")
             
      )
    )
  )
)

)
)

server ← function(input, output, session) {

  output$estado <- renderPrint({input$UF})

output$menu ← renderMenu({
sidebarMenu()
})

}

shinyApp(ui, server)

#################################################################################

Código 02 → este código gera como saída o texto selecionado no menu.

library(shiny)
library(shinydashboard)
library(shinyWidgets)
library(mapview)
library(geobr)

ui ← dashboardPage(

dashboardHeader(

title = "Estados do Brasil",
titleWidth = 200

),
dashboardSidebar(sidebarMenuOutput(“menu”)
),
dashboardBody(
tabsetPanel(
id = “tabs”,
tabPanel(
title = “Unidades da Federacao”,
radioGroupButtons(
inputId = “UF”,
label = “UF”,
choices = c(“all”, sort(c(“RS”, “MT”, “MS”, “SC”, “RR”, “AL”, “RJ”, “MG”, “GO”, “BA”, “PR”, “TO”, “SP”, “PE”, “RN”, “PB”, “ES”, “SE”, “PI”, “RO”, “CE”, “MA”, “PA”, “DF”, “AM”, “AC”, “AP”))),
selected = “all”,
status = “primary”,
justified = TRUE
),

    fluidRow(
      column(12,
             mapviewOutput("estado", height = "1000px")
             
      )
    )
  )
)

)
)

server ← function(input, output, session) {

#Geracao de mapa a partir da UF selecionada. Ex.: UF = “RS”

output$estado ← renderMapview({
mapview(read_state(code_state = “RS”, year = 2020), col.regions = “orange”, layer.name = “RS”)
})

output$menu ← renderMenu({
sidebarMenu()
})

}

shinyApp(ui, server)

#################################################################################

Minha dúvida é como construir uma estrutura reativa capaz de gerar mapas a partir de dados de entrada selecionados no menu. Tentei construir estruturas mais simplificadas utilizando reactive (), observe () ou observeEvent (). Porém elas apresentaram mensagens de erro ao executar cada um dos códigos.

Oi Marcelo,

Você deve ter tido vários problemas de reatividade nos seus testes e nenhum deu certo. Pelo o que pesquisei a biblioteca {mapview} está com problemas mesmo. Veja aqui: r - mapview for shiny - Stack Overflow

Consegui fazer uma adaptação no código abaixo. Uma dica: carregue a geometria dos estados antes de gerar o mapa. O ideal seria já ter isso até salvo como um arquivo rda que seria lido na inicialização do app.

library(shiny)
library(geobr)
library(leaflet)
library(mapview)

# Carrega os todos os estados brasileiros
states <- read_state()

ui <- fluidPage(

    titlePanel("Teste mapa"),

    sidebarLayout(
        sidebarPanel(
            selectInput(inputId = "uf", label = "UF", choices = c("RJ", "SP", "ES", "MG"))
        ),

        mainPanel(
           leafletOutput("mapa")
        )
    )
)


server <- function(input, output) {
    
    output$mapa <- renderLeaflet({
        req(input$uf)
        
        # Filtra o estado selecionado
        geo <- subset(states, abbrev_state == input$uf, layer.name = input$uf)
        
        # Cria o objeto do mapview
        m <- mapview(geo, col.regions = "orange")
        
        # Recupera o mapa gerado para ser renderizado pelo leaflet
        m@map
    })
}


shinyApp(ui = ui, server = server)

Abraços!

Obrigado por sua resposta @raphaelsaldanha ! De fato, tive dificuldades para a construção de estruturas de reatividade utilizando somente a biblioteca {mapview}. Quanto à sua dica para carregar as geometrias dos estados antes de gerar o mapa, eu empreguei essa estratégia em meu código original (por simplificação, utilizei a base de dados do {geobr}) salvando-as como arquivos rda , pois foram geradas camadas contendo pontos, regiões e trajetórias.

Perfeito! Uma outra dica, dê uma olhada na biblioteca {ttmap}. Ela está mais atualizada.