From 7ce5f2911201ba3704346a54faaac6f6ee693bb7 Mon Sep 17 00:00:00 2001 From: Nicolas Berard Date: Mon, 12 Nov 2018 16:44:16 +0100 Subject: [PATCH] handle stop.location_type = 2 for ntfs --- src/model.rs | 3 +++ src/ntfs/mod.rs | 62 +++++++++++++++++++++++++++++++++++++++++------ src/ntfs/read.rs | 51 +++++++++++++++++++++++++------------- src/ntfs/write.rs | 27 +++++++++++++++++++++ src/objects.rs | 43 ++++++++++++++++++++++++++++++++ 5 files changed, 161 insertions(+), 25 deletions(-) diff --git a/src/model.rs b/src/model.rs index cff5876e2..84dd4e8e3 100644 --- a/src/model.rs +++ b/src/model.rs @@ -39,6 +39,7 @@ pub struct Collections { pub physical_modes: CollectionWithId, pub stop_areas: CollectionWithId, pub stop_points: CollectionWithId, + pub stop_zones: CollectionWithId, pub feed_infos: HashMap, pub calendars: CollectionWithId, pub companies: CollectionWithId, @@ -65,6 +66,7 @@ impl Collections { physical_modes, stop_areas, stop_points, + stop_zones, feed_infos, calendars, companies, @@ -83,6 +85,7 @@ impl Collections { self.routes.merge(routes)?; self.physical_modes.extend(physical_modes); self.stop_areas.merge(stop_areas)?; + self.stop_zones.merge(stop_zones)?; fn get_new_idx( old_idx: Idx, diff --git a/src/ntfs/mod.rs b/src/ntfs/mod.rs index 2b6af85da..1dbf24aa1 100644 --- a/src/ntfs/mod.rs +++ b/src/ntfs/mod.rs @@ -168,7 +168,12 @@ pub fn write>(model: &Model, path: P) -> Result<()> { &model.stop_points, )?; common_format::write_calendar_dates(path, &model.calendars)?; - write::write_stops(path, &model.stop_points, &model.stop_areas)?; + write::write_stops( + path, + &model.stop_points, + &model.stop_areas, + &model.stop_zones, + )?; write::write_comments(path, model)?; write::write_codes(path, model)?; write::write_object_properties(path, model)?; @@ -721,14 +726,31 @@ mod tests { }, ]).unwrap(); + let stop_zones = CollectionWithId::new(vec![StopZone { + id: "Navitia:sz_1".to_string(), + name: "sz_name_1".to_string(), + codes: KeysValues::default(), + object_properties: KeysValues::default(), + comment_links: CommentLinksT::default(), + visible: true, + coord: Coord { + lon: 2.173, + lat: 47.899, + }, + timezone: None, + geometry_id: None, + equipment_id: None, + }]).unwrap(); + ser_deser_in_tmp_dir(|path| { - write::write_stops(path, &stop_points, &stop_areas).unwrap(); + write::write_stops(path, &stop_points, &stop_areas, &stop_zones).unwrap(); let mut collections = Collections::default(); read::manage_stops(&mut collections, path).unwrap(); assert_eq!(collections.stop_points, stop_points); assert_eq!(collections.stop_areas, stop_areas); + assert_eq!(collections.stop_zones, stop_zones); }); } @@ -805,6 +827,28 @@ mod tests { equipment_id: None, }]).unwrap(); + let stop_zones = CollectionWithId::new(vec![StopZone { + id: "sz_1".to_string(), + name: "sz_name_1".to_string(), + codes: btree_set_from_vec(vec![( + "object_system:3".to_string(), + "object_code:3".to_string(), + )]), + object_properties: btree_set_from_vec(vec![( + "prop_name:3".to_string(), + "prop_value:3".to_string(), + )]), + comment_links: btree_set_from_vec(vec![comments.get_idx("c:3").unwrap()]), + visible: true, + coord: Coord { + lon: 2.073034, + lat: 48.799115, + }, + timezone: None, + geometry_id: None, + equipment_id: None, + }]).unwrap(); + let lines = CollectionWithId::new(vec![Line { id: "OIF:002002003:3OIF829".to_string(), name: "3".to_string(), @@ -891,6 +935,7 @@ mod tests { ser_collections.comments = comments; ser_collections.stop_areas = stop_areas; ser_collections.stop_points = stop_points; + ser_collections.stop_zones = stop_zones; ser_collections.lines = lines; ser_collections.routes = routes; ser_collections.vehicle_journeys = vehicle_journeys; @@ -902,6 +947,7 @@ mod tests { path, &ser_collections.stop_points, &ser_collections.stop_areas, + &ser_collections.stop_zones, ).unwrap(); write::write_collection_with_id(path, "routes.txt", &ser_collections.routes).unwrap(); write::write_collection_with_id(path, "trips.txt", &ser_collections.vehicle_journeys) @@ -953,13 +999,13 @@ mod tests { assert_eq!( ser_collections - .stop_points - .get("sp_1") + .stop_zones + .get("sz_1") .unwrap() .comment_links, des_collections - .stop_points - .get("sp_1") + .stop_zones + .get("sz_1") .unwrap() .comment_links ); @@ -1023,8 +1069,8 @@ mod tests { ); assert_eq!( - ser_collections.stop_points.get("sp_1").unwrap().codes, - des_collections.stop_points.get("sp_1").unwrap().codes + ser_collections.stop_zones.get("sz_1").unwrap().codes, + des_collections.stop_zones.get("sz_1").unwrap().codes ); assert_eq!( diff --git a/src/ntfs/read.rs b/src/ntfs/read.rs index 04bc26cd5..2cff82897 100644 --- a/src/ntfs/read.rs +++ b/src/ntfs/read.rs @@ -25,25 +25,32 @@ use objects::*; use utils::make_collection_with_id; use Result; -impl From for StopArea { - fn from(stop: Stop) -> StopArea { - StopArea { - id: stop.id, - name: stop.name, - codes: KeysValues::default(), - object_properties: KeysValues::default(), - comment_links: CommentLinksT::default(), - visible: stop.visible, - coord: Coord { - lon: stop.lon, - lat: stop.lat, - }, - timezone: stop.timezone, - geometry_id: stop.geometry_id, - equipment_id: stop.equipment_id, - } +macro_rules! impl_from_stop_common { + ($($t:ident),+) => { + $(impl From for $t { + fn from(stop: Stop) -> $t { + $t { + id: stop.id, + name: stop.name, + codes: KeysValues::default(), + object_properties: KeysValues::default(), + comment_links: CommentLinksT::default(), + visible: stop.visible, + coord: Coord { + lon: stop.lon, + lat: stop.lat, + }, + timezone: stop.timezone, + geometry_id: stop.geometry_id, + equipment_id: stop.equipment_id, + } + } + })+ } } + +impl_from_stop_common!(StopArea, StopZone); + impl From for StopPoint { fn from(stop: Stop) -> StopPoint { let id = stop.id; @@ -74,6 +81,7 @@ pub fn manage_stops(collections: &mut Collections, path: &path::Path) -> Result< let mut rdr = csv::Reader::from_path(&path).with_context(ctx_from_path!(path))?; let mut stop_areas = vec![]; let mut stop_points = vec![]; + let mut stop_zones = vec![]; for stop in rdr.deserialize() { let stop: Stop = stop.with_context(ctx_from_path!(path))?; match stop.location_type { @@ -86,11 +94,13 @@ pub fn manage_stops(collections: &mut Collections, path: &path::Path) -> Result< stop_points.push(StopPoint::from(stop)); } 1 => stop_areas.push(StopArea::from(stop)), + 2 => stop_zones.push(StopZone::from(stop)), i => warn!("stop.location_type = {} not yet supported, skipping.", i), } } collections.stop_areas = CollectionWithId::new(stop_areas)?; collections.stop_points = CollectionWithId::new(stop_points)?; + collections.stop_zones = CollectionWithId::new(stop_zones)?; Ok(()) } @@ -185,6 +195,7 @@ pub fn manage_codes(collections: &mut Collections, path: &path::Path) -> Result< let code: Code = code.with_context(ctx_from_path!(path))?; match code.object_type { ObjectType::StopArea => insert_code(&mut collections.stop_areas, code), + ObjectType::StopZone => insert_code(&mut collections.stop_zones, code), ObjectType::StopPoint => insert_code(&mut collections.stop_points, code), ObjectType::Network => insert_code(&mut collections.networks, code), ObjectType::Line => insert_code(&mut collections.lines, code), @@ -276,6 +287,11 @@ pub fn manage_comments(collections: &mut Collections, path: &path::Path) -> Resu &collections.comments, &comment_link, )?, + ObjectType::StopZone => insert_comment_link( + &mut collections.stop_zones, + &collections.comments, + &comment_link, + )?, ObjectType::StopPoint => insert_comment_link( &mut collections.stop_points, &collections.comments, @@ -343,6 +359,7 @@ pub fn manage_object_properties(collections: &mut Collections, path: &path::Path let obj_prop: ObjectProperty = obj_prop.with_context(ctx_from_path!(path))?; match obj_prop.object_type { ObjectType::StopArea => insert_object_property(&mut collections.stop_areas, obj_prop), + ObjectType::StopZone => insert_object_property(&mut collections.stop_zones, obj_prop), ObjectType::StopPoint => insert_object_property(&mut collections.stop_points, obj_prop), ObjectType::Line => insert_object_property(&mut collections.lines, obj_prop), ObjectType::Route => insert_object_property(&mut collections.routes, obj_prop), diff --git a/src/ntfs/write.rs b/src/ntfs/write.rs index 8042cf16c..ec6f662e0 100644 --- a/src/ntfs/write.rs +++ b/src/ntfs/write.rs @@ -125,6 +125,7 @@ pub fn write_stops( path: &path::Path, stop_points: &CollectionWithId, stop_areas: &CollectionWithId, + stop_zones: &CollectionWithId, ) -> Result<()> { info!("Writing stops.txt"); let path = path.join("stops.txt"); @@ -160,6 +161,22 @@ pub fn write_stops( geometry_id: sa.geometry_id.clone(), }).with_context(ctx_from_path!(path))?; } + + for sz in stop_zones.values() { + wtr.serialize(Stop { + id: sz.id.clone(), + visible: sz.visible, + name: sz.name.clone(), + lat: sz.coord.lat, + lon: sz.coord.lon, + fare_zone_id: None, + location_type: 2, + parent_station: None, + timezone: sz.timezone.clone(), + equipment_id: sz.equipment_id.clone(), + geometry_id: sz.geometry_id.clone(), + }).with_context(ctx_from_path!(path))?; + } wtr.flush().with_context(ctx_from_path!(path))?; Ok(()) @@ -212,6 +229,12 @@ pub fn write_comments(path: &path::Path, collections: &Collections) -> Result<() &collections.comments, &comment_links_path, )?; + write_comment_links_from_collection_with_id( + &mut cl_wtr, + &collections.stop_zones, + &collections.comments, + &comment_links_path, + )?; write_comment_links_from_collection_with_id( &mut cl_wtr, &collections.stop_points, @@ -274,6 +297,7 @@ pub fn write_codes(path: &path::Path, collections: &Collections) -> Result<()> { collection.values().all(|c| c.codes().is_empty()) } if collection_has_no_codes(&collections.stop_areas) + && collection_has_no_codes(&collections.stop_zones) && collection_has_no_codes(&collections.stop_points) && collection_has_no_codes(&collections.networks) && collection_has_no_codes(&collections.lines) @@ -292,6 +316,7 @@ pub fn write_codes(path: &path::Path, collections: &Collections) -> Result<()> { let mut wtr = csv::Writer::from_path(&path).with_context(ctx_from_path!(path))?; write_codes_from_collection_with_id(&mut wtr, &collections.stop_areas, &path)?; + write_codes_from_collection_with_id(&mut wtr, &collections.stop_zones, &path)?; write_codes_from_collection_with_id(&mut wtr, &collections.stop_points, &path)?; write_codes_from_collection_with_id(&mut wtr, &collections.networks, &path)?; write_codes_from_collection_with_id(&mut wtr, &collections.lines, &path)?; @@ -333,6 +358,7 @@ pub fn write_object_properties(path: &path::Path, collections: &Collections) -> collection.values().all(|c| c.properties().is_empty()) } if collection_has_no_object_properties(&collections.stop_areas) + && collection_has_no_object_properties(&collections.stop_zones) && collection_has_no_object_properties(&collections.stop_points) && collection_has_no_object_properties(&collections.lines) && collection_has_no_object_properties(&collections.routes) @@ -347,6 +373,7 @@ pub fn write_object_properties(path: &path::Path, collections: &Collections) -> let mut wtr = csv::Writer::from_path(&path).with_context(ctx_from_path!(path))?; write_object_properties_from_collection_with_id(&mut wtr, &collections.stop_areas, &path)?; + write_object_properties_from_collection_with_id(&mut wtr, &collections.stop_zones, &path)?; write_object_properties_from_collection_with_id(&mut wtr, &collections.stop_points, &path)?; write_object_properties_from_collection_with_id(&mut wtr, &collections.lines, &path)?; write_object_properties_from_collection_with_id(&mut wtr, &collections.routes, &path)?; diff --git a/src/objects.rs b/src/objects.rs index 0e9a006eb..648b089d5 100644 --- a/src/objects.rs +++ b/src/objects.rs @@ -37,6 +37,7 @@ pub trait AddPrefix { pub enum ObjectType { StopArea, StopPoint, + StopZone, Network, Line, Route, @@ -54,6 +55,7 @@ impl ObjectType { pub fn as_str(&self) -> &'static str { match *self { ObjectType::StopArea => "stop_area", + ObjectType::StopZone => "stop_zone", ObjectType::StopPoint => "stop_point", ObjectType::Network => "network", ObjectType::Line => "line", @@ -960,6 +962,47 @@ impl GetObjectType for StopPoint { } } +#[derive(Serialize, Deserialize, Debug, PartialEq)] +pub struct StopZone { + pub id: String, + pub name: String, + #[serde(skip)] + pub codes: KeysValues, + #[serde(skip)] + pub object_properties: KeysValues, + #[serde(skip)] + pub comment_links: CommentLinksT, + pub visible: bool, + pub coord: Coord, + pub timezone: Option, + pub geometry_id: Option, + pub equipment_id: Option, +} +impl Id for StopZone { + fn id(&self) -> &str { + &self.id + } +} +impl AddPrefix for StopZone { + fn add_prefix(&mut self, prefix: &str) { + self.id = prefix.to_string() + &self.id; + self.equipment_id = self + .equipment_id + .as_ref() + .map(|id| prefix.to_string() + &id); + self.geometry_id = self.geometry_id.as_ref().map(|id| prefix.to_string() + &id); + } +} +impl_codes!(StopZone); +impl_properties!(StopZone); +impl_comment_links!(StopZone); + +impl GetObjectType for StopZone { + fn get_object_type() -> ObjectType { + ObjectType::StopZone + } +} + pub type Date = chrono::NaiveDate; #[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]