2017-05-02 5 views
1

Ich arbeite an einem Datenrahmen in eine GTFS-Echtzeit zu verwandeln, und bin am Fahrzeug Position Teil kämpfen.Erstellen Sie eine GTFS-Echtzeit (Fahrzeugpositionen) mit R

Meine Daten sieht so aus (gespeichert in einem Datenrahmen genannt "Fahrzeug"):

## 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 

Die Einzelheiten meiner Code ist:

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") 

Wenn das vehicle_position_update protobuffer Objekt erstellen, stürzt mit der Nachricht:

type mismatch, expecting a 'Message' object 

Ich ging durch die gtfs-realtime.proto, und Mein Verständnis der verschiedenen Botschaften scheint gut zu sein (naja, offensichtlich ist es nicht ...).

Kann jemand sehen, warum diese protobuffer-Datei nicht erstellt werden kann?

ZUSÄTZLICH FÜR eine klare Lösung:

Mein Problem war, dass ich folgende genau was'nt die gtfs proto Beschreibungen der verschiedenen Botschaften. Sobald dieser Punkt korrigiert, wird die Schleife über die Fahrzeuge:

## 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 

und es funktioniert

+0

ist der Fehler speziell an der Linie 'vehicle_position_update <- neu (...)'? – SymbolixAU

+0

ja, mit einem einfachen Druck (1) und Drucken (2) vor und nach dieser Zeile, es druckt nie 2 –

Antwort

1

Die Meldung Definition sagt Ihnen, welche Felder es erfordert, zum Beispiel

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 

Dann, wenn Sie nehmen ein Blick auf die Position Nachricht finden Sie die Felder

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; 
} 

So Sie definieren die Position unter Verwendung dieser Werte, z.

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

Und die VehiclePosition Nachricht ist

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; 
} 

So ist die Nachricht sein wird

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

Richtig, das Problem war klar zu folgen, die Bedürfnisse und Definitionen jeder Nachricht wie von der Proto-Datei erstellt. Vielen Dank! –

Verwandte Themen