只有在Shiny中缩放超过阈值时才渲染leaflet地图。

huangapple go评论113阅读模式
英文:

Only render leaflet map when zoom passes a threshold in Shiny

问题

在Shiny应用程序中,我已经构建了一个Leaflet地图,根据缩放级别的不同显示不同的图层。

我使用了leafletProxyobserveEvent以及Leaflet的input$MAPID_zoom来构建这个地图。

server <- shinyServer(function(input, output, session) {
  
  output$map <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      mapOptions(zoomToLimits="first") %>%
      setView(lat = 47.218637, lng = -1.554136, zoom = 7)
  })
  
  observeEvent(
    eventExpr = input$map_zoom, {
      map_proxy <- leafletProxy(mapId = "map", session = session)
      
        if(input$map_zoom < 8){
          map_proxy %>%
            clearMarkers() %>%
            addMarkers(
              data = df, lng = ~lng, lat = ~lat
            )
        } else {
          map_proxy %>%
            clearMarkers() %>%
            addMarkers(
              data = df_2, lng = ~lng, lat = ~lat
            )
        }
      
    }
  )
})

然而,这会在缩放级别变化时重新渲染Leaflet地图。我希望地图只在if语句中的阈值被超过时才重新渲染。有什么方法可以解决这个问题?

UI和数据的代码如下:

library(shiny)
library(leaflet)

df <- data.frame(
  location_name = c('S1', 'S2'),
  lng = c(-1.554136,  -2.10401),
  lat = c(47.218637, 47.218637), 
  stringsAsFactors = FALSE
)

df_2 <- data.frame(
  location_name = c('S3', 'S4'),
  lng = c(-1.654136,  -2.2401),
  lat = c(47.218637, 47.218637), 
  stringsAsFactors = FALSE
)

ui <- shinyUI(
  fluidPage(
    leafletOutput(outputId = 'map')
  )
)
英文:

I have built a leaflet map in a Shiny application that shows different layers depending on what zoom you have.

I have built this combining leafletProxy with observeEvent and leaflet's input$MAPID_zoom.

server &lt;- shinyServer(function(input, output, session) {
  
  output$map &lt;- renderLeaflet({
    leaflet() |&gt; 
      addTiles() |&gt; 
      mapOptions(zoomToLimits=&quot;first&quot;) |&gt; 
      setView(lat = 47.218637, lng = -1.554136, zoom = 7)
  })
  
  observeEvent(
    eventExpr = input$map_zoom, {
      map_proxy &lt;- leafletProxy(mapId = &quot;map&quot;, session = session)
      
        if(input$map_zoom &lt; 8){
          map_proxy |&gt; 
            clearMarkers() |&gt; 
        addMarkers(
          data = df, lng = ~lng, lat = ~lat
        )
        } else {
          map_proxy |&gt; 
            clearMarkers() |&gt; 
          addMarkers(
            data = df_2, lng = ~lng, lat = ~lat
          )
        }
      
    }
  )
})

However, this rerenders the leaflet map every time the zoom changes. I would like the map to only render when the threshold in the if-statement is surpassed. What would be a way to approach this?

Code for UI and data:

library(shiny)
library(leaflet)

df &lt;- data.frame(
  location_name = c(&#39;S1&#39;, &#39;S2&#39;),
  lng = c(-1.554136,  -2.10401),
  lat = c(47.218637, 47.218637), 
  stringsAsFactors = FALSE
)

df_2 &lt;- data.frame(
  location_name = c(&#39;S3&#39;, &#39;S4&#39;),
  lng = c(-1.654136,  -2.2401),
  lat = c(47.218637, 47.218637), 
  stringsAsFactors = FALSE
)

ui &lt;- shinyUI(
  fluidPage(
    leafletOutput(outputId = &#39;map&#39;)
  )
)

答案1

得分: 1

我无法重现你的问题,但这里有一个解决方案。
你需要创建两个图层并调整可见性。

server <- shinyServer(function(input, output, session) {
  
  output$map <- renderLeaflet({
    leaflet() %>%
      addTiles() %>%
      mapOptions(zoomToLimits="first") %>%
      setView(lat = 47.218637, lng = -1.554136, zoom = 7) %>%
      addMarkers(
        data = df, lng = ~lng, lat = ~lat, group = "S1S2"
      ) %>%
      addMarkers(
        data = df_2, lng = ~lng, lat = ~lat, group="S3S4")
  })
  
  observeEvent(
    eventExpr = input$map_zoom, {
      map_proxy <- leafletProxy(mapId = "map", session = session)
      
      if(input$map_zoom < 8){
        map_proxy %>%
          showGroup("S1S2") %>%
          hideGroup("S3S4")
      } else {
        map_proxy %>%
          showGroup("S3S4") %>%
          hideGroup("S1S2")
      }
      
    }
  )
})

在这里,每个图层都有不同的组ID,根据缩放级别,我们隐藏或显示相应的组。

英文:

I can't reproduce your problem but here is a solution.
You have to create both layers and play with visibility.

server &lt;- shinyServer(function(input, output, session) {
  
  output$map &lt;- renderLeaflet({
    leaflet() |&gt; 
      addTiles() |&gt; 
      mapOptions(zoomToLimits=&quot;first&quot;) |&gt; 
      setView(lat = 47.218637, lng = -1.554136, zoom = 7) |&gt;
      addMarkers(
        data = df, lng = ~lng, lat = ~lat, group = &quot;S1S2&quot;
      ) |&gt; 
      addMarkers(
        data = df_2, lng = ~lng, lat = ~lat, group=&quot;S3S4&quot;)
  })
  
  observeEvent(
    eventExpr = input$map_zoom, {
      map_proxy &lt;- leafletProxy(mapId = &quot;map&quot;, session = session)
      
      if(input$map_zoom &lt; 8){
        map_proxy |&gt; 
          showGroup(&quot;S1S2&quot;) |&gt;
          hideGroup(&quot;S3S4&quot;)
      } else {
        map_proxy |&gt; 
          showGroup(&quot;S3S4&quot;) |&gt;
          hideGroup(&quot;S1S2&quot;)
      }
      
    }
  )
})

Here each layer gets a different group id and depending of the zoom level we hide or show corresponding group.

huangapple
  • 本文由 发表于 2023年6月26日 17:44:53
  • 转载请务必保留本文链接:https://go.coder-hub.com/76555480.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定