diff --git a/editoast/editoast_models/src/tables.rs b/editoast/editoast_models/src/tables.rs index db0a4992c0d..eb63752fe83 100644 --- a/editoast/editoast_models/src/tables.rs +++ b/editoast/editoast_models/src/tables.rs @@ -191,6 +191,7 @@ diesel::table! { geographic -> Geometry, infra_id -> Int8, kp -> Nullable, + track_section -> Text, } } diff --git a/editoast/map_layers.yml b/editoast/map_layers.yml index 6bcd2c72f42..21ff0692731 100644 --- a/editoast/map_layers.yml +++ b/editoast/map_layers.yml @@ -80,9 +80,10 @@ layers: views: geo: on_field: geographic - data_expr: operational_point.data - 'parts' || jsonb_build_object('kp', layer.kp) + data_expr: operational_point.data - 'parts' || jsonb_build_object('kp', layer.kp, 'track_id', layer.track_section, 'track_name', track_section.data->'extensions'->'sncf'->'track_name') joins: - inner join infra_object_operational_point operational_point on operational_point.obj_id = layer.obj_id and operational_point.infra_id = layer.infra_id + - inner join infra_object_track_section track_section on track_section.obj_id = layer.track_section and track_section.infra_id = layer.infra_id electrifications: table_name: infra_layer_electrification diff --git a/editoast/migrations/2024-11-27-095410_add_track_section_operational_point_layer/down.sql b/editoast/migrations/2024-11-27-095410_add_track_section_operational_point_layer/down.sql new file mode 100644 index 00000000000..0cd5cbac064 --- /dev/null +++ b/editoast/migrations/2024-11-27-095410_add_track_section_operational_point_layer/down.sql @@ -0,0 +1 @@ +ALTER TABLE infra_layer_operational_point DROP COLUMN track_section; diff --git a/editoast/migrations/2024-11-27-095410_add_track_section_operational_point_layer/up.sql b/editoast/migrations/2024-11-27-095410_add_track_section_operational_point_layer/up.sql new file mode 100644 index 00000000000..bed0546770c --- /dev/null +++ b/editoast/migrations/2024-11-27-095410_add_track_section_operational_point_layer/up.sql @@ -0,0 +1,40 @@ +DELETE FROM infra_layer_operational_point; +ALTER TABLE infra_layer_operational_point ADD COLUMN track_section text NOT NULL; + +WITH ops AS ( + SELECT obj_id AS op_id, + infra_id, + ( + jsonb_array_elements(data->'parts')->'position' + )::float AS position, + jsonb_array_elements(data->'parts')->>'track' AS track_id, + jsonb_array_elements(data->'parts')->'extensions'->'sncf'->>'kp' AS kp + FROM infra_object_operational_point +), +collect AS ( + SELECT ops.op_id, + ST_LineInterpolatePoint( + tracks_layer.geographic, + LEAST( + GREATEST( + ops.position / (tracks.data->'length')::float, + 0. + ), + 1. + ) + ) AS geo, + ops.kp AS kp, + ops.infra_id AS infra_id, + ops.track_id AS track_section + FROM ops + INNER JOIN infra_object_track_section AS tracks ON tracks.obj_id = ops.track_id AND tracks.infra_id = ops.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 +) +INSERT INTO infra_layer_operational_point (obj_id, infra_id, geographic, kp, track_section) +SELECT op_id, + infra_id, + geo, + kp, + track_section +FROM collect; diff --git a/editoast/src/generated_data/sql/generate_operational_point_layer.sql b/editoast/src/generated_data/sql/generate_operational_point_layer.sql index ca1b44d9b1a..4f3bf0e565b 100644 --- a/editoast/src/generated_data/sql/generate_operational_point_layer.sql +++ b/editoast/src/generated_data/sql/generate_operational_point_layer.sql @@ -20,16 +20,18 @@ collect AS ( 1. ) ) AS geo, - ops.kp AS kp + ops.kp AS kp, + ops.track_id AS track_section FROM ops INNER JOIN infra_object_track_section AS tracks ON tracks.obj_id = ops.track_id AND tracks.infra_id = $1 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 ) -INSERT INTO infra_layer_operational_point (obj_id, infra_id, geographic, kp) +INSERT INTO infra_layer_operational_point (obj_id, infra_id, geographic, kp, track_section) SELECT op_id, $1, geo, - kp + kp, + track_section FROM collect diff --git a/editoast/src/generated_data/sql/insert_operational_point_layer.sql b/editoast/src/generated_data/sql/insert_operational_point_layer.sql index 686a4d0388c..9dd6d7102ee 100644 --- a/editoast/src/generated_data/sql/insert_operational_point_layer.sql +++ b/editoast/src/generated_data/sql/insert_operational_point_layer.sql @@ -21,16 +21,18 @@ collect AS ( 1. ) ) AS geo, - ops.kp AS kp + ops.kp AS kp, + ops.track_id AS track_section FROM ops INNER JOIN infra_object_track_section AS tracks ON tracks.obj_id = ops.track_id AND tracks.infra_id = $1 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 ) -INSERT INTO infra_layer_operational_point (obj_id, infra_id, geographic, kp) +INSERT INTO infra_layer_operational_point (obj_id, infra_id, geographic, kp, track_section) SELECT op_id, $1, geo, - kp + kp, + track_section FROM collect diff --git a/editoast/src/models/infra.rs b/editoast/src/models/infra.rs index 065f61fe060..9836bd8b56c 100644 --- a/editoast/src/models/infra.rs +++ b/editoast/src/models/infra.rs @@ -148,11 +148,19 @@ impl Infra { if let Some(layer_table) = get_geometry_layer_table(&object) { let layer_table = layer_table.to_string(); - let sql = if object != ObjectType::Signal { - format!("INSERT INTO {layer_table}(obj_id,geographic,infra_id) SELECT obj_id,geographic,$1 FROM {layer_table} WHERE infra_id=$2") - } else { - format!("INSERT INTO {layer_table}(obj_id,geographic,infra_id, angle_geo, signaling_system, sprite) + let sql = match object { + ObjectType::Signal => { + format!("INSERT INTO {layer_table}(obj_id,geographic,infra_id, angle_geo, signaling_system, sprite) SELECT obj_id,geographic,$1,angle_geo, signaling_system, sprite FROM {layer_table} WHERE infra_id = $2") + } + , + ObjectType::OperationalPoint => { + format!("INSERT INTO {layer_table}(obj_id,geographic,infra_id, kp, track_section) + SELECT obj_id,geographic,$1,kp, track_section FROM {layer_table} WHERE infra_id = $2") + } + _ => { + format!("INSERT INTO {layer_table}(obj_id,geographic,infra_id) SELECT obj_id,geographic,$1 FROM {layer_table} WHERE infra_id=$2") + } }; sql_query(sql) diff --git a/editoast/src/views/path/path_item_cache.rs b/editoast/src/views/path/path_item_cache.rs index 51cbed1a014..ee9cc4c5e1a 100644 --- a/editoast/src/views/path/path_item_cache.rs +++ b/editoast/src/views/path/path_item_cache.rs @@ -117,28 +117,21 @@ impl PathItemCache { PathItemLocation::OperationalPointReference(OperationalPointReference { reference: OperationalPointIdentifier::OperationalPointId { operational_point }, track_reference, - }) => match self.get_from_id(&operational_point.0) { - Some(op) => { - let track_offsets = op.track_offset(); - let track_offsets = - self.track_reference_filter(track_offsets, track_reference); - if track_offsets.is_empty() { - invalid_path_items.push(InvalidPathItem { - index, - path_item: path_item.clone(), - }); - continue; - }; - track_offsets + }) => { + let mut track_offsets = vec![]; + if let Some(op) = self.get_from_id(&operational_point.0) { + track_offsets = op.track_offset(); + track_offsets = self.track_reference_filter(track_offsets, track_reference); } - None => { + if track_offsets.is_empty() { invalid_path_items.push(InvalidPathItem { index, path_item: path_item.clone(), }); continue; } - }, + track_offsets + } PathItemLocation::OperationalPointReference(OperationalPointReference { reference: OperationalPointIdentifier::OperationalPointDescription { @@ -152,13 +145,6 @@ impl PathItemCache { .cloned() .unwrap_or_default(); let ops = secondary_code_filter(secondary_code, ops); - if ops.is_empty() { - invalid_path_items.push(InvalidPathItem { - index, - path_item: path_item.clone(), - }); - continue; - } let track_offsets = track_offsets_from_ops(&ops); let track_offsets = self.track_reference_filter(track_offsets, track_reference); if track_offsets.is_empty() { @@ -183,13 +169,6 @@ impl PathItemCache { .cloned() .unwrap_or_default(); let ops = secondary_code_filter(secondary_code, ops); - if ops.is_empty() { - invalid_path_items.push(InvalidPathItem { - index, - path_item: path_item.clone(), - }); - continue; - } let track_offsets = track_offsets_from_ops(&ops); let track_offsets = self.track_reference_filter(track_offsets, track_reference); if track_offsets.is_empty() { diff --git a/editoast/src/views/path/pathfinding.rs b/editoast/src/views/path/pathfinding.rs index a0a6cb5f50e..7ecb6f5417e 100644 --- a/editoast/src/views/path/pathfinding.rs +++ b/editoast/src/views/path/pathfinding.rs @@ -505,7 +505,7 @@ pub mod tests { .json(&json!({ "path_items":[ {"uic":3,"secondary_code":"BV", "track_reference": {"track_name": "V2"}}, - {"uic":8 ,"secondary_code":"BV", "track_reference": {"track_name": "V245"}}, + {"uic":8 ,"secondary_code":"BV", "track_reference": {"track_name": "V_INVALID"}}, ], "rolling_stock_is_thermal":true, "rolling_stock_loading_gauge":"G1", @@ -525,15 +525,13 @@ pub mod tests { index: 1, path_item: PathItemLocation::OperationalPointReference( OperationalPointReference { - reference: - OperationalPointIdentifier::OperationalPointUic { - uic: 8, - secondary_code: Some("BV".into()) - }, - track_reference: - Some(TrackReference::Name { - track_name: "V245".into() - }), + reference: OperationalPointIdentifier::OperationalPointUic { + uic: 8, + secondary_code: Some("BV".into()) + }, + track_reference: Some(TrackReference::Name { + track_name: "V_INVALID".into() + }), } ) }]