Mapping the shortest flight path across the date line in R leaflet/Shiny, using gcIntermediate [duplicate]

。_饼干妹妹 提交于 2019-11-30 08:46:31

问题


I'm creating a map of Australian airports and their international destinations using R-Leaflet.

Here is my sample data:

df<-data.frame("Australian_Airport" = "Brisbane", 
           "International" =  c("Auckland", "Bandar Seri Begawan","Bangkok","Christchurch","Denpasar","Dunedin","Hamilton","Hong Kong","Honiara","Kuala Lumpur"),
           "Australian_lon" = c(153.117, 153.117,153.117,153.117,153.117,153.117, 153.117, 153.117, 153.117, 153.117),
           "Australian_lat" = c(-27.3842,-27.3842,-27.3842,-27.3842,-27.3842,-27.3842, -27.3842, -27.3842, -27.3842, -27.3842),
           "International_lon" = c(174.7633, 114.9398, 100.5018, 172.6362, 115.2126,-82.77177, -84.56134, 114.10950, 159.97290, 101.68685),
           "International_lat" = c(-36.848460, 4.903052, 13.756331, -43.532054,-8.670458,28.019740, 39.399501, 22.396428, -9.445638,  3.139003)
           )

I thought it would be cool to use curved flight paths using gcIntermediate, so I created a SpatialLines object:

library(rgeos)
library(geosphere)

p1<-as.matrix(df[,c(3,4)])

p2<-as.matrix(df[,c(5,6)])

df2 <-gcIntermediate(p1, p2, breakAtDateLine=F, 
                    n=100, 
                    addStartEnd=TRUE,
                    sp=T) 

And then I plotted it using leaflet and Shiny:

server <-function(input, output) {

airportmap<- leaflet() %>% addTiles() %>% 
    addCircleMarkers(df, lng = df$Australian_lon, lat = df$Australian_lat, 
    radius = 2, label = paste(df$Australian_Airport, "Airport"))%>% 
    addPolylines(data = df2, weight = 1)

output$mymap <- renderLeaflet({airportmap}) # render the base map
  }


ui<-  navbarPage("International flight path statistics - top routes",
      tabPanel("Interactive map",

      leafletOutput('mymap',  width="100%", height=900)

         )
         )

# Run the application 
shinyApp(ui = ui, server = server)

It looks like this:

So the paths are incorrect if they cross the date line. Changing breakAtDateLine to FALSE doesn't fix it (the line disappears but the path is still broken). At this stage, I suspect I may need to use a different mapping system or something but I'd be very grateful if anyone has some advice.

Thanks in advance.


回答1:


If you are interested in another mapping library, then googleway uses Google Maps, which in my experience is better at handling lines that cross the date line.

Notes

  1. To use Google Maps you need an API key
  2. Currently only sf objects are supported, not sp
  3. This will also work in shiny; I'm just showing you the basic map here
  4. I authored googleway

library(sf)
library(googleway)

## convert the sp object to sf
sf <- sf::st_as_sf(df2)

set_key("your_api_key")

google_map() %>%
    add_polylines(data = sf)




回答2:


Overview

I set the max bounds and minimum zoom level to only display the world map once. It looks okay in the RStudio viewer but fails when I display it in browser. I'm hoping this helps spark other answers.

Code

# load necessary packages
library( leaflet )
library( geosphere )

# create data
df <- 
  data.frame("Australian_Airport" = "Brisbane", 
             "International" =  c("Auckland", "Bandar Seri Begawan","Bangkok","Christchurch","Denpasar","Dunedin","Hamilton","Hong Kong","Honiara","Kuala Lumpur"),
             "Australian_lon" = c(153.117, 153.117,153.117,153.117,153.117,153.117, 153.117, 153.117, 153.117, 153.117),
             "Australian_lat" = c(-27.3842,-27.3842,-27.3842,-27.3842,-27.3842,-27.3842, -27.3842, -27.3842, -27.3842, -27.3842),
             "International_lon" = c(174.7633, 114.9398, 100.5018, 172.6362, 115.2126,-82.77177, -84.56134, 114.10950, 159.97290, 101.68685),
             "International_lat" = c(-36.848460, 4.903052, 13.756331, -43.532054,-8.670458,28.019740, 39.399501, 22.396428, -9.445638,  3.139003)
             , stringsAsFactors = FALSE
  )

# create curved lines
curved.lines <-
  gcIntermediate(
    p1 = as.matrix( x = df[ , 3:4 ] )
    , p2 = as.matrix( x = df[ , 5:6 ] )
    , breakAtDateLine = TRUE
    , n = 1000
    , addStartEnd = TRUE
    , sp = TRUE
  ) 

# create leaflet
airport <-
  leaflet( options = leafletOptions( minZoom = 1) ) %>%
  setMaxBounds( lng1 = -180
                , lat1 = -89.98155760646617
                , lng2 = 180
                , lat2 = 89.99346179538875 ) %>%
  addTiles() %>% 
  addCircleMarkers( data = df
                    , lng = ~Australian_lon
                    , lat = ~Australian_lat
                    , radius = 2
                    , color = "red"
                    , label = paste( ~Australian_Airport
                                     , "Airport" )
  ) %>% 
  addCircleMarkers( data = df
                    , lng = ~International_lon
                    , lat = ~International_lat
                    , radius = 2
                    , color = "blue"
                    , label = paste( ~International
                                     , "Airport" )
  ) %>% 
  addPolylines( data = curved.lines
                , weight = 1 
                )
# display map
airport

# end of script #


来源:https://stackoverflow.com/questions/48857748/mapping-the-shortest-flight-path-across-the-date-line-in-r-leaflet-shiny-using

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