packages = c('igraph', 'tidygraph', 'ggraph', 'visNetwork', 'lubridate', 'tidyverse', 'ggplot2', 'ggmap', 'leaflet', 'ggiraph', 'sf', 'tmap')

for(p in packages){library
  if(!require(p, character.only = T)){
    install.packages(p)
  }
  library(p, character.only = T)
}
#top_bus <- c('51','61','961','66','67','14','30','143','10','147','178','197','154','167','166','174','196','171','2','12','21','170','970','13')

busstops <- read_csv('data/busstops_with_planning_area_XY.csv')
busstops$BusStopCode <- as.character(busstops$BusStopCode)
busstops <- busstops[c('BusStopCode', 'Description', 'RoadName', 'planning_area', 'Latitude', 'Longitude')] %>%
          filter(planning_area == 'QUEENSTOWN')

#busstops <- busstops[busstops$BusStopCode %in% as.list(unique(busroute['BusStopCode']))[['BusStopCode']], ] 
                      

busstops
## # A tibble: 226 x 6
##    BusStopCode Description          RoadName    planning_area Latitude Longitude
##    <chr>       <chr>                <chr>       <chr>            <dbl>     <dbl>
##  1 10289       Opp SIS Bldg         Alexandra ~ QUEENSTOWN        1.29      104.
##  2 10299       Aft Dawson Rd        Alexandra ~ QUEENSTOWN        1.29      104.
##  3 10321       Aft Margaret Dr      Tanglin Rd  QUEENSTOWN        1.29      104.
##  4 10469       Bef Margaret Dr      Kay Siang ~ QUEENSTOWN        1.30      104.
##  5 10479       Aft Tanglin Rd       Kay Siang ~ QUEENSTOWN        1.30      104.
##  6 11009       Ghim Moh Ter         Ghim Moh Rd QUEENSTOWN        1.31      104.
##  7 11021       Aft Queenstown NPC ~ Queensway   QUEENSTOWN        1.29      104.
##  8 11029       Blk 166              Queensway   QUEENSTOWN        1.29      104.
##  9 11031       Opp Queen's Cl       Queensway   QUEENSTOWN        1.29      104.
## 10 11039       Blk 19               Queensway   QUEENSTOWN        1.29      104.
## # ... with 216 more rows
busroute <- read_csv('data/bus_route_overall.csv')
busroute$BusStopCode <- as.character(busroute$BusStopCode)
busroute <- busroute[c('BusStopCode', 'Direction', 'Distance', 'ServiceNo', 'StopSequence')]
 #       %>% dplyr::filter(ServiceNo %in% top_bus)

busroute <- busroute[busroute$BusStopCode %in% as.list(unique(busstops['BusStopCode']))[['BusStopCode']], ] 

busroute
## # A tibble: 1,144 x 5
##    BusStopCode Direction Distance ServiceNo StopSequence
##    <chr>           <dbl>    <dbl> <chr>            <dbl>
##  1 15141               1     26.6 10                  59
##  2 15151               1     26.9 10                  60
##  3 15161               1     27.1 10                  61
##  4 15191               1     27.6 10                  62
##  5 15201               1     27.9 10                  63
##  6 15221               1     28.5 10                  64
##  7 16201               1     28.8 10                  65
##  8 16011               1     29.1 10                  66
##  9 16021               1     29.6 10                  67
## 10 16031               1     29.9 10                  68
## # ... with 1,134 more rows
busroute_2 <- busroute

busroute_2['StopSequence'] = busroute_2['StopSequence']-1
busroute_2['BusStopCode_dest'] = busroute_2['BusStopCode']
busroute_2 <- busroute_2[c('BusStopCode_dest', 'Direction', 'ServiceNo', 'StopSequence')]

