From 5fb976b789c622e7f73100e587b22717cb0dfae1 Mon Sep 17 00:00:00 2001 From: eric bryant Date: Fri, 8 Mar 2024 01:12:52 -0500 Subject: [PATCH] avoid DISCONNECTED_ROUTE false negatives (#610) rebase 49288bc itself a rebase of c627aec --- .../classes/HighwaySystem/route_integrity.cpp | 62 ++++++++++--------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/siteupdate/cplusplus/classes/HighwaySystem/route_integrity.cpp b/siteupdate/cplusplus/classes/HighwaySystem/route_integrity.cpp index dea1727f..522dbc61 100644 --- a/siteupdate/cplusplus/classes/HighwaySystem/route_integrity.cpp +++ b/siteupdate/cplusplus/classes/HighwaySystem/route_integrity.cpp @@ -12,8 +12,8 @@ void HighwaySystem::route_integrity(ErrorList& el) { // check for unconnected chopped routes if (!r.con_route) el.add_error(systemname + ".csv: root " + r.root + " not matched by any connected route root."); - // per-route CSV datachecks + else r.con_mismatch(); #define CSV_LINE r.system->systemname + ".csv#L" + std::to_string(r.index()+2) if (r.abbrev.empty()) { if ( r.banner.size() && !strncmp(r.banner.data(), r.city.data(), r.banner.size()) ) @@ -78,33 +78,35 @@ void HighwaySystem::route_integrity(ErrorList& el) } for (ConnectedRoute& cr : con_routes) - { if (cr.roots.empty()) continue; // because there could be an invalid _con.csv entry - // check cr.roots[0] by itself outside of loop - cr.roots[0]->con_mismatch(); - for (size_t i = 1; i < cr.roots.size(); i++) - { // check for mismatched route endpoints within connected routes - auto& q = cr.roots[i-1]; - auto& r = cr.roots[i]; - r->con_mismatch(); - if ( q->points.size > 1 && r->points.size > 1 && !r->con_beg()->same_coords(q->con_end()) ) - { if ( q->con_beg()->same_coords(r->con_beg()) ) - q->set_reversed(); - else if ( q->con_end()->same_coords(r->con_end()) ) - r->set_reversed(); - else if ( q->con_beg()->same_coords(r->con_end()) ) - { q->set_reversed(); - r->set_reversed(); - } - else - { Datacheck::add(r, r->con_beg()->label, "", "", - "DISCONNECTED_ROUTE", q->con_end()->root_at_label()); - Datacheck::add(q, q->con_end()->label, "", "", - "DISCONNECTED_ROUTE", r->con_beg()->root_at_label()); - cr.disconnected = 1; - q->set_disconnected(); - r->set_disconnected(); - } - } - } - } + for (size_t i = 1; i < cr.roots.size(); i++) + { // check for mismatched route endpoints within connected routes + auto& q = cr.roots[i-1]; + auto& r = cr.roots[i]; + auto flag = [&]() + { Datacheck::add(q, q->con_end()->label, "", "", "DISCONNECTED_ROUTE", r->points[0].root_at_label()); + Datacheck::add(r, r->points[0].label, "", "", "DISCONNECTED_ROUTE", q->con_end()->root_at_label()); + cr.disconnected = 1; + q->set_disconnected(); + r->set_disconnected(); + }; + if ( q->points.size > 1 && r->points.size > 1 && !r->points.begin()->same_coords(q->con_end()) ) + if ( q->con_end()->same_coords(&r->points.back()) ) // R can be reversed + if ( q->con_beg()->same_coords(r->points.begin()) // Can Q be reversed instead? + && ( q == cr.roots[0] || q->is_disconnected() ) // Is Q not locked into one direction? + && ( i+1 < cr.roots.size() ) // Is there another chopped route after R? + && ( r->points.back().same_coords(cr.roots[i+1]->points.begin()) // And does its beginning + || r->points.back().same_coords(&cr.roots[i+1]->points.back()) )) // or end link to R as-is? + q->set_reversed(); + else r->set_reversed(); + else if ( q->con_beg()->same_coords(&r->points.back()) ) // Q & R can both be reversed together + if ( q == cr.roots[0] || q->is_disconnected() ) // as long as Q's direction is unknown + { q->set_reversed(); + r->set_reversed(); + } + else flag(); + else if ( q->con_beg()->same_coords(r->points.begin()) // Only Q can be reversed + && ( q == cr.roots[0] || q->is_disconnected() )) // as long as its direction is unknown + q->set_reversed(); + else flag(); + } }