Skip to content

Commit

Permalink
Merge pull request #961 from hove-io/feature/2nd_iteration_on_pickup_…
Browse files Browse the repository at this point in the history
…drop_off_windows

2nd iteration on GTFS adaptation
  • Loading branch information
datanel authored Oct 7, 2024
2 parents 3c744b4 + 315bbb8 commit 90985fb
Show file tree
Hide file tree
Showing 45 changed files with 744 additions and 282 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["Hove <[email protected]>", "Guillaume Pinot <[email protected]>"]
name = "transit_model"
version = "0.67.0"
version = "0.68.0"
license = "AGPL-3.0-only"
description = "Transit data management"
repository = "https://github.com/hove-io/transit_model"
Expand Down Expand Up @@ -39,7 +39,7 @@ parser = []
[dependencies]
anyhow = "1"
chrono = { version = "0.4", default-features = false, features = ["std", "clock"] }
chrono-tz = { version = "0.9", features = ["serde"] }
chrono-tz = { version = "0.10", features = ["serde"] }
csv = "1"
derivative = "2"
geo = "0.28"
Expand Down
8 changes: 6 additions & 2 deletions gtfs2netexfr/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use tracing_subscriber::{
layer::SubscriberExt as _,
util::SubscriberInitExt as _,
};
use transit_model::{configuration, Result};
use transit_model::{configuration, objects::VehicleJourneyScheduleType, Model, Result};