busstops_from_to <- dplyr::inner_join(busroute, busroute_2, by =c('StopSequence', 'ServiceNo', 'Direction'))
busstops_from_to
## # A tibble: 975 x 6
##    BusStopCode Direction Distance ServiceNo StopSequence BusStopCode_dest
##    <chr>           <dbl>    <dbl> <chr>            <dbl> <chr>           
##  1 15141               1     26.6 10                  59 15151           
##  2 15151               1     26.9 10                  60 15161           
##  3 15161               1     27.1 10                  61 15191           
##  4 15191               1     27.6 10                  62 15201           
##  5 15201               1     27.9 10                  63 15221           
##  6 15221               1     28.5 10                  64 16201           
##  7 16201               1     28.8 10                  65 16011           
##  8 16011               1     29.1 10                  66 16021           
##  9 16021               1     29.6 10                  67 16031           
## 10 16031               1     29.9 10                  68 16041           
## # ... with 965 more rows
#join the two tables together

busroute_busstop <- dplyr::inner_join(busstops_from_to, busstops, by ='BusStopCode')
keeps <- c('BusStopCode', 'BusStopCode_dest', 'Direction', 'Distance', 'ServiceNo', 'Latitude', 'Longitude', 'planning_area', 'Description')
busroute_busstop <- busroute_busstop[, keeps, drop = FALSE] %>% 
  rename(from = BusStopCode) %>%
  rename(to = BusStopCode_dest)
  
head(busroute_busstop)
## # A tibble: 6 x 9
##   from  to    Direction Distance ServiceNo Latitude Longitude planning_area
##   <chr> <chr>     <dbl>    <dbl> <chr>        <dbl>     <dbl> <chr>        
## 1 15141 15151         1     26.6 10            1.27      104. QUEENSTOWN   
## 2 15151 15161         1     26.9 10            1.27      104. QUEENSTOWN   
## 3 15161 15191         1     27.1 10            1.27      104. QUEENSTOWN   
## 4 15191 15201         1     27.6 10            1.28      104. QUEENSTOWN   
## 5 15201 15221         1     27.9 10            1.28      104. QUEENSTOWN   
## 6 15221 16201         1     28.5 10            1.28      104. QUEENSTOWN   
## # ... with 1 more variable: Description <chr>
busroute_busstop_aggregated <- busroute_busstop %>%
  group_by(from, to, planning_area) %>%
    summarise(Weight = n()) %>%
  filter(from!=to) %>%
  filter(Weight > 1) %>%
  ungroup()

busroute_busstop_aggregated$from <- as.character(busroute_busstop_aggregated$from)
busroute_busstop_aggregated$to <- as.character(busroute_busstop_aggregated$to)

busroute_busstop_aggregated
## # A tibble: 195 x 4
##    from  to    planning_area Weight
##    <chr> <chr> <chr>          <int>
##  1 10299 10289 QUEENSTOWN         5
##  2 10321 10479 QUEENSTOWN         2
##  3 10469 11499 QUEENSTOWN         2
##  4 10479 10469 QUEENSTOWN         2
##  5 11009 11359 QUEENSTOWN         6
##  6 11021 11031 QUEENSTOWN        12
##  7 11029 11519 QUEENSTOWN         4
##  8 11031 11041 QUEENSTOWN        11
##  9 11039 11029 QUEENSTOWN        12
## 10 11041 11051 QUEENSTOWN        11
## # ... with 185 more rows
#busstops_nodes_a <- unique(busroute_busstop_aggregated[c('target', 'planning_area')]) %>%
#      rename(Id = target)

#busstops_nodes_b <- unique(busroute_busstop_aggregated[c('source', 'planning_area')]) %>%
#      rename(Id = source)

#total <- unique(rbind(busstops_nodes_a, busstops_nodes_b))

total <- busstops %>%
  rename(id = BusStopCode)
total$id <- as.character(total$id)

total
## # A tibble: 226 x 6
##    id    Description           RoadName     planning_area Latitude Longitude
##    <chr> <chr>                 <chr>        <chr>            <dbl>     <dbl>
##  1 10289 Opp SIS Bldg          Alexandra Rd QUEENSTOWN        1.29      104.
##  2 10299 Aft Dawson Rd         Alexandra Rd QUEENSTOWN        1.29      104.
##  3 10321 Aft Margaret Dr       Tanglin Rd   QUEENSTOWN        1.29      104.
##  4 10469 Bef Margaret Dr       Kay Siang Rd QUEENSTOWN        1.30      104.
##  5 10479 Aft Tanglin Rd        Kay Siang Rd QUEENSTOWN        1.30      104.
##  6 11009 Ghim Moh Ter          Ghim Moh Rd  QUEENSTOWN        1.31      104.
##  7 11021 Aft Queenstown NPC HQ Queensway    QUEENSTOWN        1.29      104.
##  8 11029 Blk 166               Queensway    QUEENSTOWN        1.29      104.
##  9 11031 Opp Queen's Cl        Queensway    QUEENSTOWN        1.29      104.
## 10 11039 Blk 19                Queensway    QUEENSTOWN        1.29      104.
## # ... with 216 more rows
bus_graph <- tbl_graph(nodes = total, edges = busroute_busstop_aggregated, directed = TRUE)

