Routing and analysis engine for GTFS (General Transit Feed Specification) data
at main 110 lines 3.8 kB view raw
1#include "csa.h" 2 3//' rcpp_make_timetable 4//' 5//' Make timetable from GTFS stop_times. Both stop_ids and trip_ids are vectors 6//' of unique values which are converted to unordered_maps on to 1-indexed 7//' integer values. 8//' 9//' @noRd 10// [[Rcpp::export]] 11Rcpp::DataFrame rcpp_make_timetable (Rcpp::DataFrame stop_times, 12 std::vector <std::string> stop_ids, std::vector <std::string> trip_ids) 13{ 14 Timetable_Inputs tt_in; 15 timetable::timetable_in_from_df (stop_times, tt_in); 16 17 size_t n = timetable::count_connections (tt_in); 18 19 Timetable_Outputs tt_out; 20 timetable::initialise_tt_outputs (tt_out, n); 21 timetable::make_timetable (tt_in, tt_out, stop_ids, trip_ids); 22 23 Rcpp::DataFrame timetable = Rcpp::DataFrame::create ( 24 Rcpp::Named ("departure_station") = tt_out.departure_station, 25 Rcpp::Named ("arrival_station") = tt_out.arrival_station, 26 Rcpp::Named ("departure_time") = tt_out.departure_time, 27 Rcpp::Named ("arrival_time") = tt_out.arrival_time, 28 Rcpp::Named ("trip_id") = tt_out.trip_id, 29 Rcpp::_["stringsAsFactors"] = false); 30 31 return timetable; 32} 33 34void timetable::timetable_in_from_df (Rcpp::DataFrame &stop_times, 35 Timetable_Inputs &tt_in) 36{ 37 tt_in.stop_id = Rcpp::as <std::vector <std::string> > (stop_times ["stop_id"]); 38 tt_in.trip_id = Rcpp::as <std::vector <std::string> > (stop_times ["trip_id"]); 39 tt_in.arrival_time = Rcpp::as <std::vector <int> > ( 40 stop_times ["arrival_time"]); 41 tt_in.departure_time = Rcpp::as <std::vector <int> > ( 42 stop_times ["departure_time"]); 43} 44 45size_t timetable::count_connections (const Timetable_Inputs &tt_in) 46{ 47 size_t n_connections = 0; 48 std::string trip_id_i = tt_in.trip_id [0]; 49 for (size_t i = 1; i < tt_in.trip_id.size (); i++) 50 { 51 if (tt_in.trip_id [i] == trip_id_i) 52 n_connections++; 53 else 54 { 55 trip_id_i = tt_in.trip_id [i]; 56 } 57 } 58 return n_connections; 59} 60 61void timetable::initialise_tt_outputs (Timetable_Outputs &tt_out, size_t n) 62{ 63 tt_out.departure_time.resize (n); 64 tt_out.arrival_time.resize (n); 65 tt_out.departure_station.resize (n); 66 tt_out.arrival_station.resize (n); 67 tt_out.trip_id.resize (n); 68} 69 70void timetable::make_trip_stop_map (const std::vector <std::string> &input, 71 std::unordered_map <std::string, int> &output_map) 72{ 73 int count = 1; // 1-indexed 74 for (auto i: input) 75 output_map.emplace (i, count++); 76} 77 78void timetable::make_timetable (const Timetable_Inputs &tt_in, 79 Timetable_Outputs &tt_out, 80 const std::vector <std::string> &stop_ids, 81 const std::vector <std::string> &trip_ids) 82{ 83 std::unordered_map <std::string, int> trip_id_map; 84 make_trip_stop_map (trip_ids, trip_id_map); 85 86 std::unordered_map <std::string, int> stop_id_map; 87 make_trip_stop_map (stop_ids, stop_id_map); 88 89 size_t n_connections = 0; 90 std::string trip_id_i = tt_in.trip_id [0]; 91 int dest_stop = stop_id_map.at (tt_in.stop_id [0]); 92 for (size_t i = 1; i < tt_in.trip_id.size (); i++) 93 { 94 if (tt_in.trip_id [i] == trip_id_i) 95 { 96 int arrival_stop = stop_id_map.at (tt_in.stop_id [i]); 97 tt_out.departure_station [n_connections] = dest_stop; 98 tt_out.arrival_station [n_connections] = arrival_stop; 99 tt_out.departure_time [n_connections] = tt_in.departure_time [i - 1]; 100 tt_out.arrival_time [n_connections] = tt_in.arrival_time [i]; 101 tt_out.trip_id [n_connections] = trip_id_map.at (trip_id_i); 102 dest_stop = arrival_stop; 103 n_connections++; 104 } else 105 { 106 dest_stop = stop_id_map.at (tt_in.stop_id [i]); 107 trip_id_i = tt_in.trip_id [i]; 108 } 109 } 110}