feat(simulation): road-graph hub refinement — scaled-cap hubs, co-location collapse, minor-attach edge split, RailHeadFacing (T-1076)

is_standalone_hq threaded through CityRecord/CityPlacement via corporations LEFT JOIN (both readers); hubs = top-cap by population among non-HQ settlements (HUB_SPACING_DIAG_PX=64, HUB_CAP_MIN=6); exact-name collapse keeping lowest city_id with loud warn; nearest-point-on-polyline snap (SNAP_MAX_PX=8) with Junction edge-split preserving from<to via norm_edge, else A*-spur to nearest hub; FoundingOrientation::RailHeadFacing{bearing_degrees} assigned at degree>=3 junctions (octant bearing toward dominant incident edge), consumed by skeleton_gen railhead_edge() through the D-234b flush-frontage machinery; believability reader now honours baked settlement_class (stale hardcode since T-1075). 11 new targeted tests; existing suites green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-16 16:23:07 +02:00
co-authored by Claude Fable 5
parent a0ebdbe6b8
commit 98991284bf
9 changed files with 993 additions and 63 deletions
+17
View File
@@ -984,6 +984,7 @@ mod tests {
founding_orientation: orientation,
population: 100_000,
is_capital: false,
is_standalone_hq: false,
}
}
@@ -1005,6 +1006,7 @@ mod tests {
founding_orientation: orientation,
population: 100_000,
is_capital: false,
is_standalone_hq: false,
}
}
@@ -1110,6 +1112,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 2,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(90),
@@ -1117,6 +1120,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(91),
@@ -1124,6 +1128,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
],
edges: vec![
@@ -1460,6 +1465,7 @@ mod tests {
founding_orientation: FoundingOrientation::Cardinal,
population: 100_000,
is_capital: false,
is_standalone_hq: false,
};
assert_eq!(
@@ -1592,6 +1598,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(2),
@@ -1599,6 +1606,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
],
edges: vec![RoadEdge {
@@ -1634,6 +1642,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 2,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(11),
@@ -1641,6 +1650,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(12),
@@ -1648,6 +1658,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
],
edges: vec![
@@ -1694,6 +1705,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 2,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(2),
@@ -1701,6 +1713,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(3),
@@ -1708,6 +1721,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
],
edges: vec![
@@ -1756,6 +1770,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
RoadNode {
city_id: Some(6),
@@ -1763,6 +1778,7 @@ mod tests {
kind: RoadNodeKind::Settlement,
degree: 1,
parent_edge: None,
is_hub: false,
},
],
edges: vec![RoadEdge {
@@ -1788,6 +1804,7 @@ mod tests {
founding_orientation: FoundingOrientation::Cardinal,
population: 100_000,
is_capital: false,
is_standalone_hq: false,
};
let GenWorkItem::GenerateSkeleton {