1

First of all, I will make a brief example for you to understand the idea.

library(googleway)

set_key( "API KEY")


df<-structure(list(Properties = c(1,2,3,4), 
                     Latitude = c(-24.930473, -24.95575,-24.990473, -24.99575), 
                     Longitude = c(-49.994889, -49.990162,-49.999889, -49.999162), 
                     cluster = c(1,2,1,2)), class = "data.frame", row.names = c(NA, -4L))
  
  df1<-structure(list(Latitude = c(-24.924361,-24.95575), 
                      Longitude = c(-50.004343, -50.007371), 
                      cluster = c(1,2)), class = "data.frame", row.names = c(NA, -2L))
  
 # considering `Filter1= 1`, that is, cluster 1 that I want to see, and `Filter2= 3`, that is property number 3, so:

Filter1=1

Filter2=3

  data_table1<-df1[df1$cluster==Filter1,c(1:2)]
  data_table2<-df[df$Properties==Filter2,c(2:3)]
  
 
   #Generate the map with routes
  
  df2<-google_directions(origin = data_table1, destination = data_table2, 
                         mode = "driving")
  
  df_routes <- data.frame(polyline = direction_polyline(df2))
  
  
  m1<-google_map() %>%
    add_polylines(data = df_routes, polyline = "polyline")

  

enter image description here

Now, my idea is to use shiny. In this sense, I created two selecInput, the first corresponds to Filter 1 (which cluster do you want to see) and the other to Filter 2 (which property do you want to see). Choosing these two pieces of information generates the route as I did in the example above. However, I am not able to fix this problem in shiny.

This question is very similar and might help: How to Link selected cluster in shiny app However, it has some differences, for example I have inserted one more filter .

library(shiny)
library(rdist)
library(geosphere)
library(shinythemes)
library(googleway)


set_key( "API KEY")



function.cl<-function(df,df1,k,Filter1){
  
  #database df
  df<-structure(list(Properties = c(1,2,3,4), 
                     Latitude = c(-24.930473, -24.95575,-24.990473, -24.99575), 
                     Longitude = c(-49.994889, -49.990162,-49.999889, -49.999162), 
                     cluster = c(1,2,1,2)), class = "data.frame", row.names = c(NA, -4L))
  
  df1<-structure(list(Latitude = c(-24.924361,-24.95575), 
                      Longitude = c(-50.004343, -50.007371), 
                      cluster = c(1,2)), class = "data.frame", row.names = c(NA, -2L))
  

  data_table1<-df1[df1$cluster==Filter1,c(1:2)]
  data_table2<-df[df$Properties==Filter2,c(2:3)]
  
 
   #Generate the map with routes
  
  df2<-google_directions(origin = data_table1, destination = data_table1, 
                         mode = "driving")
  
  df_routes <- data.frame(polyline = direction_polyline(df2))
  
  
  m1<-google_map() %>%
    add_polylines(data = df_routes, polyline = "polyline")
  
  plot1<-m1 
  
  return(list(
    "Plot1" = plot1,
    "Data" = df
  ))
}

ui <- bootstrapPage(
  
  navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
             "Cl", 
             tabPanel("Map of all clusters",
                      sidebarLayout(
                        sidebarPanel(
                          tags$b(h3("Choose the cluster number?")),
                          sliderInput("Slider", h5(""),
                                      min = 2, max = 2, value = 2),
                          selectInput("Filter1", label = h4("Select just one cluster to show"),""),
                          selectInput("Filter2", label = h4("Select the propertie"),""),
                        ),
                        
                        mainPanel(
                          tabsetPanel(      
                            tabPanel("Solution", (google_mapOutput("G2",width = "95%", height = "600")))))
                        
                      ))))


server <- function(input, output, session) {
  
  Modelcl<-reactive({
    function.cl(df,df1,input$Slider,input$Filter1)
  })
  
  output$G2 <- renderGoogle_map({
    Modelcl()[[1]]
  })
  
  
  observeEvent(input$Slider, {
    abc <- req(Modelcl()$Data)
    updateSelectInput(session,'Filter1',
                      choices=sort(unique(abc$cluster)))
  }) 
  
  observeEvent(c(input$Filter1 ),{
    abc <- req(Modelcl()$Data) %>% filter(cluster == as.numeric(input$Filter1))   
    updateSelectInput(session,'Filter2',
                      choices = unique(abc$Propertie))
    
  })
  
}

shinyApp(ui = ui, server = server)

enter image description here

Antonio
  • 1,091
  • 7
  • 24

1 Answers1

2

Your shiny example as three inputs:

  1. Slider, which gets passed to k in the function signature
  2. Filter1, which appears to be the same as k (i.e. choosing a cluster), and currently gets passed to Filter1 in the function signature
  3. Filter2, which is for selecting the Property, but never gets passed to the function.

I think what you want to do is include only Slider and Filter2 (or Filter1 and Filter2).

Then change the Modelcl to

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

Then, in your actual function, rename your inputs in the signature so that they are better aligned with what you are passing in. I suggest something like this:

