使用 R 读取 GTFS 实时文件?

Reading GTFS-realtime files using R?

我想用 R 分析 GTFS-realtime 文件,与静态 GTFS 相比,这些文件是编译的,读取它们比较棘手。

谷歌搜索,我只找到了这个包来处理 GTFS https://github.com/ropenscilabs/gtfsr

但同样,这仅适用于静态 GTFS。

您是否知道处理 GTFS 实时的 cran/github R 包?

另一种解决方案是将 GTFS-RT 转换为更易读的格式,例如 json streaming gtfs real time data into human readable format

我注意到您已经找到了我的 development package, gtfsway. In particular, the example in issue 1 示例,说明了该程序包的工作原理以及它解析实时提要的方式

devtools::install_github("SymbolixAU/gtfsway")
library(gtfsway)
url <- "https://gtfsrt.api.translink.com.au/Feed/SEQ"

response <- httr::GET(url)

FeedMessage <- gtfs_realtime(response)

## the function gtfs_tripUpdates() extracts the 'trip_update' feed
lst <- gtfs_tripUpdates(FeedMessage)  

## The results will obviously change depending on when you read the data
lst[[32]]
# $dt_trip_info
# trip_id start_time start_date route_id
# 1: 8959814-SBL 16_17-SBL_FUL-Friday-04   12:21:00   20170303  709-739
# 
# $dt_stop_time_update
#     stop_sequence stop_id arrival_time arrival_delay departure_time departure_delay
#  1:             1  318944   1488504104         -3556     1488507660               0
#  2:             2  318946   1488507741            21     1488507741              21
#  3:             3  300444   1488507903             3     1488507903               3
#  4:             4  300058   1488507977            17     1488507977              17
#  5:             5  300059   1488508022             2     1488508022               2
#  6:             6  300060   1488508094           -46     1488508094             -46
#  7:             7  300061   1488508115           -25     1488508115             -25
#  8:             8  300062   1488508148           -52     1488508148             -52
#  9:             9  300063   1488508175           -85     1488508175             -85
# 10:            10  300005   1488508299          -141     1488508299            -141
# 11:            11  300053   1488508398          -102     1488508398            -102
# 12:            12  300054   1488508458          -102     1488508458            -102
# 13:            13  300056   1488508638          -102     1488508638            -102
# 14:            14  300055   1488508758          -102     1488508758            -102
# 15:            15  300272   1488508998          -102     1488508998            -102
# 16:            16  319160   1488509058          -102     1488509058            -102

如果您有任何意见和建议,我愿意接受。

GTFS 实时源是二进制 Protocol Buffers, that can be processed by the RProtoBuf 包。

使用本地 South-east 昆士兰 Translink 提要的简单示例:

library(RProtoBuf)

加载指定提要文件实际遵循的格式的实际原型文件:

download.file(url="https://gtfsrt.api.translink.com.au/api/realtime/protobuf", destfile="translink-gtfs-realtime.proto")
readProtoFiles("translink-gtfs-realtime.proto")

选中 'Descriptor Pool'

中现在可用于加载提要的所有 'Descriptors'
ls("RProtoBuf:DescriptorPool")
## [1] "GTFSv2.Realtime.Alert"             "GTFSv2.Realtime.EntitySelector"   
## [3] "GTFSv2.Realtime.FeedEntity"        "GTFSv2.Realtime.FeedHeader"       
## [5] "GTFSv2.Realtime.FeedMessage"       "GTFSv2.Realtime.Position"
## ...

读取实际提要 - 在本例中存储在 'FeedMessage'/'entity'

download.file(url="https://gtfsrt.api.translink.com.au/api/realtime/SEQ/TripUpdates", destfile="SEQ-TripUpdates.pb")
download.file(url="https://gtfsrt.api.translink.com.au/api/realtime/SEQ/VehiclePositions", destfile="SEQ-VehiclePositions.pb")

vehicle_position_feed <- read(GTFSv2.Realtime.FeedMessage,  "SEQ-VehiclePositions.pb")[["entity"]]
trip_update_feed  <- read(GTFSv2.Realtime.FeedMessage,  "SEQ-TripUpdates.pb")[["entity"]]

读取时,每个对象只是一组指向二进制文件部分的指针:

str(vehicle_position_feed)
##List of 6
## $ :Formal class 'Message' [package "RProtoBuf"] with 2 slots
##  .. ..@ pointer:<externalptr> 
##  .. ..@ type   : chr "GTFSv2.Realtime.FeedEntity"
## $ :Formal class 'Message' [package "RProtoBuf"] with 2 slots
##  .. ..@ pointer:<externalptr> 
##  .. ..@ type   : chr "GTFSv2.Realtime.FeedEntity"
## .. 

然后您可以通过遍历文件来构建要使用的数据集,从而从每个数据点提取信息,例如:

data.frame(
  id = sapply(vehicle_position_feed, \(x) x[["id"]] ),
  latitude = sapply(vehicle_position_feed, \(x) x[["vehicle"]][["position"]][["latitude"]] ),
  longitude = sapply(vehicle_position_feed, \(x) x[["vehicle"]][["position"]][["longitude"]] )
)
##                   id  latitude longitude
##1     VU-2123549587_1 -27.06561  153.1595
##2    VU-1176076363_10 -27.30158  152.9881
##3   VU--1272517086_10 -27.49080  153.2397
## ...