Using an API to calculate distance between two airports (two columns) within R?

时间:2022-01-30 15:21:48

I was wondering whether there was a way to compare airport distances(IATA codes). There are some scripts but not is using R. So I tried that with with the API:

我想知道是否有办法比较机场距离(IATA代码)。有一些脚本,但没有使用R.所以我尝试使用API​​:

developer.aero

Example data:

library(curl) # for curl post

departure <- c("DRS","TXL","STR","DUS","LEJ","FKB","LNZ")
arrival <- c("FKB","HER","BOJ","FUE","PMI","AYT","FUE")
flyID <- c(1,2,3,4,5,6,7)
df <- data.frame(departure,arrival,flyID)  

     departure arrival flyID
1       DRS     FKB     1
2       TXL     HER     2
3       STR     BOJ     3
4       DUS     FUE     4
5       LEJ     PMI     5
6       FKB     AYT     6
7       LNZ     FUE     7

api<- curl_fetch_memory("https://airport.api.aero/airport/distance/DRS/FUE?user_key=d805e84363494ca03b9b52d5a505c4d1")

cat(rawToChar(api$content))

callback({"processingDurationMillis":0,"authorisedAPI":true,"success":true,"airline":null,"errorMessage":null,"distance":"3,416.1","units":"km"})

where DRS corresponds to departure and FUE arrival airport

其中DRS对应于出发和FUE到达机场

So I though to loop over dfand paste into url. However that seems somehow difficult for a R - Newbie

所以我想把dfand粘贴到url上。然而,对于R - Newbie而言,这似乎有些困难

df$distance<- list(length = nrow(df))
for (i in 1:nrow(df)){
  url <- paste0("https://airport.api.aero/airport/distance/", i, "FUE   ?user_key=d805e84363494ca03b9b52d5a505c4d1")
  myData[[i]] <- read.table(url, header=T,sep="|")
}

Desired Output:

departure arrival flyID    distance
1       DRS     FKB     1    1000
2       TXL     HER     2    499
3       STR     BOJ     3    300
4       DUS     FUE     4    200
5       LEJ     PMI     5    586
6       FKB     AYT     6   10292
7       LNZ     FUE     7   3939

3 个解决方案

#1


6  

Here's another way with the httr package:

这是httr包的另一种方式:

library(httr)

callAPI <- function(from, to) {
  res <- GET("https://airport.api.aero",
             path = paste0("airport/distance/", from, "/", to),
             query = list(user_key = "d805e84363494ca03b9b52d5a505c4d1"))
  stop_for_status(res)
  return(content(res, encoding = "UTF-8"))
}


test <- callAPI("DRS", "FKB")
# test
test$distance
# [1] "484.6"

for (i in 1:nrow(df)) {
  from = df[i, "departure"]
  to = df[i, "arrival"]
  df[i, "distance"] <- callAPI(from, to)$distance
}

#   departure arrival flyID distance
# 1       DRS     FKB     1    484.6
# 2       TXL     HER     2  2,131.8
# 3       STR     BOJ     3  1,575.0
# 4       DUS     FUE     4  3,066.3
# 5       LEJ     PMI     5  1,512.4
# 6       FKB     AYT     6  2,264.2
# 7       LNZ     FUE     7  3,258.0

If you want to get the full results, you could use:

如果您想获得完整的结果,可以使用:

all_results <- mapply(function(x,y) { callAPI(x,y) }, df$departure, df$arrival)
cbind(df, t(all_results))
#   departure arrival flyID processingDurationMillis authorisedAPI success airline errorMessage distance units
# 1       DRS     FKB     1                        0          TRUE    TRUE    NULL         NULL    484.6    km
# 2       TXL     HER     2                        0          TRUE    TRUE    NULL         NULL  2,131.8    km
# 3       STR     BOJ     3                        0          TRUE    TRUE    NULL         NULL  1,575.0    km
# 4       DUS     FUE     4                        0          TRUE    TRUE    NULL         NULL  3,066.3    km
# 5       LEJ     PMI     5                        0          TRUE    TRUE    NULL         NULL  1,512.4    km
# 6       FKB     AYT     6                        0          TRUE    TRUE    NULL         NULL  2,264.2    km
# 7       LNZ     FUE     7                        1          TRUE    TRUE    NULL         NULL  3,258.0    km

#2


7  

You can do this without an API, just using the co-ordinates of airports, which are available freely in a database here https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat

你可以在没有API的情况下做到这一点,只需使用机场的坐标,这些坐标可以在数据库中免费获得https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat

## Import airport data
airports <- read.csv("https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat", header = F)