lazy_static::lazy_static! {
pub static ref GIT_VERSION: String = transit_model::binary_full_version(env!("CARGO_PKG_VERSION"));
Expand Down Expand Up @@ -115,7 +115,11 @@ fn run(opt: Opt) -> Result<()> {
..Default::default()
};

let model = transit_model::gtfs::Reader::new(configuration).parse(opt.input)?;
let mut collections =
transit_model::gtfs::Reader::new(configuration).parse_collections(opt.input)?;
collections
.filter_by_vj_schedule_types(vec![VehicleJourneyScheduleType::ArrivalDepartureTimesOnly])?;
let model = Model::new(collections)?;

let mut config = transit_model::netex_france::WriteConfiguration::new(opt.participant)
.current_datetime(opt.current_datetime);
Expand Down
6 changes: 3 additions & 3 deletions ntfs2gtfs/tests/fixtures/output/stop_times.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
trip_id,arrival_time,departure_time,stop_id,stop_sequence,pickup_type,drop_off_type,local_zone_id,stop_headsign,timepoint
trip:1,09:00:00,09:00:00,stop:point:1,0,0,1,,,1
trip:1,09:10:00,09:10:00,stop:point:2,2,1,0,,,1
trip_id,arrival_time,departure_time,start_pickup_drop_off_window,end_pickup_drop_off_window,stop_id,stop_sequence,pickup_type,drop_off_type,local_zone_id,stop_headsign,timepoint,pickup_booking_rule_id,drop_off_booking_rule_id
trip:1,09:00:00,09:00:00,,,stop:point:1,0,0,1,,,1,,
trip:1,09:10:00,09:10:00,,,stop:point:2,2,1,0,,,1,,
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
agency_id,agency_name,agency_url,agency_timezone,agency_lang,agency_phone,agency_email,agency_fare_url
MFDI:1061,Vélizy Vallées,http://www.navitia.io/,Europe/Paris,,,,
MFDI:1071,Roissy Ouest,http://www.navitia.io/,Europe/Paris,,,,
MFDI:1062,Saint Germain Boucles de Seine,http://www.navitia.io/,Europe/Paris,,,,
MFDI:Operator_100,RATP,http://www.navitia.io/,Europe/Paris,,,,
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
id,booking_type,message,phone_number,info_url,booking_url
MFDI:10,0,"Bus de soirée : Le service fonctionne sans réservation, il suffit d'indiquer l'arrêt de descente au conducteur",,,
MFDI:11,0,24h/24 et 7j/7,01 74 37 24 77,https://www.fileo.com/se-deplacer/reserver-votre-fileo/,https://www.fileo.com/tad
MFDI:12,0,,,,
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
route_id,agency_id,route_short_name,route_long_name,route_desc,route_type,route_url,route_color,route_text_color,route_sort_order
MFDI:C01376,MFDI:Operator_100,6,6,,1,,6ECA97,000000,
MFDI:C02060,MFDI:1071,Filéo RS,Filéo Roissy Sud - Villeparisis et Mitry (sur réservation),,3,,4890CD,FFFFFF,
MFDI:C02491,MFDI:1062,Soir,Soir Saint-Germain-en-Laye,,3,,652C8F,FFFFFF,
MFDI:C02513,MFDI:1061,Soir,Soir Versailles-Chantiers,,3,,640082,FFFFFF,
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
object_id,object_system,object_code
MFDI:22167,source,FR::Quay:22167:FR1
MFDI:22173,source,FR::Quay:22173:FR1
MFDI:22073,source,FR::Quay:22073:FR1
MFDI:41403,source,FR::Quay:41403:FR1
MFDI:463194,source,FR::Quay:463194:FR1
MFDI:463042,source,FR::Quay:463042:FR1
MFDI:426813,source,FR::Quay:426813:FR1
MFDI:426214,source,FR::Quay:426214:FR1
MFDI:477725,source,FR::Quay:477725:FR1
MFDI:34582,source,FR::Quay:34582:FR1
MFDI:38175,source,FR::Quay:38175:FR1
MFDI:461909,source,FR::Quay:461909:FR1
MFDI:18995,source,FR::Quay:18995:FR1
MFDI:34605,source,FR::Quay:34605:FR1
MFDI:34744,source,FR::Quay:34744:FR1
MFDI:11584,source,FR::Quay:11584:FR1
MFDI:14081,source,FR::Quay:14081:FR1
MFDI:20324,source,FR::Quay:20324:FR1
MFDI:20312,source,FR::Quay:20312:FR1
MFDI:485179,source,FR::Quay:485179:FR1
MFDI:461827,source,FR::multimodalStopPlace:461827:FR1
MFDI:426072,source,FR::multimodalStopPlace:426072:FR1
MFDI:71639,source,FR::multimodalStopPlace:71639:FR1
MFDI:71673,source,FR::multimodalStopPlace:71673:FR1
MFDI:64589,source,FR::multimodalStopPlace:64589:FR1
MFDI:63880,source,FR::multimodalStopPlace:63880:FR1
MFDI:71026,source,FR::multimodalStopPlace:71026:FR1
MFDI:64509,source,FR::multimodalStopPlace:64509:FR1
MFDI:64485,source,FR::multimodalStopPlace:64485:FR1
MFDI:63534,source,FR::multimodalStopPlace:63534:FR1
MFDI:63529,source,FR::multimodalStopPlace:63529:FR1
MFDI:63438,source,FR::multimodalStopPlace:63438:FR1
MFDI:73556,source,FR::multimodalStopPlace:73556:FR1
MFDI:73596,source,FR::multimodalStopPlace:73596:FR1
MFDI:73591,source,FR::multimodalStopPlace:73591:FR1
MFDI:71347,source,FR::multimodalStopPlace:71347:FR1
MFDI:73486,source,FR::multimodalStopPlace:73486:FR1
MFDI:71199,source,FR::multimodalStopPlace:71199:FR1
MFDI:480959,source,FR::multimodalStopPlace:480959:FR1
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
trip_id,arrival_time,departure_time,start_pickup_drop_off_window,end_pickup_drop_off_window,stop_id,stop_sequence,pickup_type,drop_off_type,local_zone_id,stop_headsign,timepoint,pickup_booking_rule_id,drop_off_booking_rule_id
MFDI:KVVB:158023-C02513-1638-260,22:30:00,22:31:00,,,MFDI:485179,0,0,1,,,1,,
MFDI:KVVB:158023-C02513-1638-260,22:33:00,22:34:00,,,MFDI:426214,1,0,0,,,1,,
MFDI:KVVB:158023-C02513-1638-260,,,22:36:00,22:55:00,MFDI:20312,12,1,2,,,0,MFDI:10,MFDI:10
MFDI:KVVB:158023-C02513-1638-260,,,22:36:00,22:55:00,MFDI:20324,24,1,2,,,0,MFDI:10,MFDI:10
MFDI:KVVB:158023-C02513-1638-260,,,22:36:00,22:55:00,MFDI:11584,32,1,2,,,0,MFDI:10,MFDI:10
MFDI:BOUCLE_DE_LYS:149996-C02491-18777678,,,23:15:00,23:48:00,MFDI:34605,0,2,1,,,0,MFDI:12,MFDI:12
MFDI:BOUCLE_DE_LYS:149996-C02491-18777678,,,23:15:00,23:48:00,MFDI:34744,1,2,2,,,0,MFDI:12,MFDI:12
MFDI:BOUCLE_DE_LYS:149996-C02491-18777678,,,23:15:00,23:48:00,MFDI:14081,15,2,2,,,0,MFDI:12,MFDI:12
MFDI:BOUCLE_DE_LYS:149996-C02491-18777678,,,23:15:00,23:48:00,MFDI:34582,25,2,2,,,0,MFDI:12,MFDI:12
MFDI:BOUCLE_DE_LYS:149996-C02491-18777678,,,23:15:00,23:48:00,MFDI:461909,35,1,2,,,0,MFDI:12,MFDI:12
MFDI:KRO6:153358-C02060-680-260,26:39:00,26:39:00,,,MFDI:477725,0,2,1,,,1,MFDI:11,MFDI:11
MFDI:KRO6:153358-C02060-680-260,26:40:00,26:40:00,,,MFDI:38175,1,2,2,,,1,MFDI:11,MFDI:11
MFDI:KRO6:153358-C02060-680-260,26:52:00,26:52:00,,,MFDI:18995,17,2,2,,,1,MFDI:11,MFDI:11
MFDI:KRO6:153358-C02060-680-260,27:06:00,27:06:00,,,MFDI:41403,32,2,2,,,1,MFDI:11,MFDI:11
MFDI:KRO6:153358-C02060-680-260,27:15:00,27:15:00,,,MFDI:426813,37,1,2,,,1,MFDI:11,MFDI:11
MFDI:RATP:153912-C01376-COU_RATP_5086613_2991428_116,10:30:00,10:30:00,,,MFDI:22073,0,0,1,,,1,,
MFDI:RATP:153912-C01376-COU_RATP_5086613_2991428_116,10:31:00,10:31:00,,,MFDI:22167,1,0,0,,,1,,
MFDI:RATP:153912-C01376-COU_RATP_5086613_2991428_116,10:43:00,10:43:00,,,MFDI:22173,11,0,0,,,1,,
MFDI:RATP:153912-C01376-COU_RATP_5086613_2991428_116,10:54:00,10:54:00,,,MFDI:463194,20,0,0,,,1,,
MFDI:RATP:153912-C01376-COU_RATP_5086613_2991428_116,11:03:00,11:03:00,,,MFDI:463042,27,1,0,,,1,,
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
stop_id,stop_code,stop_name,stop_desc,stop_lon,stop_lat,zone_id,stop_url,location_type,parent_station,stop_timezone,level_id,wheelchair_boarding,platform_code
MFDI:22167,,Picpus,,2.401248269453829,48.84501767720269,1,,0,MFDI:71639,Europe/Paris,,2,
MFDI:22173,,Glacière,,2.3434974927179884,48.831170235245835,1,,0,MFDI:71026,Europe/Paris,,2,
MFDI:22073,,Nation,,2.3958598043279085,48.84789550545761,1,,0,MFDI:71673,Europe/Paris,,2,
MFDI:41403,,Cargo Centre,,2.526990016633599,48.99817129747993,5,,0,MFDI:73591,Europe/Paris,,1,
MFDI:463194,,La Motte-Picquet - Grenelle,,2.298957096977008,48.848765448122315,1,,0,MFDI:71199,Europe/Paris,,2,
MFDI:463042,,Charles de Gaulle - Etoile,,2.2947520493673434,48.87371127132366,1,,0,MFDI:71347,Europe/Paris,,2,
MFDI:426813,,Gare de Roissypole - Aéroport CDG1 Terminal 3 (C4),,2.559069276593061,49.010290004685544,,,0,MFDI:73596,Europe/Paris,,2,
MFDI:426214,,La Logeraie,,2.1359934967138585,48.766289059613705,4,,0,MFDI:63529,Europe/Paris,,1,
MFDI:477725,,Verdi,,2.577391101137773,48.961194121418,4,,0,MFDI:480959,Europe/Paris,,2,
MFDI:34582,,Fourqueux,,2.0804267048554177,48.89058561987773,,,0,MFDI:64509,Europe/Paris,,1,
MFDI:38175,,Parmentier,,2.561581492140883,48.947693512717194,4,,0,MFDI:73486,Europe/Paris,,2,
MFDI:461909,,Gare de Saint-Germain-en-Laye,,2.094588526727687,48.898931576292874,,,0,MFDI:64589,Europe/Paris,,1,
MFDI:18995,,Croix l'Aumône,,2.524710804326184,48.96497157469924,4,,0,MFDI:73556,Europe/Paris,,2,
MFDI:34605,,Gare de Saint-Germain-en-Laye,,2.0939283750483924,48.89924135453759,,,0,MFDI:64589,Europe/Paris,,1,
MFDI:34744,,République,,2.0927460449808457,48.89812620815719,,,0,MFDI:426072,Europe/Paris,,1,
MFDI:11584,,Porte Jaune,,2.229129261380777,48.76610796421317,4,,0,MFDI:63534,Europe/Paris,,1,
MFDI:14081,,Victor Hugo,,2.063504165681303,48.886623198199004,,,0,MFDI:64485,Europe/Paris,,2,
MFDI:20324,,Clos Normand,,2.186312472329811,48.75818767629223,4,,0,MFDI:63438,Europe/Paris,,1,
MFDI:20312,,Les Tilleuls,,2.1615499577506054,48.76517599148135,4,,0,MFDI:461827,Europe/Paris,,2,
MFDI:485179,,Gare routière de Versailles Chantiers - Quai G,,2.1340608589561016,48.795848498088226,4,,0,MFDI:63880,Europe/Paris,,1,
MFDI:461827,,Les Tilleuls,,2.1613451720416506,48.76521952597488,,,1,,,,0,
MFDI:426072,,République / Rue de la Salle,,2.092660713832334,48.89762192758876,,,1,,,,0,
MFDI:71639,,Picpus,,2.402166806721031,48.845125696754025,,,1,,,,0,
MFDI:71673,,Nation,,2.3963316057344417,48.848927647042316,,,1,,,,0,
MFDI:64589,,Saint-Germain-en-Laye,,2.0951814549394174,48.899349756253876,,,1,,,,0,
MFDI:63880,,Versailles Chantiers,,2.134652391388478,48.79588875952142,,,1,,,,0,
MFDI:71026,,Glacière,,2.3438687884909264,48.8308934672617,,,1,,,,0,
MFDI:64509,,Fourqueux,,2.080767458510045,48.89098395203159,,,1,,,,0,
MFDI:64485,,Victor Hugo,,2.063504165681303,48.886623198199004,,,1,,,,0,
MFDI:63534,,Porte Jaune,,2.2291546111332714,48.766234048830825,,,1,,,,0,
MFDI:63529,,La Logeraie,,2.1363481054691924,48.76623765829017,,,1,,,,0,
MFDI:63438,,Clos Normand,,2.1861969917891195,48.758177894949306,,,1,,,,0,
MFDI:73556,,Croix l'Aumône,,2.524833265434999,48.965021518604,,,1,,,,0,
MFDI:73596,,Roissy Aéroport CDG 1 (Terminal 3) (Tremblay-en-France),,2.5601295519817535,49.01033329803776,,,1,,,,0,
MFDI:73591,,Cargo Centre,,2.5261341855607036,48.998356758085166,,,1,,,,0,
MFDI:71347,,Charles de Gaulle - Etoile,,2.2946168784613463,48.87362503818625,,,1,,,,0,
MFDI:73486,,Parmentier / Saint Vincent de Paul,,2.5608350156242676,48.94635987507931,,,1,,,,0,
MFDI:71199,,La Motte-Picquet - Grenelle,,2.2984077121284154,48.84918377697637,,,1,,,,0,
MFDI:480959,,Verdi,,2.577391101137773,48.961194121418,,,1,,,,0,
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from_stop_id,to_stop_id,transfer_type,min_transfer_time
MFDI:34744,MFDI:461909,2,206
MFDI:34744,MFDI:34605,2,192
MFDI:34605,MFDI:34744,2,192
MFDI:461909,MFDI:34744,2,206
MFDI:461909,MFDI:34605,2,62
MFDI:34605,MFDI:461909,2,62
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
route_id,service_id,trip_id,trip_headsign,trip_short_name,direction_id,block_id,shape_id,wheelchair_accessible,bikes_allowed
MFDI:C02513,MFDI:1000,MFDI:KVVB:158023-C02513-1638-260,Porte Jaune,,1,,,0,0
MFDI:C02491,MFDI:1,MFDI:BOUCLE_DE_LYS:149996-C02491-18777678,Gare de St-Germain-en-Laye - Gare Routière,,0,,,0,0
MFDI:C02060,MFDI:1000,MFDI:KRO6:153358-C02060-680-260,Gare de Roissypole Aéroport CDG 1,,1,,,0,0
MFDI:C01376,MFDI:1,MFDI:RATP:153912-C01376-COU_RATP_5086613_2991428_116,Charles de Gaulle-Etoile,,1,,,2,0
18 changes: 18 additions & 0 deletions ntfs2gtfs/tests/ntfs2gtfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,21 @@ fn test_ntfs2gtfs_with_fare_urls_and_deeplinks() {
"./tests/fixtures/output_gtfs_with_fare_url_deeplinks",
);
}

