From d1cc944be23d2cae36fa1fe4473ab6f5ff4a2e7d Mon Sep 17 00:00:00 2001 From: atsunatsu Date: Mon, 3 Aug 2026 03:47:25 +0800 Subject: [PATCH] feat: filter mutual page curves to minElev window (satlover.de style) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../look4sat/feature/mutual/MutualScreen.kt | 36 +++++++++++++++---- 1 file changed, 29 insertions(+), 7 deletions(-) diff --git a/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt b/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt index 7830be3c..98630322 100644 --- a/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt +++ b/feature/mutual/src/main/java/com/rtbishop/look4sat/feature/mutual/MutualScreen.kt @@ -356,6 +356,8 @@ private fun MutualContent( pass = pass, isExpanded = state.selectedPassIndex == index, timeFormat = timeFormat, + minElevA = state.stationAMinElev, + minElevB = state.stationBMinElev, onClick = { onSelectPass(if (state.selectedPassIndex == index) -1 else index) }, onNavigateToRadar = { onNavigateToRadar(pass.catNum, pass.startTime, mutualData) } ) @@ -368,12 +370,32 @@ private fun MutualPassCard( pass: MutualPass, isExpanded: Boolean, timeFormat: SimpleDateFormat, + minElevA: Double, + minElevB: Double, onClick: () -> Unit, onNavigateToRadar: () -> Unit ) { // Shared time cursor: both the elevation curve and the radar track view // are controlled by this single progress value for bidirectional drag sync. 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( modifier = Modifier .fillMaxWidth() @@ -423,7 +445,7 @@ private fun MutualPassCard( Column { HorizontalDivider(modifier = Modifier.padding(vertical = 8.dp)) // Dual-station radar track (polar plot) - if (pass.trackSamples.isNotEmpty()) { + if (visibleTracks.isNotEmpty()) { Text( text = "双方轨迹(雷达图)", style = MaterialTheme.typography.titleSmall, @@ -431,19 +453,19 @@ private fun MutualPassCard( color = MaterialTheme.colorScheme.onSurfaceVariant ) MutualRadarView( - trackSamples = pass.trackSamples, + trackSamples = visibleTracks, progress = dragProgress, labelA = "你", labelB = "友台" ) Spacer(Modifier.height(8.dp)) } - if (pass.elevationSamples.isNotEmpty()) { + if (visibleSamples.isNotEmpty()) { ElevationCurveChart( - samples = pass.elevationSamples, - startTime = pass.startTime, - endTime = pass.endTime, - maxElev = maxOf(pass.maxElevationA, pass.maxElevationB, 10.0), + samples = visibleSamples, + startTime = visibleStart, + endTime = visibleEnd, + maxElev = adjustedMaxElev, progress = dragProgress, onProgressChange = { dragProgress = it } )