Листовка R: определяет, на каком полигоне находится центр границ карты

#r #shiny #leaflet

#r #блестящий #листовка

Вопрос:

Я хотел бы автоматически определять, какой полигон находится в центре карты. И он должен обновляться динамически, когда пользователь перемещается по карте.

На данный момент я не мог найти способ обратного поиска, на каком полигоне находятся некоторые координаты.

Я думаю, что мог бы смоделировать a input$map_shape_click с помощью shinyjs или javascript и таким образом получить input $map_shape_click $ id, но прежде чем перейти к этому решению, я хотел бы убедиться, что другого пути нет.

Вот минимальный пример

 library(leaflet)
library(shiny)

# data source :  https://biogeo.ucdavis.edu/data/gadm3.6/Rsp/gadm36_FRA_2_sp.rds
cities <- readRDS(file = "../gadm36_FRA_2_sf.rds")

ui <- fluidPage(leafletOutput("map"))

server <- function(input, output, session) {
  rv <- reactiveValues()
  
  output$map <- renderLeaflet({
    leaflet() %>%
      addProviderTiles(provider = providers$CartoDB.Positron) %>%
      setView(lng = 1, lat = 45, zoom = 8) %>%
      addPolygons(data = cities,layerId = ~NAME_2,label = ~NAME_2)
  })
  
  observeEvent(input$map_bounds,{
    rv$center <- c(mean(input$map_bounds$north, input$map_bounds$south), mean(input$map_bounds$east, input$map_bounds$west))
    # how can I detect on which polygon the center is ?
  })
}
shinyApp(ui = ui, server = server)
 

Ответ №1:

   library(leaflet)
  library(shiny)
  library(sf)
  cities <- readRDS(file = "gadm36_FRA_2_sp.rds") %>%
    st_as_sf()
  ui <- fluidPage(leafletOutput("map"))
  server <- function(input, output, session) {
    rv <- reactiveValues()
    output$map <- renderLeaflet({
      leaflet() %>%
        addProviderTiles(provider = providers$CartoDB.Positron) %>%
        setView(lng = 1, lat = 45, zoom = 8) %>%
        addPolygons(data = cities, layerId = ~NAME_2, label = ~NAME_2)
    })
    observeEvent(input$map_bounds, {
      rv$center <- c(mean(input$map_bounds$north, input$map_bounds$south), mean(input$map_bounds$east,
                                                                                input$map_bounds$west))
      pnt       <- st_point(c(rv$center[2], rv$center[1]))
  
      rslt <- cities[which(st_intersects(pnt, cities, sparse = FALSE)),]$NAME_1
      print(rslt)
    })
  }
  shinyApp(ui = ui, server = server)

 

Ответ №2:

Итак, я нашел способ сделать это с помощью функции sf::st_intersects

   observeEvent(input$map_bounds,{
        rv$center <- data.frame(x = mean(c(input$map_bounds$north, input$map_bounds$south)),
                            y = mean(c(input$map_bounds$east, input$map_bounds$west)))


    res <- sf::st_as_sf(rv$center, coords=c("y","x"), crs=st_crs(cities$geometry))
    
    intersection <- as.integer(st_intersects(res, cities$geometry))
    print(if_else(is.na(intersection), '', cities$NAME_2[intersection]))
  })