mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-03 19:27:24 +00:00
Even more restructuring and code cleanup
This commit is contained in:
1 parent
a807cfd8f6
commit
f8e7bcdf39
12 files changed
+222
-217
No files matched your search
+2
-2
@@ -1,8 +1,8 @@
|
||||
package com.rtbishop.look4sat.domain
|
||||
package com.rtbishop.look4sat.data
|
||||
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface ISensorsRepo {
|
||||
interface ISensorSource {
|
||||
|
||||
val orientation: StateFlow<Pair<Float, Float>>
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package com.rtbishop.look4sat.data
|
||||
|
||||
import com.rtbishop.look4sat.domain.ISatelliteRepo
|
||||
import com.rtbishop.look4sat.domain.ISettingsRepo
|
||||
import com.rtbishop.look4sat.domain.Satellite
|
||||
import com.rtbishop.look4sat.model.GeoPos
|
||||
import com.rtbishop.look4sat.model.SatPass
|
||||
@@ -26,25 +27,33 @@ import com.rtbishop.look4sat.model.SatRadio
|
||||
import com.rtbishop.look4sat.utility.round
|
||||
import com.rtbishop.look4sat.utility.toDegrees
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
class SatelliteRepo(
|
||||
private val dispatcher: CoroutineDispatcher,
|
||||
private val localStorage: ILocalStorage
|
||||
private val localStorage: ILocalStorage,
|
||||
private val settingsRepo: ISettingsRepo
|
||||
) : ISatelliteRepo {
|
||||
|
||||
private var passes = listOf<SatPass>()
|
||||
private val _calculatedPasses = MutableSharedFlow<List<SatPass>>(replay = 1)
|
||||
override val calculatedPasses: SharedFlow<List<SatPass>> = _calculatedPasses
|
||||
private val _passes = MutableStateFlow<List<SatPass>>(emptyList())
|
||||
override val passes: StateFlow<List<SatPass>> = _passes
|
||||
|
||||
override fun getPasses(): List<SatPass> = passes
|
||||
|
||||
override suspend fun getEntriesWithIds(ids: List<Int>) = localStorage.getEntriesWithIds(ids)
|
||||
private val _satellites = MutableStateFlow<List<Satellite>>(emptyList())
|
||||
override val satellites: StateFlow<List<Satellite>> = _satellites
|
||||
|
||||
override suspend fun getRadiosWithId(id: Int) = localStorage.getRadiosWithId(id)
|
||||
|
||||
override suspend fun initRepository() = withContext(dispatcher) {
|
||||
settingsRepo.satelliteSelection.collect { selectedIds ->
|
||||
_satellites.update { localStorage.getEntriesWithIds(selectedIds) }
|
||||
val (hoursAhead, minElevation) = settingsRepo.passesSettings.value
|
||||
calculatePasses(System.currentTimeMillis(), hoursAhead, minElevation)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getPosition(sat: Satellite, pos: GeoPos, time: Long): SatPos {
|
||||
return withContext(dispatcher) { sat.getPosition(pos, time) }
|
||||
}
|
||||
@@ -70,12 +79,8 @@ class SatelliteRepo(
|
||||
val satPos = sat.getPosition(pos, time)
|
||||
val copiedList = radios.map { it.copy() }
|
||||
copiedList.forEach { transmitter ->
|
||||
transmitter.downlink?.let {
|
||||
transmitter.downlink = satPos.getDownlinkFreq(it)
|
||||
}
|
||||
transmitter.uplink?.let {
|
||||
transmitter.uplink = satPos.getUplinkFreq(it)
|
||||
}
|
||||
transmitter.downlink?.let { transmitter.downlink = satPos.getDownlinkFreq(it) }
|
||||
transmitter.uplink?.let { transmitter.uplink = satPos.getUplinkFreq(it) }
|
||||
}
|
||||
copiedList.map { it.copy() }
|
||||
}
|
||||
@@ -97,23 +102,18 @@ class SatelliteRepo(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun calculatePasses(
|
||||
satList: List<Satellite>, pos: GeoPos, time: Long, hoursAhead: Int, minElevation: Double
|
||||
) {
|
||||
if (satList.isEmpty()) {
|
||||
val newPasses = emptyList<SatPass>()
|
||||
passes = newPasses
|
||||
_calculatedPasses.emit(newPasses)
|
||||
} else {
|
||||
override suspend fun calculatePasses(time: Long, hoursAhead: Int, minElevation: Double) {
|
||||
if (_satellites.value.isNotEmpty()) {
|
||||
withContext(dispatcher) {
|
||||
val allPasses = mutableListOf<SatPass>()
|
||||
satList.forEach { satellite ->
|
||||
allPasses.addAll(satellite.getPasses(pos, time, hoursAhead))
|
||||
val stationPos = settingsRepo.stationPosition.value
|
||||
_satellites.value.forEach { satellite ->
|
||||
allPasses.addAll(satellite.getPasses(stationPos, time, hoursAhead))
|
||||
}
|
||||
val newPasses = allPasses.filter(time, hoursAhead, minElevation)
|
||||
passes = newPasses
|
||||
_calculatedPasses.emit(newPasses)
|
||||
_passes.update { allPasses.filter(time, hoursAhead, minElevation) }
|
||||
}
|
||||
} else {
|
||||
_passes.update { emptyList() }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,8 +151,7 @@ class SatelliteRepo(
|
||||
private fun getGeoPass(sat: Satellite, pos: GeoPos, time: Long): SatPass {
|
||||
val satPos = sat.getPosition(pos, time)
|
||||
val aos = time - 24 * 60L * 60L * 1000L
|
||||
val los = time + 24 * 60L * 60L * 1000L
|
||||
// val tca = (aos + los) / 2
|
||||
val los = time + 24 * 60L * 60L * 1000L // val tca = (aos + los) / 2
|
||||
val az = satPos.azimuth.toDegrees().round(1)
|
||||
val elev = satPos.elevation.toDegrees().round(1)
|
||||
val alt = satPos.altitude
|
||||
@@ -164,8 +163,7 @@ class SatelliteRepo(
|
||||
var calendarTimeMillis = time
|
||||
var elevation: Double
|
||||
var maxElevation = 0.0
|
||||
var alt = 0.0
|
||||
// var tcaAz = 0.0
|
||||
var alt = 0.0 // var tcaAz = 0.0
|
||||
// rewind 1/4 of an orbit
|
||||
if (rewind) calendarTimeMillis += -quarterOrbitMin * 60L * 1000L
|
||||
|
||||
@@ -187,8 +185,7 @@ class SatelliteRepo(
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
// tcaAz = satPos.azimuth.toDegrees()
|
||||
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||
}
|
||||
} while (satPos.elevation < 0.0)
|
||||
|
||||
@@ -200,8 +197,7 @@ class SatelliteRepo(
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
// tcaAz = satPos.azimuth.toDegrees()
|
||||
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||
}
|
||||
} while (satPos.elevation < 0.0)
|
||||
|
||||
@@ -215,8 +211,7 @@ class SatelliteRepo(
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
// tcaAz = satPos.azimuth.toDegrees()
|
||||
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||
}
|
||||
} while (satPos.elevation > 0.0)
|
||||
|
||||
@@ -228,14 +223,12 @@ class SatelliteRepo(
|
||||
elevation = satPos.elevation
|
||||
if (elevation > maxElevation) {
|
||||
maxElevation = elevation
|
||||
alt = satPos.altitude
|
||||
// tcaAz = satPos.azimuth.toDegrees()
|
||||
alt = satPos.altitude // tcaAz = satPos.azimuth.toDegrees()
|
||||
}
|
||||
} while (satPos.elevation > 0.0)
|
||||
|
||||
val los = satPos.time
|
||||
val los = satPos.time // val tca = (aos + los) / 2
|
||||
val losAz = satPos.azimuth.toDegrees().round(1)
|
||||
// val tca = (aos + los) / 2
|
||||
val elev = maxElevation.toDegrees().round(1)
|
||||
return SatPass(aos, aosAz, los, losAz, alt.toInt(), elev, sat)
|
||||
}
|
||||
|
||||
@@ -4,36 +4,27 @@ import com.rtbishop.look4sat.model.GeoPos
|
||||
import com.rtbishop.look4sat.model.SatPass
|
||||
import com.rtbishop.look4sat.model.SatPos
|
||||
import com.rtbishop.look4sat.model.SatRadio
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface ISatelliteRepo {
|
||||
|
||||
val calculatedPasses: SharedFlow<List<SatPass>>
|
||||
val passes: StateFlow<List<SatPass>>
|
||||
|
||||
fun getPasses(): List<SatPass>
|
||||
|
||||
suspend fun getEntriesWithIds(ids: List<Int>): List<Satellite>
|
||||
val satellites: StateFlow<List<Satellite>>
|
||||
|
||||
suspend fun getRadiosWithId(id: Int): List<SatRadio>
|
||||
|
||||
suspend fun initRepository()
|
||||
|
||||
suspend fun getPosition(sat: Satellite, pos: GeoPos, time: Long): SatPos
|
||||
|
||||
suspend fun getTrack(sat: Satellite, pos: GeoPos, start: Long, end: Long): List<SatPos>
|
||||
|
||||
suspend fun processRadios(
|
||||
sat: Satellite,
|
||||
pos: GeoPos,
|
||||
radios: List<SatRadio>,
|
||||
time: Long
|
||||
sat: Satellite, pos: GeoPos, radios: List<SatRadio>, time: Long
|
||||
): List<SatRadio>
|
||||
|
||||
suspend fun processPasses(passList: List<SatPass>, time: Long): List<SatPass>
|
||||
|
||||
suspend fun calculatePasses(
|
||||
satList: List<Satellite>,
|
||||
pos: GeoPos,
|
||||
time: Long,
|
||||
hoursAhead: Int = 8,
|
||||
minElevation: Double = 16.0
|
||||
)
|
||||
suspend fun calculatePasses(time: Long, hoursAhead: Int = 8, minElevation: Double = 16.0)
|
||||
}
|
||||
@@ -20,12 +20,12 @@ package com.rtbishop.look4sat.domain
|
||||
import com.rtbishop.look4sat.model.DatabaseState
|
||||
import com.rtbishop.look4sat.model.GeoPos
|
||||
import com.rtbishop.look4sat.model.OtherSettings
|
||||
import com.rtbishop.look4sat.model.PassesSettings
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
interface ISettingsRepo {
|
||||
|
||||
val radioSourceUrl: String get() = "https://db.satnogs.org/api/transmitters/?format=json"
|
||||
|
||||
val satelliteSourcesMap: Map<String, String>
|
||||
get() = mapOf(
|
||||
"All" to "https://celestrak.com/NORAD/elements/gp.php?GROUP=active&FORMAT=csv",
|
||||
@@ -56,9 +56,9 @@ interface ISettingsRepo {
|
||||
"X-Comm" to "https://celestrak.com/NORAD/elements/gp.php?GROUP=x-comm&FORMAT=csv"
|
||||
)
|
||||
|
||||
val stationPosition: StateFlow<GeoPos>
|
||||
//region # Station position settings
|
||||
|
||||
val satelliteSelection: StateFlow<List<Int>>
|
||||
val stationPosition: StateFlow<GeoPos>
|
||||
|
||||
fun setGpsPosition(): Boolean
|
||||
|
||||
@@ -66,18 +66,42 @@ interface ISettingsRepo {
|
||||
|
||||
fun setQthPosition(locator: String): Boolean
|
||||
|
||||
fun getHoursAhead(): Int
|
||||
//endregion
|
||||
|
||||
fun setHoursAhead(hoursAhead: Int)
|
||||
|
||||
fun getMinElevation(): Double
|
||||
|
||||
fun setMinElevation(minElevation: Double)
|
||||
//region # Database update settings
|
||||
|
||||
val databaseState: StateFlow<DatabaseState>
|
||||
|
||||
fun saveDatabaseState(state: DatabaseState)
|
||||
|
||||
fun saveSatType(type: String, catnums: List<Int>)
|
||||
|
||||
fun loadSatType(type: String): List<Int>
|
||||
|
||||
//endregion
|
||||
|
||||
//region # Entries selection settings
|
||||
|
||||
val satelliteSelection: StateFlow<List<Int>>
|
||||
|
||||
fun saveEntriesSelection(catnums: List<Int>)
|
||||
|
||||
//endregion
|
||||
|
||||
//region # Passes filter settings
|
||||
|
||||
val passesSettings: StateFlow<PassesSettings>
|
||||
|
||||
fun savePassesSettings(settings: PassesSettings)
|
||||
|
||||
fun saveModesSelection(modes: List<String>)
|
||||
|
||||
fun loadModesSelection(): List<String>
|
||||
|
||||
//endregion
|
||||
|
||||
//region # Other settings
|
||||
|
||||
val otherSettings: StateFlow<OtherSettings>
|
||||
|
||||
fun toggleUtc(value: Boolean)
|
||||
@@ -88,15 +112,9 @@ interface ISettingsRepo {
|
||||
|
||||
fun toggleSensor(value: Boolean)
|
||||
|
||||
fun saveModesSelection(modes: List<String>)
|
||||
//endregion
|
||||
|
||||
fun loadModesSelection(): List<String>
|
||||
|
||||
fun saveEntriesSelection(catnums: List<Int>)
|
||||
|
||||
fun saveSatType(type: String, catnums: List<Int>)
|
||||
|
||||
fun loadSatType(type: String): List<Int>
|
||||
//region # Undefined settings
|
||||
|
||||
fun getRotatorEnabled(): Boolean
|
||||
|
||||
@@ -125,4 +143,6 @@ interface ISettingsRepo {
|
||||
fun getBTFormat(): String
|
||||
|
||||
fun setBTFormat(value: String)
|
||||
|
||||
//endregion
|
||||
}
|
||||
@@ -1,10 +1,12 @@
|
||||
package com.rtbishop.look4sat.model
|
||||
|
||||
data class DatabaseState(val entriesTotal: Int, val radiosTotal: Int, val timestamp: Long)
|
||||
|
||||
data class PassesSettings(val hoursAhead: Int, val minElevation: Double)
|
||||
|
||||
data class OtherSettings(
|
||||
val utcState: Boolean,
|
||||
val updateState: Boolean,
|
||||
val sweepState: Boolean,
|
||||
val sensorState: Boolean
|
||||
)
|
||||
|
||||
data class DatabaseState(val entriesTotal: Int, val radiosTotal: Int, val timestamp: Long)
|
||||
Reference in new issue
Block a user