使用R创建GTFS实时(车辆位置) [英] Create a GTFS realtime (vehicle positions) with R

查看:96
本文介绍了使用R创建GTFS实时(车辆位置)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我致力于将数据帧实时转换为GTFS,并在车辆位置方面苦苦挣扎.

I work on turning a dataframe into a GTFS realtime, and am struggling on the vehicle position part.

我的数据看起来像这样(存储在称为车辆"的数据框中):

My data looks like that (stored in a dataframe called "vehicle"):

## Input data looks that way, one line per on-going vehicle
vehicle_id      trip_id   lat    lon bear speed           stop_time
52108 4.264930e+05 45.40 -71.92    1     9 2017-05-02 15:19:05
60105 4.273610e+05 45.40 -71.90  246     6 2017-05-02 15:18:59
59104 4.270150e+05 45.40 -71.87   81     7 2017-05-02 15:18:54

我的代码的详细信息是:

The details of my code is:

library(dplyr)
library(XML)
library(stringr)
library(RProtoBuf)
library(RODBC)

## Read the google gtfs proto file
readProtoFiles("gtfs-realtime.proto")

## List of current vehicles
current_vehicles <- unique(vehicle$vehicle_id)

## Create an empty list, 1 entry for each vehicle
protobuf_list <- vector(mode = "list", length = length(current_vehicles))

## Loop over all current vehicles
for(i in 1:length(current_vehicles)) {
  ## protobuf object 
  vehicle_position_update <- new(transit_realtime.VehiclePosition,
                                   vehicle = vehicle$vehicle_id[i],
                                   stop_id = vehicle$stop_id[i],
                                   trip = vehicle$trip_id[i],
                                   latitude = vehicle$lat[i],
                                   longitude = vehicle$lon[i],
                                   bearing = vehicle$bear[i],
                                   speed = vehicle$speed[i])

        ## protobuf feed entity
  e <- new(transit_realtime.FeedEntity,
           id = as.character(vehicle$vehicle_id[i]),
           vehicle = new(transit_realtime.VehiclePosition,
                             trip = new(transit_realtime.VehicleDescriptor,
                                        id = vehicle$vehicle_id[i]),
                         VehiclePosition = vehicle_position_update))

  ## Fill the list
  protobuf_list[[i]] <- e
}# Loop over vehicles

## GTFS header
header_object <- new(transit_realtime.FeedHeader,
                     gtfs_realtime_version = "1.0",
                     incrementality = "FULL_DATASET",
                     timestamp = as.numeric(as.POSIXlt(Sys.time())))

## Build the full GTFS
m <- new(transit_realtime.FeedMessage,
         header = header_object,
         entity = protobuf_list) # use entity_list

## Write the GTFS
writeLines(as.character(m))

## Turn it into binary
serialize(m, "vehiclePositions.pb")

创建原型缓冲区对象vehicle_position_update时,它崩溃并显示以下消息:

When creating the protobuffer object vehicle_position_update, it crashes with the message:

  type mismatch, expecting a 'Message' object

我通过了gtfs-realtime.proto,对包含的不同消息的理解似乎还不错(嗯,显然不是.)

I went through the gtfs-realtime.proto, and my understanding of the different messages to include seems fine (well, obviously it'nt..).

有人知道为什么无法创建该protobuffer文件吗?

Does anyone see why this protobuffer file cannot be created?

添加了一个清晰的解决方案:

ADDED FOR A CLEAR SOLUTION:

我的问题是我没有完全遵循不同消息的gtfs原型描述.一旦更正了这一点,车辆上的循环就变成:

My issue was that I was'nt following exactly the gtfs proto descriptions of the different messages. Once this point corrected, the loop over the vehicles becomes:

## Loop over all current vehicles
for(i in 1:length(current_vehicles)) {
    ## protobuf object
     vehicle_position_update <- new(transit_realtime.Position,
                                   latitude = vehicle$lat[i],
                                   longitude = vehicle$lon[i],
                                   bearing = vehicle$bear[i],
                                   speed = vehicle$speed[i])
        ## protobuf feed entity
  e <- new(transit_realtime.FeedEntity,
           id = as.character(vehicle$vehicle_id[i]),
           vehicle = new(transit_realtime.VehiclePosition,
                             trip = new(transit_realtime.TripDescriptor,
                                        trip_id = vehicle$trip_id[i],
                                        route_id = vehicle$route_id[i]),
                         stop_id = vehicle$stop_id[i],
                         position = vehicle_position_update))
  ## Fill the list
  protobuf_list[[i]] <- e
}# Loop over vehicles

它有效

推荐答案

消息定义告诉您它需要哪些字段,例如

The message definition tells you what fields it requires, for example

writeLines(as.character(RProtoBuf::fileDescriptor(transit_realtime.FeedMessage)))

message FeedMessage {
  required .transit_realtime.FeedHeader header = 1;
  repeated .transit_realtime.FeedEntity entity = 2;
  extensions 1000 to 1999;
}

message FeedHeader {
  enum Incrementality {
    FULL_DATASET = 0;
    DIFFERENTIAL = 1;
  }
  required string gtfs_realtime_version = 1;
  optional .transit_realtime.FeedHeader.Incrementality incrementality = 2 [default = FULL_DATASET];
  optional uint64 timestamp = 3;
  extensions 1000 to 1999;
}

message FeedEntity {
  required string id = 1;
  optional bool is_deleted = 2 [default = false];
  optional .transit_realtime.TripUpdate trip_update = 3;
  optional .transit_realtime.VehiclePosition vehicle = 4;
  optional .transit_realtime.Alert alert = 5;
  extensions 1000 to 1999;
}
... etc

然后,如果您查看Position消息,则会看到字段

Then, if you take a look at the Position message, you see the fields

message Position {
  required float latitude = 1;
  required float longitude = 2;
  optional float bearing = 3;
  optional double odometer = 4;
  optional float speed = 5;
  extensions 1000 to 1999;
}

因此,您可以使用这些值来定义Position,例如

So you define the Position using those values, e.g.

RProtoBuf::new(transit_realtime.Position, latitude = 0, longitude = 0)  

VehiclePosition消息是

message VehiclePosition {
  enum VehicleStopStatus {
    INCOMING_AT = 0;
    STOPPED_AT = 1;
    IN_TRANSIT_TO = 2;
  }
  enum CongestionLevel {
    UNKNOWN_CONGESTION_LEVEL = 0;
    RUNNING_SMOOTHLY = 1;
    STOP_AND_GO = 2;
    CONGESTION = 3;
    SEVERE_CONGESTION = 4;
  }
  enum OccupancyStatus {
    EMPTY = 0;
    MANY_SEATS_AVAILABLE = 1;
    FEW_SEATS_AVAILABLE = 2;
    STANDING_ROOM_ONLY = 3;
    CRUSHED_STANDING_ROOM_ONLY = 4;
    FULL = 5;
    NOT_ACCEPTING_PASSENGERS = 6;
  }
  optional .transit_realtime.TripDescriptor trip = 1;
  optional .transit_realtime.VehicleDescriptor vehicle = 8;
  optional .transit_realtime.Position position = 2;
  optional uint32 current_stop_sequence = 3;
  optional string stop_id = 7;
  optional .transit_realtime.VehiclePosition.VehicleStopStatus current_status = 4 [default = IN_TRANSIT_TO];
  optional uint64 timestamp = 5;
  optional .transit_realtime.VehiclePosition.CongestionLevel congestion_level = 6;
  optional .transit_realtime.VehiclePosition.OccupancyStatus occupancy_status = 9;
  extensions 1000 to 1999;
}

所以消息会像

RProtoBuf::new(transit_realtime.VehiclePosition, 
                             current_status = 1,
                             congestion_level = 0,
                             stop_id = "7", 
                             current_stop_sequence = 1)

这篇关于使用R创建GTFS实时(车辆位置)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