feat: filter mutual page curves to minElev window (satlover.de style)

Elevation curve chart and mutual radar plot now only show the portion
where both stations are above their respective minimum elevation.
The curves are filtered at display time, the pass search still uses
the 0° horizon boundary for consistency with the Passes page.
This commit is contained in:
atsunatsu committed 2026-08-03 03:47:25 +08:00
1 parent fb28283679
commit d1cc944be2
1 file changed
+29 -7
@@ -356,6 +356,8 @@ private fun MutualContent(
pass = pass, pass = pass,
isExpanded = state.selectedPassIndex == index, isExpanded = state.selectedPassIndex == index,
timeFormat = timeFormat, timeFormat = timeFormat,
minElevA = state.stationAMinElev,
minElevB = state.stationBMinElev,
onClick = { onSelectPass(if (state.selectedPassIndex == index) -1 else index) }, onClick = { onSelectPass(if (state.selectedPassIndex == index) -1 else index) },
onNavigateToRadar = { onNavigateToRadar(pass.catNum, pass.startTime, mutualData) } onNavigateToRadar = { onNavigateToRadar(pass.catNum, pass.startTime, mutualData) }
) )
@@ -368,12 +370,32 @@ private fun MutualPassCard(
pass: MutualPass, pass: MutualPass,
isExpanded: Boolean, isExpanded: Boolean,
timeFormat: SimpleDateFormat, timeFormat: SimpleDateFormat,
minElevA: Double,
minElevB: Double,
onClick: () -> Unit, onClick: () -> Unit,
onNavigateToRadar: () -> Unit onNavigateToRadar: () -> Unit
) { ) {
// Shared time cursor: both the elevation curve and the radar track view // Shared time cursor: both the elevation curve and the radar track view
// are controlled by this single progress value for bidirectional drag sync. // are controlled by this single progress value for bidirectional drag sync.
var dragProgress by remember(pass) { mutableFloatStateOf(0.5f) } var dragProgress by remember(pass) { mutableFloatStateOf(0.5f) }
// Filter to only show the portion where both stations are above their minElev
// (satlover.de style — only the usable common window)
val visibleSamples = remember(pass, minElevA, minElevB) {
pass.elevationSamples.filter { (_, elev) ->
elev.first >= minElevA && elev.second >= minElevB
}
}
val visibleTracks = remember(pass, minElevA, minElevB) {
pass.trackSamples.filter { it.elevationA >= minElevA && it.elevationB >= minElevB }
}
val visibleStart = visibleSamples.firstOrNull()?.first ?: pass.startTime
val visibleEnd = visibleSamples.lastOrNull()?.first ?: pass.endTime
val adjustedMaxElev = maxOf(
visibleSamples.maxOfOrNull { (_, elev) -> elev.first } ?: 10.0,
visibleSamples.maxOfOrNull { (_, elev) -> elev.second } ?: 10.0,
10.0
)
ElevatedCard( ElevatedCard(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@@ -423,7 +445,7 @@ private fun MutualPassCard(
Column { Column {
HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp))
// Dual-station radar track (polar plot) // Dual-station radar track (polar plot)
if (pass.trackSamples.isNotEmpty()) { if (visibleTracks.isNotEmpty()) {
Text( Text(
text = "双方轨迹(雷达图)", text = "双方轨迹(雷达图)",
style = MaterialTheme.typography.titleSmall, style = MaterialTheme.typography.titleSmall,
@@ -431,19 +453,19 @@ private fun MutualPassCard(
color = MaterialTheme.colorScheme.onSurfaceVariant color = MaterialTheme.colorScheme.onSurfaceVariant
) )
MutualRadarView( MutualRadarView(
trackSamples = pass.trackSamples, trackSamples = visibleTracks,
progress = dragProgress, progress = dragProgress,
labelA = "你", labelA = "你",
labelB = "友台" labelB = "友台"
) )
Spacer(Modifier.height(8.dp)) Spacer(Modifier.height(8.dp))
} }
if (pass.elevationSamples.isNotEmpty()) { if (visibleSamples.isNotEmpty()) {
ElevationCurveChart( ElevationCurveChart(
samples = pass.elevationSamples, samples = visibleSamples,
startTime = pass.startTime, startTime = visibleStart,
endTime = pass.endTime, endTime = visibleEnd,
maxElev = maxOf(pass.maxElevationA, pass.maxElevationB, 10.0), maxElev = adjustedMaxElev,
progress = dragProgress, progress = dragProgress,
onProgressChange = { dragProgress = it } onProgressChange = { dragProgress = it }
) )