#[test]
fn test_ntfs2gtfs_with_pickup_drop_off_windows_stoptimes() {
let output_dir = TempDir::new().expect("create temp dir failed");
Command::cargo_bin("ntfs2gtfs")
.expect("Failed to find binary 'ntfs2gtfs'")
.arg("--input")
.arg("../tests/fixtures/pickup_drop_off_windows/input_ntfs")
.arg("--output")
.arg(output_dir.path().to_str().unwrap())
.assert()
.success();
compare_output_dir_with_expected(
output_dir,
None,
"./tests/fixtures/output_gtfs_pickup_drop_off_windows",
);
}
4 changes: 3 additions & 1 deletion ntfs2netexfr/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use tracing_subscriber::{
layer::SubscriberExt as _,
util::SubscriberInitExt as _,
};
use transit_model::{Model, Result};
use transit_model::{objects::VehicleJourneyScheduleType, Model, Result};

lazy_static::lazy_static! {
pub static ref GIT_VERSION: String = transit_model::binary_full_version(env!("CARGO_PKG_VERSION"));
Expand Down Expand Up @@ -91,6 +91,8 @@ fn run(opt: Opt) -> Result<()> {

let mut collections = transit_model::ntfs::read_collections(opt.input)?;
collections.remove_route_points();
collections
.filter_by_vj_schedule_types(vec![VehicleJourneyScheduleType::ArrivalDepartureTimesOnly])?;
let model = Model::new(collections)?;

let mut config = transit_model::netex_france::WriteConfiguration::new(opt.participant)
Expand Down
23 changes: 23 additions & 0 deletions ntfs2netexfr/tests/ntfs2netexfr.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use assert_cmd::prelude::*;
use std::process::Command;
use tempfile::TempDir;
use transit_model::test_utils::*;

#[test]
fn test_ntfs2netexfr() {
Expand Down Expand Up @@ -78,3 +79,25 @@ fn test_ntfs2netexfr_create_foobar() {
.success();
assert!(netexfr_foobar.join("arrets.xml").is_file());
}

#[test]
fn test_ntfs2netexfr_with_pickup_drop_off_windows_stoptimes() {
let output_dir = TempDir::new().expect("create temp dir failed");
Command::cargo_bin("ntfs2netexfr")
.expect("Failed to find binary 'ntfs2netexfr'")
.arg("--input")
.arg("../tests/fixtures/pickup_drop_off_windows/input_ntfs")
.arg("--output")
.arg(output_dir.path().to_str().unwrap())
.arg("--participant")
.arg("Participant")
.arg("--current-datetime")
.arg("2024-04-03T17:19:00Z")
.assert()
.success();
compare_output_dir_with_expected(
output_dir,
Some(vec!["lignes.xml"]),
"../tests/fixtures/netex_france/output_netexfr_pickup_drop_off_windows",
);
}
37 changes: 37 additions & 0 deletions src/gtfs/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,8 @@ struct StopTime {
trip_id: String,
arrival_time: Option<Time>,
departure_time: Option<Time>,
start_pickup_drop_off_window: Option<Time>,
end_pickup_drop_off_window: Option<Time>,
#[serde(deserialize_with = "de_without_slashes")]
stop_id: String,
stop_sequence: u32,
Expand All @@ -222,6 +224,40 @@ struct StopTime {
default = "default_true_bool"
)]
timepoint: bool,
pickup_booking_rule_id: Option<String>,
drop_off_booking_rule_id: Option<String>,
}

#[derive(Derivative, Serialize)]
#[derivative(Default)]
enum BookingType {
#[derivative(Default)]
#[serde(rename = "0")]
RealTime,
}

#[derive(Derivative, Serialize)]
#[derivative(Default)]
struct BookingRule {
id: String,
booking_type: BookingType,
message: Option<String>,
phone_number: Option<String>,
info_url: Option<String>,
booking_url: Option<String>,
}

impl<'a> From<&'a objects::BookingRule> for BookingRule {
fn from(obj: &objects::BookingRule) -> BookingRule {
BookingRule {
id: obj.id.clone(),
message: obj.message.clone(),
phone_number: obj.phone.clone(),
info_url: obj.info_url.clone(),
booking_url: obj.booking_url.clone(),
..Default::default()
}
}
}

#[derive(Serialize, Deserialize, Debug, Derivative, PartialEq, Clone)]
Expand Down Expand Up @@ -705,6 +741,7 @@ pub fn write<P: AsRef<Path>>(model: Model, path: P, extend_route_type: bool) ->
&model.stop_points,
&model.stop_time_headsigns,
)?;
write::write_booking_rules(path, &model.booking_rules)?;
write::write_shapes(path, &model.geometries)?;
write_collection_with_id(path, "pathways.txt", &model.pathways)?;
write_collection_with_id(path, "levels.txt", &model.levels)?;
Expand Down
Loading

0 comments on commit 90985fb

Please sign in to comment.