mirror of
https://github.com/atsunatsu/Look4Sat.git
synced 2026-10-03 11:17:25 +00:00
Optimized transmitters adapter, changes to the recycler and ViewHolders
This commit is contained in:
1 parent
69b3e4f70b
commit
810fa5b85c
12 files changed
+152
-303
No files matched your search
@@ -30,17 +30,25 @@ import com.rtbishop.look4sat.databinding.ItemTransBinding
|
||||
import com.rtbishop.look4sat.utility.PassPredictor
|
||||
import java.util.*
|
||||
|
||||
class TransAdapter : RecyclerView.Adapter<TransAdapter.TransHolder>() {
|
||||
class TransAdapter(context: Context) : RecyclerView.Adapter<TransAdapter.TransHolder>() {
|
||||
|
||||
private var transmittersList = emptyList<SatTrans>()
|
||||
private lateinit var predictor: PassPredictor
|
||||
private val divider = 1000000f
|
||||
private val strNo = context.getString(R.string.btn_no)
|
||||
private val strYes = context.getString(R.string.btn_yes)
|
||||
private val mode = context.getString(R.string.trans_mode)
|
||||
private val formatLink = context.getString(R.string.trans_down_low_doppler)
|
||||
private val formatLinkNull = context.getString(R.string.no_downlink_doppler)
|
||||
private val isInverted = context.getString(R.string.trans_inverted)
|
||||
private var transmittersList = emptyList<SatTrans>()
|
||||
|
||||
fun setPredictor(predict: PassPredictor) {
|
||||
predictor = predict
|
||||
fun setPredictor(predictor: PassPredictor) {
|
||||
this.predictor = predictor
|
||||
}
|
||||
|
||||
fun setList(list: List<SatTrans>) {
|
||||
transmittersList = list
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
@@ -61,82 +69,24 @@ class TransAdapter : RecyclerView.Adapter<TransAdapter.TransHolder>() {
|
||||
RecyclerView.ViewHolder(itemView) {
|
||||
|
||||
fun bind(satTrans: SatTrans) {
|
||||
val context: Context = itemView.context
|
||||
val freqDivider = 1000000f
|
||||
val dateNow = Date()
|
||||
binding.description.text = satTrans.description
|
||||
|
||||
binding.transDescription.text = satTrans.description
|
||||
if (satTrans.downlinkLow != null) {
|
||||
val downFreq = predictor.getDownlinkFreq(satTrans.downlinkLow, dateNow) / divider
|
||||
binding.downlink.text = String.format(formatLink, downFreq)
|
||||
} else binding.downlink.text = formatLinkNull
|
||||
|
||||
if (satTrans.downlinkLow != null && satTrans.downlinkHigh == null) {
|
||||
binding.transDownlink.text = String
|
||||
.format(
|
||||
context.getString(R.string.trans_down_low),
|
||||
satTrans.downlinkLow / freqDivider
|
||||
)
|
||||
binding.transDownlinkDoppler.text = String
|
||||
.format(
|
||||
context.getString(R.string.trans_down_low_doppler),
|
||||
predictor.getDownlinkFreq(satTrans.downlinkLow, Date()) / freqDivider
|
||||
)
|
||||
} else if (satTrans.downlinkLow != null && satTrans.downlinkHigh != null) {
|
||||
binding.transDownlink.text = String
|
||||
.format(
|
||||
context.getString(R.string.trans_down_lowHigh),
|
||||
satTrans.downlinkLow / freqDivider,
|
||||
satTrans.downlinkHigh / freqDivider
|
||||
)
|
||||
binding.transDownlinkDoppler.text = String
|
||||
.format(
|
||||
context.getString(R.string.trans_down_lowHigh_doppler),
|
||||
predictor.getDownlinkFreq(satTrans.downlinkLow, Date()) / freqDivider,
|
||||
predictor.getDownlinkFreq(satTrans.downlinkHigh, Date()) / freqDivider
|
||||
)
|
||||
} else {
|
||||
binding.transDownlink.text = context.getString(R.string.no_downlink)
|
||||
binding.transDownlinkDoppler.text = context.getString(R.string.no_downlink_doppler)
|
||||
}
|
||||
if (satTrans.uplinkLow != null) {
|
||||
val upFreq = predictor.getUplinkFreq(satTrans.uplinkLow, dateNow) / divider
|
||||
binding.uplink.text = String.format(formatLink, upFreq)
|
||||
} else binding.uplink.text = formatLinkNull
|
||||
|
||||
if (satTrans.uplinkLow != null && satTrans.uplinkHigh == null) {
|
||||
binding.transUplink.text = String.format(
|
||||
context.getString(R.string.trans_up_low),
|
||||
satTrans.uplinkLow / freqDivider
|
||||
)
|
||||
binding.transUplinkDoppler.text = String.format(
|
||||
context.getString(R.string.trans_up_low_doppler),
|
||||
predictor.getUplinkFreq(satTrans.uplinkLow, Date()) / freqDivider
|
||||
)
|
||||
} else if (satTrans.uplinkLow != null && satTrans.uplinkHigh != null) {
|
||||
binding.transUplink.text = String.format(
|
||||
context.getString(R.string.trans_up_lowHigh),
|
||||
satTrans.uplinkLow / freqDivider,
|
||||
satTrans.uplinkHigh / freqDivider
|
||||
)
|
||||
binding.transUplinkDoppler.text = String.format(
|
||||
context.getString(R.string.trans_up_lowHigh_doppler),
|
||||
predictor.getUplinkFreq(satTrans.uplinkLow, Date()) / freqDivider,
|
||||
predictor.getUplinkFreq(satTrans.uplinkHigh, Date()) / freqDivider
|
||||
)
|
||||
} else {
|
||||
binding.transUplink.text = context.getString(R.string.no_uplink)
|
||||
binding.transUplinkDoppler.text = context.getString(R.string.no_uplink_doppler)
|
||||
}
|
||||
if (satTrans.mode != null) binding.mode.text = String.format(mode, satTrans.mode)
|
||||
else binding.mode.text = String.format(mode, strNo)
|
||||
|
||||
if (satTrans.mode != null) {
|
||||
binding.transMode.text =
|
||||
String.format(context.getString(R.string.trans_mode), satTrans.mode)
|
||||
} else {
|
||||
binding.transMode.text = context.getString(R.string.no_mode)
|
||||
}
|
||||
if (satTrans.isInverted) {
|
||||
binding.transInverted.text = String.format(
|
||||
context.getString(R.string.trans_inverted),
|
||||
context.getString(R.string.btn_yes)
|
||||
)
|
||||
} else {
|
||||
binding.transInverted.text = String.format(
|
||||
context.getString(R.string.trans_inverted),
|
||||
context.getString(R.string.btn_no)
|
||||
)
|
||||
}
|
||||
if (satTrans.isInverted) binding.isInverted.text = String.format(isInverted, strYes)
|
||||
else binding.isInverted.text = String.format(isInverted, strNo)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,9 +24,7 @@ import android.hardware.*
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.rtbishop.look4sat.R
|
||||
@@ -37,9 +35,8 @@ import com.rtbishop.look4sat.databinding.FragmentPolarBinding
|
||||
import com.rtbishop.look4sat.ui.adapters.TransAdapter
|
||||
import com.rtbishop.look4sat.ui.views.PolarView
|
||||
import com.rtbishop.look4sat.utility.PrefsManager
|
||||
import com.rtbishop.look4sat.utility.RecyclerDivider
|
||||
import dagger.hilt.android.AndroidEntryPoint
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.round
|
||||
@@ -50,24 +47,26 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
@Inject
|
||||
lateinit var prefsManager: PrefsManager
|
||||
|
||||
private lateinit var mainActivity: FragmentActivity
|
||||
private lateinit var transmitterAdapter: TransAdapter
|
||||
private lateinit var binding: FragmentPolarBinding
|
||||
private lateinit var satPass: SatPass
|
||||
private lateinit var sensorManager: SensorManager
|
||||
private val viewModel: SharedViewModel by activityViewModels()
|
||||
private val args: PolarFragmentArgs by navArgs()
|
||||
private val transmitterAdapter = TransAdapter()
|
||||
private var magneticDeclination = 0f
|
||||
private var polarView: PolarView? = null
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
mainActivity = requireActivity()
|
||||
binding = FragmentPolarBinding.bind(view)
|
||||
sensorManager = mainActivity.getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
sensorManager = requireContext().getSystemService(Context.SENSOR_SERVICE) as SensorManager
|
||||
transmitterAdapter = TransAdapter(requireContext())
|
||||
binding.recycler.apply {
|
||||
layoutManager = LinearLayoutManager(mainActivity)
|
||||
setHasFixedSize(true)
|
||||
adapter = transmitterAdapter
|
||||
isVerticalScrollBarEnabled = false
|
||||
layoutManager = LinearLayoutManager(context)
|
||||
addItemDecoration(RecyclerDivider(R.drawable.rec_divider_dark))
|
||||
}
|
||||
calculateMagneticDeclination()
|
||||
observePasses()
|
||||
@@ -109,20 +108,26 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
viewModel.getPasses().observe(viewLifecycleOwner, { result ->
|
||||
if (result is Result.Success) {
|
||||
satPass = result.data[args.satPassIndex]
|
||||
polarView = PolarView(mainActivity, satPass)
|
||||
polarView = PolarView(requireContext(), satPass)
|
||||
binding.frame.addView(polarView)
|
||||
observeTimer()
|
||||
observeTransmitters()
|
||||
refreshText()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun observeTimer() {
|
||||
viewModel.getCurrentTimeMillis().observe(viewLifecycleOwner, {
|
||||
transmitterAdapter.notifyDataSetChanged()
|
||||
setPassText(Date(it))
|
||||
})
|
||||
}
|
||||
|
||||
private fun observeTransmitters() {
|
||||
viewModel.getTransmittersForSat(satPass.tle.catnum).observe(viewLifecycleOwner, {
|
||||
if (it.isNotEmpty()) {
|
||||
transmitterAdapter.setPredictor(satPass.predictor)
|
||||
transmitterAdapter.setList(it)
|
||||
transmitterAdapter.notifyDataSetChanged()
|
||||
binding.recycler.visibility = View.VISIBLE
|
||||
binding.noTransMsg.visibility = View.INVISIBLE
|
||||
} else {
|
||||
@@ -133,33 +138,22 @@ class PolarFragment : Fragment(R.layout.fragment_polar), SensorEventListener {
|
||||
}
|
||||
|
||||
private fun calculateMagneticDeclination() {
|
||||
val position = prefsManager.getStationPosition()
|
||||
val geoField = GeomagneticField(
|
||||
position.latitude.toFloat(),
|
||||
position.longitude.toFloat(),
|
||||
position.heightAMSL.toFloat(),
|
||||
System.currentTimeMillis()
|
||||
)
|
||||
magneticDeclination = geoField.declination
|
||||
}
|
||||
|
||||
private fun refreshText() {
|
||||
lifecycleScope.launch {
|
||||
while (true) {
|
||||
setPassText()
|
||||
polarView?.invalidate()
|
||||
transmitterAdapter.notifyDataSetChanged()
|
||||
delay(3000)
|
||||
}
|
||||
prefsManager.getStationPosition().let {
|
||||
magneticDeclination = GeomagneticField(
|
||||
it.latitude.toFloat(),
|
||||
it.longitude.toFloat(),
|
||||
it.heightAMSL.toFloat(),
|
||||
System.currentTimeMillis()
|
||||
).declination
|
||||
}
|
||||
}
|
||||
|
||||
private fun setPassText() {
|
||||
val satPos = satPass.predictor.getSatPos(Date())
|
||||
val polarAz = mainActivity.getString(R.string.pat_azimuth)
|
||||
val polarEl = mainActivity.getString(R.string.pat_elevation)
|
||||
val polarRng = mainActivity.getString(R.string.pat_distance)
|
||||
val polarAlt = mainActivity.getString(R.string.pat_altitude)
|
||||
private fun setPassText(date: Date) {
|
||||
val satPos = satPass.predictor.getSatPos(date)
|
||||
val polarAz = getString(R.string.pat_azimuth)
|
||||
val polarEl = getString(R.string.pat_elevation)
|
||||
val polarRng = getString(R.string.pat_distance)
|
||||
val polarAlt = getString(R.string.pat_altitude)
|
||||
binding.azimuth.text = String.format(polarAz, Math.toDegrees(satPos.azimuth))
|
||||
binding.elevation.text = String.format(polarEl, Math.toDegrees(satPos.elevation))
|
||||
binding.distance.text = String.format(polarRng, satPos.range)
|
||||
|
||||
@@ -22,16 +22,16 @@ class PolarView(context: Context) : View(context) {
|
||||
private val polarWidth = resources.displayMetrics.widthPixels
|
||||
private val polarCenter = polarWidth / 2f
|
||||
private val scale = resources.displayMetrics.density
|
||||
private val radius = polarWidth * 0.49f
|
||||
private val txtSize = scale * 15
|
||||
private val radius = polarWidth * 0.48f
|
||||
private val txtSize = scale * 16
|
||||
private val path: Path = Path()
|
||||
private var azimuth = 0f
|
||||
private val piDiv2 = Math.PI / 2.0
|
||||
|
||||
private val radarPaint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
color = ContextCompat.getColor(context, R.color.greyLight)
|
||||
style = Paint.Style.STROKE
|
||||
strokeWidth = scale
|
||||
strokeWidth = scale * 1.6f
|
||||
}
|
||||
private val txtPaint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
@@ -42,7 +42,7 @@ class PolarView(context: Context) : View(context) {
|
||||
isAntiAlias = true
|
||||
color = ContextCompat.getColor(context, R.color.satTrack)
|
||||
style = Paint.Style.STROKE
|
||||
strokeWidth = scale
|
||||
strokeWidth = scale * 1.6f
|
||||
}
|
||||
private val satPaint = Paint().apply {
|
||||
isAntiAlias = true
|
||||
@@ -51,13 +51,10 @@ class PolarView(context: Context) : View(context) {
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
canvas.rotate(-azimuth, polarCenter, polarCenter)
|
||||
canvas.translate(polarCenter, polarCenter)
|
||||
drawRadarView(canvas)
|
||||
drawRadarText(canvas)
|
||||
if (!pass.tle.isDeepspace) {
|
||||
drawPassTrajectory(canvas, pass)
|
||||
}
|
||||
if (!pass.tle.isDeepspace) drawPassTrajectory(canvas, pass)
|
||||
drawSatellite(canvas, pass)
|
||||
}
|
||||
|
||||
@@ -99,18 +96,16 @@ class PolarView(context: Context) : View(context) {
|
||||
if (satPos.elevation > 0) {
|
||||
val x = sph2CartX(satPos.azimuth, satPos.elevation, radius.toDouble())
|
||||
val y = sph2CartY(satPos.azimuth, satPos.elevation, radius.toDouble())
|
||||
cvs.drawCircle(x, -y, txtSize / 3, satPaint)
|
||||
cvs.drawCircle(x, -y, txtSize / 2.6f, satPaint)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sph2CartX(azimuth: Double, elevation: Double, r: Double): Float {
|
||||
val piDiv2 = Math.PI / 2.0
|
||||
val radius = r * (piDiv2 - elevation) / piDiv2
|
||||
return (radius * cos(piDiv2 - azimuth)).toFloat()
|
||||
}
|
||||
|
||||
private fun sph2CartY(azimuth: Double, elevation: Double, r: Double): Float {
|
||||
val piDiv2 = Math.PI / 2.0
|
||||
val radius = r * (piDiv2 - elevation) / piDiv2
|
||||
return (radius * sin(piDiv2 - azimuth)).toFloat()
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user