fix(simulation): PR #178 review round — H1-H4, T1, T2
H1: split_edge_at now splits length_cells geometric-distance proportionally (fixed-order f64 polyline sums, halves sum exactly to parent) — subsumes the 2-point-parent all-or-nothing bug. H2: chained-snap test (minor onto minor spur) + determinism assertion actually exercising attach_minors + direct 2-point split unit test. H3: cascade-level RailHeadFacing end-to-end assertion on a plus-shaped landmass fixture (2 deterministic degree-3 settlement junctions). H4+T2: STANDALONE_HQ_JOIN_SQL shared constant, both readers compose it; believability lockstep unit test. T1: HUB_SPACING_DIAG_PX doc cross-refs D-243 elastic seam. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -62,6 +62,25 @@ use crate::simulation::generator::{
|
||||
ProductionUbiquity, SettingType, SettlementClass, WorldTier,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Shared SQL fragments
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// The D-242 standalone-corp-HQ LEFT JOIN (T-1076 §1; single source of truth,
|
||||
/// PR #178 T2). Marks an `atlas_city_names` row (aliased `acn`) as a Standalone
|
||||
/// corp-HQ company town when a `corporations` row (aliased `c`) matches on
|
||||
/// `hq_placement = 'Standalone'`, `headquarters_body = body_id`, and
|
||||
/// `proper_name = name` — the exact shape
|
||||
/// `populate_standalone_hq_settlements` (economy_import/corporations.py) emits
|
||||
/// settlement rows with. Composed into a query whose FROM clause aliases
|
||||
/// `atlas_city_names AS acn`; the flag is read as `c.corp_id IS NOT NULL`.
|
||||
/// Used by [`CityContextReader::read_body_settlements`] and the believability
|
||||
/// harness's `read_cities` — extend both if the join shape ever changes.
|
||||
pub(crate) const STANDALONE_HQ_JOIN_SQL: &str = "LEFT JOIN corporations AS c
|
||||
ON c.hq_placement = 'Standalone'
|
||||
AND c.headquarters_body = acn.body_id
|
||||
AND c.proper_name = acn.name";
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Error type
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -266,14 +285,12 @@ impl CityContextReader {
|
||||
/// any malformed field), this method is best-effort: it never fails on row
|
||||
/// content, only on a DB/connection error.
|
||||
///
|
||||
/// `is_standalone_hq` (T-1076 §1): a LEFT JOIN against `corporations`
|
||||
/// marks the rows that are D-242 Standalone corp-HQ company towns
|
||||
/// (`hq_placement = 'Standalone'`, `headquarters_body = body_id`,
|
||||
/// `proper_name = name` — the exact shape `populate_standalone_hq_settlements`
|
||||
/// emits them with). The road-graph hub rule demotes these to minor nodes
|
||||
/// regardless of population. The believability harness's own settlement
|
||||
/// read (`believability::read_cities`) performs the identical join — keep
|
||||
/// the two in lockstep.
|
||||
/// `is_standalone_hq` (T-1076 §1): the [`STANDALONE_HQ_JOIN_SQL`] LEFT JOIN
|
||||
/// marks the rows that are D-242 Standalone corp-HQ company towns. The
|
||||
/// road-graph hub rule demotes these to minor nodes regardless of
|
||||
/// population. The believability harness's own settlement read
|
||||
/// (`believability::read_cities`) composes the same shared constant —
|
||||
/// single source of truth for the join (PR #178 T2).
|
||||
pub fn read_body_settlements(
|
||||
&self,
|
||||
body_id: &str,
|
||||
@@ -282,19 +299,17 @@ impl CityContextReader {
|
||||
.conn
|
||||
.lock()
|
||||
.map_err(|e| CityContextReadError::Db(format!("mutex poisoned: {e}")))?;
|
||||
let sql = format!(
|
||||
"SELECT acn.id, acn.name, acn.economic_role, acn.population,
|
||||
acn.settlement_class, COALESCE(acn.kind, 'city'),
|
||||
c.corp_id IS NOT NULL
|
||||
FROM atlas_city_names AS acn
|
||||
{STANDALONE_HQ_JOIN_SQL}
|
||||
WHERE acn.body_id = ?1
|
||||
ORDER BY acn.id"
|
||||
);
|
||||
let mut stmt = conn
|
||||
.prepare(
|
||||
"SELECT acn.id, acn.name, acn.economic_role, acn.population,
|
||||
acn.settlement_class, COALESCE(acn.kind, 'city'),
|
||||
c.corp_id IS NOT NULL
|
||||
FROM atlas_city_names AS acn
|
||||
LEFT JOIN corporations AS c
|
||||
ON c.hq_placement = 'Standalone'
|
||||
AND c.headquarters_body = acn.body_id
|
||||
AND c.proper_name = acn.name
|
||||
WHERE acn.body_id = ?1
|
||||
ORDER BY acn.id",
|
||||
)
|
||||
.prepare(&sql)
|
||||
.map_err(|e| CityContextReadError::Db(e.to_string()))?;
|
||||
let rows = stmt
|
||||
.query_map([body_id], |row| {
|
||||
|
||||
Reference in New Issue
Block a user