在Shiny中使用Leaflet绘制多个多边形

5
我是一个Shiny应用程序的开发者,正在尝试使用leaflet包绘制多边形。以下是我希望得到的非应用程序输出:
data <- list(
    beam1 = data.frame(lat = c(-115,-125, -125, -115),
               lon = c(32, 32, 45,45)),
    beam2 =     data.frame(lat = c(-100, -111, -111, -100),
                           lon = c(42, 42, 50,50))
)
dataTemp <- do.call(rbind, lapply(data, function(x) rbind(x, NA)))

library(leaflet)
m = leaflet() %>% addTiles()
m %>%
    addPolygons(
        dataTemp[,"lat"],
        dataTemp[,"lon"],
        color = c('red', 'green'), weight = 3
    )

然而,将其制作成Shiny应用程序却很困难——多边形被绘制后,一旦绘制新的多边形,它们就会逐个消失。以下是我使用的代码。您需要单击“Draw”才能绘制多边形。 请注意: 1-当绘制绿色多边形(3秒后)时,红色多边形消失了 2-这里的多边形是三角形,而上面的代码中它们是矩形。 3-如果您查看下面server.R中的代码,我实际上不得不翻转'lat'和'lon'列才能得到正确的图片。 ui.R:
library(shiny)
library(leaflet)

shinyUI(navbarPage("Beams", id="nav",

    tabPanel("Interactive map",
            div(class="outer",

                leafletMap("map", "100%", 650,
                           options = list(center = c(37.45, -93.85), zoom = 4)),
                actionButton("drawPoints", "Draw")
            )
    )
))

server.R:

library(shiny)
library(leaflet)

data <- list(
    beam1 = data.frame(lat = c(-115,-125, -125, -115),
                       lon = c(32, 32, 45,45)),
    beam2 =     data.frame(lat = c(-100, -111, -111, -100),
                           lon = c(42, 42, 50,50))
)

# server activity
shinyServer(function(input, output, session) {

    map <- createLeafletMap(session, "map")

    observe({

            if(input$drawPoints == 0) {
                return(NULL)
            } else {

                map$clearShapes()

                for (i in seq_along(data)) {
                    map$addPolygon(
                        data[[i]][,"lon"],  # - notice, i had to change lat and lon
                        data[[i]][,"lat"],
                        layerId=c("1"),
                        list( fillOpacity=0.4),
                        list(color = c('red','green')[i])

                    )
                    Sys.sleep(3)  # - this is to see first (red) polygon
                }
            }
        })


})

任何想法都将不胜感激!


我是偶然来到这里的...所以对这个话题不是很专业。作为shiny的用户,我可以说你的做法并不符合我的期望...我建议你使用renderLeaflet命令来生成输出。我找到了一篇文章,可能对你有用:http://www.r-bloggers.com/the-leaflet-package-for-online-mapping-in-r/。 - Picarus
你还在寻找答案吗?如果你仍然感兴趣并且还没有找到解决方案,我可能有一个答案。 - ndimhypervol
@ndimhypervol 即使 OP 没有特别在寻找,你的回答也可能对其他人有帮助。 - Dean MacGregor
1个回答

2
我已经更新了您的代码,使用了leaflet代理,这是一种更干净的方式来更新现有的地图,并且是在leaflet包的持续更新中目前维护的方法(据我所知)。我将数据框中的“lat”和“lon”交换以使它们正确。我还在您的坐标末尾再次添加了原点以完成形状——这就是为什么您有三角形而不是矩形的原因。最后,我将多边形的layerId更改为i,使它们不同——这就是它们互相擦除的原因。
我假设您希望将形状硬编码,但是有方法可以向用户打开多边形绘图选择(甚至是绘制)的方式。有趣的是:在解决此问题时,我了解了leafletProxy中的deferUntilFlush参数——如果不将其设置为FALSE,则两个形状只有在Sys.sleep完成计数后才会绘制。 ui.R
library(shiny)
library(leaflet)

shinyUI(navbarPage("Beams", id="nav",

                   tabPanel("Interactive map",
                            div(class="outer",
                                leafletOutput("map", "100%", 650),
                                actionButton("drawPoints", "Draw")
                            )
                   )
))

server.R

library(shiny)
library(leaflet)

data <- list(
  beam1 = data.frame(lon = c(-115,-125, -125, -115, -115),
                     lat = c(32, 32, 45, 45, 32)),
  beam2 =     data.frame(lon = c(-100, -111, -111, -100, -100),
                         lat = c(42, 42, 50, 50, 42))
)

shinyServer(function(input, output, session) {

  map <- leaflet() %>% addTiles() %>% setView(-93.85, 37.45, zoom = 4)
  output$map <- renderLeaflet(map)
  proxy <- leafletProxy("map", deferUntilFlush = FALSE)

  observeEvent(input$drawPoints, {
    proxy %>% clearShapes()
    for (i in seq_along(data)) {
      proxy %>% addPolygons(
        data[[i]][,"lon"],
        data[[i]][,"lat"],
        layerId=i,
        opacity=0.4,
        color = c('red','green')[i]
      )
      Sys.sleep(2)  # - this is to see first (red) polygon
    }
  })
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接