如何使用leaflet在R闪亮的小地图中添加点?

问题描述 投票:0回答:1

我已经创建了闪亮的应用程序,您正在寻找一个地方,并向您显示数据表和地图中的点。它在地图主体中有效,但在小地图中则不然。我希望这些点也能出现在小地图中。这是所有应用程序及其库的代码。

library(shiny)
library(leaflet)
library(leaflet.extras)
library(shinyjs)
library(tidyverse)

leafletMiniMapDependencies <- function() {
  list(
    htmltools::htmlDependency(
      "leaflet-minimap",
      "3.3.1",
      "htmlwidgets/plugins/Leaflet-MiniMap",
      package = "leaflet",
      script = c("Control.MiniMap.min.js", "Minimap-binding.js"),
      stylesheet = c("Control.MiniMap.min.css")
    )
  )
}

addMiniMap <- function(
  map,
  position = "bottomleft",
  width = 300,
  height = 225,
  collapsedWidth = 19,
  collapsedHeight = 19,
  zoomLevelOffset = -5,
  zoomLevelFixed = 6,
  centerFixed = c(28, -15.5),
  zoomAnimation = FALSE,
  toggleDisplay = T,
  autoToggleDisplay = FALSE,
  minimized = FALSE,
  aimingRectOptions = list(color = "rgba(0,0,0,0)", weight = 1, clickable = FALSE),
  shadowRectOptions = list(color = "#000000", weight = 1, clickable = FALSE,
                           opacity = 0, fillOpacity = 0),
  strings = list(hideText = "Hide MiniMap", showText = "Show MiniMap"),
  tiles = NULL,
  mapOptions = list(minZoom = 6, maxZoom = 6)
) {
  
  # determin tiles to use
  tilesURL <- NULL
  tilesProvider <- NULL
  if (!is.null(tiles)) {
    if (tiles %in% providers) {
      map$dependencies <- c(map$dependencies, leafletProviderDependencies())
      tilesProvider <- tiles
    } else {
      tilesURL <- tiles
    }
  }
  
  map$dependencies <- c(map$dependencies, leafletMiniMapDependencies())
  invokeMethod(
    map
    , getMapData(map)
    , "addMiniMap"
    , tilesURL
    , tilesProvider
    , position
    , width
    , height
    , collapsedWidth
    , collapsedHeight
    , zoomLevelOffset
    , zoomLevelFixed
    , centerFixed
    , zoomAnimation
    , toggleDisplay
    , autoToggleDisplay
    , minimized
    , aimingRectOptions
    , shadowRectOptions
    , strings
    , mapOptions
  )
}

topologia <- data.frame(
  etiqueta = c("El Hierro", "Fuerteventura", "Gran Canaria",  "La Palma", "Lanzarote", "Tenerife"),
  longitud = c(-18.038165, -14.004885, -15.606239, -17.857377, -13.636218, -16.621481),
  latitud = c(27.743606, 28.400363, 27.958157, 28.655223, 29.039468, 28.293378),
  geocode = c("ES703", "ES704", "ES705", "ES707", "ES708", "ES709"),
  valor = 1:6
)

topologia <-  topologia %>% 
  mutate(
    longitud = as.numeric(gsub("\\.", "", longitud)) / 10^6,
    latitud = as.numeric(gsub("\\.", "", latitud)) / 10^6
  )

