Further changes to MapViewModel.kt, removed bottomNav ripple effect

This commit is contained in:
Arty Bishop committed 2020-11-28 16:46:11 +00:00
1 parent 4556d2d975
commit f055d96e5a
3 files changed
+85 -94

No files matched your search

@@ -10,7 +10,6 @@ import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment
import androidx.fragment.app.activityViewModels
import androidx.fragment.app.viewModels
import com.github.amsacode.predict4java.GroundStationPosition
import com.github.amsacode.predict4java.Position
import com.rtbishop.look4sat.R
import com.rtbishop.look4sat.SharedViewModel
@@ -36,23 +35,11 @@ class MapFragment : Fragment(R.layout.fragment_map) {
@Inject
lateinit var preferences: SharedPreferences
private lateinit var binding: FragmentMapBinding
private lateinit var nameFormat: String
private lateinit var qthFormat: String
private lateinit var altFormat: String
private lateinit var distFormat: String
private lateinit var velFormat: String
private lateinit var latLonFormat: String
private lateinit var coverageFormat: String
private val viewModel: MapViewModel by viewModels()
private val mapViewModel: MapViewModel by viewModels()
private val sharedViewModel: SharedViewModel by activityViewModels()
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
setupComponents(view)
setupObservers()
}
private fun setupComponents(view: View) {
Configuration.getInstance().load(requireContext().applicationContext, preferences)
binding = FragmentMapBinding.bind(view).apply {
mapView.apply {
@@ -70,35 +57,29 @@ class MapFragment : Fragment(R.layout.fragment_map) {
overlays.addAll(Array(4) { FolderOverlay() })
}
}
nameFormat = getString(R.string.pat_osm_idName)
qthFormat = getString(R.string.map_qth)
altFormat = getString(R.string.pat_altitude)
distFormat = getString(R.string.pat_distance)
velFormat = getString(R.string.pat_osm_vel)
latLonFormat = getString(R.string.pat_osm_latLon)
coverageFormat = getString(R.string.map_coverage)
setupObservers()
}
private fun setupObservers() {
viewModel.getGSP().observe(viewLifecycleOwner, { setupPosOverlay(it) })
mapViewModel.getGSP().observe(viewLifecycleOwner, { setupPosOverlay(it) })
sharedViewModel.getPasses().observe(viewLifecycleOwner, {
if (it is Result.Success && it.data.isNotEmpty()) {
viewModel.setPasses(it.data)
binding.fabPrev.setOnClickListener { viewModel.changeSelection(true) }
binding.fabNext.setOnClickListener { viewModel.changeSelection(false) }
mapViewModel.setPasses(it.data)
binding.fabPrev.setOnClickListener { mapViewModel.scrollSelection(true) }
binding.fabNext.setOnClickListener { mapViewModel.scrollSelection(false) }
}
})
viewModel.getSelectedSat().observe(viewLifecycleOwner, { setSelectedSatDetails(it) })
viewModel.getSatMarkers().observe(viewLifecycleOwner, { setMarkers(it) })
mapViewModel.getSelectedSat().observe(viewLifecycleOwner, { setSelectedSatDetails(it) })
mapViewModel.getSatMarkers().observe(viewLifecycleOwner, { setMarkers(it) })
}
private fun setupPosOverlay(gsp: GroundStationPosition) {
private fun setupPosOverlay(osmPos: Position) {
binding.apply {
Marker(mapView).apply {
setInfoWindow(null)
setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_BOTTOM)
icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_map_pos)
position = GeoPoint(gsp.latitude, gsp.longitude)
position = GeoPoint(osmPos.lat, osmPos.lon)
mapView.overlays[0] = this
mapView.invalidate()
}
@@ -107,13 +88,14 @@ class MapFragment : Fragment(R.layout.fragment_map) {
private fun setSelectedSatDetails(sat: SelectedSat) {
binding.apply {
idName.text = String.format(nameFormat, sat.catNum, sat.name)
qthLocator.text = String.format(qthFormat, sat.qthLoc)
altitude.text = String.format(altFormat, sat.altitude)
distance.text = String.format(distFormat, sat.range)
velocity.text = String.format(velFormat, sat.velocity)
latLon.text = String.format(latLonFormat, sat.osmPos.lat, sat.osmPos.lon)
mapCoverage.text = String.format(coverageFormat, sat.coverage)
idName.text = String.format(getString(R.string.pat_osm_idName), sat.catNum, sat.name)
qthLocator.text = String.format(getString(R.string.map_qth), sat.qthLoc)
altitude.text = String.format(getString(R.string.pat_altitude), sat.altitude)
distance.text = String.format(getString(R.string.pat_distance), sat.range)
velocity.text = String.format(getString(R.string.pat_osm_vel), sat.velocity)
latLon.text =
String.format(getString(R.string.pat_osm_latLon), sat.osmPos.lat, sat.osmPos.lon)
mapCoverage.text = String.format(getString(R.string.map_coverage), sat.coverage)
mapView.overlays[1] = sat.groundTrack
mapView.overlays[2] = sat.footprint
mapView.invalidate()
@@ -130,7 +112,7 @@ class MapFragment : Fragment(R.layout.fragment_map) {
icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_map_sat)
position = GeoPoint(it.value.lat, it.value.lon)
setOnMarkerClickListener { _, _ ->
viewModel.setSelectedSat(it.key)
mapViewModel.selectSatellite(it.key)
return@setOnMarkerClickListener true
}
markers.add(this)
@@ -7,8 +7,8 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.github.amsacode.predict4java.GroundStationPosition
import com.github.amsacode.predict4java.Position
import com.github.amsacode.predict4java.SatPos
import com.rtbishop.look4sat.data.SatPass
import com.rtbishop.look4sat.data.SelectedSat
import com.rtbishop.look4sat.utility.PrefsManager
@@ -16,6 +16,7 @@ import com.rtbishop.look4sat.utility.Utilities
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.osmdroid.util.GeoPoint
import org.osmdroid.views.overlay.FolderOverlay
import org.osmdroid.views.overlay.Overlay
@@ -25,7 +26,7 @@ import java.util.*
import kotlin.math.pow
import kotlin.math.sqrt
class MapViewModel @ViewModelInject constructor(prefsManager: PrefsManager) : ViewModel() {
class MapViewModel @ViewModelInject constructor(val prefsManager: PrefsManager) : ViewModel() {
private val dateNow = Date()
private val trackPaint = Paint().apply {
@@ -42,9 +43,10 @@ class MapViewModel @ViewModelInject constructor(prefsManager: PrefsManager) : Vi
isAntiAlias = true
}
private var filteredPasses = listOf<SatPass>()
private lateinit var selectedPass: SatPass
private val _gsp = MutableLiveData(prefsManager.getStationPosition())
fun getGSP(): LiveData<GroundStationPosition> = _gsp
private val _gsp = MutableLiveData(getStationPosition())
fun getGSP(): LiveData<Position> = _gsp
private val _selectedSat = MutableLiveData<SelectedSat>()
fun getSelectedSat(): LiveData<SelectedSat> = _selectedSat
@@ -54,70 +56,58 @@ class MapViewModel @ViewModelInject constructor(prefsManager: PrefsManager) : Vi
fun setPasses(passesList: List<SatPass>) {
filteredPasses = passesList.distinctBy { it.tle }
setSelectedSat(filteredPasses[0])
calculatePositions(filteredPasses)
}
fun changeSelection(decrement: Boolean) {
val index = filteredPasses.indexOf(_selectedSat.value?.pass)
if (decrement) {
if (index > 0) setSelectedSat(filteredPasses[index - 1])
else setSelectedSat(filteredPasses[filteredPasses.size - 1])
} else {
if (index < filteredPasses.size - 1) setSelectedSat(filteredPasses[index + 1])
else setSelectedSat(filteredPasses[0])
}
}
fun setSelectedSat(pass: SatPass?) {
pass?.let {
viewModelScope.launch(Dispatchers.Default) {
val satPos = pass.predictor.getSatPos(dateNow)
val osmPos = getOsmPosition(satPos.latitude, satPos.longitude, true)
val qthLoc = Utilities.locToQTH(osmPos.lat, osmPos.lon)
val velocity = getSatVelocity(satPos.altitude)
val coverage = satPos.rangeCircleRadiusKm * 2
val footprint = getSatFootprint(pass)
val track = getSatTrack(pass)
_selectedSat.postValue(
SelectedSat(
pass, pass.tle.catnum, pass.tle.name, satPos.range,
satPos.altitude, velocity, qthLoc, osmPos, coverage, footprint, track
)
)
}
}
}
private fun calculatePositions(passes: List<SatPass>) {
val passesMap = mutableMapOf<SatPass, Position>()
selectedPass = filteredPasses[0]
viewModelScope.launch {
while (true) {
dateNow.time = System.currentTimeMillis()
passes.forEach {
val satPos = it.predictor.getSatPos(dateNow)
passesMap[it] = getOsmPosition(satPos.latitude, satPos.longitude, true)
}
setSelectedSat(_selectedSat.value?.pass)
_satMarkers.postValue(passesMap)
_selectedSat.value = getDataForSelSatellite(selectedPass)
_satMarkers.value = getDataForAllSatellites(filteredPasses)
delay(2000)
}
}
}
private fun getSatFootprint(pass: SatPass): Overlay {
val rangePoints = mutableListOf<GeoPoint>()
pass.predictor.getSatPos(dateNow).rangeCircle.withIndex().forEach {
val osmPos = getOsmPosition(it.value.lat, it.value.lon, false)
rangePoints.add(GeoPoint(osmPos.lat, osmPos.lon))
}
return Polygon().apply {
fillPaint.set(footprintPaint)
outlinePaint.set(footprintPaint)
points = rangePoints
fun scrollSelection(decrement: Boolean) {
val index = filteredPasses.indexOf(selectedPass)
if (decrement) {
if (index > 0) selectSatellite(filteredPasses[index - 1])
else selectSatellite(filteredPasses[filteredPasses.size - 1])
} else {
if (index < filteredPasses.size - 1) selectSatellite(filteredPasses[index + 1])
else selectSatellite(filteredPasses[0])
}
}
fun selectSatellite(satPass: SatPass) {
selectedPass = satPass
viewModelScope.launch { _selectedSat.value = getDataForSelSatellite(selectedPass) }
}
private suspend fun getDataForSelSatellite(pass: SatPass): SelectedSat =
withContext(Dispatchers.Default) {
val satPos = pass.predictor.getSatPos(dateNow)
val osmPos = getOsmPosition(satPos.latitude, satPos.longitude, true)
val qthLoc = Utilities.locToQTH(osmPos.lat, osmPos.lon)
val velocity = getSatVelocity(satPos.altitude)
val coverage = satPos.rangeCircleRadiusKm * 2
val footprint = getSatFootprint(satPos)
val track = getSatTrack(pass)
return@withContext SelectedSat(
pass, pass.tle.catnum, pass.tle.name, satPos.range,
satPos.altitude, velocity, qthLoc, osmPos, coverage, footprint, track
)
}
private suspend fun getDataForAllSatellites(passes: List<SatPass>): Map<SatPass, Position> =
withContext(Dispatchers.Default) {
val passesMap = mutableMapOf<SatPass, Position>()
passes.forEach {
val satPos = it.predictor.getSatPos(dateNow)
passesMap[it] = getOsmPosition(satPos.latitude, satPos.longitude, true)
}
return@withContext passesMap
}
private fun getSatTrack(pass: SatPass): Overlay {
val period = (24 * 60 / pass.tle.meanmo).toInt()
val positions = pass.predictor.getPositions(dateNow, 20, 0, period * 3)
@@ -147,6 +137,24 @@ class MapViewModel @ViewModelInject constructor(prefsManager: PrefsManager) : Vi
return trackOverlay
}
private fun getSatFootprint(satPos: SatPos): Overlay {
val rangePoints = mutableListOf<GeoPoint>()
satPos.rangeCircle.withIndex().forEach {
val osmPos = getOsmPosition(it.value.lat, it.value.lon, false)
rangePoints.add(GeoPoint(osmPos.lat, osmPos.lon))
}
return Polygon().apply {
fillPaint.set(footprintPaint)
outlinePaint.set(footprintPaint)
points = rangePoints
}
}
private fun getStationPosition(): Position {
val stationPosition = prefsManager.getStationPosition()
return getOsmPosition(stationPosition.latitude, stationPosition.longitude, false)
}
private fun getSatVelocity(altitude: Double): Double {
val earthG = 6.674 * 10.0.pow(-11)
val earthM = 5.98 * 10.0.pow(24)
@@ -21,6 +21,7 @@
android:layout_width="match_parent"
android:layout_height="48dp"
app:elevation="1dp"
app:itemRippleColor="@android:color/transparent"
app:labelVisibilityMode="labeled"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"