library(geosphere)
## Calculate matrix of differences in km
distance.matrix <- distm(x = airports[,c("V8", "V7")],  y = airports[,c("V8", "V7")])/1000
## This may take a while, and will generate a matrix 8107 by 8107, about 0.5gb in size.

## Rename dimensions to airport codes
rownames(distance.matrix) <- airports$V5
colnames(distance.matrix) <- airports$V5

## Example: km between Gatwick and Heathrow
distance.matrix["LGW", "LHR"]
[1] 41.24091

#3


1  

What about the following loop over your api calls?

api调用的以下循环怎么样?

df$distance <- 0

for (i in nrow(df)){
  drs <- df[i,]$departure
  fue <- df[i,]$arrival
  url <- paste0("https://airport.api.aero/airport/distance/", drs, "/", fue, "?user_key=4e816a2bf391f8379df1c42d2762069e")
  api <- curl_fetch_memory(url)
  text <- rawToChar(api$content)
  distance <- as.numeric(gsub(',','',substr(text,regexpr('distance',text)+11,regexpr('units',text)-4)))
  df[1,]$distance <- distance
}

df

#1


6  

Here's another way with the httr package:

这是httr包的另一种方式:

library(httr)

callAPI <- function(from, to) {
  res <- GET("https://airport.api.aero",
             path = paste0("airport/distance/", from, "/", to),
             query = list(user_key = "d805e84363494ca03b9b52d5a505c4d1"))
  stop_for_status(res)
  return(content(res, encoding = "UTF-8"))
}


test <- callAPI("DRS", "FKB")
# test
test$distance
# [1] "484.6"

for (i in 1:nrow(df)) {
  from = df[i, "departure"]
  to = df[i, "arrival"]
  df[i, "distance"] <- callAPI(from, to)$distance
}

#   departure arrival flyID distance
# 1       DRS     FKB     1    484.6
# 2       TXL     HER     2  2,131.8
# 3       STR     BOJ     3  1,575.0
# 4       DUS     FUE     4  3,066.3
# 5       LEJ     PMI     5  1,512.4
# 6       FKB     AYT     6  2,264.2
# 7       LNZ     FUE     7  3,258.0

If you want to get the full results, you could use:

如果您想获得完整的结果,可以使用:

all_results <- mapply(function(x,y) { callAPI(x,y) }, df$departure, df$arrival)
cbind(df, t(all_results))
#   departure arrival flyID processingDurationMillis authorisedAPI success airline errorMessage distance units
# 1       DRS     FKB     1                        0          TRUE    TRUE    NULL         NULL    484.6    km
# 2       TXL     HER     2                        0          TRUE    TRUE    NULL         NULL  2,131.8    km
# 3       STR     BOJ     3                        0          TRUE    TRUE    NULL         NULL  1,575.0    km
# 4       DUS     FUE     4                        0          TRUE    TRUE    NULL         NULL  3,066.3    km
# 5       LEJ     PMI     5                        0          TRUE    TRUE    NULL         NULL  1,512.4    km
# 6       FKB     AYT     6                        0          TRUE    TRUE    NULL         NULL  2,264.2    km
# 7       LNZ     FUE     7                        1          TRUE    TRUE    NULL         NULL  3,258.0    km

#2


7  

You can do this without an API, just using the co-ordinates of airports, which are available freely in a database here https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat

你可以在没有API的情况下做到这一点,只需使用机场的坐标,这些坐标可以在数据库中免费获得https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat

## Import airport data
airports <- read.csv("https://raw.githubusercontent.com/jpatokal/openflights/master/data/airports.dat", header = F)

library(geosphere)
## Calculate matrix of differences in km
distance.matrix <- distm(x = airports[,c("V8", "V7")],  y = airports[,c("V8", "V7")])/1000
## This may take a while, and will generate a matrix 8107 by 8107, about 0.5gb in size.

## Rename dimensions to airport codes
rownames(distance.matrix) <- airports$V5
colnames(distance.matrix) <- airports$V5

## Example: km between Gatwick and Heathrow
distance.matrix["LGW", "LHR"]
[1] 41.24091

#3


1  

What about the following loop over your api calls?

api调用的以下循环怎么样?

df$distance <- 0

for (i in nrow(df)){
  drs <- df[i,]$departure
  fue <- df[i,]$arrival
  url <- paste0("https://airport.api.aero/airport/distance/", drs, "/", fue, "?user_key=4e816a2bf391f8379df1c42d2762069e")
  api <- curl_fetch_memory(url)
  text <- rawToChar(api$content)
  distance <- as.numeric(gsub(',','',substr(text,regexpr('distance',text)+11,regexpr('units',text)-4)))
  df[1,]$distance <- distance
}

df