# Define UI for application
ui <- fluidPage(
  tags$head(
    tags$style(HTML("
      body{
      .leaflet-control-search{
        position: absolute !important;
        left: 50% !important;
        transform: translateX(-50%) !important;
        margin-left: 0 !important;
      }

      .leaflet-top.leaflet-left{
        width: 100%;
      }
      "))
    
  ),
  
  useShinyjs(),
  titlePanel("Mapa"),
  sidebarPanel(
    selectInput("provincia_seleccionada", "Provincia", choices = unique(topologia$etiqueta)), 
    actionButton("consultar", "Consulta")
  ),
  column(width = 12, leafletOutput("map", height = "600px")),
  column(width = 12, dataTableOutput("data"))
)

# Define server logic
server <- function(input, output, session) {
  
  # processing with click of consultar data
  topologia_consulta <- eventReactive(input$consultar, {
    topologia %>% filter(etiqueta %in% input$provincia_seleccionada) %>% 
      filter(!is.na(latitud) & !is.na(longitud))
  })
  
  # show data in datatable
  output$data <- renderDataTable(topologia_consulta())
  
  
  # Render the map
  output$map <- renderLeaflet({
    leaflet() %>%
      leaflet(options = leafletOptions(minZoom = 5)) %>%
      addTiles(options = tileOptions(updateWhenIdle = TRUE, updateWhenZooming = FALSE)) %>%
      addFullscreenControl() %>%
      addProviderTiles(providers$OpenStreetMap) %>%
      setView(lat = 40.416775, lng = -3.703790, zoom = 6) %>%
      addMiniMap() %>%
      addEasyButton(easyButton(
        icon = "fa-crosshairs", title = "Locate Me",
        onClick = JS("function(btn, map){ map.locate({setView: true}); }")
      )) %>%
      # addSearchOSM(options = searchOptions(collapsed = FALSE, autoCollapse = TRUE, minLength = 2)) %>%
      leaflet.extras::addSearchOSM(options = searchOptions(collapsed = F)) %>%
      addEasyButton(easyButton(states = list(
        easyButtonState(
          stateName = "Canarias",
          icon = '<strong>Ir a Islas Canarias</strong>',
          title = "Ir a Islas Canarias",
          onClick = JS("
          function(btn, map) {
            map.flyTo(L.latLng(28, -15.5), 7);
            btn.state('Peninsula');
          }")
        ),
        easyButtonState(
          stateName = "Peninsula",
          icon = '<strong>Ir a Península</strong>',
          title = "Ir a Península",
          onClick = JS("
          function(btn, map) {
            map.flyTo(L.latLng(40.416775, -3.703790), 6);
            btn.state('Canarias');
          }")
        )), id = 'botonCanarias', position = 'bottomleft')) %>% 
      
      htmlwidgets::onRender(paste0("
        function(el, t) {
          var myMap = this;
          
       $('#searchtext25').attr('placeholder', 'Buscar localización...');

          $('#searchtext25').on('input', function(){
            if($(this).val() === '')
              $(\"path.leaflet-interactive[stroke='#3388ff'][stroke-linecap='round']\").hide();
          });

          $('#map ul.search-tooltip').on('mouseup', 'li', function(){
            $(\"path.leaflet-interactive[stroke='#3388ff'][stroke-linecap='round']\").show();
          });

          $('#map a.search-cancel').on('click', function(){
            $(\"path.leaflet-interactive[stroke='#3388ff'][stroke-linecap='round']\").hide();
          });
          
        }")) %>% 
      addLayersControl(
        overlayGroups = c("Pintar"),
        options = layersControlOptions(collapsed = TRUE)
      )
    
    
  })
  
 # When click in consultar bottom show the map 
  observeEvent(input$consultar, {
    mapProxy <- leafletProxy("map")
    mapProxy %>%
      clearGroup("Pintar") %>% 
    addAwesomeMarkers(data = topologia_consulta(),
                      lng = ~topologia_consulta()$longitud,
                      lat = ~topologia_consulta()$latitud,
                      group = "Pintar",
                      popup =  ~paste0(
                        "<b>Isla:</b> ", topologia_consulta()$etiqueta, "</b><br/>",
                        "<b>GeoCode:</b> ", topologia_consulta()$geocode, "</b><br/>",
                        "<b>Valor:</b> ", topologia_consulta()$valor, "<br/>"
                        
                      )
    )
  })
 
  
 
  
  }

# Run the application
shinyApp(ui = ui, server = server)

我希望这些点都在小地图上。

javascript shiny maps r-leaflet
1个回答
0
投票

您可以在

htmlwidgets::onRender()
中使用以下事件处理程序:

myMap.on('layeradd', // if we add a layer on the original map
        function(e) {
            if (e.layer._eventParents != null) {
                var layers = new L.LayerGroup(
                    // set a new layer group consisting out of the initial layer
                    // and a marker at the position of the one from the map
                    [initialLayer, L.marker(e.layer._latlng)]
                );
                // assign the layergroup to the minimap
                myMap.minimap.changeLayer(layers);
            })

enter image description here

library(shiny)
library(leaflet)
library(leaflet.extras)
library(shinyjs)
library(tidyverse)

leafletMiniMapDependencies <- function() {
  list(
    htmltools::htmlDependency(
      "leaflet-minimap",
      "3.3.1",
      "htmlwidgets/plugins/Leaflet-MiniMap",
      package = "leaflet",
      script = c("Control.MiniMap.min.js", "Minimap-binding.js"),
      stylesheet = c("Control.MiniMap.min.css")
    )
  )
}

addMiniMap <- function(
    map,
    position = "bottomleft",
    width = 300,
    height = 225,
    collapsedWidth = 19,
    collapsedHeight = 19,
    zoomLevelOffset = -5,
    zoomLevelFixed = 6,
    centerFixed = c(28, -15.5),
    zoomAnimation = FALSE,
    toggleDisplay = T,
    autoToggleDisplay = FALSE,
    minimized = FALSE,
    aimingRectOptions = list(color = "rgba(0,0,0,0)", weight = 1, clickable = FALSE),
    shadowRectOptions = list(color = "#000000", weight = 1, clickable = FALSE,
                             opacity = 0, fillOpacity = 0),
    strings = list(hideText = "Hide MiniMap", showText = "Show MiniMap"),
    tiles = NULL,
    mapOptions = list(minZoom = 6, maxZoom = 6)
) {
  
  # determin tiles to use
  tilesURL <- NULL
  tilesProvider <- NULL
  if (!is.null(tiles)) {
    if (tiles %in% providers) {
      map$dependencies <- c(map$dependencies, leafletProviderDependencies())
      tilesProvider <- tiles
    } else {
      tilesURL <- tiles
    }
  }
  
  map$dependencies <- c(map$dependencies, leafletMiniMapDependencies())
  invokeMethod(
    map
    , getMapData(map)
    , "addMiniMap"
    , tilesURL
    , tilesProvider
    , position
    , width
    , height
    , collapsedWidth
    , collapsedHeight
    , zoomLevelOffset
    , zoomLevelFixed
    , centerFixed
    , zoomAnimation
    , toggleDisplay
    , autoToggleDisplay
    , minimized
    , aimingRectOptions
    , shadowRectOptions
    , strings
    , mapOptions
  )
}

topologia <- data.frame(
  etiqueta = c("El Hierro", "Fuerteventura", "Gran Canaria",  "La Palma", "Lanzarote", "Tenerife"),
  longitud = c(-18.038165, -14.004885, -15.606239, -17.857377, -13.636218, -16.621481),
  latitud = c(27.743606, 28.400363, 27.958157, 28.655223, 29.039468, 28.293378),
  geocode = c("ES703", "ES704", "ES705", "ES707", "ES708", "ES709"),
  valor = 1:6
)

topologia <-  topologia %>% 
  mutate(
    longitud = as.numeric(gsub("\\.", "", longitud)) / 10^6,
    latitud = as.numeric(gsub("\\.", "", latitud)) / 10^6
  )

# Define UI for application
ui <- fluidPage(
  tags$head(
    tags$style(HTML("
      body{
      .leaflet-control-search{
        position: absolute !important;
        left: 50% !important;
        transform: translateX(-50%) !important;
        margin-left: 0 !important;
      }

      .leaflet-top.leaflet-left{
        width: 100%;
      }
      "))
    
  ),
  
  useShinyjs(),
  titlePanel("Mapa"),
  sidebarPanel(
    selectInput("provincia_seleccionada", "Provincia", choices = unique(topologia$etiqueta)), 
    actionButton("consultar", "Consulta")
  ),
  column(width = 12, leafletOutput("map", height = "600px")),
  column(width = 12, dataTableOutput("data"))
)

# Define server logic
server <- function(input, output, session) {
  
  # processing with click of consultar data
  topologia_consulta <- eventReactive(input$consultar, {
    topologia %>% filter(etiqueta %in% input$provincia_seleccionada) %>% 
      filter(!is.na(latitud) & !is.na(longitud))
  })
  
  # show data in datatable
  output$data <- renderDataTable(topologia_consulta())
  
  
  # Render the map
  output$map <- renderLeaflet({
    leaflet() %>%
      leaflet(options = leafletOptions(minZoom = 5)) %>%
      addTiles(options = tileOptions(updateWhenIdle = TRUE, updateWhenZooming = FALSE)) %>%
      addFullscreenControl() %>%
      addProviderTiles(providers$OpenStreetMap) %>%
      setView(lat = 40.416775, lng = -3.703790, zoom = 6) %>%
      addMiniMap() %>%
      addEasyButton(easyButton(
        icon = "fa-crosshairs", title = "Locate Me",
        onClick = JS("function(btn, map){ map.locate({setView: true}); }")
      )) %>%
      # addSearchOSM(options = searchOptions(collapsed = FALSE, autoCollapse = TRUE, minLength = 2)) %>%
      leaflet.extras::addSearchOSM(options = searchOptions(collapsed = F)) %>%
      addEasyButton(easyButton(states = list(
        easyButtonState(
          stateName = "Canarias",
          icon = '<strong>Ir a Islas Canarias</strong>',
          title = "Ir a Islas Canarias",
          onClick = JS("
          function(btn, map) {
            map.flyTo(L.latLng(28, -15.5), 7);
            btn.state('Peninsula');
          }")
        ),
        easyButtonState(
          stateName = "Peninsula",
          icon = '<strong>Ir a Península</strong>',
          title = "Ir a Península",
          onClick = JS("
          function(btn, map) {
            map.flyTo(L.latLng(40.416775, -3.703790), 6);
            btn.state('Canarias');
          }")
        )), id = 'botonCanarias', position = 'bottomleft')) %>% 
      
      htmlwidgets::onRender(paste0("
        function(el, t) {
          var myMap = this;
          
          $('#searchtext25').attr('placeholder', 'Buscar localización...');

          $('#searchtext25').on('input', function(){
            if($(this).val() === '')
              $(\"path.leaflet-interactive[stroke='#3388ff'][stroke-linecap='round']\").hide();
          });

          $('#map ul.search-tooltip').on('mouseup', 'li', function(){
            $(\"path.leaflet-interactive[stroke='#3388ff'][stroke-linecap='round']\").show();
          });

          $('#map a.search-cancel').on('click', function(){
            $(\"path.leaflet-interactive[stroke='#3388ff'][stroke-linecap='round']\").hide();
          });
          
          // save initial layer (so that we can remove older markers)
          var initialLayer = myMap.minimap._layer;
          
          myMap.on('layeradd',  // if we add a layer on the original map
            function (e) {
              if (e.layer._eventParents != null) {
                var layers = new L.LayerGroup(
                  // set a new layer group consisting out of the initial layer
                  // and a marker at the position of the one from the map
                  [initialLayer, L.marker(e.layer._latlng)]
                );
                // assign the layergroup to the minimap
                myMap.minimap.changeLayer(layers);
              }
            })
          
        }")) %>% 
      addLayersControl(
        overlayGroups = c("Pintar"),
        options = layersControlOptions(collapsed = TRUE)
      )
    
    
  })
  
  # When click in consultar bottom show the map 
  observeEvent(input$consultar, {
    mapProxy <- leafletProxy("map")
    mapProxy %>%
      clearGroup("Pintar") %>% 
      addAwesomeMarkers(data = topologia_consulta(),
                        lng = ~topologia_consulta()$longitud,
                        lat = ~topologia_consulta()$latitud,
                        group = "Pintar",
                        popup =  ~paste0(
                          "<b>Isla:</b> ", topologia_consulta()$etiqueta, "</b><br/>",
                          "<b>GeoCode:</b> ", topologia_consulta()$geocode, "</b><br/>",
                          "<b>Valor:</b> ", topologia_consulta()$valor, "<br/>"
                          
                        )
      )
  })
  
  
  
  
}

# Run the application
shinyApp(ui = ui, server = server)
© www.soinside.com 2019 - 2024. All rights reserved.