2

I am working with google-way in a Shiny app.

I started from this example: Drawing journey path using leaflet in R and modified it a little to include 2 extra waypoints between the Destination and Origin and have google_directions render the optimal route between them.

The route plotted is indeed optimal and I am able to replicate this for 5-6-7 or 10 waypoints. However in each case for the route to be plotted I need to put addresses for all waypoints. If some of the waypoints are left blank the app returns an error and I'm not sure how to solve this. I suppose some kind of "if" operator should be used but not sure how and where exactly.

This is my code:

library(shiny)
library(googleway)

ui <- navbarPage("APP NAME", position = c("static-top"),
tabPanel("MAP",
       google_mapOutput(outputId = "mapWarsaw"),
       textInput(inputId = "origin", label = "Departure point"
       ),
       textInput(inputId = "waypoint", label = "Waypoint 1"
       ),
       textInput(inputId = "waypoint2", label = "Waypoint 2",
       ),
       textInput(inputId = "destination", label = "Destination point"
       ),
       actionButton(inputId = "getRoute", label = "Get Route")
       )
)

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


map_key <- '<APIKEY>'
api_key <- '<APIKEY>'

df_route <- eventReactive(input$getRoute,{

print("getting route")

o <- input$origin
w <- input$waypoint
q <- input$waypoint2
d <- input$destination

return(data.frame(origin = o, waypoint = w, waypoint2 = q, destination = d, stringsAsFactors = F))

})


output$mapWarsaw <- renderGoogle_map({
df <- df_route()
print(df)
if(df$origin == "" | df$waypoint == ""| df$waypoint2 == "" | df$destination == "")
  return()

res <- google_directions(key = api_key,
                         origin = df$origin,
                         waypoints = list(stop = df$waypoint,
                                          stop = df$waypoint2),
                         destination = df$destination,
                         optimise_waypoints = TRUE,
                         mode = "driving")

df_route <- data.frame(route = res$routes$overview_polyline$points)

google_map(key = map_key, search_box = TRUE, scale_control = TRUE, height = 1000) %>%
  add_traffic()%>%
  add_polylines(data = df_route,
                polyline = "route",
                stroke_colour = "#FF33D6",
                stroke_weight = 7,
                stroke_opacity = 0.7,
                info_window = "New route",
                load_interval = 100)
})
}


shinyApp(ui, server)

Data file:

popupcontent;label;lat;lng          
Location 1;Location Label 1;52.2572126;20.9845778   
Location 2;Location Label 2;52.2423875;21.0244197   
Location 3;Location Label 3;52.238209;21.0202826    
Location 4;Location Label 4;52.23048060000001;21.0108891
Location 5;Location Label 5;52.231755;21.006482 
Location 6;Location Label 6;52.2376719;21.0158829A7 
Location 7;Location Label 7;52.2540379;21.0347079   
Location 8;Location Label 8;52.2550605;21.052299    
Location 9;Location Label 9;52.247861;21.049922 
Location 10;Location Label 10;52.2720819;21.0151038
Location 11;Location Label 11;52.2582368;21.0396915
Location 12;Location Label 12;52.2569792;21.0294134
Location 13;Location Label 13;52.2549106;21.0475752
Location 14;Location Label 14;52.206521;20.999852   
Location 15;Location Label 15;52.2937449;21.0333861
Location 16;Location Label 16;52.2878479;21.0412171
Location 17;Location Label 17;52.305039;21.0584014  
SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
  • Yes, I modified your example to include waypoints. Here's my code: https://www.dropbox.com/s/pe7be91k7i7a86w/test_code.r?dl=0 I went through your documentation and vignettes and I am overall familiar with markers. I added some to the map from a .csv file with lat/lon. I am struggling with 2 issues though: 1. How to visualise the order of waypoints optimised by google_directions? For instance by numerated markers. 2. How to make the app work if one or more waypoints are not selected? if both waypoints aren't selected an error comes up. I suppose some 'if' operator should be used... – user9534023 Mar 26 '18 at 11:32
  • Thanks a lot @SymbolixAU! That's really helpful. I modified the question - hope it's ok now. – user9534023 Mar 27 '18 at 03:50
  • Thanks. Sure, just give me a second for the data. – user9534023 Mar 27 '18 at 04:04
  • Unable to decide on voting to reopen because there's no data. – IRTFM Mar 27 '18 at 04:10
  • Here's the link to the data: https://www.dropbox.com/s/8ymmilt7jgej206/Locations_2_CSV.csv.csv?dl=0 "popupcontent" is what goes into the info_window of the marker. "label" should go into the mouse_over but tha's not relevant. Initially the file was used to visualize all markers on the map but I deleted that function from the code in the question. – user9534023 Mar 27 '18 at 04:14
  • 1
    Made it minimal then - the data and the code related to it has been deleted. – user9534023 Mar 27 '18 at 04:29
  • To clarify your requirement: are you after a marker at each of the user-specified waypoints? And, you want it to handle none, one or many waypoints, without error? – SymbolixAU Mar 27 '18 at 04:50
  • Yes, exactly that. – user9534023 Mar 27 '18 at 05:02
  • Thank you, I really appreciate it! – user9534023 Mar 27 '18 at 05:05
  • OK, voted to reopen. I still don't understand why "no data required". – IRTFM Mar 27 '18 at 06:37
  • Thank you!! It is really helpful. I shall try it tonight. – user9534023 Mar 27 '18 at 12:09
  • No worries. Thank you for updating your question, it makes it much easier to help with a reproducible example. – SymbolixAU Mar 28 '18 at 10:16
  • My first question on Stack so thanks for the guidelines! – user9534023 Mar 28 '18 at 16:49

