Conflict when generating addPolylines on the map made by Leaflet

泄露秘密 提交于 2020-05-17 07:45:11

问题


Friends, could you help me with the following question: I am having a conflict when inserting the addPolylines function to generate my second leaflet map. In general, Map 1 involves showing all clusters and Map 2 involves a specific cluster. For this specific cluster I inserted a feature to adhere the same colors as the clusters formed on the map1. The first code is doing the above descriptions correctly. However, I also inserted the second code that refers to addPolylines for the second map. But when I insert this second code in the first code, in the part that concerns the generation of map 2, it gives an error: Warning: Error in eval: object 'm2' not found. Could you help me solve this problem please?

library(shiny)
library(ggplot2)
library(rdist)
library(geosphere)
library(shinythemes)
library(leaflet)

function.cl<-function(df,k,Filter1,Filter2){

  #database df
  df<-structure(list(Properties = c(1,2,3,4,5,6,7), 
                     Latitude = c(-23.8, -23.8, -23.9, -23.9, -23.9,-23.4,-23.5), 
                     Longitude = c(-49.6, -49.3, -49.4, -49.8, -49.6,-49.4,-49.2), 
                     Waste = c(526, 350, 526, 469, 285, 433, 456)), class = "data.frame", row.names = c(NA, -7L))


  #clusters
  coordinates<-df[c("Latitude","Longitude")]
  d<-as.dist(distm(coordinates[,2:1]))
  fit.average<-hclust(d,method="average") 
  clusters<-cutree(fit.average, k) 
  nclusters<-matrix(table(clusters))  
  df$cluster <- clusters 

  #specific cluster and specific propertie
  df1<-df[c("Latitude","Longitude")]
  df1$cluster<-as.factor(clusters)
  df_spec_clust <- df1[df1$cluster == Filter1,]
  df_spec_prop<-df[df$Properties==Filter2,]

  #Table to join df and df1
  data_table <- Reduce(merge, list(df, df1))

  #Color and Icon for map
  ai_colors <-c("red","gray","blue","orange","green","beige","darkgreen","lightgreen", "lightred", "darkblue","lightblue",
                "purple","darkpurple","pink", "cadetblue","white","darkred", "lightgray","black")
  clust_colors <- ai_colors[df$cluster]
  icons <- awesomeIcons(
    icon = 'ios-close',
    iconColor = 'black',
    library = 'ion',
    markerColor =  clust_colors)

  leafIcons <- icons(
    iconUrl = ifelse(df1$Properties,
                     "https://image.flaticon.com/icons/svg/542/542461.svg"
    ),
    iconWidth = 45, iconHeight = 40,
    iconAnchorX = 25, iconAnchorY = 12)
  html_legend <- "<img src='https://image.flaticon.com/icons/svg/542/542461.svg'>"

  # Map for all clusters:
  m1<-leaflet(df1) %>% addTiles() %>%
    addMarkers(~Longitude, ~Latitude, icon = leafIcons) %>%
    addAwesomeMarkers(lat=~df$Latitude, lng = ~df$Longitude, icon=icons, label=~as.character(df$cluster)) %>% 
    addPolylines(lat=~df$Latitude, lng = ~df$Longitude,color="red") %>% 
    addLegend( position = "topright", title="Cluster", colors = ai_colors[1:max(df$cluster)],labels = unique(df$cluster))

  plot1<-m1

  # Map for specific cluster and propertie
  if(nrow(df_spec_clust)>0){
    clust_colors <- ai_colors[df_spec_clust$cluster]
    icons <- awesomeIcons(
      icon = 'ios-close',
      iconColor = 'black',
      library = 'ion',
      markerColor =  clust_colors)
    m2<-leaflet(df_spec_clust) %>% addTiles() %>%
      addAwesomeMarkers(lat=~Latitude, lng = ~Longitude, icon=icons, label=~cluster) 
    plot2<-m2} else plot2 <- NULL   

  return(list(
    "Plot1" = plot1,
    "Plot2" = plot2,
    "Data" = data_table
  ))
}

