fix(map): 多格台址覆盖单格台址时通联计入单格统计(方案A单向覆盖)

- scopedToStation 由 key 精确匹配改为网格集合包含(记录 MY 网格集 ⊇ 选中台址网格集):
  选中 OL62 时 OL62/63(四格点同理)的通联一并计入;反向不泄漏(选中宽台址不见单格记录)
- stationGroups 每组 worked 改经 scopedToStation 推导——地图填绿/VUCC 计数/选择器计数/
  首通标签/点格子弹窗详情五出口单源;分组条目仍只列实际拥有的台址
- GridQsoStationScopeTest 改写精确匹配断言 + 新增覆盖/不泄漏/集合包含 3 例(共 14),
  全量 test 通过
This commit is contained in:
atsunatsu committed 2026-10-05 15:06:19 +08:00
1 parent 09539ff13a
commit f35d78186c
3 files changed
+50 -12

No files matched your search

@@ -314,16 +314,24 @@ private fun MapScreen(
// can differ between records of the same physical 台址 when LoTW omits
// optional fields). Data synced before multi-grid support falls back to
// one group per grid, preserving the old selector exactly.
// Each group's `worked` cells are derived through scopedToStation (the
// covering rule): a single-grid 台址 also counts the cells worked by any
// multi-grid 台址 covering it (OL62 ← OL62/63, 四格点同理) — the reverse
// never leaks (2026-10-05 用户定稿, 方案 A).
val stationGroups: List<StationGroup> = remember(uiState.workedGridQsos) {
val byGridSet = LinkedHashMap<String, Pair<Set<String>, MutableSet<String>>>()
for ((grid, qsos) in uiState.workedGridQsos) {
val gridSets = LinkedHashMap<String, Set<String>>()
for ((_, qsos) in uiState.workedGridQsos) {
for (q in qsos) {
val key = q.stationGridSetKey() ?: continue
byGridSet.getOrPut(key) { q.myStationGrids() to mutableSetOf() }.second.add(grid)
gridSets.getOrPut(key) { q.myStationGrids() }
}
}
byGridSet.map { (key, v) -> StationGroup(id = key, grids = v.first, worked = v.second) }
.sortedByDescending { it.workedCount }
gridSets.map { (key, grids) ->
val worked = uiState.workedGridQsos.filterValues { qsos ->
qsos.scopedToStation(key).isNotEmpty()
}.keys
StationGroup(id = key, grids = grids, worked = worked)
}.sortedByDescending { it.workedCount }
}
// Selected 台址 for VUCC counting; defaults to the group with the most
// worked grids. Null = "All" (every 台址 combined). Empty when the store