#          activate(edges) %>%
#          arrange(desc(Weight))
#%>%
 #         filter(id %in% union(.E()$to, .E()$from))
bus_graph
## # A tbl_graph: 226 nodes and 195 edges
## #
## # A directed simple graph with 52 components
## #
## # Node Data: 226 x 6 (active)
##   id    Description     RoadName     planning_area Latitude Longitude
##   <chr> <chr>           <chr>        <chr>            <dbl>     <dbl>
## 1 10289 Opp SIS Bldg    Alexandra Rd QUEENSTOWN        1.29      104.
## 2 10299 Aft Dawson Rd   Alexandra Rd QUEENSTOWN        1.29      104.
## 3 10321 Aft Margaret Dr Tanglin Rd   QUEENSTOWN        1.29      104.
## 4 10469 Bef Margaret Dr Kay Siang Rd QUEENSTOWN        1.30      104.
## 5 10479 Aft Tanglin Rd  Kay Siang Rd QUEENSTOWN        1.30      104.
## 6 11009 Ghim Moh Ter    Ghim Moh Rd  QUEENSTOWN        1.31      104.
## # ... with 220 more rows
## #
## # Edge Data: 195 x 4
##    from    to planning_area Weight
##   <int> <int> <chr>          <int>
## 1     1     2 QUEENSTOWN         5
## 2     3     4 QUEENSTOWN         2
## 3     5     6 QUEENSTOWN         2
## # ... with 192 more rows
ggraph(bus_graph) +
  geom_edge_link() +
  geom_node_point()

bus_graph=bus_graph%>%mutate(betweenness_centrality = centrality_betweenness(normalized = T)) %>%mutate(closeness_centrality = centrality_closeness(normalized = T))%>%mutate(centrality_degree=centrality_degree(mode='out',normalized = T))%>%mutate(centrality_eigen=centrality_eigen(weights=bus_graph$Weight,directed=T))

bus_graph
## # A tbl_graph: 226 nodes and 195 edges
## #
## # A directed simple graph with 52 components
## #
## # Node Data: 226 x 10 (active)
##   id    Description RoadName planning_area Latitude Longitude betweenness_cen~
##   <chr> <chr>       <chr>    <chr>            <dbl>     <dbl>            <dbl>
## 1 10289 Opp SIS Bl~ Alexand~ QUEENSTOWN        1.29      104.        0.00228  
## 2 10299 Aft Dawson~ Alexand~ QUEENSTOWN        1.29      104.        0        
## 3 10321 Aft Margar~ Tanglin~ QUEENSTOWN        1.29      104.        0        
## 4 10469 Bef Margar~ Kay Sia~ QUEENSTOWN        1.30      104.        0.0000992
## 5 10479 Aft Tangli~ Kay Sia~ QUEENSTOWN        1.30      104.        0.000159 
## 6 11009 Ghim Moh T~ Ghim Mo~ QUEENSTOWN        1.31      104.        0.000179 
## # ... with 220 more rows, and 3 more variables: closeness_centrality <dbl>,
## #   centrality_degree <dbl>, centrality_eigen <dbl>
## #
## # Edge Data: 195 x 4
##    from    to planning_area Weight
##   <int> <int> <chr>          <int>
## 1     1     2 QUEENSTOWN         5
## 2     3     4 QUEENSTOWN         2
## 3     5     6 QUEENSTOWN         2
## # ... with 192 more rows
G=bus_graph