1 Answers1

4

A few comments & changes I've made:

  • using a single observeEvent() to observe the button click & update the map
  • added a update_google_map() to clear & update the map each time a route is searched'
  • the Google API can handle empty waypoints, so there's no requirement for extra error handling

library(shiny)
library(googleway)

ui <- navbarPage("APP NAME", position = c("static-top"),tabPanel("MAP",
               google_mapOutput(outputId = "mapWarsaw"),
               textInput(inputId = "origin", label = "Departure point"),
               textInput(inputId = "waypoint", label = "Waypoint 1"),
               textInput(inputId = "waypoint2", label = "Waypoint 2"),
               textInput(inputId = "destination", label = "Destination point"),
               actionButton(inputId = "getRoute", label = "Get Route")
)
)

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

  map_key <- "MAP_KEY"
  api_key <- "API_KEY"

  output$mapWarsaw <- renderGoogle_map({
    google_map(key = map_key, 
               search_box = TRUE, 
               scale_control = TRUE, 
               height = 1000) %>%
      add_traffic()
  })

  observeEvent(input$getRoute,{

    print("getting route")

    o <- input$origin
    w <- input$waypoint
    q <- input$waypoint2
    d <- input$destination

    res <- google_directions(key = api_key,
                             origin = o,
                             waypoints = list(stop = w,
                                              stop = q),
                             destination = d,
                             optimise_waypoints = TRUE,
                             mode = "driving")

    df_route <- data.frame(route = res$routes$overview_polyline$points)

    df_way <- cbind(
      res$routes$legs[[1]]$end_location,
      data.frame(address = res$routes$legs[[1]]$end_address)
    )

    df_way$order <- as.character(1:nrow(df_way))

    google_map_update(map_id = "mapWarsaw") %>%
      clear_traffic() %>%
      clear_polylines() %>%
      clear_markers() %>%
      add_traffic() %>%
      add_polylines(data = df_route,
                    polyline = "route",
                    stroke_colour = "#FF33D6",
                    stroke_weight = 7,
                    stroke_opacity = 0.7,
                    info_window = "New route",
                    load_interval = 100) %>%
      add_markers(data = df_way,
                  info_window = "end_address",
                  label = "order")
  })
}


shinyApp(ui, server)

enter image description here

SymbolixAU
  • 25,502
  • 4
  • 67
  • 139
  • @user9534023 - if this answers your question you can press the grey 'tick' next to the voting arrows to make it as 'accepted' and close it. – SymbolixAU Mar 29 '18 at 10:31
  • SymbolixAU, You can take a look at this question: https://stackoverflow.com/questions/71499596/generate-routes-between-two-points-in-google-maps-on-shiny I believe it is similar to this one and you can help – Antonio Mar 16 '22 at 17:57