mirror of
https://github.com/rt-bishop/Look4Sat.git
synced 2026-10-02 03:15:37 +00:00
Added SatPass class to get the full info of a pass for the recycler items. Still trying to figure out what the final app is going to look like. Sitting at home with a cold.
This commit is contained in:
1 parent
b7291db0f9
commit
a0f723e233
6 files changed
+100
-28
No files matched your search
@@ -46,6 +46,7 @@ dependencies {
|
||||
implementation "androidx.navigation:navigation-ui-ktx:$navigation"
|
||||
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle"
|
||||
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle"
|
||||
implementation "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle"
|
||||
implementation "androidx.work:work-runtime-ktx:$work"
|
||||
implementation "androidx.room:room-runtime:$room"
|
||||
implementation "androidx.room:room-ktx:$room"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
package com.rtbishop.lookingsat.repo
|
||||
|
||||
import com.github.amsacode.predict4java.SatPassTime
|
||||
|
||||
data class SatPass(val satName: String, val catNum: Int, val pass: SatPassTime)
|
||||
@@ -5,12 +5,12 @@ import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.amsacode.predict4java.SatPassTime
|
||||
import com.rtbishop.lookingsat.R
|
||||
import com.rtbishop.lookingsat.repo.SatPass
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
class SatPassAdapter(private val satPassList: MutableList<SatPassTime>) :
|
||||
class SatPassAdapter(private val satPassList: List<SatPass>) :
|
||||
RecyclerView.Adapter<SatPassAdapter.ViewHolder>() {
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
@@ -27,16 +27,19 @@ class SatPassAdapter(private val satPassList: MutableList<SatPassTime>) :
|
||||
val satPass = satPassList[position]
|
||||
|
||||
val satName = holder.itemView.findViewById<TextView>(R.id.card_sat_name)
|
||||
val passVector = holder.itemView.findViewById<TextView>(R.id.card_pass_vector)
|
||||
val maxEl = holder.itemView.findViewById<TextView>(R.id.card_max_el)
|
||||
val passVector = holder.itemView.findViewById<TextView>(R.id.card_pass_vector)
|
||||
val passStart = holder.itemView.findViewById<TextView>(R.id.card_pass_start)
|
||||
val passEnd = holder.itemView.findViewById<TextView>(R.id.card_pass_end)
|
||||
|
||||
satName.text = String.format("%s", "Meteor M2-2")
|
||||
passVector.text = String.format("V: %02d° -> %02d°", satPass.aosAzimuth, satPass.losAzimuth)
|
||||
maxEl.text = String.format("%.1f°", satPass.maxEl)
|
||||
passStart.text = SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.startTime)
|
||||
passEnd.text = SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.endTime)
|
||||
satName.text = String.format("%s", satPass.satName)
|
||||
maxEl.text = String.format("%.1f°", satPass.pass.maxEl)
|
||||
passVector.text =
|
||||
String.format("V: %02d° -> %02d°", satPass.pass.aosAzimuth, satPass.pass.losAzimuth)
|
||||
passStart.text =
|
||||
SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.startTime)
|
||||
passEnd.text =
|
||||
SimpleDateFormat("HH:mm:ss", Locale.getDefault()).format(satPass.pass.endTime)
|
||||
}
|
||||
|
||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView),
|
||||
|
||||
@@ -5,20 +5,31 @@ import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageButton
|
||||
import android.widget.ProgressBar
|
||||
import androidx.appcompat.app.AlertDialog
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.github.amsacode.predict4java.TLE
|
||||
import com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
import com.rtbishop.lookingsat.R
|
||||
import com.rtbishop.lookingsat.repo.SatPass
|
||||
import com.rtbishop.lookingsat.vm.MainViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class SkyFragment : Fragment() {
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
private lateinit var recView: RecyclerView
|
||||
private lateinit var recAdapter: RecyclerView.Adapter<*>
|
||||
private lateinit var recLayoutManager: RecyclerView.LayoutManager
|
||||
private lateinit var btnRefresh: ImageButton
|
||||
private lateinit var progressBar: ProgressBar
|
||||
private lateinit var fab: FloatingActionButton
|
||||
|
||||
private var satPassList: List<SatPass> = emptyList()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
@@ -32,17 +43,25 @@ class SkyFragment : Fragment() {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
viewModel = ViewModelProvider(activity as MainActivity).get(MainViewModel::class.java)
|
||||
btnRefresh = (activity as MainActivity).findViewById(R.id.toolbar_btn_refresh)
|
||||
progressBar = view.findViewById(R.id.sky_progressbar)
|
||||
recView = view.findViewById(R.id.sky_recycler)
|
||||
fab = view.findViewById(R.id.sky_fab)
|
||||
|
||||
recView.layoutManager = LinearLayoutManager(activity)
|
||||
recView.setHasFixedSize(true)
|
||||
|
||||
btnRefresh.setOnClickListener {
|
||||
val satPassList = viewModel.updateRecycler()
|
||||
|
||||
recLayoutManager = LinearLayoutManager(activity)
|
||||
recAdapter = SatPassAdapter(satPassList)
|
||||
recView = view.findViewById(R.id.recycler_sky)
|
||||
|
||||
recView.setHasFixedSize(true)
|
||||
recView.layoutManager = recLayoutManager
|
||||
recView.adapter = recAdapter
|
||||
lifecycleScope.launch(Dispatchers.Main) {
|
||||
recView.visibility = View.INVISIBLE
|
||||
progressBar.visibility = View.VISIBLE
|
||||
progressBar.isIndeterminate = true
|
||||
satPassList = viewModel.updateRecycler()
|
||||
recAdapter = SatPassAdapter(satPassList)
|
||||
recView.adapter = recAdapter
|
||||
progressBar.isIndeterminate = false
|
||||
progressBar.visibility = View.INVISIBLE
|
||||
recView.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import android.app.Application
|
||||
import android.content.Context
|
||||
import android.content.SharedPreferences
|
||||
import android.location.Location
|
||||
import android.util.Log
|
||||
import androidx.core.content.edit
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
@@ -12,13 +13,15 @@ import androidx.lifecycle.viewModelScope
|
||||
import androidx.preference.PreferenceManager
|
||||
import com.github.amsacode.predict4java.GroundStationPosition
|
||||
import com.github.amsacode.predict4java.PassPredictor
|
||||
import com.github.amsacode.predict4java.SatPassTime
|
||||
import com.github.amsacode.predict4java.SatNotFoundException
|
||||
import com.github.amsacode.predict4java.TLE
|
||||
import com.google.android.gms.location.LocationServices
|
||||
import com.rtbishop.lookingsat.Injector
|
||||
import com.rtbishop.lookingsat.repo.Repository
|
||||
import com.rtbishop.lookingsat.repo.SatPass
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
@@ -29,12 +32,15 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
private val keyLon = "LONGITUDE"
|
||||
private val keyHeight = "HEIGHT"
|
||||
private val tleFile = "tles.txt"
|
||||
private val tag = "myTag"
|
||||
|
||||
private val repository: Repository = Injector.provideRepository(application)
|
||||
private val preferences = PreferenceManager.getDefaultSharedPreferences(application)
|
||||
private val fusedLocationClient = LocationServices.getFusedLocationProviderClient(application)
|
||||
|
||||
private val _debugMessage = MutableLiveData("")
|
||||
val debugMessage: LiveData<String> = _debugMessage
|
||||
|
||||
private val _gsp = MutableLiveData<GroundStationPosition>(
|
||||
GroundStationPosition(
|
||||
preferences.getDouble(keyLat, 0.0),
|
||||
@@ -44,17 +50,41 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
)
|
||||
val gsp: LiveData<GroundStationPosition> = _gsp
|
||||
|
||||
fun updateRecycler(): MutableList<SatPassTime> {
|
||||
var satPassList = mutableListOf<SatPassTime>()
|
||||
try {
|
||||
val tles = TLE.importSat(getApplication<Application>().openFileInput(tleFile))
|
||||
var tleList: List<TLE> = loadTwoLineElementFile().sortedWith(compareBy { it.name })
|
||||
|
||||
val passPredictor = PassPredictor(tles[0], _gsp.value)
|
||||
satPassList = passPredictor.getPasses(Date(), 6, false)
|
||||
private fun loadTwoLineElementFile(): List<TLE> {
|
||||
return try {
|
||||
TLE.importSat(getApplication<Application>().openFileInput(tleFile))
|
||||
} catch (exception: FileNotFoundException) {
|
||||
_debugMessage.postValue("TLE file wasn't found")
|
||||
emptyList()
|
||||
}
|
||||
return satPassList
|
||||
}
|
||||
|
||||
suspend fun updateRecycler(): List<SatPass> {
|
||||
val satPassList = mutableListOf<SatPass>()
|
||||
var sortedList = listOf<SatPass>()
|
||||
withContext(Dispatchers.Default) {
|
||||
for (tle in tleList.subList(0, 1)) {
|
||||
try {
|
||||
Log.d(tag, "Trying ${tle.name}")
|
||||
val passPredictor = PassPredictor(tle, gsp.value)
|
||||
val passes = passPredictor.getPasses(Date(), 6, false)
|
||||
for (pass in passes) {
|
||||
Log.d(tag, "Trying ${pass.maxEl}")
|
||||
satPassList.add(SatPass(tle.name, tle.catnum, pass))
|
||||
}
|
||||
} catch (exception: IllegalArgumentException) {
|
||||
val tleProblem = "There was a problem with TLE"
|
||||
Log.d(tag, tleProblem)
|
||||
_debugMessage.postValue(tleProblem)
|
||||
} catch (exception: SatNotFoundException) {
|
||||
Log.d(tag, "Certain satellites shall not pass")
|
||||
}
|
||||
}
|
||||
sortedList = satPassList.sortedWith(compareBy { it.pass.startTime })
|
||||
}
|
||||
return sortedList
|
||||
}
|
||||
|
||||
fun updateLocation() {
|
||||
@@ -77,9 +107,11 @@ class MainViewModel(application: Application) : AndroidViewModel(application) {
|
||||
fun updateTwoLineElementFile() {
|
||||
viewModelScope.launch(Dispatchers.IO) {
|
||||
try {
|
||||
val stream = repository.fetchTleStream()
|
||||
getApplication<Application>().openFileOutput(tleFile, Context.MODE_PRIVATE).use {
|
||||
it.write(repository.fetchTleStream().readBytes())
|
||||
it.write(stream.readBytes())
|
||||
}
|
||||
tleList = TLE.importSat(stream)
|
||||
_debugMessage.postValue("TLE file was updated")
|
||||
} catch (exception: IOException) {
|
||||
_debugMessage.postValue("Couldn't update TLE file")
|
||||
|
||||
@@ -6,10 +6,22 @@
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".ui.SkyFragment">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/sky_progressbar"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/sky_recycler"
|
||||
app:layout_constraintEnd_toEndOf="@+id/sky_recycler"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_sky"
|
||||
android:id="@+id/sky_recycler"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
||||
Reference in new issue
Block a user