#Normally we need to create two vectors in order to plot both the network data and the coordinates on a map
#plot_vector takes the longitude and latitude to be plotted on a map.
#plot_vector1 takes the lon, lat and the network centrality values.
plot_vector<- as.data.frame(cbind(V(G)$Longitude,V(G)$Latitude))
plot_vector1<- as.data.frame(cbind(V(G)$Longitude,V(G)$Latitude,V(G)$betweenness_centrality,V(G)$closeness_centrality))

#we are taking the edgelist which is being used to get the origin and destination of the airport data.
#edgelist[,1]- takes the origin values and the edgelist[,2] takes the destination values.
edgelist <- get.edgelist(G)
edgelist[,1]<-as.numeric(match(edgelist[,1],V(G)))
edgelist[,2]<-as.numeric(match(edgelist[,2],V(G)))

#the edges now consists of the edge between the origin and the destination values
edges <- data.frame(plot_vector[edgelist[,1],], plot_vector[edgelist[,2],])

#naming the coloumns obtained to plot
colnames(edges) <- c("X1","Y1","X2","Y2")

#Here we are taking ggmap as our base layer. on top of ggmap we are plotting the origin and destination coordinates using the plot_vector as our 2nd layer, then we are plotting the coordinates of all the centrality from the plot_vector1 as our 3rd layer and then we are ploting the geom_segment i.e. the edges as our 4th layer.
#register_google(key = ) #create your own key

#Singapore
#map <- get_map(location = c(lon = 103.8279248, lat = 1.3438295), zoom=11, source = "google", maptype = 'roadmap')
#Queenstown
map <- get_map(location = c(lon = 103.7662684, lat = 1.2869421), zoom=14, source = "google", maptype = 'toner')

p <- ggmap(map) 

z=p + 
  geom_segment(aes(x=X1, y=Y1, xend = X2, yend = Y2), color='black',data=edges,arrow = arrow(length = unit(0.2,"cm")))+ 
  #geom_point(aes(V1, V2), data=plot_vector1)+
  geom_point(aes(x=V1,y=V2,size=plot_vector1$V3,colour=plot_vector1$V4),plot_vector1)+
  scale_colour_gradientn(colours=rainbow(5))+scale_size_continuous(range = c(1, 10))
z

#we use the node3 to get our origin and destination airport for plotting it on our map
node1=data.frame(plot_vector1[edgelist[,1],])
node2=data.frame(plot_vector1[edgelist[,2],])
node3=data.frame(cbind(node1,node2))

#Then we use a for loop in order to put the destination and origin airport on to the leaflet

map3 = leaflet(node3) %>%
  addProviderTiles("CartoDB", group = "CartoDB") %>% 
  addTiles()

for(i in 1:nrow(node3)){
    map3 <- addPolylines(map3, lat = as.numeric(node3[i, c(2, 6)]), 
                               lng = as.numeric(node3[i, c(1, 5)]))
    
    
    #origin
    map3<-addCircleMarkers(map3, lat = as.numeric(node3[i, 2]), 
                               lng = as.numeric(node3[i,1]),radius =(as.numeric(node3[i, 4]))*100,color='red')
    #destination
    map3<-addCircleMarkers(map3, lat = as.numeric(node3[i, 6]), 
                               lng = as.numeric(node3[i, 5]),radius =(as.numeric(node3[i, 8]))*100,color='red' )
    
}
map3
map <- get_map(location = c(lon = 103.7662684, lat = 1.2869421), zoom=14, source = "google", maptype = 'watercolor')

bus_graph$layout=cbind(V(bus_graph)$Longitude,V(bus_graph)$Latitude)

#arrow formating
a <- arrow(type = "closed", length = unit(.09, "inches"))

#from the below code we are telling ggmap to take ggraph as your base layer with layout as the cordinates. 
#Here we get the curvature using geom_edge_arc.

g<-ggmap(map, fullpage = TRUE, base_layer = ggraph(bus_graph)) + 
  geom_edge_arc(aes(edge_size=E(bus_graph)$centrality_degree),edge_colour = 'red', edge_alpha = 0.5,curvature = 0.2, arrow=a, end_cap = circle(.008, 'inches')) +
  geom_node_point(aes(colour = closeness_centrality,size=betweenness_centrality))+ scale_colour_gradientn(colours=rainbow(3))+scale_size_continuous(range = c(1, 10))

plot(g)