使用 R 读取 GTFS 实时文件?

Xav*_*ent 5 r gtfs

我想使用 R 分析 GTFS 实时文件,与静态 GTFS 相比,这些文件被编译并且读取它们更棘手。

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

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

你知道处理 GTFS-realtime 的 cran/github R 包吗?

另一种解决方案是将 GTFS-RT 转换为更具可读性的格式,例如 json 流 gtfs 实时数据转换为人类可读的格式

the*_*ail 1

GTFS 实时源是二进制Protocol Buffers ,可以由RProtoBuf包处理。

使用我当地的昆士兰东南部 Translink feed 的一个简单的工作示例:

library(RProtoBuf)
Run Code Online (Sandbox Code Playgroud)

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

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

检查现在可用于在“描述符池”中加载提要的所有“描述符”

ls("RProtoBuf:DescriptorPool")
## [1] "GTFSv2.Realtime.Alert"             "GTFSv2.Realtime.EntitySelector"   
## [3] "GTFSv2.Realtime.FeedEntity"        "GTFSv2.Realtime.FeedHeader"       
## [5] "GTFSv2.Realtime.FeedMessage"       "GTFSv2.Realtime.Position"
## ...
Run Code Online (Sandbox Code Playgroud)

读取实际的 feed - 在本例中存储在“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"]]
Run Code Online (Sandbox Code Playgroud)

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

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"
## .. 
Run Code Online (Sandbox Code Playgroud)

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

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
## ...
Run Code Online (Sandbox Code Playgroud)