From 4cfab174134af12f1de1caee2e07713fb1b65f6e Mon Sep 17 00:00:00 2001 From: Arty Bishop Date: Mon, 26 Apr 2021 20:00:56 +0100 Subject: [PATCH] Further fixes to MapFragment.kt and MapViewModel.kt --- app/build.gradle | 1 + .../look4sat/framework/model/SatData.kt | 15 + .../look4sat/framework/model/SelectedSat.kt | 35 --- .../presentation/mapScreen/MapFragment.kt | 109 ++++--- .../presentation/mapScreen/MapViewModel.kt | 265 +++++++++--------- .../passesScreen/PassesFragment.kt | 12 +- .../presentation/polarScreen/PolarFragment.kt | 10 +- .../rtbishop/look4sat/utility/Extensions.kt | 22 +- 8 files changed, 243 insertions(+), 226 deletions(-) create mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/model/SatData.kt delete mode 100644 app/src/main/java/com/rtbishop/look4sat/framework/model/SelectedSat.kt diff --git a/app/build.gradle b/app/build.gradle index 3f57f618..d1e32d2e 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,6 +42,7 @@ android { buildFeatures { viewBinding = true } + kotlinOptions.useIR = true } dependencies { diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/model/SatData.kt b/app/src/main/java/com/rtbishop/look4sat/framework/model/SatData.kt new file mode 100644 index 00000000..b558504c --- /dev/null +++ b/app/src/main/java/com/rtbishop/look4sat/framework/model/SatData.kt @@ -0,0 +1,15 @@ +package com.rtbishop.look4sat.framework.model + +import com.rtbishop.look4sat.domain.predict4kotlin.Position +import com.rtbishop.look4sat.domain.predict4kotlin.Satellite + +data class SatData( + val pass: Satellite, + val catNum: Int, + val name: String, + val range: Double, + val altitude: Double, + val velocity: Double, + val qthLoc: String, + val osmPos: Position +) \ No newline at end of file diff --git a/app/src/main/java/com/rtbishop/look4sat/framework/model/SelectedSat.kt b/app/src/main/java/com/rtbishop/look4sat/framework/model/SelectedSat.kt deleted file mode 100644 index df94382b..00000000 --- a/app/src/main/java/com/rtbishop/look4sat/framework/model/SelectedSat.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Look4Sat. Amateur radio satellite tracker and pass predictor. - * Copyright (C) 2019-2021 Arty Bishop (bishop.arty@gmail.com) - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -package com.rtbishop.look4sat.framework.model - -import com.rtbishop.look4sat.domain.predict4kotlin.Position -import com.rtbishop.look4sat.domain.predict4kotlin.Satellite -import org.osmdroid.views.overlay.Overlay - -data class SelectedSat( - val pass: Satellite, - val catNum: Int, - val name: String, - val range: Double, - val altitude: Double, - val velocity: Double, - val qthLoc: String, - val osmPos: Position, - val footprint: Overlay, - val groundTrack: Overlay -) diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt index 7682fae1..027c5ea9 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapFragment.kt @@ -20,6 +20,7 @@ package com.rtbishop.look4sat.presentation.mapScreen import android.graphics.Color import android.graphics.ColorMatrix import android.graphics.ColorMatrixColorFilter +import android.graphics.Paint import android.os.Bundle import android.view.View import androidx.core.content.ContextCompat @@ -29,7 +30,7 @@ import com.rtbishop.look4sat.R import com.rtbishop.look4sat.databinding.FragmentMapBinding import com.rtbishop.look4sat.domain.predict4kotlin.Position import com.rtbishop.look4sat.domain.predict4kotlin.Satellite -import com.rtbishop.look4sat.framework.model.SelectedSat +import com.rtbishop.look4sat.framework.model.SatData import dagger.hilt.android.AndroidEntryPoint import org.osmdroid.config.Configuration import org.osmdroid.tileprovider.tilesource.TileSourceFactory @@ -43,13 +44,26 @@ import java.util.* @AndroidEntryPoint class MapFragment : Fragment(R.layout.fragment_map) { - private val mapViewModel: MapViewModel by viewModels() + private val viewModel: MapViewModel by viewModels() private val minLat = MapView.getTileSystem().minLatitude private val maxLat = MapView.getTileSystem().maxLatitude + private val trackPaint = Paint().apply { + strokeWidth = 2f + style = Paint.Style.STROKE + color = Color.RED + strokeCap = Paint.Cap.ROUND + strokeJoin = Paint.Join.ROUND + isAntiAlias = true + } + private val footprintPaint = Paint().apply { + style = Paint.Style.FILL_AND_STROKE + color = Color.parseColor("#26FFE082") + isAntiAlias = true + } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - Configuration.getInstance().load(requireContext(), mapViewModel.getPreferences()) + Configuration.getInstance().load(requireContext(), viewModel.getPreferences()) val binding = FragmentMapBinding.bind(view).apply { mapView.apply { setMultiTouchControls(true) @@ -67,50 +81,37 @@ class MapFragment : Fragment(R.layout.fragment_map) { overlays.addAll(Array(4) { FolderOverlay() }) } } - binding.fabPrev.setOnClickListener { mapViewModel.scrollSelection(true) } - binding.fabNext.setOnClickListener { mapViewModel.scrollSelection(false) } + binding.fabPrev.setOnClickListener { viewModel.scrollSelection(true) } + binding.fabNext.setOnClickListener { viewModel.scrollSelection(false) } setupObservers(binding) } private fun setupObservers(binding: FragmentMapBinding) { - mapViewModel.stationPosition.observe(viewLifecycleOwner, { setupPosOverlay(it, binding) }) - mapViewModel.getSelectedSat().observe(viewLifecycleOwner, { setSatDetails(it, binding) }) - mapViewModel.getSatMarkers().observe(viewLifecycleOwner, { setMarkers(it, binding) }) + viewModel.stationPos.observe(viewLifecycleOwner, { renderStationPos(it, binding) }) + viewModel.allSatPositions.observe(viewLifecycleOwner, { renderSatPositions(it, binding) }) + viewModel.satTrack.observe(viewLifecycleOwner, { renderSatTrack(it, binding) }) + viewModel.satFootprint.observe(viewLifecycleOwner, { renderSatFootprint(it, binding) }) + viewModel.satData.observe(viewLifecycleOwner, { renderSatData(it, binding) }) } - private fun setupPosOverlay(osmPos: Position, binding: FragmentMapBinding) { + private fun renderStationPos(stationPos: Position, binding: FragmentMapBinding) { 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(osmPos.latitude, osmPos.longitude) + position = GeoPoint(stationPos.latitude, stationPos.longitude) mapView.overlays[0] = this mapView.invalidate() } } } - private fun setSatDetails(sat: SelectedSat, binding: FragmentMapBinding) { - binding.apply { - 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) - mapLat.text = String.format(getString(R.string.pat_osm_lat), sat.osmPos.latitude) - mapLon.text = String.format(getString(R.string.pat_osm_lon), sat.osmPos.longitude) - mapView.overlays[1] = sat.groundTrack - mapView.overlays[2] = sat.footprint - mapView.invalidate() - } - } - - private fun setMarkers(map: Map, binding: FragmentMapBinding) { + private fun renderSatPositions(posMap: Map, binding: FragmentMapBinding) { binding.apply { val markers = FolderOverlay() - map.entries.forEach { - if (mapViewModel.shouldUseTextLabels()) { + posMap.entries.forEach { + if (viewModel.shouldUseTextLabels()) { Marker(mapView).apply { setInfoWindow(null) textLabelFontSize = 24 @@ -121,11 +122,11 @@ class MapFragment : Fragment(R.layout.fragment_map) { setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER) try { position = GeoPoint(it.value.latitude, it.value.longitude) - } catch (e: IllegalArgumentException) { - Timber.d("Position: $position") + } catch (exception: IllegalArgumentException) { + Timber.d(exception) } setOnMarkerClickListener { _, _ -> - mapViewModel.selectSatellite(it.key) + viewModel.selectSatellite(it.key) return@setOnMarkerClickListener true } markers.add(this) @@ -137,11 +138,11 @@ class MapFragment : Fragment(R.layout.fragment_map) { icon = ContextCompat.getDrawable(requireContext(), R.drawable.ic_map_sat) try { position = GeoPoint(it.value.latitude, it.value.longitude) - } catch (e: IllegalArgumentException) { - Timber.d("Position: $position") + } catch (exception: IllegalArgumentException) { + Timber.d(exception) } setOnMarkerClickListener { _, _ -> - mapViewModel.selectSatellite(it.key) + viewModel.selectSatellite(it.key) return@setOnMarkerClickListener true } markers.add(this) @@ -153,6 +154,46 @@ class MapFragment : Fragment(R.layout.fragment_map) { } } + private fun renderSatTrack(satTrack: List>, binding: FragmentMapBinding) { + val trackOverlay = FolderOverlay() + satTrack.forEach { track -> + val trackPoints = track.map { GeoPoint(it.latitude, it.longitude) } + Polyline().apply { + outlinePaint.set(trackPaint) + setPoints(trackPoints) + trackOverlay.add(this) + } + } + binding.mapView.overlays[1] = trackOverlay + } + + private fun renderSatFootprint(satFootprint: List, binding: FragmentMapBinding) { + val footprintPoints = satFootprint.map { GeoPoint(it.latitude, it.longitude) } + val footprintOverlay = Polygon().apply { + fillPaint.set(footprintPaint) + outlinePaint.set(footprintPaint) + try { + this.points = footprintPoints + } catch (exception: IllegalArgumentException) { + Timber.d(exception) + } + } + binding.mapView.overlays[2] = footprintOverlay + } + + private fun renderSatData(satData: SatData, binding: FragmentMapBinding) { + binding.apply { + idName.text = String.format(getString(R.string.pat_osm_idName), satData.catNum, satData.name) + qthLocator.text = String.format(getString(R.string.map_qth), satData.qthLoc) + altitude.text = String.format(getString(R.string.pat_altitude), satData.altitude) + distance.text = String.format(getString(R.string.pat_distance), satData.range) + velocity.text = String.format(getString(R.string.pat_osm_vel), satData.velocity) + mapLat.text = String.format(getString(R.string.pat_osm_lat), satData.osmPos.latitude) + mapLon.text = String.format(getString(R.string.pat_osm_lon), satData.osmPos.longitude) + } + binding.mapView.invalidate() + } + private fun getColorFilter(): ColorMatrixColorFilter { val grayScaleMatrix = ColorMatrix().apply { setSaturation(0f) } val negativeMatrix = ColorMatrix( diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt index d399c400..5ce41ff3 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/mapScreen/MapViewModel.kt @@ -18,76 +18,59 @@ package com.rtbishop.look4sat.presentation.mapScreen import android.content.SharedPreferences -import android.graphics.Color -import android.graphics.Paint import androidx.lifecycle.* +import com.rtbishop.look4sat.di.DefaultDispatcher import com.rtbishop.look4sat.domain.predict4kotlin.Position import com.rtbishop.look4sat.domain.predict4kotlin.QthConverter -import com.rtbishop.look4sat.domain.predict4kotlin.SatPos import com.rtbishop.look4sat.domain.predict4kotlin.Satellite -import com.rtbishop.look4sat.framework.model.SelectedSat +import com.rtbishop.look4sat.domain.predict4kotlin.StationPosition +import com.rtbishop.look4sat.framework.model.SatData import com.rtbishop.look4sat.interactors.GetSelectedSatellites -import com.rtbishop.look4sat.utility.* +import com.rtbishop.look4sat.utility.PrefsManager import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.* -import org.osmdroid.util.GeoPoint -import org.osmdroid.views.overlay.FolderOverlay -import org.osmdroid.views.overlay.Overlay -import org.osmdroid.views.overlay.Polygon -import org.osmdroid.views.overlay.Polyline -import timber.log.Timber import java.util.* import javax.inject.Inject +import kotlin.math.max +import kotlin.math.min +import kotlin.math.pow +import kotlin.math.sqrt @HiltViewModel class MapViewModel @Inject constructor( private val getSelectedSatellites: GetSelectedSatellites, private val prefsManager: PrefsManager, - private val qthConverter: QthConverter + private val qthConverter: QthConverter, + @DefaultDispatcher private val defaultDispatcher: CoroutineDispatcher ) : ViewModel() { - private val dateNow = Date() - private val trackPaint = Paint().apply { - strokeWidth = 2f - style = Paint.Style.STROKE - color = Color.RED - strokeCap = Paint.Cap.ROUND - strokeJoin = Paint.Join.ROUND - isAntiAlias = true - } - private val footprintPaint = Paint().apply { - style = Paint.Style.FILL_AND_STROKE - color = Color.parseColor("#26FFE082") - isAntiAlias = true - } - private val gsp = prefsManager.getStationPosition() - - private var filteredSats = listOf() + private var dataUpdateJob: Job? = null + private var allSatList = listOf() private lateinit var selectedSat: Satellite - private val _selectedSat = MutableLiveData() - fun getSelectedSat(): LiveData = _selectedSat - - private val _satMarkers = MutableLiveData>() - fun getSatMarkers(): LiveData> = _satMarkers - - val stationPosition = liveData { + val stationPos = liveData { emit(Position(gsp.latitude.toOsmLat(), gsp.longitude.toOsmLon())) } + private val _satTrack = MutableLiveData>>() + val satTrack: LiveData>> = _satTrack + + private val _satFootprint = MutableLiveData>() + val satFootprint: LiveData> = _satFootprint + + private val _satData = MutableLiveData() + val satData: LiveData = this._satData + + private val _allSatPositions = MutableLiveData>() + val allSatPositions: LiveData> = _allSatPositions + init { viewModelScope.launch { - val satellites = getSelectedSatellites() - if (satellites.isNotEmpty()) { - filteredSats = satellites - selectedSat = satellites.first() - while (true) { - ensureActive() - dateNow.time = System.currentTimeMillis() - _selectedSat.value = getDataForSelSatellite(selectedSat) - _satMarkers.value = getDataForAllSatellites(filteredSats) - delay(2000) + getSelectedSatellites().also { selectedSatellites -> + if (selectedSatellites.isNotEmpty()) { + allSatList = selectedSatellites + selectSatellite(selectedSatellites.first()) } } } @@ -102,98 +85,130 @@ class MapViewModel @Inject constructor( } fun scrollSelection(decrement: Boolean) { - if (filteredSats.isNotEmpty()) { - val index = filteredSats.indexOf(selectedSat) + if (allSatList.isNotEmpty()) { + val index = allSatList.indexOf(selectedSat) if (decrement) { - if (index > 0) selectSatellite(filteredSats[index - 1]) - else selectSatellite(filteredSats[filteredSats.size - 1]) + if (index > 0) selectSatellite(allSatList[index - 1]) + else selectSatellite(allSatList[allSatList.size - 1]) } else { - if (index < filteredSats.size - 1) selectSatellite(filteredSats[index + 1]) - else selectSatellite(filteredSats[0]) + if (index < allSatList.size - 1) selectSatellite(allSatList[index + 1]) + else selectSatellite(allSatList[0]) } } } - fun selectSatellite(satellite: Satellite) { + fun selectSatellite(satellite: Satellite, updateFreq: Long = 2000) { selectedSat = satellite - viewModelScope.launch { _selectedSat.value = getDataForSelSatellite(selectedSat) } - } - - private suspend fun getDataForSelSatellite(satellite: Satellite): SelectedSat = - withContext(Dispatchers.Default) { - val satPos = satellite.getPredictor(gsp).getSatPos(dateNow) - val osmPos = Position( - Math.toDegrees(satPos.latitude).toOsmLat(), - Math.toDegrees(satPos.longitude).toOsmLon() - ) - val qthLoc = qthConverter.positionToQTH(osmPos.latitude, osmPos.longitude) ?: "-- --" - val velocity = satPos.altitude.getOrbitalVelocity() - val footprint = getSatFootprint(satPos) - val track = getSatTrack(satellite) - return@withContext SelectedSat( - satellite, satellite.tle.catnum, satellite.tle.name, satPos.range, - satPos.altitude, velocity, qthLoc, osmPos, footprint, track - ) - } - - private suspend fun getDataForAllSatellites(satellites: List): Map = - withContext(Dispatchers.Default) { - val passesMap = mutableMapOf() - satellites.forEach { satellite -> - val satPos = satellite.getPredictor(gsp).getSatPos(dateNow) - passesMap[satellite] = Position( - Math.toDegrees(satPos.latitude).toOsmLat(), - Math.toDegrees(satPos.longitude).toOsmLon() - ) - } - return@withContext passesMap - } - - private fun getSatTrack(satellite: Satellite): Overlay { - val positions = satellite.getPredictor(gsp).getPositions(dateNow, 15, 0, 3.2) - val trackOverlay = FolderOverlay() - val trackPoints = mutableListOf() - var oldLon = 0.0 - positions.forEach { - val osmPos = Position( - Math.toDegrees(it.latitude).toOsmLat(), - Math.toDegrees(it.longitude).toOsmLon() - ) - if (oldLon < -170.0 && osmPos.longitude > 170.0 || oldLon > 170.0 && osmPos.longitude < -170.0) { - val currentPoints = mutableListOf() - currentPoints.addAll(trackPoints) - Polyline().apply { - outlinePaint.set(trackPaint) - setPoints(currentPoints) - trackOverlay.add(this) + viewModelScope.launch { + dataUpdateJob?.cancelAndJoin() + dataUpdateJob = launch { + val dateNow = Date() + setSelectedSatTrack(selectedSat, gsp, dateNow) + while (isActive) { + dateNow.time = System.currentTimeMillis() + setSatPositions(allSatList, gsp, dateNow) + setSelectedSatFootprint(selectedSat, gsp, dateNow) + setSelectedSatData(selectedSat, gsp, dateNow) + delay(updateFreq) } - trackPoints.clear() } - oldLon = osmPos.longitude - trackPoints.add(GeoPoint(osmPos.latitude, osmPos.longitude)) } - Polyline().apply { - outlinePaint.set(trackPaint) - setPoints(trackPoints) - trackOverlay.add(this) - } - return trackOverlay } - private fun getSatFootprint(satPos: SatPos): Overlay { - val points = mutableListOf() - satPos.getRangeCircle().forEach { - val osmPos = Position(it.latitude.toOsmLat(), it.longitude.toOsmLon()) - points.add(GeoPoint(osmPos.latitude, osmPos.longitude)) - } - return Polygon().apply { - fillPaint.set(footprintPaint) - outlinePaint.set(footprintPaint) - try { - this.points = points - } catch (e: IllegalArgumentException) { - Timber.d("RangeCircle: ${satPos.getRangeCircle()}, RangePoints: $points") + private suspend fun setSatPositions(list: List, gsp: StationPosition, date: Date) { + withContext(defaultDispatcher) { + val satPositions = mutableMapOf() + list.forEach { satellite -> + val satPos = satellite.getPredictor(gsp).getSatPos(date) + val osmLat = Math.toDegrees(satPos.latitude).toOsmLat() + val osmLon = Math.toDegrees(satPos.longitude).toOsmLon() + satPositions[satellite] = Position(osmLat, osmLon) } + _allSatPositions.postValue(satPositions) } } + + private suspend fun setSelectedSatTrack(sat: Satellite, gsp: StationPosition, date: Date) { + withContext(defaultDispatcher) { + val satTracks = mutableListOf>() + val currentTrack = mutableListOf() + var oldLongitude = 0.0 + sat.getPredictor(gsp).getPositions(date, 15, 0, 2.4).forEach { pos -> + val osmLat = Math.toDegrees(pos.latitude).toOsmLat() + val osmLon = Math.toDegrees(pos.longitude).toOsmLon() + val currentPosition = Position(osmLat, osmLon) + if (oldLongitude < -170.0 && currentPosition.longitude > 170.0) { + // adding left terminal position + currentTrack.add(Position(osmLat, -180.0)) + val finishedTrack = mutableListOf().apply { addAll(currentTrack) } + satTracks.add(finishedTrack) + currentTrack.clear() + } else if (oldLongitude > 170.0 && currentPosition.longitude < -170.0) { + // adding right terminal position + currentTrack.add(Position(osmLat, 180.0)) + val finishedTrack = mutableListOf().apply { addAll(currentTrack) } + satTracks.add(finishedTrack) + currentTrack.clear() + } + oldLongitude = currentPosition.longitude + currentTrack.add(currentPosition) + } + satTracks.add(currentTrack) + _satTrack.postValue(satTracks) + } + } + + private suspend fun setSelectedSatFootprint(sat: Satellite, gsp: StationPosition, date: Date) { + withContext(defaultDispatcher) { + val satFootprint = sat.getPosition(gsp, date).getRangeCircle().map { rangePos -> + Position(rangePos.latitude.toOsmLat(), rangePos.longitude.toOsmLon()) + } + _satFootprint.postValue(satFootprint) + } + } + + private suspend fun setSelectedSatData(sat: Satellite, gsp: StationPosition, date: Date) { + withContext(defaultDispatcher) { + val satPos = sat.getPredictor(gsp).getSatPos(date) + val osmLat = Math.toDegrees(satPos.latitude).toOsmLat() + val osmLon = Math.toDegrees(satPos.longitude).toOsmLon() + val osmPos = Position(osmLat, osmLon) + val qthLoc = qthConverter.positionToQTH(osmPos.latitude, osmPos.longitude) ?: "-- --" + val velocity = getOrbitalVelocity(satPos.altitude) + val satData = SatData( + sat, sat.tle.catnum, sat.tle.name, satPos.range, + satPos.altitude, velocity, qthLoc, osmPos + ) + this@MapViewModel._satData.postValue(satData) + } + } + + private fun Double.toOsmLat(): Double { + return min(max(this, -85.0), 85.0) + } + + private fun getOsmLat(latitude: Double): Double { + return min(max(latitude, -85.0), 85.0) + } + + private fun Double.toOsmLon(): Double { + val newLon = if (this < -180.0) this + 360.0 else if (this > 180.0) this - 360.0 else this + return min(max(newLon, -180.0), 180.0) + } + + private fun getOsmLon(longitude: Double): Double { + val newLongitude = when { + longitude < -180.0 -> longitude + 360.0 + longitude > 180.0 -> longitude - 360.0 + else -> longitude + } + return min(max(newLongitude, -180.0), 180.0) + } + + private fun getOrbitalVelocity(altitude: Double): Double { + val earthG = 6.674 * 10.0.pow(-11) + val earthM = 5.98 * 10.0.pow(24) + val radius = 6.37 * 10.0.pow(6) + altitude * 10.0.pow(3) + return sqrt(earthG * earthM / radius) / 1000 + } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt index b88ab8cb..acb0811c 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/passesScreen/PassesFragment.kt @@ -30,7 +30,7 @@ import com.rtbishop.look4sat.framework.model.Result import com.rtbishop.look4sat.databinding.FragmentPassesBinding import com.rtbishop.look4sat.domain.predict4kotlin.SatPass import com.rtbishop.look4sat.utility.RecyclerDivider -import com.rtbishop.look4sat.utility.formatForTimer +import com.rtbishop.look4sat.utility.toTimerString import com.rtbishop.look4sat.utility.navigateSafe import dagger.hilt.android.AndroidEntryPoint import java.util.* @@ -80,7 +80,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC } is Result.InProgress -> { binding.apply { - passesTimer.text = 0L.formatForTimer() + passesTimer.text = 0L.toTimerString() passesError.visibility = View.INVISIBLE passesRecycler.visibility = View.INVISIBLE passesProgress.visibility = View.VISIBLE @@ -88,7 +88,7 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC } is Result.Error -> { binding.apply { - passesTimer.text = 0L.formatForTimer() + passesTimer.text = 0L.toTimerString() passesProgress.visibility = View.INVISIBLE passesRecycler.visibility = View.INVISIBLE passesError.visibility = View.VISIBLE @@ -103,14 +103,14 @@ class PassesFragment : Fragment(R.layout.fragment_passes), PassesAdapter.PassesC try { val nextPass = passes.first { it.aosDate.time.minus(timeNow) > 0 } val millisBeforeStart = nextPass.aosDate.time.minus(timeNow) - binding.passesTimer.text = millisBeforeStart.formatForTimer() + binding.passesTimer.text = millisBeforeStart.toTimerString() } catch (e: NoSuchElementException) { val lastPass = passes.last() val millisBeforeEnd = lastPass.losDate.time.minus(timeNow) - binding.passesTimer.text = millisBeforeEnd.formatForTimer() + binding.passesTimer.text = millisBeforeEnd.toTimerString() } } else { - binding.passesTimer.text = 0L.formatForTimer() + binding.passesTimer.text = 0L.toTimerString() } } diff --git a/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarFragment.kt b/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarFragment.kt index e431b309..572cd338 100644 --- a/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarFragment.kt +++ b/app/src/main/java/com/rtbishop/look4sat/presentation/polarScreen/PolarFragment.kt @@ -28,7 +28,7 @@ import com.rtbishop.look4sat.R import com.rtbishop.look4sat.databinding.FragmentPolarBinding import com.rtbishop.look4sat.domain.predict4kotlin.SatPass import com.rtbishop.look4sat.utility.RecyclerDivider -import com.rtbishop.look4sat.utility.formatForTimer +import com.rtbishop.look4sat.utility.toTimerString import com.rtbishop.look4sat.utility.navigateSafe import dagger.hilt.android.AndroidEntryPoint import java.util.* @@ -113,17 +113,17 @@ class PolarFragment : Fragment(R.layout.fragment_polar) { if (!satPass.isDeepSpace) { if (dateNow.before(satPass.aosDate)) { val millisBeforeStart = satPass.aosDate.time.minus(timeNow) - binding.polarTimer.text = millisBeforeStart.formatForTimer() + binding.polarTimer.text = millisBeforeStart.toTimerString() } else { val millisBeforeEnd = satPass.losDate.time.minus(timeNow) - binding.polarTimer.text = millisBeforeEnd.formatForTimer() + binding.polarTimer.text = millisBeforeEnd.toTimerString() if (dateNow.after(satPass.losDate)) { - binding.polarTimer.text = 0L.formatForTimer() + binding.polarTimer.text = 0L.toTimerString() findNavController().navigateSafe(R.id.action_polar_to_passes) } } } else { - binding.polarTimer.text = 0L.formatForTimer() + binding.polarTimer.text = 0L.toTimerString() } } } diff --git a/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt b/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt index faea0b3e..92c4e2c2 100644 --- a/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt +++ b/app/src/main/java/com/rtbishop/look4sat/utility/Extensions.kt @@ -27,12 +27,8 @@ import androidx.navigation.NavOptions import androidx.navigation.Navigator import androidx.navigation.fragment.findNavController import java.util.concurrent.TimeUnit -import kotlin.math.max -import kotlin.math.min -import kotlin.math.pow -import kotlin.math.sqrt -fun Long.formatForTimer(): String { +fun Long.toTimerString(): String { val format = "%02d:%02d:%02d" val hours = TimeUnit.MILLISECONDS.toHours(this) val minutes = TimeUnit.MILLISECONDS.toMinutes(this) % 60 @@ -46,22 +42,6 @@ fun Double.round(decimals: Int): Double { return kotlin.math.round(this * multiplier) / multiplier } -fun Double.toOsmLat(): Double { - return min(max(this, -85.0), 85.0) -} - -fun Double.toOsmLon(): Double { - val newLon = if (this < -180.0) this + 360.0 else if (this > 180.0) this - 360.0 else this - return min(max(newLon, -180.0), 180.0) -} - -fun Double.getOrbitalVelocity(): Double { - val earthG = 6.674 * 10.0.pow(-11) - val earthM = 5.98 * 10.0.pow(24) - val radius = 6.37 * 10.0.pow(6) + this * 10.0.pow(3) - return sqrt(earthG * earthM / radius) / 1000 -} - fun NavController.navigateSafe( @IdRes resId: Int, args: Bundle? = null,