【问题标题】:How to add a text on a leaflet map?如何在传单地图上添加文字?
【发布时间】:2019-03-06 07:18:20
【问题描述】:

每天我都需要在地图上绘制一条路径并添加一个文本,例如 4、5 或 8 分钟。表示从起点到目的地的车程(见下图)。我认为在 R 中使用 Leaflet 创建一个闪亮的应用程序会很有帮助(代码如下所示)。

我使用 leaflet.extras 包中的 addDrawToolbar 来绘制路径,如所附地图所示。但我不知道也找不到如何以与绘制路径相同的方式添加文本。解决方案不一定必须在 R 中。我的目标是为那些想做这些事情但同时不知道如何编码的人创建一个应用程序。

library(shiny)
library(leaflet)
library(leaflet.extras)


ui = fluidPage(
      tags$style(type = "text/css", "#map {height: calc(100vh - 20px) 
      !important;}"),
      leafletOutput("map")
      )

server = function(input,output,session){
             output$map = renderLeaflet(
                 leaflet()%>%

         addTiles(urlTemplate = "http://mt0.google.com/vt/lyrs=m&hl=en&x= 
              {x}&y={y}&z={z}&s=Ga")%>%

         addMeasure(
              primaryLengthUnit = "kilometers",
              secondaryAreaUnit = FALSE
         )%>%

         addDrawToolbar(
              targetGroup='draw',

              editOptions = editToolbarOptions(selectedPathOptions = 
                    selectedPathOptions()),

              polylineOptions = filterNULL(list(shapeOptions = 
                    drawShapeOptions(lineJoin = "round", weight = 8))),

              circleOptions = filterNULL(list(shapeOptions = 
                    drawShapeOptions(),
                    repeatMode = F,
                    showRadius = T,
                    metric = T,
                    feet = F,
                    nautic = F))) %>%
        setView(lat = 45, lng = 9, zoom = 3) %>%
        addStyleEditor(position = "bottomleft", 
                 openOnLeafletDraw = TRUE)
 )
}

 shinyApp(ui,server)

【问题讨论】:

  • 您是否考虑过使用弹出窗口:rstudio.github.io/leaflet/popups.html?您可以使用 HTML 设置文本样式并使用纬度/经度指定位置,...
  • 我已经考虑了您的建议。非常感谢,但正如问题中所解释的,此应用程序将由非编码人员使用,并且使用弹出窗口将文本放置在传单地图上需要事先对其进行编码。
  • 你能创建一个用户输入的文本框并使用它来填充弹出窗口吗?
  • 您还需要纬度和经度数据才能使用弹出窗口或 addLabelOnlyMarkers(这是另一个选项),而不仅仅是文本。我的意思是为那些想以最少的努力做到这一点的人,为那些不想关心纬度和经度值的人实现这样的应用程序。

标签: r shiny leaflet r-leaflet


【解决方案1】:

这样做的一种方法是提示用户在双击传单地图时添加文本。双击坐标处理放置文本的位置,弹出提示处理文本应该说的内容。

library(shiny)
library(leaflet)
library(leaflet.extras)

server = function(input,output,session){

  # Create reactive boolean value that indicates a double-click on the leaflet widget
  react_list <- reactiveValues(doubleClick = FALSE, lastClick = NA)
  observeEvent(input$map_click$.nonce, {
    react_list$doubleClick <- identical(react_list$lastClick, input$map_click[1:2])
    react_list$lastClick   <- input$map_click[1:2]
  })

  # Upon double-click, create pop-up prompt allowing user to enter text
  observeEvent(input$map_click[1:2], {
    if (react_list$doubleClick) {
      shinyWidgets::inputSweetAlert(session, "addText", title = "Add text:")
    }
  })

  # Upon entering the text, place the text on leaflet widget at the location of the double-click
  observeEvent(input$addText, {
    leafletProxy("map") %>% 
      addLabelOnlyMarkers(
        input$map_click$lng, input$map_click$lat, label = input$addText, 
        labelOptions = labelOptions(noHide = TRUE, direction = "right", textOnly = TRUE,
                                    textsize = "15px"))
  })

  # Clear out all text if user clears all layers via the toolbar
  observeEvent(input$map_draw_deletestop, {
    if ( length(input$map_draw_all_features$features) < 1 ) {
      leafletProxy("map") %>% clearMarkers()
    }
  })

  output$map <- renderLeaflet({
    leaflet(options = leafletOptions(doubleClickZoom = FALSE)) %>%
      addProviderTiles(providers$CartoDB.Positron) %>% 
      addMeasure(
        primaryLengthUnit = "kilometers",
        secondaryAreaUnit = FALSE) %>%
      addDrawToolbar(
        targetGroup     ='draw',
        editOptions     = editToolbarOptions(selectedPathOptions = selectedPathOptions()),
        polylineOptions = filterNULL(list(shapeOptions = drawShapeOptions(lineJoin = "round", weight = 8))),
        circleOptions   = filterNULL(list(shapeOptions = drawShapeOptions(), repeatMode = F, showRadius = T,
                                          metric = T, feet = F, nautic = F))) %>%
      setView(lng = -73.97721, lat = 40.7640, zoom = 15)
  })
}

shinyApp(ui = fluidPage( leafletOutput("map") ) , server)

【讨论】:

  • 我正在查看您的解决方案,想知道以“# Clear out all text if user clear all layers via the toolbar”开头的位是否输入正确。我的意思是在“input$mapp_draw_all_features$features”中:mapp 还是 map?
  • 非常感谢您的回答。如果无论您作为用户是否通过工具栏清除所有图层,我们都可以删除和更新文本,那不是很好吗?我一直想知道您对此是否有任何建议。
  • 是的,有办法。这是针对这个特定问题的最简单的解决方案。至于删除文本,您可能希望保留已添加到地图中的所有文本的反应列表(就像leaflet.extrasinput$map_draw_all_features 所做的那样)。您可以将此列表显示为带有DT 的表格。观察点击一行的时间(input$tableId_cell_clicked),然后用leaflet::removeMarker从小部件中删除相应的文本。
  • 我问了另一个与此相关的问题:stackoverflow.com/questions/53650039/…。不久,我想将带有绘制的形状、线条和添加的文本的地图保存为 pdf。也许,你可以给我一个提示。
猜你喜欢
  • 1970-01-01
  • 2017-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2015-02-11
  • 1970-01-01
相关资源
最近更新 更多