ui <- bootstrapPage(
  navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
             "Cl", 
             tabPanel("Solution",
                      sidebarLayout(
                        sidebarPanel(
                          tags$b(h3("Choose the cluster number?")),
                          sliderInput("Slider", h5(""),
                                      min = 2, max = 5, value = 3),
                        ),
                        mainPanel(
                          tabsetPanel(      
                            tabPanel("Solution", (leafletOutput("Leaf1",width = "95%", height = "600")))))

                      ))),
  tabPanel("",
           sidebarLayout(
             sidebarPanel(
               selectInput("Filter1", label = h4("Select just one cluster to show"),""),
               selectInput("Filter2",label=h4("Select the cluster property designated above"),""),
             ),
             mainPanel(
               tabsetPanel(
                 tabPanel("Map", (leafletOutput("Leaf2",width = "95%", height = "600")))))
           )))

server <- function(input, output, session) {

  Modelcl<-reactive({
    function.cl(df,input$Slider,input$Filter1,input$Filter2)
  })

  output$Leaf1 <- renderLeaflet({
    Modelcl()[[1]]
  })

  output$Leaf2 <- renderLeaflet({
    Modelcl()[[2]]
  })

  observeEvent(input$Slider, {
    abc <- req(Modelcl()$Data)
    updateSelectInput(session,'Filter1',
                      choices=sort(unique(abc$cluster)))
  }) 

  observeEvent(input$Filter1,{
    abc <- req(Modelcl()$Data) %>% filter(cluster == as.numeric(input$Filter1))
    updateSelectInput(session,'Filter2',
                      choices=sort(unique(abc$Properties)))
  }) 


}

shinyApp(ui = ui, server = server)

Code to insert addPolyline in the second map

for(i in 1:nrow(df_spec_clust)){
    df_line <- rbind(df_spec_prop[,c("Latitude","Longitude")],
                     df_spec_clust[i,c("Latitude","Longitude")])
    m2 <- m2 %>%
      addPolylines(data = df_line, 
                   lat=~Latitude, 
                   lng = ~Longitude,
                   color="red")
  }
  plot2<-m2

When I insert this second code into the first code regarding the generation of map 2:

 # Map for specific cluster and propertie
      if(nrow(df_spec_clust)>0){
        clust_colors <- ai_colors[df_spec_clust$cluster]
        icons <- awesomeIcons(
          icon = 'ios-close',
          iconColor = 'black',
          library = 'ion',
          markerColor =  clust_colors)
        m2<-leaflet(df_spec_clust) %>% addTiles() %>%
          addAwesomeMarkers(lat=~Latitude, lng = ~Longitude, icon=icons, label=~cluster) 
        plot2<-m2} else plot2 <- NULL   

for(i in 1:nrow(df_spec_clust)){
        df_line <- rbind(df_spec_prop[,c("Latitude","Longitude")],
                         df_spec_clust[i,c("Latitude","Longitude")])
        m2 <- m2 %>%
          addPolylines(data = df_line, 
                       lat=~Latitude, 
                       lng = ~Longitude,
                       color="red")
      }
      plot2<-m2