function.cl<-function(df,df1,cluster,property){

Then, you can

data_table1<-df1[df1$cluster==cluster,c(1:2)]
data_table2<-df[df$Properties==property,c(2:3)]

Finally, notice that you have an error in your call to google_directions(). you need to make sure that the origin and destination parameters are different. currently, they are both set to data_table1

Here is an example, with the changes made:


library(shiny)
library(rdist)
library(geosphere)
library(shinythemes)
library(googleway)


function.cl<-function(df,df1,cluster,property){
  

  #database df
  df<-structure(list(Properties = c(1,2,3,4), 
                     Latitude = c(-24.930473, -24.95575,-24.990473, -24.99575), 
                     Longitude = c(-49.994889, -49.990162,-49.999889, -49.999162), 
                     cluster = c(1,2,1,2)), class = "data.frame", row.names = c(NA, -4L))
  
  df1<-structure(list(Latitude = c(-24.924361,-24.95575), 
                      Longitude = c(-50.004343, -50.007371), 
                      cluster = c(1,2)), class = "data.frame", row.names = c(NA, -2L))
  
  
  data_table1<-df1[df1$cluster==cluster,c(1:2)]
  data_table2<-df[df$Properties==property,c(2:3)]
  

  #Generate the map with routes
  
  df2<-google_directions(origin = data_table1, destination = data_table2, 
                         mode = "driving")
  
  df_routes <- data.frame(polyline = direction_polyline(df2))
  
  
  m1<-google_map() %>%
    add_polylines(data = df_routes, polyline = "polyline")
  
  plot1<-m1 
  
  return(list(
    "Plot1" = plot1,
    "Data" = df
  ))
}

ui <- bootstrapPage(
  
  navbarPage(theme = shinytheme("flatly"), collapsible = TRUE,
             "Cl", 
             tabPanel("Map of all clusters",
                      sidebarLayout(
                        sidebarPanel(
                          tags$b(h3("Choose the cluster number?")),
                          sliderInput("Slider", h5(""),
                                      min = 1, max = 2, value = 1,step = 1),
                          selectInput("Filter2", label = h4("Select the properties"),choices =c(1,2,3,4)),
                        ),
                        
                        mainPanel(
                          tabsetPanel(      
                            tabPanel("Solution", (google_mapOutput("G2",width = "95%", height = "600")))))
                        
                      ))))


server <- function(input, output, session) {
  
  Modelcl<-reactive({
    function.cl(df,df1,input$Slider,input$Filter2)
  })
  
  output$G2 <- renderGoogle_map({
    Modelcl()[[1]]
  })
  
  
  observeEvent(input$Slider, {
    abc <- req(Modelcl()$Data)
    updateSelectInput(session,'Filter1',
                      choices=sort(unique(abc$cluster)))
  }) 
  
  # observeEvent(c(input$Filter1 ),{
  #   abc <- req(Modelcl()$Data) %>% filter(cluster == as.numeric(input$Filter1))   
  #   updateSelectInput(session,'Filter2',
  #                     choices = unique(abc$Propertie))
  #   
  # })
  
}

shinyApp(ui = ui, server = server)
langtang
  • 22,248
  • 1
  • 12
  • 27
  • Thanks for the answer! However, it is not generating the routes properly. The `selectInput` options are ok, but when I chose, for example, cluster 1 and property 3, I would have to route between the coordinates of property 3 that is in the `df` dataset with the coordinate of cluster 1 that is in `df1`, as was done in the first example, but this is not happening. In this case, I would have to generate a graph equal to the one I inserted in the first example. – Antonio Mar 20 '22 at 13:25
  • you'll have to explain what your problem is. the approach/code i have is correct – langtang Mar 20 '22 at 13:38
  • you have to be careful with your coding. notice that your origin and destination sources are the same in the call to `google_directions()` – langtang Mar 20 '22 at 13:48
  • Thanks for your comments @langtang. I adjusted the same as your code and also insert `destination = data_table2`, in `google_directions`, it was supposed to work, however it didn't in shiny code. Strange! If I do `cluster=1` and `property = 3` and then `data_table1<-df1[df1$cluster==cluster,c(1:2)]` I have the coordinates properly of cluster 1 and if I do `data_table2< -df[df$Properties==property,c(2:3)]`, I have the coordinates of property 3 properly. After that, I can properly generate the graph of the route. But on shiny, it doesn't work, do you know why? – Antonio Mar 20 '22 at 14:06
  • You probably are NOT passing cluster and property to the function. Do some debugging. A simple approach is to have the function (add as first line of the function) print property and cluster so you can see exactly what it is receiving from the shiny inputs. Also your shiny app example doesn’t provide any values in the Filter1 input choices – langtang Mar 20 '22 at 14:18
  • Sorry for the delay, I had to leave. I understand what you want me to do, buti don't know how to do what you said in the code, can you help me? – Antonio Mar 20 '22 at 22:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/243126/discussion-between-langtang-and-antonio). – langtang Mar 21 '22 at 00:04
  • langtang, I asked a question similar to this one, and a question we were chatting about. I detailed it to make it understandable. If you can take a look, I'd appreciate it. https://stackoverflow.com/questions/71608236/problems-generating-route-between-two-coordinates-in-a-shiny-app – Antonio Mar 24 '22 at 19:30