在R Shiny中使用gcIntermediate的问题?

时间:2015-08-20 11:24:33

标签: r shiny shiny-server great-circle

我一直在使用R Shiny处理应用程序,除了我在Shiny服务器中调用gcIntermediate之外的一小部分外,一切正常。我想知道这是一个典型的问题,还是我正在做一些可怕的错误,我很遗憾地忘记了。我有一套约30,000个城市,他们的国家,坐标,邮政编码等。在这个应用程序的一部分,我想R绘制世界地图上连接点A和B的大圆圈。但是,由于在Shiny环境中运行时draw_line的值未定义,因此我没有成功。如果我提供它并在Shiny之外运行它,它确实可以正常工作。因此,我被困住了。

这是UI

#GC Plot Test UI

shinyUI(pageWithSidebar(

  headerPanel("Great Circles on a Map"),

  sidebarPanel(

    h3("Select Origin Codes"),

    uiOutput("choose_origin_code1"),

    uiOutput("choose_origin_code2"),

    h3("Select Destination Codes"),

    uiOutput("choose_destination_code1"),

    uiOutput("choose_destination_code2"),

    br()
  ),


  mainPanel(
    #tableOutput("MapPlot")

    plotOutput("MapPlot")

  )
))

这是服务器:

#GC Plot Test Server

library(shiny)
library(RColorBrewer)
library(ggplot2)
library(maps)
library(mapdata)
library(geosphere)
library(sp)

#Some random cities and locations from my larger data set
city_name <- c("Tunceli", "Udomlya", "Moscow", "Kaunas")
country_code <- c("TR", "RU", "RU", "LT")
city_code <- c(62, 17, 10, 44)
latitude <- c(39.108, 57.879, 55.752, 54.90)
longitude <- c(39.547, 34.993, 37.616, 23.90)
df <- data.frame(city_name, country_code, city_code, latitude, longitude)

map.dat <- map_data("world")

shinyServer(function(input, output) {

  output$choose_origin_code1 <- renderUI({
    selectInput("origin.code1", "Country of Origin", unique(as.character(df$country_code)))
  })

  output$choose_origin_code2 <- renderUI({
    #If missing input, return to avoid error later in function
    if(is.null(input$origin.code1))
      return()

    origin.code2.list1 <- df[grep(as.character(input$origin.code1), as.character(df$country_code)),]
    origin.code2.list2 <- unique(as.character(origin.code2.list1$city_code))

    #Create the checkboxes and deselect them all by default
    selectInput("origin.code2", "Source Location Code", origin.code2.list2)

  })


  output$choose_destination_code1 <- renderUI({
    #Check ship.from.code1 and ship.from.code2 input value
    if(is.null(input$origin.code1) | is.null(input$origin.code2))
      return()

    selectInput("dest.code1", "Destination Country", unique(as.character(df$country_code)))   

  })

  #Destination Location Input
  output$choose_destination_code2 <- renderUI({
    #Check ship.from.code1 and ship.from.code2 input value
    if(is.null(input$dest.code1))
      return()

    dest.code2.list1 <- df[grep(as.character(input$dest.code1), as.character(df$country_code)),]
    dest.code2.list2 <- unique(as.character(dest.code2.list1$city_code))

    selectInput("dest.code2", "Destination Location Code 2", dest.code2.list2)

  })

  #Map the routes
  output$MapPlot <- renderPlot({
    # If missing input, return to avoid error later in function
    if(is.null(input$origin.code1) | is.null(input$origin.code1) | is.null(input$dest.code1) | is.null(input$dest.code2))
      return()

    #Find the row with starting point information
    Origin_Row <- which(df$country_code == input$origin.code1 
                        & df$city_code == input$origin.code2)

    #Find the row with the destination information
    Dest_Row <- which(df$country_code == input$dest.code1
                      & df$city_code == input$dest.code2)

    #Make coordinate data for origin and destination explicit
    Origin_lat <- df$latitude[Origin_Row]
    Origin_lon <- df$longitude[Origin_Row]
    Dest_lat <- df$latitude[Dest_Row]
    Dest_lon <- df$longitude[Dest_Row]

    coords <- data.frame( c(Origin_lon, Dest_lon), c(Origin_lat, Dest_lat))
    colnames(coords) <- c("Lon", "Lat")

    draw_line <- gcIntermediate(coords[1,], coords[2,], n = 100, addStartEnd = TRUE)

    Map_center <- c(mean(coords[(1:2),1]), mean(coords[(1:2),2]), 0) #Centered on Zurich, CH

    p <- ggplot() 
    p <- p + geom_polygon(aes(long,lat, group=group), fill="grey65", data = map.dat) + theme_bw() + theme(axis.text = element_blank(), axis.title = element_blank()) 
    p <- p + geom_line(aes(x = draw_line[,1],
                           y = draw_line[,2]),
                       color = 'red')
    p <- p + coord_map("ortho", orientation = c(Map_center))
    p

  })

})

错误始终发生在我调用draw_line的{​​{1}}部分。我尝试了很多不同的方法来进行故障排除,但我想到的是gcIntermediate()功能与Shiny不兼容。如果是这种情况,是否有人知道如何解决它或可能的解决方法?

额外奖励:我希望我的情节在显示时放大路线,但是当我这样做时,我会对地图失真,所以我坚持世界观。有谁知道如何实现这一目标?

1 个答案:

答案 0 :(得分:1)

我发现问题不是将gcIntermediate的输出放入数据框并重新定义geom_line()图层中的数据。

 draw_line <- data.frame(gcIntermediate(coords[1,], coords[2,], n = 100, addStartEnd = TRUE))

      p <- ggplot() 
      p <- p + geom_polygon(aes(long,lat, group=group), fill="grey65", data = map.dat) + theme_bw() + theme(axis.text = element_blank(), axis.title = element_blank()) 
      p <- p + geom_line(data = draw_line, aes(x = draw_line[,1], y = draw_line[,2], color = 'red'))
      p <- p + coord_map("ortho", orientation = c(Map_center))
      p