Skip to content

Commit

Permalink
Merge pull request #686 from datanel/tranfers_condition
Browse files Browse the repository at this point in the history
[feature] Transfers: add the possibility to determine if a transfer could be created
  • Loading branch information
datanel authored Aug 6, 2020
2 parents f5eea7c + d48996d commit 6ac4d27
Show file tree
Hide file tree
Showing 16 changed files with 126 additions and 47 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
authors = ["Kisio Digital <[email protected]>", "Guillaume Pinot <[email protected]>"]
name = "transit_model"
version = "0.26.1"
version = "0.27.0"
license = "AGPL-3.0-only"
description = "Transit data management"
repository = "https://github.com/CanalTP/transit_model"
Expand Down
2 changes: 1 addition & 1 deletion gtfs2netexfr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ slog-scope = "4.1"
slog-stdlog = "4.0"
slog-term = "2.4"
structopt = "0.3"
transit_model = { version = "0.26", path = "../", features = ["proj"] }
transit_model = { version = "0.27", path = "../", features = ["proj"] }
2 changes: 1 addition & 1 deletion gtfs2ntfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ slog-scope = "4.1"
slog-stdlog = "4.0"
slog-term = "2.4"
structopt = "0.3"
transit_model = { version = "0.26", path = "../" }
transit_model = { version = "0.27", path = "../" }
8 changes: 7 additions & 1 deletion gtfs2ntfs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,13 @@ fn run(opt: Opt) -> Result<()> {
bail!("Invalid input data: must be an existing directory or a ZIP archive");
};

let model = generates_transfers(model, opt.max_distance, opt.walking_speed, opt.waiting_time)?;
let model = generates_transfers(
model,
opt.max_distance,
opt.walking_speed,
opt.waiting_time,
None,
)?;

