Home > other >  How to plot arcs between two cities on a globe map using ggplot and sf
How to plot arcs between two cities on a globe map using ggplot and sf

Time:06-11

I have seen R codes generating a global map with ggplot and sf library, but I couldn't understand many of the details as I have limited knowledge in geography. Here is a visualization task I need to do with R.

If I have the coordinates (e.g. latitude and longitude) of two cities in the world, and I want to draw a red arc between them, which is the shorter arc on the great circle passing the two cities, how could I do that? The result should look like what we will get when we look up airline routes on google map.

Here is where I stopped at a fixed global map plot:

library("ggplot2")
library("sf")
world <- ne_countries(scale = "medium", returnclass = "sf")
ggplot(data = world)  
    geom_sf()  
    coord_sf(crs = "some crs code")

The crs part requires specific knowledge in geography, I don't know what to use and the meaning of different codes.

CodePudding user response:

Now, getting back to your question, you may want to plot "Great Circles" between cities, that is the curve that represent the shortest path between points on a sphere (flights uses these lines for optimizing the flight time and fuel):

library(sf)
#> Linking to GEOS 3.9.1, GDAL 3.2.1, PROJ 7.2.1; sf_use_s2() is TRUE
library(rnaturalearth)
library(tidyverse)
world <- ne_countries(scale = "medium", returnclass = "sf")

# Get three cities
cities <- ne_download(type = "populated_places", returnclass = "sf") %>%
  filter(NAME %in% c("San Francisco", "Rio de Janeiro", "Oslo"))

# On Mercator
ggplot(world)  
  geom_sf()  
  geom_sf(data=cities, color="red", size=3)  
  coord_sf(crs="EPSG:3857")

# On Robinson projection
ggplot(world)  
  geom_sf()  
  geom_sf(data=cities, color="red", size=3)  
  coord_sf(crs="ESRI:54030")


# Create great circles
library(geosphere)

init <- cities %>% as("Spatial")
dest <- bind_rows(cities[-1,], cities[1,]) %>% as("Spatial")

lines <- gcIntermediate(
  init,
  dest,
  sp = TRUE,
  addStartEnd = TRUE,
  n = 100,
  breakAtDateLine = FALSE
)
#> Warning in showSRID(uprojargs, format = "PROJ", multiline = "NO", prefer_proj
#> = prefer_proj): Discarded datum Unknown based on WGS84 ellipsoid in Proj4
#> definition

lines_sf <- st_union(st_as_sf(lines))

# Now we have the lines
ggplot(lines_sf)  
  geom_sf()  
  geom_sf(data=cities, color="red")

# Create a nice plot

ggplot(world)  
  geom_sf()  
  geom_sf(data=lines_sf)  
  geom_sf(data=cities, color="red", size=3)  
  coord_sf(crs=" proj=laea  x_0=0  y_0=0  lon_0=-74  lat_0=40")

Created on 2022-06-10 by the reprex package (v2.0.1)

  • Related