The following error appears: Warning: Error in eval: object 'm2' not found.```

Thank you very much!


回答1:


@Jovani SouzA @Jose m2 the object doesnt exist when you are passing it into your method chain, you are meaning to pass m1 into the method chain in order to addPolylines to create m2.

library(shiny)
library(ggplot2)
library(rdist)
library(geosphere)
library(shinythemes)
library(leaflet)

function.cl<-function(df,k,Filter1,Filter2){

  #database df
  df<-structure(list(Properties = c(1,2,3,4,5,6,7), 
                     Latitude = c(-23.8, -23.8, -23.9, -23.9, -23.9,-23.4,-23.5), 
                     Longitude = c(-49.6, -49.3, -49.4, -49.8, -49.6,-49.4,-49.2), 
                     Waste = c(526, 350, 526, 469, 285, 433, 456)), class = "data.frame", row.names = c(NA, -7L))


  #clusters
  coordinates<-df[c("Latitude","Longitude")]
  d<-as.dist(distm(coordinates[,2:1]))
  fit.average<-hclust(d,method="average") 
  clusters<-cutree(fit.average, k) 
  nclusters<-matrix(table(clusters))  
  df$cluster <- clusters 

  #specific cluster and specific propertie
  df1<-df[c("Latitude","Longitude")]
  df1$cluster<-as.factor(clusters)
  df_spec_clust <- df1[df1$cluster == Filter1,]
  df_spec_prop<-df[df$Properties==Filter2,]

  #Table to join df and df1
  data_table <- Reduce(merge, list(df, df1))

  #Color and Icon for map
  ai_colors <-c("red","gray","blue","orange","green","beige","darkgreen","lightgreen", "lightred", "darkblue","lightblue",
                "purple","darkpurple","pink", "cadetblue","white","darkred", "lightgray","black")
  clust_colors <- ai_colors[df$cluster]
  icons <- awesomeIcons(
    icon = 'ios-close',
    iconColor = 'black',
    library = 'ion',
    markerColor =  clust_colors)

  leafIcons <- icons(
    iconUrl = ifelse(df1$Properties,
                     "https://image.flaticon.com/icons/svg/542/542461.svg"
    ),
    iconWidth = 45, iconHeight = 40,
    iconAnchorX = 25, iconAnchorY = 12)
  html_legend <- "<img src='https://image.flaticon.com/icons/svg/542/542461.svg'>"

  # Map for all clusters:
  m1<-leaflet(df1) %>% addTiles() %>%
    addMarkers(~Longitude, ~Latitude, icon = leafIcons) %>%
    addAwesomeMarkers(lat=~df$Latitude, lng = ~df$Longitude, icon=icons, label=~as.character(df$cluster)) %>% 
    addPolylines(lat=~df$Latitude, lng = ~df$Longitude,color="red") %>% 
    addLegend( position = "topright", title="Cluster", colors = ai_colors[1:max(df$cluster)],labels = unique(df$cluster))

  plot1<-m1

  # Map for specific cluster and propertie
  if(nrow(df_spec_clust)>0){
    clust_colors <- ai_colors[df_spec_clust$cluster]
    icons <- awesomeIcons(
      icon = 'ios-close',
      iconColor = 'black',
      library = 'ion',
      markerColor =  clust_colors)
    m2<-leaflet(df_spec_clust) %>% addTiles() %>%
      addAwesomeMarkers(lat=~Latitude, lng = ~Longitude, icon=icons, label=~cluster) 
    plot2<-m2} else plot2 <- NULL


  for(i in 1:nrow(df_spec_clust)){
    df_line <- rbind(df_spec_prop[,c("Latitude","Longitude")],
                     df_spec_clust[i,c("Latitude","Longitude")])
    m2 <- m1 %>%
      addPolylines(data = df_line, 
                   lat=~Latitude, 
                   lng = ~Longitude,
                   color="red")
  }
  plot2<-m2


  return(list(
    "Plot1" = plot1,
    "Plot2" = plot2,
    "Data" = data_table
  ))
}

ui <- bootstrapPage(
  navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
             "Cl", 
             tabPanel("Solution",
                      sidebarLayout(
                        sidebarPanel(
                          tags$b(h3("Choose the cluster number?")),
                          sliderInput("Slider", h5(""),
                                      min = 2, max = 5, value = 3),
                        ),
                        mainPanel(
                          tabsetPanel(      
                            tabPanel("Solution", (leafletOutput("Leaf1",width = "95%", height = "600")))))

                      ))),
  tabPanel("",
           sidebarLayout(
             sidebarPanel(
               selectInput("Filter1", label = h4("Select just one cluster to show"),""),
               selectInput("Filter2",label=h4("Select the cluster property designated above"),""),
             ),
             mainPanel(
               tabsetPanel(
                 tabPanel("Map", (leafletOutput("Leaf2",width = "95%", height = "600")))))
           )))

server <- function(input, output, session) {

  Modelcl<-reactive({
    function.cl(df,input$Slider,input$Filter1,input$Filter2)
  })

  output$Leaf1 <- renderLeaflet({
    Modelcl()[[1]]
  })

  output$Leaf2 <- renderLeaflet({
    Modelcl()[[2]]
  })

  observeEvent(input$Slider, {
    abc <- req(Modelcl()$Data)
    updateSelectInput(session,'Filter1',
                      choices=sort(unique(abc$cluster)))
  }) 

  observeEvent(input$Filter1,{
    abc <- req(Modelcl()$Data) %>% filter(cluster == as.numeric(input$Filter1))
    updateSelectInput(session,'Filter2',
                      choices=sort(unique(abc$Properties)))
  }) 


}

shinyApp(ui = ui, server = server)


来源:https://stackoverflow.com/questions/61830727/conflict-when-generating-addpolylines-on-the-map-made-by-leaflet

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!