diff --git a/core/osrd-railjson/src/main/java/fr/sncf/osrd/railjson/schema/infra/RJSInfra.java b/core/osrd-railjson/src/main/java/fr/sncf/osrd/railjson/schema/infra/RJSInfra.java index ef124fd9aa5..417cb425755 100644 --- a/core/osrd-railjson/src/main/java/fr/sncf/osrd/railjson/schema/infra/RJSInfra.java +++ b/core/osrd-railjson/src/main/java/fr/sncf/osrd/railjson/schema/infra/RJSInfra.java @@ -22,7 +22,7 @@ public class RJSInfra { .build() .adapter(RJSInfra.class); - public static final transient String CURRENT_VERSION = "3.4.3"; + public static final transient String CURRENT_VERSION = "3.4.4"; /** The version of the infra format used */ public String version; @@ -31,9 +31,6 @@ public class RJSInfra { @Json(name = "track_sections") public Collection trackSections; - @Json(name = "track_section_links") - public Collection trackSectionLinks; - /** Switches are at the ends of track sections, and link those together. */ public Collection switches; diff --git a/core/osrd-railjson/src/main/java/fr/sncf/osrd/railjson/schema/infra/RJSTrackSectionLink.java b/core/osrd-railjson/src/main/java/fr/sncf/osrd/railjson/schema/infra/RJSTrackSectionLink.java deleted file mode 100644 index 651b32958e4..00000000000 --- a/core/osrd-railjson/src/main/java/fr/sncf/osrd/railjson/schema/infra/RJSTrackSectionLink.java +++ /dev/null @@ -1,32 +0,0 @@ -package fr.sncf.osrd.railjson.schema.infra; - -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import fr.sncf.osrd.railjson.schema.common.Identified; - -/** This class represents a link between two track sections */ -@SuppressFBWarnings({"URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD"}) -public class RJSTrackSectionLink implements Identified { - public String id; - public RJSTrackEndpoint src; - public RJSTrackEndpoint dst; - - /** - * Create a serialized track section link - * @param src the beginning of the link - * @param dst end end of the link - */ - public RJSTrackSectionLink( - String id, - RJSTrackEndpoint src, - RJSTrackEndpoint dst - ) { - this.id = id; - this.src = src; - this.dst = dst; - } - - @Override - public String getID() { - return id; - } -} diff --git a/core/src/main/java/fr/sncf/osrd/infra/implementation/tracks/undirected/UndirectedInfraBuilder.java b/core/src/main/java/fr/sncf/osrd/infra/implementation/tracks/undirected/UndirectedInfraBuilder.java index c87456284b4..e0e59f8de22 100644 --- a/core/src/main/java/fr/sncf/osrd/infra/implementation/tracks/undirected/UndirectedInfraBuilder.java +++ b/core/src/main/java/fr/sncf/osrd/infra/implementation/tracks/undirected/UndirectedInfraBuilder.java @@ -162,8 +162,6 @@ private TrackInfra parse(RJSInfra infra) { switches.put(s.id, parseSwitch(s, switchTypeMap)); } - addRemainingLinks(infra); - var trackSectionsByID = new HashMap(); for (var track : infra.trackSections) { var newTrack = makeTrackSection(track); @@ -227,37 +225,6 @@ private void loadNeutralRanges(boolean announcement, RJSNeutralSection neutralSe } } - /** Creates all the track section links that haven't already been created by switches */ - private void addRemainingLinks(RJSInfra infra) { - int generatedID = 0; - for (var link : infra.trackSectionLinks) { - var srcID = link.src.track; - var dstID = link.dst.track; - var oldSrcNode = getNode(srcID, link.src.endpoint); - var oldDstNode = getNode(dstID, link.dst.endpoint); - if (oldSrcNode != null || oldDstNode != null) { - // At least one of the node already exists: - // either both are the same switch node, or there is an error in the infra - if (oldSrcNode instanceof SwitchPort srcSwitchPort - && oldDstNode instanceof SwitchPort dstSwitchPort - && srcSwitchPort.getSwitch().getID().equals(dstSwitchPort.getSwitch().getID())) - continue; - throw newEndpointAlreadyLinkedError( - link.id, - oldSrcNode, - oldDstNode - ); - } - if (link.id == null || link.id.equals("")) { - // Forcing a unique ID avoids node equality troubles, and makes debugging easier - link.id = String.format("generated_%d", generatedID++); - } - var newNode = new TrackNodeImpl.Joint(link.id); - addNode(srcID, link.src.endpoint, newNode); - addNode(dstID, link.dst.endpoint, newNode); - } - } - /** Adds all the speed sections to track attributes */ private void addSpeedSections( List speedSections, diff --git a/core/src/test/java/fr/sncf/osrd/infra/tracks/undirected/RJSParsingTests.java b/core/src/test/java/fr/sncf/osrd/infra/tracks/undirected/RJSParsingTests.java index bce4f0e3381..ca4fbaf289f 100644 --- a/core/src/test/java/fr/sncf/osrd/infra/tracks/undirected/RJSParsingTests.java +++ b/core/src/test/java/fr/sncf/osrd/infra/tracks/undirected/RJSParsingTests.java @@ -15,7 +15,6 @@ import fr.sncf.osrd.railjson.schema.common.graph.ApplicableDirection; import fr.sncf.osrd.railjson.schema.common.graph.EdgeEndpoint; import fr.sncf.osrd.railjson.schema.infra.RJSTrackEndpoint; -import fr.sncf.osrd.railjson.schema.infra.RJSTrackSectionLink; import fr.sncf.osrd.railjson.schema.infra.trackranges.RJSApplicableDirectionsTrackRange; import fr.sncf.osrd.railjson.schema.infra.trackranges.RJSSpeedSection; import fr.sncf.osrd.reporting.exceptions.ErrorType; @@ -55,23 +54,6 @@ public void testDuplicatedSwitch() throws Exception { assertEquals(thrown.osrdErrorType, ErrorType.StrictWarningError); } - @Test - public void testLinkOnSwitch() throws Exception { - var rjsInfra = Helpers.getExampleInfra("tiny_infra/infra.json"); - var s = rjsInfra.switches.iterator().next(); - var ports = new ArrayList<>(s.ports.values()); - rjsInfra.trackSectionLinks.add(new RJSTrackSectionLink( - "broken", - ports.get(0), - new RJSTrackEndpoint("ne.micro.bar_a", EdgeEndpoint.END) - )); - var thrown = assertThrows( - OSRDError.class, - () -> UndirectedInfraBuilder.parseInfra(rjsInfra, new DiagnosticRecorderImpl(true)) - ); - assertEquals(thrown.osrdErrorType, ErrorType.InvalidInfraEndpointAlreadyLinked); - } - @Test public void testDuplicateDetector() throws Exception { var rjsInfra = Helpers.getExampleInfra("tiny_infra/infra.json"); @@ -83,15 +65,6 @@ public void testDuplicateDetector() throws Exception { assertEquals(thrown.osrdErrorType, ErrorType.StrictWarningError); } - @Test - public void testUnlabeledLinks() throws Exception { - var rjsInfra = Helpers.getExampleInfra("one_line/infra.json"); - for (var link : rjsInfra.trackSectionLinks) - link.id = null; - // We check that no warning or assertion is raised when importing the infra - UndirectedInfraBuilder.parseInfra(rjsInfra, new DiagnosticRecorderImpl(true)); - } - @Test public void testOverlappingSpeedSections() throws Exception { var rjsInfra = Helpers.getExampleInfra("one_line/infra.json"); diff --git a/editoast/map_layers.yml b/editoast/map_layers.yml index c15ec274bda..c050a54671b 100644 --- a/editoast/map_layers.yml +++ b/editoast/map_layers.yml @@ -77,23 +77,6 @@ layers: where: - speed_section.data @? '$.extensions.psl_sncf.z' - track_section_links: - table_name: infra_layer_track_section_link - id_field: id - views: - geo: - on_field: geographic - cache_duration: 3600 - data_expr: track_section_link.data - joins: - - inner join infra_object_track_section_link track_section_link on track_section_link.obj_id = layer.obj_id and track_section_link.infra_id = layer.infra_id - sch: - on_field: schematic - cache_duration: 3600 - data_expr: track_section_link.data - joins: - - inner join infra_object_track_section_link track_section_link on track_section_link.obj_id = layer.obj_id and track_section_link.infra_id = layer.infra_id - switches: table_name: infra_layer_switch id_field: id diff --git a/editoast/migrations/2023-10-11-222214_delete_track_links/down.sql b/editoast/migrations/2023-10-11-222214_delete_track_links/down.sql new file mode 100644 index 00000000000..27e2e1d0a9b --- /dev/null +++ b/editoast/migrations/2023-10-11-222214_delete_track_links/down.sql @@ -0,0 +1,20 @@ +-- This file should undo anything in `up.sql` + +CREATE TABLE infra_layer_track_section_link ( + id int8 PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, + obj_id varchar(255) NOT NULL, + geographic geometry(point, 3857) NOT NULL, + schematic geometry(point, 3857) NOT NULL, + infra_id int8 NOT NULL REFERENCES infra(id) ON DELETE CASCADE, + UNIQUE (infra_id, obj_id) +); +CREATE INDEX infra_layer_track_section_link_geographic ON infra_layer_track_section_link USING gist (geographic); +CREATE INDEX infra_layer_track_section_link_schematic ON infra_layer_track_section_link USING gist (schematic); + +CREATE TABLE infra_object_track_section_link ( + id int8 PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY, + obj_id varchar(255) NOT NULL, + data jsonb NOT NULL, + infra_id int8 NOT NULL REFERENCES infra(id) ON DELETE CASCADE, + UNIQUE (infra_id, obj_id) +); diff --git a/editoast/migrations/2023-10-11-222214_delete_track_links/up.sql b/editoast/migrations/2023-10-11-222214_delete_track_links/up.sql new file mode 100644 index 00000000000..f9dcc129e76 --- /dev/null +++ b/editoast/migrations/2023-10-11-222214_delete_track_links/up.sql @@ -0,0 +1,10 @@ +-- Your SQL goes here +DROP TABLE infra_layer_track_section_link; +DROP TABLE infra_object_track_section_link; +DELETE FROM infra_layer_error +WHERE information->>'obj_type' = 'TrackSectionLink'; +ALTER TABLE infra +ALTER column railjson_version +SET DEFAULT '3.4.4'; +UPDATE infra +SET railjson_version = '3.4.4'; diff --git a/editoast/openapi.yaml b/editoast/openapi.yaml index 8a14d66372c..ba7d0ab9592 100644 --- a/editoast/openapi.yaml +++ b/editoast/openapi.yaml @@ -521,7 +521,6 @@ components: - out_of_range - overlapping_speed_sections - overlapping_switches - - overlapping_track_links - overlapping_catenaries - unknown_port_name - unused_port @@ -659,7 +658,6 @@ components: - Signal - SpeedSection - Detector - - TrackSectionLink - Switch - SwitchType - BufferStop @@ -1132,8 +1130,6 @@ components: type: array switches: type: array - track_section_links: - type: array track_sections: type: array version: diff --git a/editoast/openapi_legacy.yaml b/editoast/openapi_legacy.yaml index 2a40a919725..300bbf4d1fa 100644 --- a/editoast/openapi_legacy.yaml +++ b/editoast/openapi_legacy.yaml @@ -2484,7 +2484,6 @@ components: - Signal - SpeedSection - Detector - - TrackSectionLink - Switch - SwitchType - BufferStop @@ -2504,8 +2503,6 @@ components: type: array switches: type: array - track_section_links: - type: array track_sections: type: array signals: @@ -2708,7 +2705,6 @@ components: - out_of_range - overlapping_speed_sections - overlapping_switches - - overlapping_track_links - overlapping_catenaries - unknown_port_name - unused_port diff --git a/editoast/src/converters/generate_routes.rs b/editoast/src/converters/generate_routes.rs index 13ab1702201..02c60616f4a 100644 --- a/editoast/src/converters/generate_routes.rs +++ b/editoast/src/converters/generate_routes.rs @@ -26,13 +26,12 @@ impl Node { } /// An edge connects two nodes -/// This connection can be between two tracks (switch and section link) +/// This connection can be between two tracks (switch) /// Or traversing a whole track /// Or along a track (detector and buffer stops) #[derive(Clone, Debug)] enum EdgeType { Switch { id: Identifier, port: Identifier }, - SectionLink, Track, Buffer(Direction), ToDetector, @@ -49,10 +48,9 @@ struct Graph { } impl Graph { - /* Part 2: build the graph from track sections, track sections links, switches, buffers and detectors */ + /* Part 2: build the graph from track sections, switches, buffers and detectors */ fn load(&mut self, railjson: &RailJson) { self.edges_from_track_sections(railjson); - self.edges_from_track_sections_links(railjson); self.edges_from_switches(railjson); } @@ -139,14 +137,6 @@ impl Graph { } } - fn edges_from_track_sections_links(&mut self, railjson: &RailJson) { - for link in &railjson.track_section_links { - let u = Node::TrackEndpoint(link.src.clone()); - let v = Node::TrackEndpoint(link.dst.clone()); - self.add_symmetrical_edge(u, v, EdgeType::SectionLink); - } - } - fn edges_from_switches(&mut self, railjson: &RailJson) { for switch in &railjson.switches { let switch_type = railjson diff --git a/editoast/src/converters/osm_to_railjson.rs b/editoast/src/converters/osm_to_railjson.rs index 9b0fced72ed..05c1008e29f 100644 --- a/editoast/src/converters/osm_to_railjson.rs +++ b/editoast/src/converters/osm_to_railjson.rs @@ -104,11 +104,7 @@ pub fn parse_osm(osm_pbf_in: PathBuf) -> Result railjson.track_section_links.push(TrackSectionLink { - id: node.0.to_string().into(), - src: adj.branches[0].0.clone(), - dst: adj.branches[0].1.clone(), - }), + (2, 1) => railjson.switches.push(link_switch(node, &adj.branches)), (3, 2) => railjson.switches.push(point_switch(node, &adj.branches)), (4, 2) => railjson.switches.push(cross_switch(node, &adj.branches)), (4, 4) => railjson @@ -152,8 +148,8 @@ mod tests { ports.get(&name.into()).unwrap().track.0 == expected } let mut railjson = parse_osm("src/tests/switches.osm.pbf".into()).unwrap(); - assert_eq!(3, railjson.switch_types.len()); - assert_eq!(3, railjson.switches.len()); + assert_eq!(4, railjson.switch_types.len()); + assert_eq!(4, railjson.switches.len()); assert_eq!(18, railjson.buffer_stops.len()); // Switches can be in a random order, we sort them to be sure to extract the expected ones @@ -162,6 +158,10 @@ mod tests { .sort_by(|a, b| a.switch_type.as_str().cmp(b.switch_type.as_str())); let switch = &railjson.switches[2]; + assert_eq!("link", switch.switch_type.as_str()); + assert_eq!(2, switch.ports.len()); + + let switch = &railjson.switches[3]; assert_eq!("point", switch.switch_type.as_str()); assert_eq!(3, switch.ports.len()); assert!(port_eq(&switch.ports, "BASE", "-103478-0")); diff --git a/editoast/src/converters/utils.rs b/editoast/src/converters/utils.rs index 94b97fe1a1a..dc30e4ca7a8 100644 --- a/editoast/src/converters/utils.rs +++ b/editoast/src/converters/utils.rs @@ -8,6 +8,15 @@ use osmpbfreader::Node; use std::str::FromStr; pub fn default_switch_types() -> Vec { + let mut link_group = std::collections::HashMap::new(); + link_group.insert( + "LINK".into(), + vec![SwitchPortConnection { + src: "SOURCE".into(), + dst: "DESTINATION".into(), + }], + ); + let mut point_groups = std::collections::HashMap::new(); point_groups.insert( "LEFT".into(), @@ -70,6 +79,11 @@ pub fn default_switch_types() -> Vec { ); vec![ + SwitchType { + id: "link".into(), + ports: vec!["SOURCE".into(), "DESTINATION".into()], + groups: link_group, + }, SwitchType { id: "point".into(), ports: vec!["BASE".into(), "LEFT".into(), "RIGHT".into()], @@ -158,7 +172,7 @@ fn track_section(n: NodeId, edge: &Edge) -> TrackEndpoint { } // When building the network topology, most things happen around a Node (in the OpenStreetMap sense) -// That’s where buffer stops, section links and switches happen +// That’s where buffer stops, and switches happen // To do that, we count how many edges are adjacent to that node and how many branches go through that node #[derive(Default)] pub struct NodeAdjacencies<'a> { @@ -166,6 +180,19 @@ pub struct NodeAdjacencies<'a> { pub branches: Vec, } +pub fn link_switch(node: NodeId, branches: &[Branch]) -> Switch { + let mut ports = HashMap::new(); + ports.insert("SOURCE".into(), branches[0].0.clone()); + ports.insert("DESTINATION".into(), branches[0].1.clone()); + Switch { + id: node.0.to_string().into(), + switch_type: "link".into(), + ports, + group_change_delay: 0., + ..Default::default() + } +} + pub fn point_switch(node: NodeId, branches: &[Branch]) -> Switch { let mut endpoint_count = HashMap::<&TrackEndpoint, u64>::new(); for (src, dst) in branches { diff --git a/editoast/src/generated_data/error/mod.rs b/editoast/src/generated_data/error/mod.rs index 45f33cd8b23..c246f7e27dd 100644 --- a/editoast/src/generated_data/error/mod.rs +++ b/editoast/src/generated_data/error/mod.rs @@ -7,7 +7,6 @@ pub mod signals; pub mod speed_sections; pub mod switch_types; pub mod switches; -pub mod track_section_links; pub mod track_sections; use std::collections::HashMap; @@ -153,7 +152,6 @@ fn get_insert_errors_query(obj_type: ObjectType) -> &'static str { ObjectType::NeutralSection => include_str!("sql/neutral_sections_insert_errors.sql"), ObjectType::SpeedSection => include_str!("sql/speed_sections_insert_errors.sql"), ObjectType::Detector => include_str!("sql/detectors_insert_errors.sql"), - ObjectType::TrackSectionLink => include_str!("sql/track_section_links_insert_errors.sql"), ObjectType::Switch => include_str!("sql/switches_insert_errors.sql"), ObjectType::SwitchType => include_str!("sql/switch_types_insert_errors.sql"), ObjectType::BufferStop => include_str!("sql/buffer_stops_insert_errors.sql"), @@ -265,14 +263,6 @@ impl GeneratedData for ErrorLayer { &routes::GLOBAL_GENERATORS, )); - infra_errors.extend(generate_errors( - ObjectType::TrackSectionLink, - infra_cache, - &graph, - &track_section_links::OBJECT_GENERATORS, - &track_section_links::GLOBAL_GENERATORS, - )); - infra_errors.extend(generate_errors( ObjectType::Switch, infra_cache, @@ -311,7 +301,7 @@ impl GeneratedData for ErrorLayer { mod test { use super::{ buffer_stops, catenaries, detectors, generate_errors, operational_points, routes, signals, - speed_sections, switch_types, switches, track_section_links, track_sections, Graph, + speed_sections, switch_types, switches, track_sections, Graph, }; use crate::infra_cache::tests::{create_buffer_stop_cache, create_small_infra_cache}; @@ -389,14 +379,6 @@ mod test { &[], ) .is_empty()); - assert!(generate_errors( - ObjectType::TrackSectionLink, - &small_infra_cache, - &graph, - &[], - &track_section_links::GLOBAL_GENERATORS, - ) - .is_empty()); assert!(generate_errors( ObjectType::Switch, &small_infra_cache, diff --git a/editoast/src/generated_data/error/routes.rs b/editoast/src/generated_data/error/routes.rs index 341530103ff..e37ac6b5356 100644 --- a/editoast/src/generated_data/error/routes.rs +++ b/editoast/src/generated_data/error/routes.rs @@ -414,7 +414,7 @@ mod tests { Direction::StartToStop, Waypoint::new_detector("D1"), vec!["D2".into()], - Default::default(), + [("tracklink".into(), "LINK".into())].into(), ); infra_cache.add(route.clone()); let graph = Graph::load(&infra_cache); @@ -435,7 +435,11 @@ mod tests { Direction::StartToStop, Waypoint::new_detector("D1"), vec![], - [("switch".into(), "RIGHT".into())].into(), + [ + ("tracklink".into(), "LINK".into()), + ("switch".into(), "RIGHT".into()), + ] + .into(), ); infra_cache.add(route.clone()); let graph = Graph::load(&infra_cache); diff --git a/editoast/src/generated_data/error/sql/track_section_links_insert_errors.sql b/editoast/src/generated_data/error/sql/track_section_links_insert_errors.sql deleted file mode 100644 index 212cddb8cb9..00000000000 --- a/editoast/src/generated_data/error/sql/track_section_links_insert_errors.sql +++ /dev/null @@ -1,16 +0,0 @@ -WITH errors AS ( - SELECT unnest($2) AS information -) -INSERT INTO infra_layer_error ( - infra_id, - geographic, - schematic, - information - ) -SELECT $1 AS infra_id, - links.geographic, - links.schematic, - errors.information -FROM errors - LEFT JOIN infra_layer_track_section_link AS links ON links.obj_id = information->>'obj_id' - AND links.infra_id = $1 diff --git a/editoast/src/generated_data/error/track_section_links.rs b/editoast/src/generated_data/error/track_section_links.rs deleted file mode 100644 index a3d71728b91..00000000000 --- a/editoast/src/generated_data/error/track_section_links.rs +++ /dev/null @@ -1,165 +0,0 @@ -use super::{GlobalErrorGenerator, NoContext, ObjectErrorGenerator}; -use crate::infra_cache::{Graph, InfraCache, ObjectCache}; -use crate::schema::{InfraError, OSRDObject, ObjectRef, ObjectType, TrackEndpoint}; - -use std::collections::hash_map::Entry; -use std::collections::{HashMap, HashSet}; - -pub const OBJECT_GENERATORS: [ObjectErrorGenerator; 1] = - [ObjectErrorGenerator::new(1, check_invalid_ref)]; -pub const GLOBAL_GENERATORS: [GlobalErrorGenerator; 1] = - [GlobalErrorGenerator::new(check_overlapping)]; - -/// Retrieve invalid ref for track section links -pub fn check_invalid_ref( - link: &ObjectCache, - infra_cache: &InfraCache, - _: &Graph, -) -> Vec { - let link = link.unwrap_track_section_link(); - let mut infra_errors = vec![]; - for (track_ref, pos) in [(&link.src.track, "src"), (&link.dst.track, "dst")] { - if !infra_cache - .track_sections() - .contains_key::(track_ref) - { - let obj_ref = ObjectRef::new::<&String>(ObjectType::TrackSection, track_ref); - - infra_errors.push(InfraError::new_invalid_reference( - link, - format!("{pos}.track"), - obj_ref, - )); - } - } - infra_errors -} - -fn check_overlapping(infra_cache: &InfraCache, _: &Graph) -> Vec { - let mut errors = vec![]; - - // Initialize track endpoints cache - let mut track_endpoint_cache = HashMap::<&TrackEndpoint, ObjectRef>::new(); - for switch in infra_cache.switches().values() { - let switch = switch.unwrap_switch(); - for port in switch.ports.values() { - track_endpoint_cache.insert(port, switch.get_ref()); - } - } - - // Check for overlapping track links - for link in infra_cache.track_section_links().values() { - let link = link.unwrap_track_section_link(); - let mut overlapping_objects = HashSet::new(); - for track_endpoint in [&link.src, &link.dst] { - match track_endpoint_cache.entry(track_endpoint) { - Entry::Vacant(e) => { - e.insert(link.get_ref()); - } - Entry::Occupied(e) => { - overlapping_objects.insert(e.get().clone()); - } - } - } - - // Add errors foreach overlapping object found - errors.extend( - overlapping_objects - .into_iter() - .map(|e| InfraError::new_overlapping_track_links(link, e)), - ); - } - errors -} - -#[cfg(test)] -mod tests { - use super::InfraError; - use super::{check_invalid_ref, check_overlapping}; - use crate::infra_cache::tests::{ - create_small_infra_cache, create_track_endpoint, create_track_link_cache, - }; - use crate::schema::{Endpoint, OSRDObject, ObjectRef, ObjectType, TrackEndpoint}; - - use std::collections::HashMap; - - #[test] - fn single_invalid_ref_dst() { - let mut infra_cache = create_small_infra_cache(); - let link = create_track_link_cache( - "link_error", - create_track_endpoint(Endpoint::End, "C"), - create_track_endpoint(Endpoint::Begin, "E"), - ); - infra_cache.add(link.clone()); - let errors = check_invalid_ref(&link.clone().into(), &infra_cache, &Default::default()); - assert_eq!(1, errors.len()); - let obj_ref = ObjectRef::new(ObjectType::TrackSection, "E"); - let infra_error = InfraError::new_invalid_reference(&link, "dst.track", obj_ref); - assert_eq!(infra_error, errors[0]); - } - - #[test] - fn double_invalid_ref() { - let mut infra_cache = create_small_infra_cache(); - let link = create_track_link_cache( - "link_error", - create_track_endpoint(Endpoint::End, "E"), - create_track_endpoint(Endpoint::Begin, "F"), - ); - infra_cache.add(link.clone()); - let errors = check_invalid_ref(&link.clone().into(), &infra_cache, &Default::default()); - assert_eq!(2, errors.len()); - let obj_ref = ObjectRef::new(ObjectType::TrackSection, "E"); - let infra_error = InfraError::new_invalid_reference(&link, "src.track", obj_ref); - assert_eq!(infra_error, errors[0]); - let obj_ref = ObjectRef::new(ObjectType::TrackSection, "F"); - let infra_error = InfraError::new_invalid_reference(&link, "dst.track", obj_ref); - assert_eq!(infra_error, errors[1]); - } - - #[test] - fn link_over_switch() { - let mut infra_cache = create_small_infra_cache(); - let link = create_track_link_cache( - "link_error", - create_track_endpoint(Endpoint::End, "B"), - create_track_endpoint(Endpoint::Begin, "C"), - ); - infra_cache.add(link.clone()); - let mut switch_cache = HashMap::<&TrackEndpoint, ObjectRef>::new(); - - for switch in infra_cache.switches().values() { - let switch = switch.unwrap_switch(); - for port in switch.ports.values() { - switch_cache.insert(port, switch.get_ref()); - } - } - let errors = check_overlapping(&infra_cache, &Default::default()); - assert_eq!(1, errors.len()); - let obj_ref = ObjectRef::new(ObjectType::Switch, "switch"); - let infra_error = InfraError::new_overlapping_track_links(&link, obj_ref); - assert_eq!(infra_error, errors[0]); - } - - #[test] - fn link_over_link() { - let mut infra_cache = create_small_infra_cache(); - let link = create_track_link_cache( - "link_error", - create_track_endpoint(Endpoint::End, "B"), - create_track_endpoint(Endpoint::Begin, "C"), - ); - infra_cache.add(link); - let mut switch_cache = HashMap::<&TrackEndpoint, ObjectRef>::new(); - - for switch in infra_cache.switches().values() { - let switch = switch.unwrap_switch(); - for port in switch.ports.values() { - switch_cache.insert(port, switch.get_ref()); - } - } - let errors = check_overlapping(&infra_cache, &Default::default()); - assert_eq!(1, errors.len()); - } -} diff --git a/editoast/src/generated_data/mod.rs b/editoast/src/generated_data/mod.rs index 51aaefe34b8..200056a0cfe 100644 --- a/editoast/src/generated_data/mod.rs +++ b/editoast/src/generated_data/mod.rs @@ -11,7 +11,6 @@ mod signal; mod speed_section; mod switch; mod track_section; -mod track_section_link; use async_trait::async_trait; use buffer_stop::BufferStopLayer; @@ -25,7 +24,6 @@ use signal::SignalLayer; use speed_section::SpeedSectionLayer; use switch::SwitchLayer; use track_section::TrackSectionLayer; -use track_section_link::TrackSectionLinkLayer; use crate::error::Result; use crate::infra_cache::InfraCache; @@ -99,7 +97,6 @@ pub async fn refresh_all( CatenaryLayer::refresh_pool(db_pool.clone(), infra, infra_cache), DetectorLayer::refresh_pool(db_pool.clone(), infra, infra_cache), OperationalPointLayer::refresh_pool(db_pool.clone(), infra, infra_cache), - TrackSectionLinkLayer::refresh_pool(db_pool.clone(), infra, infra_cache), PSLSignLayer::refresh_pool(db_pool.clone(), infra, infra_cache), NeutralSectionLayer::refresh_pool(db_pool.clone(), infra, infra_cache), )?; @@ -120,7 +117,6 @@ pub async fn clear_all(conn: &mut PgConnection, infra: i64) -> Result<()> { CatenaryLayer::clear(conn, infra).await?; DetectorLayer::clear(conn, infra).await?; OperationalPointLayer::clear(conn, infra).await?; - TrackSectionLinkLayer::clear(conn, infra).await?; PSLSignLayer::clear(conn, infra).await?; ErrorLayer::clear(conn, infra).await?; NeutralSectionLayer::clear(conn, infra).await?; @@ -142,7 +138,6 @@ pub async fn update_all( CatenaryLayer::update(conn, infra, operations, infra_cache).await?; DetectorLayer::update(conn, infra, operations, infra_cache).await?; OperationalPointLayer::update(conn, infra, operations, infra_cache).await?; - TrackSectionLinkLayer::update(conn, infra, operations, infra_cache).await?; PSLSignLayer::update(conn, infra, operations, infra_cache).await?; ErrorLayer::update(conn, infra, operations, infra_cache).await?; NeutralSectionLayer::update(conn, infra, operations, infra_cache).await?; diff --git a/editoast/src/generated_data/sql/generate_track_section_link_layer.sql b/editoast/src/generated_data/sql/generate_track_section_link_layer.sql deleted file mode 100644 index c99ef0bb317..00000000000 --- a/editoast/src/generated_data/sql/generate_track_section_link_layer.sql +++ /dev/null @@ -1,26 +0,0 @@ -WITH collect AS ( - SELECT links.obj_id AS link_id, - links.data->'dst'->>'endpoint' AS ep, - tracks_layer.geographic AS track_geo, - tracks_layer.schematic AS track_sch - FROM infra_object_track_section_link AS links - INNER JOIN infra_object_track_section AS tracks ON tracks.obj_id = links.data->'dst'->>'track' - AND tracks.infra_id = links.infra_id - INNER JOIN infra_layer_track_section AS tracks_layer ON tracks.obj_id = tracks_layer.obj_id - AND tracks.infra_id = tracks_layer.infra_id - WHERE links.infra_id = $1 -) -INSERT INTO infra_layer_track_section_link (obj_id, infra_id, geographic, schematic) -SELECT link_id, - $1, - CASE - ep - WHEN 'BEGIN' THEN ST_StartPoint(track_geo) - WHEN 'END' THEN ST_EndPoint(track_geo) - END, - CASE - ep - WHEN 'BEGIN' THEN ST_StartPoint(track_sch) - WHEN 'END' THEN ST_EndPoint(track_sch) - END -FROM collect diff --git a/editoast/src/generated_data/sql/insert_update_track_section_link_layer.sql b/editoast/src/generated_data/sql/insert_update_track_section_link_layer.sql deleted file mode 100644 index 429dac15c04..00000000000 --- a/editoast/src/generated_data/sql/insert_update_track_section_link_layer.sql +++ /dev/null @@ -1,30 +0,0 @@ -WITH collect AS ( - SELECT links.obj_id AS link_id, - links.data->'dst'->>'endpoint' AS ep, - tracks_layer.geographic AS track_geo, - tracks_layer.schematic AS track_sch - FROM infra_object_track_section_link AS links - INNER JOIN infra_object_track_section AS tracks ON tracks.obj_id = links.data->'dst'->>'track' - AND tracks.infra_id = links.infra_id - INNER JOIN infra_layer_track_section AS tracks_layer ON tracks.obj_id = tracks_layer.obj_id - AND tracks.infra_id = tracks_layer.infra_id - WHERE links.infra_id = $1 - AND links.obj_id = ANY($2) -) -INSERT INTO infra_layer_track_section_link (obj_id, infra_id, geographic, schematic) -SELECT link_id, - $1, - CASE - ep - WHEN 'BEGIN' THEN ST_StartPoint(track_geo) - WHEN 'END' THEN ST_EndPoint(track_geo) - END, - CASE - ep - WHEN 'BEGIN' THEN ST_StartPoint(track_sch) - WHEN 'END' THEN ST_EndPoint(track_sch) - END -FROM collect ON CONFLICT (infra_id, obj_id) DO -UPDATE -SET geographic = EXCLUDED.geographic, - schematic = EXCLUDED.schematic diff --git a/editoast/src/generated_data/track_section_link.rs b/editoast/src/generated_data/track_section_link.rs deleted file mode 100644 index 19c916570fe..00000000000 --- a/editoast/src/generated_data/track_section_link.rs +++ /dev/null @@ -1,65 +0,0 @@ -use crate::error::Result; -use async_trait::async_trait; -use diesel::delete; -use diesel::query_dsl::methods::FilterDsl; -use diesel::sql_query; -use diesel::sql_types::{Array, BigInt, Text}; -use diesel_async::{AsyncPgConnection as PgConnection, RunQueryDsl}; -use std::iter::Iterator; - -use super::utils::InvolvedObjects; -use super::GeneratedData; -use crate::diesel::ExpressionMethods; -use crate::infra_cache::InfraCache; -use crate::schema::ObjectType; -use crate::tables::infra_layer_track_section_link::dsl; - -pub struct TrackSectionLinkLayer; - -#[async_trait] -impl GeneratedData for TrackSectionLinkLayer { - fn table_name() -> &'static str { - "infra_layer_track_section_link" - } - - async fn generate(conn: &mut PgConnection, infra: i64, _cache: &InfraCache) -> Result<()> { - sql_query(include_str!("sql/generate_track_section_link_layer.sql")) - .bind::(infra) - .execute(conn) - .await?; - Ok(()) - } - - async fn update( - conn: &mut PgConnection, - infra: i64, - operations: &[crate::schema::operation::OperationResult], - infra_cache: &crate::infra_cache::InfraCache, - ) -> Result<()> { - let involved_objects = - InvolvedObjects::from_operations(operations, infra_cache, ObjectType::TrackSectionLink); - - // Delete elements - if !involved_objects.deleted.is_empty() { - delete( - dsl::infra_layer_track_section_link - .filter(dsl::infra_id.eq(infra)) - .filter(dsl::obj_id.eq_any(involved_objects.deleted)), - ) - .execute(conn) - .await?; - } - - // Update elements - if !involved_objects.updated.is_empty() { - sql_query(include_str!( - "sql/insert_update_track_section_link_layer.sql" - )) - .bind::(infra) - .bind::, _>(involved_objects.updated.into_iter().collect::>()) - .execute(conn) - .await?; - } - Ok(()) - } -} diff --git a/editoast/src/infra_cache/graph.rs b/editoast/src/infra_cache/graph.rs index 06d1de8e4b4..b0c4d6dd6af 100644 --- a/editoast/src/infra_cache/graph.rs +++ b/editoast/src/infra_cache/graph.rs @@ -9,20 +9,14 @@ pub struct Graph<'a> { /// The graph of links between `TrackEndpoint`. /// The first key is the source `TrackEndpoint`. /// The second key is the group of the link. - /// If its a simple track section link then the group is `None`. - /// If its a switch then the group is the group of the switch. - links: HashMap<&'a TrackEndpoint, HashMap, &'a TrackEndpoint>>, + /// The group is the group of the switch. + links: HashMap<&'a TrackEndpoint, HashMap<&'a Identifier, &'a TrackEndpoint>>, switches: HashMap<&'a TrackEndpoint, &'a SwitchCache>, } impl<'a> Graph<'a> { /// Add a new link to the graph given two `TrackEndpoint`. - fn link( - &mut self, - group: Option<&'a Identifier>, - src: &'a TrackEndpoint, - dst: &'a TrackEndpoint, - ) { + fn link(&mut self, group: &'a Identifier, src: &'a TrackEndpoint, dst: &'a TrackEndpoint) { self.links.entry(src).or_default().insert(group, dst); } @@ -44,22 +38,14 @@ impl<'a> Graph<'a> { let Some(dst) = switch.ports.get::(&connection.dst) else { continue; }; - graph.link(Some(group), src, dst); - graph.link(Some(group), dst, src); + graph.link(group, src, dst); + graph.link(group, dst, src); graph.switches.insert(src, switch); graph.switches.insert(dst, switch); } } } - for link in infra_cache.track_section_links().values() { - let link = link.unwrap_track_section_link(); - if !graph.links.contains_key(&link.src) && !graph.links.contains_key(&link.dst) { - graph.link(None, &link.src, &link.dst); - graph.link(None, &link.dst, &link.src); - } - } - graph } @@ -74,11 +60,10 @@ impl<'a> Graph<'a> { } /// Given an endpoint and a group retrieve the neighbour endpoint. - /// If group is `None` then the searched neighbour endpoint is the one linked by a simple track section link. pub fn get_neighbour( &'a self, track_endpoint: &TrackEndpoint, - group: Option<&Identifier>, + group: &Identifier, ) -> Option<&'a TrackEndpoint> { self.links .get(&track_endpoint) @@ -87,15 +72,14 @@ impl<'a> Graph<'a> { /// Given an endpoint return a list of groups. /// If the endpoint has no neightbours return an empty `Vec`. - /// If the endpoint has as simple track section link return a `Vec` with a single `None` element. /// Otherwise returns a `Vec` with all the switch groups. pub fn get_neighbour_groups( &'a self, track_endpoint: &'a TrackEndpoint, - ) -> Vec> { + ) -> Vec<&'a Identifier> { self.links .get(&track_endpoint) - .map(|groups| groups.keys().map(|g| g.as_deref()).collect()) + .map(|groups| groups.keys().cloned().collect()) .unwrap_or_default() } } @@ -133,21 +117,22 @@ mod tests { let track_c_begin = create_track_endpoint(Endpoint::Begin, "C"); let track_d_begin = create_track_endpoint(Endpoint::Begin, "D"); + let link: Identifier = "LINK".into(); let left: Identifier = "LEFT".into(); let right: Identifier = "RIGHT".into(); let res = HashMap::from([ - ((&track_a_end, None), &track_b_begin), - ((&track_b_begin, None), &track_a_end), - ((&track_b_end, Some(&left)), &track_c_begin), - ((&track_b_end, Some(&right)), &track_d_begin), - ((&track_c_begin, Some(&left)), &track_b_end), - ((&track_d_begin, Some(&right)), &track_b_end), + ((&track_a_end, &link), &track_b_begin), + ((&track_b_begin, &link), &track_a_end), + ((&track_b_end, &left), &track_c_begin), + ((&track_b_end, &right), &track_d_begin), + ((&track_c_begin, &left), &track_b_end), + ((&track_d_begin, &right), &track_b_end), ]); for track in 'A'..='D' { for endpoint in [Endpoint::Begin, Endpoint::End] { - for group in [None, Some(&left), Some(&right)] { + for group in [&link, &left, &right] { let track_endpoint = create_track_endpoint(endpoint, track.to_string()); let branch = graph.get_neighbour(&track_endpoint, group); let expected_branch = res.get(&(&track_endpoint, group)).cloned(); @@ -170,7 +155,8 @@ mod tests { assert!(graph.get_switch(&track_a_begin).is_none()); let track_a_end = create_track_endpoint(Endpoint::End, "A"); - assert!(graph.get_switch(&track_a_end).is_none()); + let link = graph.get_switch(&track_a_end).unwrap(); + assert_eq!(link.obj_id, "tracklink".to_string()); } #[test] @@ -181,8 +167,8 @@ mod tests { let track_b_end = create_track_endpoint(Endpoint::End, "B"); let groups = graph.get_neighbour_groups(&track_b_end); assert_eq!(groups.len(), 2); - assert!(groups.contains(&Some(&"LEFT".into()))); - assert!(groups.contains(&Some(&"RIGHT".into()))); + assert!(groups.contains(&&"LEFT".into())); + assert!(groups.contains(&&"RIGHT".into())); let track_a_begin = create_track_endpoint(Endpoint::Begin, "A"); let groups = graph.get_neighbour_groups(&track_a_begin); @@ -191,6 +177,6 @@ mod tests { let track_a_end = create_track_endpoint(Endpoint::End, "A"); let groups = graph.get_neighbour_groups(&track_a_end); assert_eq!(groups.len(), 1); - assert!(groups.contains(&None)); + assert!(groups.contains(&&"LINK".into())); } } diff --git a/editoast/src/infra_cache/mod.rs b/editoast/src/infra_cache/mod.rs index cb64dddf6fd..d20b5920835 100644 --- a/editoast/src/infra_cache/mod.rs +++ b/editoast/src/infra_cache/mod.rs @@ -39,7 +39,6 @@ pub enum ObjectCache { TrackSection(TrackSectionCache), Signal(SignalCache), SpeedSection(SpeedSection), - TrackSectionLink(TrackSectionLink), Switch(SwitchCache), Detector(DetectorCache), BufferStop(BufferStopCache), @@ -61,7 +60,6 @@ impl OSRDIdentified for ObjectCache { ObjectCache::TrackSection(obj) => obj.get_id(), ObjectCache::Signal(obj) => obj.get_id(), ObjectCache::SpeedSection(obj) => obj.get_id(), - ObjectCache::TrackSectionLink(obj) => obj.get_id(), ObjectCache::Switch(obj) => obj.get_id(), ObjectCache::Detector(obj) => obj.get_id(), ObjectCache::BufferStop(obj) => obj.get_id(), @@ -79,7 +77,6 @@ impl OSRDObject for ObjectCache { ObjectCache::TrackSection(_) => ObjectType::TrackSection, ObjectCache::Signal(_) => ObjectType::Signal, ObjectCache::SpeedSection(_) => ObjectType::SpeedSection, - ObjectCache::TrackSectionLink(_) => ObjectType::TrackSectionLink, ObjectCache::Switch(_) => ObjectType::Switch, ObjectCache::Detector(_) => ObjectType::Detector, ObjectCache::BufferStop(_) => ObjectType::BufferStop, @@ -97,7 +94,6 @@ impl ObjectCache { ObjectCache::TrackSection(track) => track.get_track_referenced_id(), ObjectCache::Signal(signal) => signal.get_track_referenced_id(), ObjectCache::SpeedSection(speed) => speed.get_track_referenced_id(), - ObjectCache::TrackSectionLink(link) => link.get_track_referenced_id(), ObjectCache::Switch(switch) => switch.get_track_referenced_id(), ObjectCache::Detector(detector) => detector.get_track_referenced_id(), ObjectCache::BufferStop(buffer_stop) => buffer_stop.get_track_referenced_id(), @@ -132,14 +128,6 @@ impl ObjectCache { } } - /// Unwrap a track section link from the object cache - pub fn unwrap_track_section_link(&self) -> &TrackSectionLink { - match self { - ObjectCache::TrackSectionLink(link) => link, - _ => panic!("ObjectCache is not a TrackSectionLink"), - } - } - /// Unwrap a switch from the object cache pub fn unwrap_switch(&self) -> &SwitchCache { match self { @@ -319,11 +307,6 @@ impl InfraCache { &self.objects[ObjectType::Route] } - /// Retrieve the cache of track section links - pub fn track_section_links(&self) -> &HashMap { - &self.objects[ObjectType::TrackSectionLink] - } - /// Retrieve the cache of switches pub fn switches(&self) -> &HashMap { &self.objects[ObjectType::Switch] @@ -399,12 +382,6 @@ impl InfraCache { infra_cache.add::(op.into()) ); - // Load track section links tracks references - find_objects(conn, infra_id) - .await - .into_iter() - .for_each(|link| infra_cache.add::(link)); - // Load switch tracks references sql_query( "SELECT obj_id, data->>'switch_type' AS switch_type, data->>'ports' AS ports FROM infra_object_switch WHERE infra_id = $1") @@ -520,9 +497,6 @@ impl InfraCache { RailjsonObject::NeutralSection { railjson: _ } => { // TODO } - RailjsonObject::TrackSectionLink { railjson } => { - self.add::(railjson.clone()) - } RailjsonObject::Switch { railjson } => self.add::(railjson.clone().into()), RailjsonObject::SwitchType { railjson } => self.add::(railjson.clone()), RailjsonObject::Detector { railjson } => { @@ -559,14 +533,14 @@ pub mod tests { use crate::map::BoundingBox; use crate::models::infra::tests::test_infra_transaction; use crate::schema::operation::create::tests::{ - create_buffer_stop, create_catenary, create_detector, create_link, create_op, create_route, + create_buffer_stop, create_catenary, create_detector, create_op, create_route, create_signal, create_speed, create_switch, create_switch_type, create_track, }; use crate::schema::utils::{Identifier, NonBlankString}; use crate::schema::{ ApplicableDirections, ApplicableDirectionsTrackRange, Catenary, Direction, Endpoint, OSRDIdentified, OperationalPoint, OperationalPointPartCache, Route, SpeedSection, Switch, - SwitchPortConnection, SwitchType, TrackEndpoint, TrackSectionLink, Waypoint, + SwitchPortConnection, SwitchType, TrackEndpoint, Waypoint, }; use actix_web::test as actix_test; use chashmap::CHashMap; @@ -668,21 +642,6 @@ pub mod tests { .await; } - #[actix_test] - async fn load_track_section_link() { - test_infra_transaction(|conn, infra| { - async move { - let link = create_link(conn, infra.id.unwrap(), Default::default()).await; - let infra_cache = InfraCache::load(conn, &infra).await.unwrap(); - assert!(infra_cache - .track_section_links() - .contains_key(link.get_id())); - } - .scope_boxed() - }) - .await; - } - #[actix_test] async fn load_switch() { test_infra_transaction(|conn, infra| { @@ -897,18 +856,6 @@ pub mod tests { } } - pub fn create_track_link_cache>( - id: T, - src: TrackEndpoint, - dst: TrackEndpoint, - ) -> TrackSectionLink { - TrackSectionLink { - id: id.as_ref().into(), - src, - dst, - } - } - pub fn create_switch_connection>(src: T, dst: T) -> SwitchPortConnection { SwitchPortConnection { src: src.as_ref().into(), @@ -945,6 +892,22 @@ pub mod tests { } } + pub fn create_switch_cache_link( + obj_id: String, + source: (&str, TrackEndpoint), + destination: (&str, TrackEndpoint), + switch_type: String, + ) -> SwitchCache { + let ports_list = [source, destination]; + let ports: HashMap = + ports_list.into_iter().map(|(s, t)| (s.into(), t)).collect(); + SwitchCache { + obj_id, + switch_type, + ports, + } + } + /// -------| C /// D1 / /// |--------+---*--- @@ -975,7 +938,7 @@ pub mod tests { Direction::StartToStop, Waypoint::new_detector("D1"), vec![], - Default::default(), + [("tracklink".into(), "LINK".into())].into(), )); infra_cache.add(create_route_cache( "R2", @@ -994,10 +957,20 @@ pub mod tests { [("switch".into(), "RIGHT".into())].into(), )); - let link = create_track_link_cache( - "tracklink", - create_track_endpoint(Endpoint::End, "A"), - create_track_endpoint(Endpoint::Begin, "B"), + infra_cache.add(create_switch_type_cache( + "link", + vec!["SOURCE".into(), "DESTINATION".into()], + HashMap::from([( + "LINK".into(), + vec![create_switch_connection("SOURCE", "DESTINATION")], + )]), + )); + + let link = create_switch_cache_link( + "tracklink".into(), + ("SOURCE", create_track_endpoint(Endpoint::End, "A")), + ("DESTINATION", create_track_endpoint(Endpoint::Begin, "B")), + "link".into(), ); infra_cache.add(link); diff --git a/editoast/src/map/bounding_box.rs b/editoast/src/map/bounding_box.rs index 8e659184245..8bb5cf8e8c3 100644 --- a/editoast/src/map/bounding_box.rs +++ b/editoast/src/map/bounding_box.rs @@ -159,17 +159,6 @@ impl Zone { Self::merge_bbox(&mut geo, &mut sch, infra_cache, track_id); } } - OperationResult::Update(RailjsonObject::TrackSectionLink { railjson }) - | OperationResult::Create(RailjsonObject::TrackSectionLink { railjson }) => { - if let Some(ObjectCache::TrackSectionLink(link)) = infra_cache - .track_section_links() - .get::(&railjson.id) - { - Self::merge_bbox(&mut geo, &mut sch, infra_cache, &link.src.track); - }; - let track_id = &railjson.src.track; - Self::merge_bbox(&mut geo, &mut sch, infra_cache, track_id); - } OperationResult::Update(RailjsonObject::Switch { railjson }) | OperationResult::Create(RailjsonObject::Switch { railjson }) => { if let Some(ObjectCache::Switch(switch)) = @@ -260,16 +249,6 @@ impl Zone { } } } - OperationResult::Delete(ObjectRef { - obj_type: ObjectType::TrackSectionLink, - obj_id, - }) => { - if let Some(ObjectCache::TrackSectionLink(link)) = - infra_cache.track_section_links().get(obj_id) - { - Self::merge_bbox(&mut geo, &mut sch, infra_cache, &link.src.track); - } - } OperationResult::Delete(ObjectRef { obj_type: ObjectType::Switch, obj_id, diff --git a/editoast/src/models/infra.rs b/editoast/src/models/infra.rs index 4f3ed61ec27..2d4f005bee1 100644 --- a/editoast/src/models/infra.rs +++ b/editoast/src/models/infra.rs @@ -4,7 +4,7 @@ use crate::infra_cache::InfraCache; use crate::models::{Identifiable, Retrieve}; use crate::schema::{ BufferStop, Catenary, Detector, NeutralSection, OperationalPoint, RailJson, RailjsonError, - Route, Signal, SpeedSection, Switch, SwitchType, TrackSection, TrackSectionLink, + Route, Signal, SpeedSection, Switch, SwitchType, TrackSection, }; use crate::tables::infra; use crate::tables::infra::dsl; @@ -23,7 +23,7 @@ use log::{debug, error}; use serde::{Deserialize, Serialize}; use uuid::Uuid; -pub const RAILJSON_VERSION: &str = "3.4.3"; +pub const RAILJSON_VERSION: &str = "3.4.4"; pub const INFRA_VERSION: &str = "0"; #[derive( @@ -113,11 +113,6 @@ impl Infra { debug!("🛤 Begin importing all railjson objects"); let res = futures::try_join!( TrackSection::persist_batch_pool(&railjson.track_sections, infra_id, db_pool.clone()), - TrackSectionLink::persist_batch_pool( - &railjson.track_section_links, - infra_id, - db_pool.clone() - ), BufferStop::persist_batch_pool(&railjson.buffer_stops, infra_id, db_pool.clone()), Catenary::persist_batch_pool(&railjson.catenaries, infra_id, db_pool.clone()), Detector::persist_batch_pool(&railjson.detectors, infra_id, db_pool.clone()), diff --git a/editoast/src/schema/errors.rs b/editoast/src/schema/errors.rs index 38b1d23f140..7074e036693 100644 --- a/editoast/src/schema/errors.rs +++ b/editoast/src/schema/errors.rs @@ -52,9 +52,6 @@ pub enum InfraErrorType { OverlappingSwitches { reference: ObjectRef, }, - OverlappingTrackLinks { - reference: ObjectRef, - }, UnknownPortName { port_name: String, }, @@ -280,16 +277,6 @@ impl InfraError { sub_type: InfraErrorType::OverlappingSwitches { reference }, } } - - pub fn new_overlapping_track_links(obj: &O, reference: ObjectRef) -> Self { - Self { - obj_id: obj.get_id().clone(), - obj_type: obj.get_type(), - field: Default::default(), - is_warning: true, - sub_type: InfraErrorType::OverlappingTrackLinks { reference }, - } - } } impl OSRDIdentified for InfraError { diff --git a/editoast/src/schema/mod.rs b/editoast/src/schema/mod.rs index 17fd43b25f6..8a092c426d6 100644 --- a/editoast/src/schema/mod.rs +++ b/editoast/src/schema/mod.rs @@ -16,7 +16,6 @@ mod switch; mod switch_type; mod track_section; -mod track_section_link; pub mod utils; pub use buffer_stop::{BufferStop, BufferStopCache}; pub use catenary::Catenary; @@ -40,7 +39,6 @@ use strum_macros::EnumIter; pub use switch::{Switch, SwitchCache}; pub use switch_type::{SwitchPortConnection, SwitchType}; pub use track_section::{Curve, Slope, TrackSection, TrackSectionCache}; -pub use track_section_link::TrackSectionLink; use self::utils::{Identifier, NonBlankString}; @@ -79,7 +77,6 @@ pub enum ObjectType { SpeedSection, Detector, NeutralSection, - TrackSectionLink, Switch, SwitchType, BufferStop, @@ -96,7 +93,6 @@ impl ObjectType { ObjectType::NeutralSection => "infra_object_neutral_section", ObjectType::SpeedSection => "infra_object_speed_section", ObjectType::Detector => "infra_object_detector", - ObjectType::TrackSectionLink => "infra_object_track_section_link", ObjectType::Switch => "infra_object_switch", ObjectType::SwitchType => "infra_object_switch_type", ObjectType::BufferStop => "infra_object_buffer_stop", @@ -114,7 +110,6 @@ impl ObjectType { ObjectType::Signal => Some("infra_layer_signal"), ObjectType::SpeedSection => Some("infra_layer_speed_section"), ObjectType::Detector => Some("infra_layer_detector"), - ObjectType::TrackSectionLink => Some("infra_layer_track_section_link"), ObjectType::Switch => Some("infra_layer_switch"), ObjectType::BufferStop => Some("infra_layer_buffer_stop"), ObjectType::OperationalPoint => Some("infra_layer_operational_point"), diff --git a/editoast/src/schema/operation/create.rs b/editoast/src/schema/operation/create.rs index eb4ef793389..dc2697767f6 100644 --- a/editoast/src/schema/operation/create.rs +++ b/editoast/src/schema/operation/create.rs @@ -2,7 +2,6 @@ use crate::error::Result; use crate::schema::{ BufferStop, Catenary, Detector, NeutralSection, OSRDIdentified, OSRDObject, ObjectType, OperationalPoint, Route, Signal, SpeedSection, Switch, SwitchType, TrackSection, - TrackSectionLink, }; use diesel::sql_query; use diesel::sql_types::{BigInt, Json, Text}; @@ -19,7 +18,6 @@ pub enum RailjsonObject { Signal { railjson: Signal }, NeutralSection { railjson: NeutralSection }, SpeedSection { railjson: SpeedSection }, - TrackSectionLink { railjson: TrackSectionLink }, Switch { railjson: Switch }, SwitchType { railjson: SwitchType }, Detector { railjson: Detector }, @@ -68,7 +66,6 @@ impl RailjsonObject { RailjsonObject::Signal { railjson: obj } => obj, RailjsonObject::NeutralSection { railjson: obj } => obj, RailjsonObject::SpeedSection { railjson: obj } => obj, - RailjsonObject::TrackSectionLink { railjson: obj } => obj, RailjsonObject::Switch { railjson: obj } => obj, RailjsonObject::SwitchType { railjson: obj } => obj, RailjsonObject::Detector { railjson: obj } => obj, @@ -85,7 +82,6 @@ impl RailjsonObject { RailjsonObject::Signal { railjson: obj } => serde_json::to_value(obj), RailjsonObject::SpeedSection { railjson: obj } => serde_json::to_value(obj), RailjsonObject::NeutralSection { railjson: obj } => serde_json::to_value(obj), - RailjsonObject::TrackSectionLink { railjson: obj } => serde_json::to_value(obj), RailjsonObject::Switch { railjson: obj } => serde_json::to_value(obj), RailjsonObject::SwitchType { railjson: obj } => serde_json::to_value(obj), RailjsonObject::Detector { railjson: obj } => serde_json::to_value(obj), @@ -124,14 +120,6 @@ impl From for RailjsonObject { } } -impl From for RailjsonObject { - fn from(tracksectionlink: TrackSectionLink) -> Self { - RailjsonObject::TrackSectionLink { - railjson: tracksectionlink, - } - } -} - impl From for RailjsonObject { fn from(switch: Switch) -> Self { RailjsonObject::Switch { railjson: switch } @@ -184,7 +172,7 @@ pub mod tests { use crate::schema::operation::create::{apply_create_operation, RailjsonObject}; use crate::schema::{ BufferStop, Catenary, Detector, OperationalPoint, Route, Signal, SpeedSection, Switch, - SwitchType, TrackSection, TrackSectionLink, + SwitchType, TrackSection, }; pub async fn create_track( @@ -217,16 +205,6 @@ pub mod tests { obj } - pub async fn create_link( - conn: &mut PgConnection, - infra_id: i64, - link: TrackSectionLink, - ) -> RailjsonObject { - let obj = RailjsonObject::TrackSectionLink { railjson: link }; - assert!(apply_create_operation(&obj, infra_id, conn).await.is_ok()); - obj - } - pub async fn create_switch( conn: &mut PgConnection, infra_id: i64, @@ -332,17 +310,6 @@ pub mod tests { .await; } - #[actix_test] - async fn create_link_test() { - test_infra_transaction(|conn, infra| { - async move { - create_link(conn, infra.id.unwrap(), Default::default()).await; - } - .scope_boxed() - }) - .await; - } - #[actix_test] async fn create_switch_test() { test_infra_transaction(|conn, infra| { diff --git a/editoast/src/schema/operation/delete.rs b/editoast/src/schema/operation/delete.rs index ccaf1e72a25..8997fcbd320 100644 --- a/editoast/src/schema/operation/delete.rs +++ b/editoast/src/schema/operation/delete.rs @@ -59,7 +59,7 @@ impl From for DeleteOperation { mod tests { use crate::models::infra::tests::test_infra_transaction; use crate::schema::operation::create::tests::{ - create_buffer_stop, create_catenary, create_detector, create_link, create_op, create_route, + create_buffer_stop, create_catenary, create_detector, create_op, create_route, create_signal, create_speed, create_switch, create_track, }; use crate::schema::operation::delete::DeleteOperation; @@ -136,26 +136,6 @@ mod tests { }.scope_boxed()).await; } - #[actix_test] - async fn delete_link() { - test_infra_transaction(|conn, infra| async move { - let link = create_link(conn, infra.id.unwrap(), Default::default()).await; - - let link_deletion: DeleteOperation = link.get_ref().into(); - - assert!(link_deletion.apply(infra.id.unwrap(), conn).await.is_ok()); - - let res_del = sql_query(format!( - "SELECT COUNT (*) AS nb FROM infra_object_track_section_link WHERE obj_id = '{}' AND infra_id = {}", - link.get_id(), - infra.id.unwrap() - )) - .get_result::(conn).await.unwrap(); - - assert_eq!(res_del.nb, 0); - }.scope_boxed()).await; - } - #[actix_test] async fn delete_switch() { test_infra_transaction(|conn, infra| async move { diff --git a/editoast/src/schema/railjson.rs b/editoast/src/schema/railjson.rs index 149feabbc9b..dc6e1f80892 100644 --- a/editoast/src/schema/railjson.rs +++ b/editoast/src/schema/railjson.rs @@ -1,6 +1,6 @@ use super::{ BufferStop, Catenary, Detector, NeutralSection, OSRDTyped, OperationalPoint, Route, Signal, - SpeedSection, Switch, SwitchType, TrackSection, TrackSectionLink, + SpeedSection, Switch, SwitchType, TrackSection, }; use crate::models::RAILJSON_VERSION; @@ -25,7 +25,6 @@ pub struct RailJson { pub routes: Vec, pub switch_types: Vec, pub switches: Vec, - pub track_section_links: Vec, pub track_sections: Vec, pub speed_sections: Vec, pub neutral_sections: Vec, @@ -120,7 +119,6 @@ pub mod test { routes: (0..10).map(|_| Default::default()).collect(), switch_types: (0..10).map(|_| Default::default()).collect(), switches: (0..10).map(|_| Default::default()).collect(), - track_section_links: (0..10).map(|_| Default::default()).collect(), track_sections: (0..10).map(|_| Default::default()).collect(), speed_sections: (0..10).map(|_| Default::default()).collect(), neutral_sections: (0..10).map(|_| Default::default()).collect(), @@ -156,10 +154,6 @@ pub mod test { &railjson.switch_types )); assert!(check_objects_eq(&s_railjson.switches, &railjson.switches)); - assert!(check_objects_eq( - &s_railjson.track_section_links, - &railjson.track_section_links - )); assert!(check_objects_eq( &s_railjson.track_sections, &railjson.track_sections @@ -203,7 +197,6 @@ pub mod test { routes: find_objects(conn, infra.id.unwrap()).await, switch_types: find_objects(conn, infra.id.unwrap()).await, switches: find_objects(conn, infra.id.unwrap()).await, - track_section_links: find_objects(conn, infra.id.unwrap()).await, track_sections: find_objects(conn, infra.id.unwrap()).await, speed_sections: find_objects(conn, infra.id.unwrap()).await, neutral_sections: find_objects(conn, infra.id.unwrap()).await, diff --git a/editoast/src/schema/route.rs b/editoast/src/schema/route.rs index dc860ffe408..d86d4a37aad 100644 --- a/editoast/src/schema/route.rs +++ b/editoast/src/schema/route.rs @@ -132,17 +132,13 @@ impl Route { if !graph.has_neighbour(&endpoint) { return None; } - let switch = graph.get_switch(&endpoint); - let next_endpoint = match switch { - None => graph.get_neighbour(&endpoint, None), - Some(switch) => { - let switch_id = switch.get_id(); - // Check we found the switch in the route - let group = self.switches_directions.get(&switch_id.clone().into())?; - used_switches.insert(switch_id.clone().into(), group.clone()); - graph.get_neighbour(&endpoint, Some(group)) - } - }?; + + let switch = graph.get_switch(&endpoint)?; + let switch_id = switch.get_id(); + // Check we found the switch in the route + let group = self.switches_directions.get(&switch_id.clone().into())?; + used_switches.insert(switch_id.clone().into(), group.clone()); + let next_endpoint = graph.get_neighbour(&endpoint, group)?; // Update current track section, offset and direction cur_track = infra_cache @@ -200,7 +196,8 @@ mod test { assert_eq!(path.track_ranges[1].track, "B".into()); assert_eq!(path.track_ranges[1].begin, 0.); assert_eq!(path.track_ranges[1].end, 250.); - assert_eq!(path.switches_directions.len(), 0); + assert_eq!(path.switches_directions.len(), 1); + assert!(path.switches_directions.contains_key(&"tracklink".into())); } #[test] diff --git a/editoast/src/schema/track_section_link.rs b/editoast/src/schema/track_section_link.rs deleted file mode 100644 index 1cca96cd5e3..00000000000 --- a/editoast/src/schema/track_section_link.rs +++ /dev/null @@ -1,74 +0,0 @@ -use super::OSRDIdentified; - -use super::utils::Identifier; -use super::OSRDTyped; -use super::ObjectType; -use super::TrackEndpoint; - -use crate::infra_cache::Cache; -use crate::infra_cache::ObjectCache; - -use derivative::Derivative; - -use editoast_derive::InfraModel; -use serde::{Deserialize, Serialize}; - -#[derive(Debug, Derivative, Clone, Deserialize, Serialize, PartialEq, Eq, InfraModel)] -#[serde(deny_unknown_fields)] -#[infra_model(table = "crate::tables::infra_object_track_section_link")] -#[derivative(Default)] -pub struct TrackSectionLink { - pub id: Identifier, - pub src: TrackEndpoint, - pub dst: TrackEndpoint, -} - -impl OSRDTyped for TrackSectionLink { - fn get_type() -> ObjectType { - ObjectType::TrackSectionLink - } -} - -impl OSRDIdentified for TrackSectionLink { - fn get_id(&self) -> &String { - &self.id - } -} - -impl Cache for TrackSectionLink { - fn get_track_referenced_id(&self) -> Vec<&String> { - vec![&self.src.track, &self.dst.track] - } - - fn get_object_cache(&self) -> ObjectCache { - ObjectCache::TrackSectionLink(self.clone()) - } -} - -#[cfg(test)] -mod test { - - use super::TrackSectionLink; - use crate::models::infra::tests::test_infra_transaction; - use actix_web::test as actix_test; - use diesel_async::scoped_futures::ScopedFutureExt; - - #[actix_test] - async fn test_persist() { - test_infra_transaction(|conn, infra| { - async move { - let data = (0..10) - .map(|_| TrackSectionLink::default()) - .collect::>(); - - assert!( - TrackSectionLink::persist_batch(&data, infra.id.unwrap(), conn) - .await - .is_ok() - ); - } - .scope_boxed() - }) - .await; - } -} diff --git a/editoast/src/tables.rs b/editoast/src/tables.rs index c88f933f0f7..c20ce493910 100644 --- a/editoast/src/tables.rs +++ b/editoast/src/tables.rs @@ -201,20 +201,6 @@ diesel::table! { } } -diesel::table! { - use diesel::sql_types::*; - use postgis_diesel::sql_types::*; - - infra_layer_track_section_link (id) { - id -> Int8, - #[max_length = 255] - obj_id -> Varchar, - geographic -> Geometry, - schematic -> Geometry, - infra_id -> Int8, - } -} - diesel::table! { use diesel::sql_types::*; use postgis_diesel::sql_types::*; @@ -358,19 +344,6 @@ diesel::table! { } } -diesel::table! { - use diesel::sql_types::*; - use postgis_diesel::sql_types::*; - - infra_object_track_section_link (id) { - id -> Int8, - #[max_length = 255] - obj_id -> Varchar, - data -> Jsonb, - infra_id -> Int8, - } -} - diesel::table! { use diesel::sql_types::*; use postgis_diesel::sql_types::*; @@ -670,7 +643,6 @@ diesel::joinable!(infra_layer_signal -> infra (infra_id)); diesel::joinable!(infra_layer_speed_section -> infra (infra_id)); diesel::joinable!(infra_layer_switch -> infra (infra_id)); diesel::joinable!(infra_layer_track_section -> infra (infra_id)); -diesel::joinable!(infra_layer_track_section_link -> infra (infra_id)); diesel::joinable!(infra_object_buffer_stop -> infra (infra_id)); diesel::joinable!(infra_object_catenary -> infra (infra_id)); diesel::joinable!(infra_object_detector -> infra (infra_id)); @@ -682,7 +654,6 @@ diesel::joinable!(infra_object_speed_section -> infra (infra_id)); diesel::joinable!(infra_object_switch -> infra (infra_id)); diesel::joinable!(infra_object_switch_type -> infra (infra_id)); diesel::joinable!(infra_object_track_section -> infra (infra_id)); -diesel::joinable!(infra_object_track_section_link -> infra (infra_id)); diesel::joinable!(pathfinding -> infra (infra_id)); diesel::joinable!(project -> document (image_id)); diesel::joinable!(rolling_stock_livery -> document (compound_image_id)); @@ -719,7 +690,6 @@ diesel::allow_tables_to_appear_in_same_query!( infra_layer_speed_section, infra_layer_switch, infra_layer_track_section, - infra_layer_track_section_link, infra_object_buffer_stop, infra_object_catenary, infra_object_detector, @@ -731,7 +701,6 @@ diesel::allow_tables_to_appear_in_same_query!( infra_object_switch, infra_object_switch_type, infra_object_track_section, - infra_object_track_section_link, pathfinding, project, rolling_stock, diff --git a/editoast/src/tests/small_infra/small_infra.json b/editoast/src/tests/small_infra/small_infra.json index 0a72351db5d..f59922eed26 100644 --- a/editoast/src/tests/small_infra/small_infra.json +++ b/editoast/src/tests/small_infra/small_infra.json @@ -1,5 +1,5 @@ { - "version": "3.4.3", + "version": "3.4.4", "operational_points": [ { "id": "South_West_station", @@ -1329,6 +1329,21 @@ } ], "switch_types": [ + { + "id": "link", + "ports": [ + "source", + "destination" + ], + "groups": { + "LINK": [ + { + "src": "source", + "dst": "destination" + } + ] + } + }, { "id": "point", "ports": [ @@ -1830,7 +1845,6 @@ } } ], - "track_section_links": [], "track_sections": [ { "geo": { diff --git a/editoast/src/views/infra/attached.rs b/editoast/src/views/infra/attached.rs index 085fb35cb0b..4a4c56f93cb 100644 --- a/editoast/src/views/infra/attached.rs +++ b/editoast/src/views/infra/attached.rs @@ -17,7 +17,6 @@ const ATTACHED_OBJECTS_TYPES: &[ObjectType] = &[ ObjectType::Signal, ObjectType::SpeedSection, ObjectType::Detector, - ObjectType::TrackSectionLink, ObjectType::Switch, ObjectType::BufferStop, ObjectType::OperationalPoint, diff --git a/editoast/src/views/infra/errors.rs b/editoast/src/views/infra/errors.rs index a4259dd3269..18f2b4bf638 100644 --- a/editoast/src/views/infra/errors.rs +++ b/editoast/src/views/infra/errors.rs @@ -135,7 +135,7 @@ mod tests { async fn list_errors_get(#[future] empty_infra: TestFixture) { let empty_infra = empty_infra.await; - let error_type = "overlapping_track_links"; + let error_type = "overlapping_catenaries"; let level = "warnings"; let app = create_test_service().await; diff --git a/editoast/src/views/infra/pathfinding.rs b/editoast/src/views/infra/pathfinding.rs index c3a97432def..f693bd5c1a0 100644 --- a/editoast/src/views/infra/pathfinding.rs +++ b/editoast/src/views/infra/pathfinding.rs @@ -241,7 +241,7 @@ fn compute_path( neighbour_track.obj_id.clone(), pos, dir, - switch.map(|s| (s.obj_id.clone().into(), neighbour_group.unwrap().clone())), + switch.map(|s| (s.obj_id.clone().into(), neighbour_group.clone())), false, step.clone(), ), @@ -377,7 +377,10 @@ mod tests { assert_eq!(path.detectors, vec!["D1".into()]); assert_eq!( path.switches_directions, - HashMap::from([("switch".into(), "LEFT".into())]) + HashMap::from([ + ("tracklink".into(), "LINK".into()), + ("switch".into(), "LEFT".into()) + ]) ); } } diff --git a/editoast/src/views/infra/railjson.rs b/editoast/src/views/infra/railjson.rs index e6d3d113b36..e50c9f6e47a 100644 --- a/editoast/src/views/infra/railjson.rs +++ b/editoast/src/views/infra/railjson.rs @@ -86,7 +86,6 @@ async fn get_railjson(infra: Path, db_pool: Data) -> Result, db_pool: Data) -> Result = [ 'out_of_range', 'overlapping_speed_sections', 'overlapping_switches', - 'overlapping_track_links', 'unknown_port_name', 'unused_port', ]; diff --git a/front/src/common/api/osrdEditoastApi.ts b/front/src/common/api/osrdEditoastApi.ts index 7ef17eef89a..c936761082c 100644 --- a/front/src/common/api/osrdEditoastApi.ts +++ b/front/src/common/api/osrdEditoastApi.ts @@ -1341,7 +1341,6 @@ export type RailjsonFile = { speed_sections?: any; switch_types?: any; switches?: any; - track_section_links?: any; track_sections?: any; version?: string; }; @@ -1350,7 +1349,6 @@ export type ObjectType = | 'Signal' | 'SpeedSection' | 'Detector' - | 'TrackSectionLink' | 'Switch' | 'SwitchType' | 'BufferStop' @@ -1431,7 +1429,6 @@ export type InfraErrorType = | 'out_of_range' | 'overlapping_speed_sections' | 'overlapping_switches' - | 'overlapping_track_links' | 'overlapping_catenaries' | 'unknown_port_name' | 'unused_port'; diff --git a/front/src/reducers/osrdconf/infra_schema.json b/front/src/reducers/osrdconf/infra_schema.json index 5736731dae1..8c57d06a85b 100644 --- a/front/src/reducers/osrdconf/infra_schema.json +++ b/front/src/reducers/osrdconf/infra_schema.json @@ -1598,41 +1598,6 @@ "title": "TrackSectionExtensions", "type": "object" }, - "TrackSectionLink": { - "description": "\n Track section links is used to connect and link two track sections.\n A track section link is characterized by its identifier.\n ", - "properties": { - "dst": { - "allOf": [ - { - "$ref": "#/$defs/TrackEndpoint" - } - ], - "description": "Finish track section, relative position in track section is defined by its end point" - }, - "id": { - "description": "Unique identifier of the object", - "maxLength": 255, - "minLength": 1, - "title": "Id", - "type": "string" - }, - "src": { - "allOf": [ - { - "$ref": "#/$defs/TrackEndpoint" - } - ], - "description": "Starting track section, relative position in track section is defined by its end point" - } - }, - "required": [ - "id", - "src", - "dst" - ], - "title": "TrackSectionLink", - "type": "object" - }, "TrackSectionSncfExtension": { "properties": { "line_code": { @@ -1841,14 +1806,6 @@ "title": "Switches", "type": "array" }, - "track_section_links": { - "description": "Track section links of the infra", - "items": { - "$ref": "#/$defs/TrackSectionLink" - }, - "title": "Track Section Links", - "type": "array" - }, "track_sections": { "description": "Track sections of the infra", "items": { @@ -1858,8 +1815,8 @@ "type": "array" }, "version": { - "const": "3.4.3", - "default": "3.4.3", + "const": "3.4.4", + "default": "3.4.4", "description": "Version of the schema", "title": "Version" } @@ -1869,7 +1826,6 @@ "routes", "switch_types", "switches", - "track_section_links", "track_sections", "speed_sections", "catenaries", diff --git a/python/osrd_schemas/osrd_schemas/generated.py b/python/osrd_schemas/osrd_schemas/generated.py index 2ca7426f188..ea2ef132c3e 100644 --- a/python/osrd_schemas/osrd_schemas/generated.py +++ b/python/osrd_schemas/osrd_schemas/generated.py @@ -98,11 +98,6 @@ class OverlappingSpeedSections(InfraWarningTrait): reference: ObjectReference -class OverlappingTrackLinks(InfraWarningTrait): - error_type: Literal["overlapping_track_links"] = Field(default="overlapping_track_links") - reference: ObjectReference - - class OverlappingCatenaries(InfraWarningTrait): error_type: Literal["overlapping_catenaries"] = Field(default="overlapping_catenaries") reference: ObjectReference @@ -124,7 +119,6 @@ class OverlappingCatenaries(InfraWarningTrait): OverlappingCatenaries, OverlappingSpeedSections, OverlappingSwitches, - OverlappingTrackLinks, UnknownPortName, UnusedPort, ], diff --git a/python/osrd_schemas/osrd_schemas/infra.py b/python/osrd_schemas/osrd_schemas/infra.py index 441346972ee..fab92c359ec 100644 --- a/python/osrd_schemas/osrd_schemas/infra.py +++ b/python/osrd_schemas/osrd_schemas/infra.py @@ -8,7 +8,7 @@ ALL_OBJECT_TYPES = [] -RAILJSON_INFRA_VERSION_TYPE = Literal["3.4.3"] +RAILJSON_INFRA_VERSION_TYPE = Literal["3.4.4"] RAILJSON_INFRA_VERSION = get_args(RAILJSON_INFRA_VERSION_TYPE)[0] # Traits @@ -259,20 +259,6 @@ class Switch(BaseObjectTrait): ) -class TrackSectionLink(BaseObjectTrait): - """ - Track section links is used to connect and link two track sections. - A track section link is characterized by its identifier. - """ - - src: TrackEndpoint = Field( - description="Starting track section, relative position in track section is defined by its end point" - ) - dst: TrackEndpoint = Field( - description="Finish track section, relative position in track section is defined by its end point" - ) - - class SpeedSection(BaseObjectTrait): """ Speed sections are recognized by their identifiers and are in meters per second. @@ -474,7 +460,6 @@ class RailJsonInfra(BaseModel): routes: List[Route] = Field(description="Routes of the infra") switch_types: List[SwitchType] = Field(description="Switch types of the infra") switches: List[Switch] = Field(description="Switches of the infra") - track_section_links: List[TrackSectionLink] = Field(description="Track section links of the infra") track_sections: List[TrackSection] = Field(description="Track sections of the infra") speed_sections: List[SpeedSection] = Field(description="Speed sections of the infra") catenaries: List[Catenary] = Field(description="Catenaries of the infra") diff --git a/python/osrd_schemas/pyproject.toml b/python/osrd_schemas/pyproject.toml index 32a94c30c7d..d66245a09b8 100644 --- a/python/osrd_schemas/pyproject.toml +++ b/python/osrd_schemas/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "osrd_schemas" -version = "0.7.3" +version = "0.7.4" description = "" authors = ["OSRD "] diff --git a/python/railjson_generator/README.md b/python/railjson_generator/README.md index ac8fcb17067..2f4b74a15ed 100644 --- a/python/railjson_generator/README.md +++ b/python/railjson_generator/README.md @@ -9,7 +9,7 @@ - `add_point_switch(self, base, left, right, label="switch.X", delay=0) -> Switch`: Add a point. - `add_cross_switch(self, north, south, east, west, label="switch.X", delay=0) -> Switch`: Add a cross switch. - `add_double_cross_switch(self, north_1, north_2, south_1, south_2, label="switch.X", delay=0) -> Switch`: Add a double cross switch. -- `add_link(self, begin, end) -> Link`: Add a link. +- `add_link(self, source, destination) -> Switch`: Add a link switch. - `add_operational_point(self, label) -> OperationPoint`: Add an operation point. - `generate_routes(self, progressive_release=True) -> Iterable[Route]`: Automatically generate routes, which must then be registered manually. When progressive_release is true, release points are added for all intermediate zones. - `register_route(self, route: Route)`: Register a route @@ -26,7 +26,7 @@ - `add_logical_signal(self, signaling_system: str, next_signaling_systems: List[str], settings: List[str]) -> LogicalSignal`: Add a logical signal to a signal. -### Switch / Link / TrackEndpoint +### Switch / TrackEndpoint - `set_coords(self, x, y)`: Set a geometry coordinates of the point diff --git a/python/railjson_generator/poetry.lock b/python/railjson_generator/poetry.lock index 64f5013d63e..89498b082b4 100644 --- a/python/railjson_generator/poetry.lock +++ b/python/railjson_generator/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.5.1 and should not be changed by hand. [[package]] name = "annotated-types" @@ -147,7 +147,7 @@ files = [ [[package]] name = "osrd-schemas" -version = "0.7.2" +version = "0.7.4" description = "" optional = false python-versions = ">=3.9,<3.12" diff --git a/python/railjson_generator/pyproject.toml b/python/railjson_generator/pyproject.toml index 84f2dfa4284..691b093824f 100644 --- a/python/railjson_generator/pyproject.toml +++ b/python/railjson_generator/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "railjson_generator" -version = "0.2.5" +version = "0.2.6" description = "" authors = ["OSRD "] diff --git a/python/railjson_generator/railjson_generator/infra_builder.py b/python/railjson_generator/railjson_generator/infra_builder.py index ce81810fdda..6d622308714 100644 --- a/python/railjson_generator/railjson_generator/infra_builder.py +++ b/python/railjson_generator/railjson_generator/infra_builder.py @@ -1,9 +1,8 @@ from dataclasses import dataclass, field -from typing import Iterable, Optional +from typing import Iterable from .schema.infra.endpoint import TrackEndpoint from .schema.infra.infra import Infra -from .schema.infra.link import Link from .schema.infra.neutral_section import NeutralSection from .schema.infra.operational_point import OperationalPoint from .schema.infra.route import Route @@ -13,27 +12,20 @@ DoubleCrossSwitch, PointSwitch, SwitchGroup, + TrackSectionLink, ) from .schema.infra.track_section import TrackSection from .utils import generate_routes def _check_connections(endpoint, connections): - links = [] switches = [] for connected_endpoint, switch_group in connections: if connected_endpoint == endpoint: raise RuntimeError("endpoint connected to itself") - category = links if switch_group is None else switches - category.append(switch_group) + switches.append(switch_group) - if not links and not switches: - return - if links and switches: - raise RuntimeError("endpoint connected to both links and switches") - if links and not switches: - if len(links) != 1: - raise RuntimeError("endpoint connected to multiple track links") + if not switches: return switch = switches[0].switch @@ -46,7 +38,7 @@ def _check_connections(endpoint, connections): groups.add(switch_group.group) -def _register_connection(endpoint_a: TrackEndpoint, endpoint_b: TrackEndpoint, switch_group: Optional[SwitchGroup]): +def _register_connection(endpoint_a: TrackEndpoint, endpoint_b: TrackEndpoint, switch_group: SwitchGroup): """Connect two track endpoints together""" a_neighbors = endpoint_a.get_neighbors() b_neighbors = endpoint_b.get_neighbors() @@ -99,11 +91,11 @@ def add_double_cross_switch( self.infra.switches.append(switch) return switch - def add_link(self, *args, **kwargs): - link = Link(*args, **kwargs) - self.infra.links.append(link) - _register_connection(link.begin, link.end, None) - return link + def add_link(self, source: TrackEndpoint, destination: TrackEndpoint, **kwargs): + switch = TrackSectionLink(source=source, destination=destination, **kwargs) + self.infra.switches.append(switch) + _register_connection(source, destination, switch.group("LINK")) + return switch def add_operational_point(self, *args, **kwargs): self.infra.operational_points.append(OperationalPoint(*args, **kwargs)) diff --git a/python/railjson_generator/railjson_generator/rjs_static/switch_types.json b/python/railjson_generator/railjson_generator/rjs_static/switch_types.json index 8b78275182d..db5a05f46e3 100644 --- a/python/railjson_generator/railjson_generator/rjs_static/switch_types.json +++ b/python/railjson_generator/railjson_generator/rjs_static/switch_types.json @@ -76,5 +76,20 @@ } ] } + }, + { + "id": "link", + "ports": [ + "source", + "destination" + ], + "groups": { + "LINK": [ + { + "src": "source", + "dst": "destination" + } + ] + } } -] \ No newline at end of file +] diff --git a/python/railjson_generator/railjson_generator/schema/infra/infra.py b/python/railjson_generator/railjson_generator/schema/infra/infra.py index 74b6a62bf09..57c5e621381 100644 --- a/python/railjson_generator/railjson_generator/schema/infra/infra.py +++ b/python/railjson_generator/railjson_generator/schema/infra/infra.py @@ -6,7 +6,6 @@ from railjson_generator.rjs_static import SWITCH_TYPES from railjson_generator.schema.infra.catenary import Catenary -from railjson_generator.schema.infra.link import Link from railjson_generator.schema.infra.neutral_section import NeutralSection from railjson_generator.schema.infra.operational_point import OperationalPoint from railjson_generator.schema.infra.route import Route @@ -20,14 +19,13 @@ class Infra: track_sections: List[TrackSection] = field(default_factory=list) switches: List[Switch] = field(default_factory=list) - links: List[Link] = field(default_factory=list) operational_points: List[OperationalPoint] = field(default_factory=list) routes: List[Route] = field(default_factory=list) speed_sections: List[SpeedSection] = field(default_factory=list) catenaries: List[Catenary] = field(default_factory=list) neutral_sections: List[NeutralSection] = field(default_factory=list) - VERSION = "3.4.3" + VERSION = "3.4.4" def add_route(self, *args, **kwargs): self.routes.append(Route(*args, **kwargs)) @@ -38,7 +36,6 @@ def to_rjs(self) -> infra.RailJsonInfra: version=self.VERSION, track_sections=[track.to_rjs() for track in self.track_sections], switches=[switch.to_rjs() for switch in self.switches], - track_section_links=[link.to_rjs() for link in self.links], routes=[route.to_rjs() for route in self.routes], signals=self.make_rjs_signals(), buffer_stops=self.make_rjs_buffer_stops(), @@ -104,7 +101,6 @@ def find_duplicates(self): for instance_list in [ self.track_sections, self.switches, - self.links, self.operational_points, self.routes, self.speed_sections, diff --git a/python/railjson_generator/railjson_generator/schema/infra/link.py b/python/railjson_generator/railjson_generator/schema/infra/link.py deleted file mode 100644 index a0da5bbe9ff..00000000000 --- a/python/railjson_generator/railjson_generator/schema/infra/link.py +++ /dev/null @@ -1,31 +0,0 @@ -from dataclasses import dataclass, field - -from osrd_schemas import infra - -from railjson_generator.schema.infra.endpoint import TrackEndpoint - - -def _link_id(): - res = f"link.{Link._INDEX}" - Link._INDEX += 1 - return res - - -@dataclass -class Link: - begin: TrackEndpoint - end: TrackEndpoint - label: str = field(default_factory=_link_id) - - _INDEX = 0 - - def set_coords(self, x: float, y: float): - for endpoint in (self.begin, self.end): - endpoint.set_coords(x, y) - - def to_rjs(self): - return infra.TrackSectionLink( - id=self.label, - src=self.begin.to_rjs(), - dst=self.end.to_rjs(), - ) diff --git a/python/railjson_generator/railjson_generator/schema/infra/switch.py b/python/railjson_generator/railjson_generator/schema/infra/switch.py index 74ffa37a708..68d8859f0c7 100644 --- a/python/railjson_generator/railjson_generator/schema/infra/switch.py +++ b/python/railjson_generator/railjson_generator/schema/infra/switch.py @@ -76,6 +76,15 @@ def to_rjs(self): ) +@dataclass +class TrackSectionLink(Switch): + source: TrackEndpoint = None + destination: TrackEndpoint = None + + PORT_NAMES = ["source", "destination"] + SWITCH_TYPE = "link" + + @dataclass class PointSwitch(Switch): base: TrackEndpoint = None diff --git a/tests/fuzzer/fuzzer.py b/tests/fuzzer/fuzzer.py index db1b1d7bbbc..06ce93d7a43 100644 --- a/tests/fuzzer/fuzzer.py +++ b/tests/fuzzer/fuzzer.py @@ -294,9 +294,6 @@ def make_graph(editoast_url: str, infra: int) -> InfraGraph: for track in infra["track_sections"]: graph.tracks[track["id"]] = track - for link in infra["track_section_links"]: - graph.link(TrackEndpoint.from_dict(link["src"]), TrackEndpoint.from_dict(link["dst"])) - switch_types = dict() for switch_type in infra["switch_types"]: switch_types[switch_type["id"]] = switch_type