transit_model::ntfs::write(&model, opt.output, opt.current_datetime)?;
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion ntfs2gtfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ slog-scope = "4.1"
slog-stdlog = "4.0"
slog-term = "2.4"
structopt = "0.3"
transit_model = { version = "0.26", path = "../" }
transit_model = { version = "0.27", path = "../" }
2 changes: 1 addition & 1 deletion ntfs2netexfr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ slog-scope = "4.1"
slog-stdlog = "4.0"
slog-term = "2.4"
structopt = "0.3"
transit_model = { version = "0.26", path = "../", features = ["proj"] }
transit_model = { version = "0.27", path = "../", features = ["proj"] }
2 changes: 1 addition & 1 deletion ntfs2ntfs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ slog-scope = "4.1"
slog-stdlog = "4.0"
slog-term = "2.4"
structopt = "0.3"
transit_model = { version = "0.26", path = "../" }
transit_model = { version = "0.27", path = "../" }
8 changes: 7 additions & 1 deletion ntfs2ntfs/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@ fn run(opt: Opt) -> Result<()> {
info!("Launching ntfs2ntfs...");

let model = transit_model::ntfs::read(opt.input)?;
let model = generates_transfers(model, opt.max_distance, opt.walking_speed, opt.waiting_time)?;
let model = generates_transfers(
model,
opt.max_distance,
opt.walking_speed,
opt.waiting_time,
None,
)?;

if let Some(output) = opt.output {
transit_model::ntfs::write(&model, output, opt.current_datetime)?;
Expand Down
2 changes: 1 addition & 1 deletion restrict-validity-period/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ slog-scope = "4.1"
slog-stdlog = "4.0"
slog-term = "2.4"
structopt = "0.3"
transit_model = { version = "0.26", path = "../" }
transit_model = { version = "0.27", path = "../" }
18 changes: 17 additions & 1 deletion src/transfers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ use typed_index_collection::{Collection, CollectionWithId, Idx};

type TransferMap = HashMap<(Idx<StopPoint>, Idx<StopPoint>), Transfer>;

/// The closure that will determine whether a connection should be created between 2 stops.
/// See [generates_transfers](./fn.generates_transfers.html).
pub type NeedTransfer<'a> = Box<dyn 'a + Fn(&Model, Idx<StopPoint>, Idx<StopPoint>) -> bool>;

fn make_transfers_map(
transfers: Collection<Transfer>,
sp: &CollectionWithId<StopPoint>,
Expand All @@ -49,6 +53,7 @@ fn generate_transfers_from_sp(
max_distance: f64,
walking_speed: f64,
waiting_time: u32,
need_transfer: Option<NeedTransfer>,
) {
info!("Adding missing transfers from stop points.");
let sq_max_distance = max_distance * max_distance;
Expand All @@ -58,6 +63,11 @@ fn generate_transfers_from_sp(
if transfers_map.contains_key(&(idx1, idx2)) {
continue;
}
if let Some(ref f) = need_transfer {
if !f(model, idx1, idx2) {
continue;
}
}
let sq_distance = approx.sq_distance_to(&sp2.coord);
if sq_distance > sq_max_distance {
continue;
Expand Down Expand Up @@ -86,7 +96,11 @@ fn generate_transfers_from_sp(
///
/// The `waiting_time` argument is the waiting transfer_time in seconds at stop.
///
/// `rule_files` are paths to csv files that contains rules for modifying
/// `need_transfer` Additional condition that determines whether a transfer
/// must be created between 2 stop points. By default transfers that do not
/// already exist and where the distance is less than `max_distance` will be created.
/// If you need an additional condition, you can use this parameter. For instance
/// you could create transfers between 2 stop points of different contributors only.
///
/// # Example
///
Expand All @@ -101,6 +115,7 @@ pub fn generates_transfers(
max_distance: f64,
walking_speed: f64,
waiting_time: u32,
need_transfer: Option<NeedTransfer>,
) -> Result<Model> {
info!("Generating transfers...");
let mut transfers_map = make_transfers_map(model.transfers.clone(), &model.stop_points);
Expand All @@ -110,6 +125,7 @@ pub fn generates_transfers(
max_distance,
walking_speed,
waiting_time,
need_transfer,
);

let mut new_transfers: Vec<_> = transfers_map.into_iter().map(|(_, v)| v).collect();
Expand Down
12 changes: 6 additions & 6 deletions tests/fixtures/transfers/multi_contributors/input/stop_times.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
trip_id,arrival_time,departure_time,stop_id,stop_sequence
trip:1,15:45:00,15:45:00,sp_1,0
trip:1,15:46:00,15:46:00,sp_2,1
trip:1,15:47:00,15:47:00,sp_3,2
trip:2,16:45:00,16:45:00,sp_4,0
trip:2,16:46:00,16:46:00,sp_5,1
trip:2,16:47:00,16:47:00,sp_6,2
trip:1,15:45:00,15:45:00,OIF:sp_1,0
trip:1,15:46:00,15:46:00,OIF:sp_2,1
trip:1,15:47:00,15:47:00,OIF:sp_3,2
trip:2,16:45:00,16:45:00,ABC:sp_4,0
trip:2,16:46:00,16:46:00,ABC:sp_5,1
trip:2,16:47:00,16:47:00,ABC:sp_6,2
12 changes: 6 additions & 6 deletions tests/fixtures/transfers/multi_contributors/input/stops.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
stop_id,stop_name,stop_lat,stop_lon,location_type,parent_station
sp_1,sp name 1,48.84608210211328,2.372075915336609,0,sa_1
sp_2,sp name 2,48.845665532277096,2.371437549591065,0,sa_1
sp_3,sp name 3,48.845301913401144,2.369517087936402,0,sa_1
OIF:sp_1,sp name 1,48.84608210211328,2.372075915336609,0,sa_1
OIF:sp_2,sp name 2,48.845665532277096,2.371437549591065,0,sa_1
OIF:sp_3,sp name 3,48.845301913401144,2.369517087936402,0,sa_1
sa_1,sa name 1,48.844745,2.372986,1,
sp_4,sp name 4,48.84608210211328,2.372075915336609,0,sa_2
sp_5,sp name 5,48.845665532277096,2.371437549591065,0,sa_2
sp_6,sp name 6,48.845301913401144,2.369517087936402,0,sa_2
ABC:sp_4,sp name 4,48.84608210211328,2.372075915336609,0,sa_2
ABC:sp_5,sp name 5,48.845665532277096,2.371437549591065,0,sa_2
ABC:sp_6,sp name 6,48.845301913401144,2.369517087936402,0,sa_2
sa_2,sa name 2,48.844745,2.372986,1,
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
from_stop_id,to_stop_id,min_transfer_time,real_min_transfer_time,equipment_id
sp_1,sp_2,50,60,
sp_1,sp_3,200,210,
OIF:sp_1,OIF:sp_2,50,60,
OIF:sp_1,OIF:sp_3,200,210,
42 changes: 21 additions & 21 deletions tests/fixtures/transfers/multi_contributors/output/transfers.txt
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
from_stop_id,to_stop_id,min_transfer_time,real_min_transfer_time,equipment_id
sp_1,sp_1,0,120,
sp_1,sp_2,50,60,
sp_1,sp_3,200,210,
sp_1,sp_4,0,120,
sp_1,sp_5,83,203,
sp_2,sp_1,83,203,
sp_2,sp_2,0,120,
sp_2,sp_4,83,203,
sp_2,sp_5,0,120,
sp_3,sp_3,0,120,
sp_3,sp_6,0,120,
sp_4,sp_1,0,120,
sp_4,sp_2,83,203,
sp_4,sp_4,0,120,
sp_4,sp_5,83,203,
sp_5,sp_1,83,203,
sp_5,sp_2,0,120,
sp_5,sp_4,83,203,
sp_5,sp_5,0,120,
sp_6,sp_3,0,120,
sp_6,sp_6,0,120,
OIF:sp_1,OIF:sp_1,0,120,
OIF:sp_1,OIF:sp_2,50,60,
OIF:sp_1,OIF:sp_3,200,210,
OIF:sp_1,ABC:sp_4,0,120,
OIF:sp_1,ABC:sp_5,83,203,
OIF:sp_2,OIF:sp_1,83,203,
OIF:sp_2,OIF:sp_2,0,120,
OIF:sp_2,ABC:sp_4,83,203,
OIF:sp_2,ABC:sp_5,0,120,
OIF:sp_3,OIF:sp_3,0,120,
OIF:sp_3,ABC:sp_6,0,120,
ABC:sp_4,OIF:sp_1,0,120,
ABC:sp_4,OIF:sp_2,83,203,
ABC:sp_4,ABC:sp_4,0,120,
ABC:sp_4,ABC:sp_5,83,203,
ABC:sp_5,OIF:sp_1,83,203,
ABC:sp_5,OIF:sp_2,0,120,
ABC:sp_5,ABC:sp_4,83,203,
ABC:sp_5,ABC:sp_5,0,120,
ABC:sp_6,OIF:sp_3,0,120,
ABC:sp_6,ABC:sp_6,0,120,
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from_stop_id,to_stop_id,min_transfer_time,real_min_transfer_time,equipment_id
OIF:sp_1,OIF:sp_2,50,60,
OIF:sp_1,OIF:sp_3,200,210,
OIF:sp_1,ABC:sp_4,0,120,
OIF:sp_1,ABC:sp_5,83,203,
OIF:sp_2,ABC:sp_4,83,203,
OIF:sp_2,ABC:sp_5,0,120,
OIF:sp_3,ABC:sp_6,0,120,
ABC:sp_4,OIF:sp_1,0,120,
ABC:sp_4,OIF:sp_2,83,203,
ABC:sp_5,OIF:sp_1,83,203,
ABC:sp_5,OIF:sp_2,0,120,
ABC:sp_6,OIF:sp_3,0,120,
42 changes: 40 additions & 2 deletions tests/transfers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn test_generates_transfers() {
test_in_tmp_dir(|path| {
let input_dir = "tests/fixtures/transfers/mono_contributor/input";
let model = transit_model::ntfs::read(input_dir).unwrap();
let model = transfers::generates_transfers(model, 100.0, 0.785, 120).unwrap();
let model = transfers::generates_transfers(model, 100.0, 0.785, 120, None).unwrap();
transit_model::ntfs::write(&model, path, get_test_datetime()).unwrap();
compare_output_dir_with_expected(
&path,
Expand All @@ -43,7 +43,7 @@ fn test_generates_all_multi_contributors_transfers() {
test_in_tmp_dir(|path| {
let input_dir = "tests/fixtures/transfers/multi_contributors/input";
let model = transit_model::ntfs::read(input_dir).unwrap();
let model = transfers::generates_transfers(model, 100.0, 0.785, 120).unwrap();
let model = transfers::generates_transfers(model, 100.0, 0.785, 120, None).unwrap();
transit_model::ntfs::write(&model, path, get_test_datetime()).unwrap();
compare_output_dir_with_expected(
&path,
Expand All @@ -52,3 +52,41 @@ fn test_generates_all_multi_contributors_transfers() {
);
});
}

#[test]
fn test_generates_transfers_with_closure_inter_contributors() {
test_in_tmp_dir(|path| {
use std::collections::BTreeSet;
use transit_model::{
objects::{Contributor, StopPoint},
Model,
};
use typed_index_collection::Idx;
let inter_contrib_tranfers = Box::new(
|model: &Model, from_idx: Idx<StopPoint>, to_idx: Idx<StopPoint>| -> bool {
let from_contributor: BTreeSet<Idx<Contributor>> =
model.get_corresponding_from_idx(from_idx);
let to_contributor: BTreeSet<Idx<Contributor>> =
model.get_corresponding_from_idx(to_idx);

if from_contributor.is_empty() || to_contributor.is_empty() {
return false;
}

from_contributor != to_contributor
},
);

let input_dir = "tests/fixtures/transfers/multi_contributors/input";
let model = transit_model::ntfs::read(input_dir).unwrap();
let model =
transfers::generates_transfers(model, 100.0, 0.785, 120, Some(inter_contrib_tranfers))
.unwrap();
transit_model::ntfs::write(&model, path, get_test_datetime()).unwrap();
compare_output_dir_with_expected(
&path,
Some(vec!["transfers.txt"]),
"./tests/fixtures/transfers/multi_contributors/output_closure_inter_contributor",
);
});
}

0 comments on commit 6ac4d27

Please sign in to comment.